Thread View: net.lang.st80
1 messages
1 total messages
Started by Steve Messick
Tue, 29 Jul 1986 00:43
Grapher (part 2)
Author: Steve Messick
Date: Tue, 29 Jul 1986 00:43
Date: Tue, 29 Jul 1986 00:43
1239 lines
34721 bytes
34721 bytes
Grapher is a Smalltalk tool to display data structures. The
distribution consists of two parts: PART 1 contains the files README
and Grapher-2.st, PART 2 has only the file Grapher-1.st. See
the README file for further information.
------------------------------ Grapher-1.st ------------------------------
ScrollController subclass: #XAxisScrollController
instanceVariableNames: 'xScrollBar xMarker xSavedArea '
classVariableNames: ''
poolDictionaries: ''
category: 'Grapher'!
XAxisScrollController comment:
'I represent control for scrolling using an x-axis scroll bar. I am a subclass of ScrollController that creates an x-axis scroll bar. My subclasses then have x and y-axis
scroll bars. I keep control as long as the cursor is inside the view or either one of the scroll bars.
The y-axis scroll bar is a rectangular area representing the length of the information being viewed. It contains an inner rectangle whose top y-coordinate represents the relative position of the information visible on the screen with respect to all of the information, and whose size represents the relative amount of that information visible on the screen. The user controls which part of the information is visible by pressing the red button. If the cursor is to the right of the inner rectangle, the windo
w onto the visible information moves upward, if the cursor is to the left, the window moves downward, and if the cursor is inside, the inner rectangle is grabbed and moved to a desired position. The x-axis scroll bar is controlled in an analogous manner.
Instance Variables:
xScrollBar <Quadrangle> inside white, the outer rectangle
xMarker <Quadrangle> inside gray, the inner rectangle
xSavedArea <Form> the area the xScrollBar overlaps, restored whenever
the xScrollBar is hidden
'!
!XAxisScrollController methodsFor: 'initialize-release'!
initialize
super initialize.
xScrollBar _ Quadrangle new.
xScrollBar borderWidthLeft: 2 right: 2 top: 0 bottom: 2.
xMarker _ Quadrangle new.
xMarker insideColor: Form gray! !
!XAxisScrollController methodsFor: 'basic control sequence'!
controlInitialize
"The scrollbar has a two-pixel border, and for alignment it assumes that this sub-view
has a one-pixel border and shares another one-pixel border from its neighbor/super view"
super controlInitialize.
xScrollBar region: (0 @ 0 extent: (view displayBox width + 2) @ 32).
xMarker region: self computeXMarkerRegion.
xScrollBar _ xScrollBar align: xScrollBar topLeft with: view displayBox bottomLeft - (1@0).
xMarker _ xMarker align: xMarker leftCenter with: xScrollBar inside leftCenter.
xSavedArea _ Form fromDisplay: xScrollBar.
xScrollBar displayOn: Display.
self moveXMarker!
controlTerminate
super controlTerminate.
xSavedArea notNil
ifTrue:
[xSavedArea displayOn: Display at: xScrollBar topLeft.
xSavedArea_ nil]! !
!XAxisScrollController methodsFor: 'control defaults'!
controlActivity
self xScrollBarContainsCursor
ifTrue: [self xScroll]
ifFalse: [super controlActivity]!
isControlActive
^self xScrollBarContainsCursor or: [super isControlActive]! !
!XAxisScrollController methodsFor: 'scroll bar region'!
repaintUnderScrollBar
"Repaint the area under the scroll bar ."
super repaintUnderScrollBar.
self repaintUnderXScrollBar!
repaintUnderXScrollBar
"Repaint the area under the scroll bar ."
xSavedArea notNil
ifTrue:
[xSavedArea displayOn: Display at: xScrollBar topLeft.
xSavedArea_ nil]! !
!XAxisScrollController methodsFor: 'scrolling'!
canXScroll
"Answer whether there is information that is not visible and can be seen
by scrolling."
^xMarker region width < xScrollBar inside width!
scrollViewLeft
"Scroll the receiver's view left the default amount."
self xScrollView: self xScrollAmount negated!
scrollViewNoDisplay: delta
| t2 |
delta ~= 0
ifTrue:
[t2 _ (delta min: view window top - model boundingBox top)
max: view window top - model boundingBox bottom.
view scrollBy: 0 @ t2]!
scrollViewRight
"Scroll the receiver's view right the default amount."
self xScrollView: self xScrollAmount!
viewXDelta
"Answer an integer that indicates how much the view should be scrolled.
The scroll bar has been moved and now the view must be so the amount to
scroll is computed as a ratio of the current scroll bar position."
^view window left - view boundingBox left -
((xMarker left - xScrollBar inside left) asFloat /
xScrollBar inside width asFloat *
view boundingBox width asFloat) rounded!
xScroll
"Check to see whether the user wishes to jump, scroll left, or scroll right."
| savedCursor regionPercent |
savedCursor _ sensor currentCursor.
[self xScrollBarContainsCursor]
whileTrue:
[Processor yield.
regionPercent _ 100 * (xScrollBar inside bottom - sensor cursorPoint y) // xScrollBar height.
regionPercent <= 40
ifTrue: [self scrollLeft]
ifFalse: [regionPercent >= 60
ifTrue: [self scrollRight]
ifFalse: [self xScrollAbsolute]]].
savedCursor show!
xScrollAmount
"Answer the number of bits of x-coordinate should be scrolled. This is a
default determination based on the view's preset display transformation."
^((view inverseDisplayTransform: sensor cursorPoint)
- (view inverseDisplayTransform: xScrollBar inside leftCenter)) x!
xScrollView
"The scroll bar jump method was used so that the view should be updated to
correspond to the location of the scroll bar gray area."
self xScrollView: self viewXDelta!
xScrollView: anInteger
"If anInteger is not zero, tell the receiver's view to scroll by anInteger amount."
anInteger ~= 0
ifTrue:
[view scrollBy: ((anInteger min: view window left - view boundingBox left)
max: view window left - view boundingBox right) @ 0.
view clearInside.
view display]! !
!XAxisScrollController methodsFor: 'cursor'!
xMarkerContainsCursor
"Answer whether the gray area inside the scroll bar area contains the cursor."
^xMarker inside containsPoint: sensor cursorPoint!
xScrollBarContainsCursor
"Answer whether the cursor is anywhere within the scroll bar area."
^xScrollBar inside containsPoint: sensor cursorPoint! !
!XAxisScrollController methodsFor: 'marker adjustment'!
computeXMarkerRegion
"Answer the rectangular area in which the gray area of the scroll bar
should be displayed."
^0@0 extent: ((view window width asFloat /
view boundingBox width *
xScrollBar inside width)
rounded min: xScrollBar inside width) @ 10!
moveXMarker
"The view window has changed. Update the xMarker."
self moveXMarker: self xMarkerDelta negated!
moveXMarker: anInteger
"Update the xMarker so that is is translated by an amount corresponding to
a distance of anInteger, constrained within the boundaries of the scroll bar."
Display fill: xMarker mask: xScrollBar insideColor.
xMarker _ xMarker translateBy: ((anInteger min: xScrollBar inside right - xMarker right) max:
xScrollBar inside left - xMarker left) @ 0.
xMarker displayOn: Display!
xMarkerDelta
^xMarker left
- xScrollBar inside left
- ((view window left - view boundingBox left) asFloat
/ view boundingBox width asFloat *
xScrollBar inside width asFloat) rounded!
xMarkerRegion: aRectangle
"Set the area defined by aRectangle as the xMarker. Fill it with gray tone."
Display fill: xMarker mask: xScrollBar insideColor.
xMarker region: aRectangle.
xMarker _ xMarker align: xMarker leftCenter with: xScrollBar inside leftCenter! !
!XAxisScrollController methodsFor: 'private'!
scrollLeft
"This is modified from the original to provide continuous scrolling"
self changeCursor: Cursor left.
sensor anyButtonPressed
ifTrue: [self canXScroll
ifTrue:
[self scrollViewLeft.
self moveXMarker]].
sensor waitNoButton!
scrollRight
"This is modified from the original to provide continuous scrolling"
self changeCursor: Cursor right.
sensor anyButtonPressed
ifTrue: [self canXScroll
ifTrue:
[self scrollViewRight.
self moveXMarker]].
sensor waitNoButton!
xAndYScrollAbsolute
| oldMarker oldXMarker savedCursor |
(((self canXScroll) or: [self canScroll])
and: [sensor redButtonPressed]) ifTrue:
[savedCursor _ sensor currentCursor.
self changeCursor: Cursor fourWay.
[sensor redButtonPressed] whileTrue:
[oldMarker _ marker.
oldXMarker _ xMarker.
marker _ marker translateBy:
0@((sensor cursorPoint y - marker center y
min: scrollBar inside bottom - marker bottom)
max: scrollBar inside top - marker top).
xMarker _ xMarker translateBy:
((sensor cursorPoint x - xMarker center x
min: xScrollBar inside right - xMarker right)
max: xScrollBar inside left - xMarker left) @ 0.
(oldMarker areasOutside: marker),
(marker areasOutside: oldMarker),
(oldXMarker areasOutside: xMarker),
(xMarker areasOutside: oldXMarker) do:
[:region | Display fill: region rule: Form reverse mask: Form gray].
self scrollViewNoDisplay: self viewDelta.
self xScrollView.
scrollBar display.
xScrollBar display.
self moveMarker.
self moveXMarker].
savedCursor show]!
xScrollAbsolute
| oldMarker |
self changeCursor: Cursor xMarker.
self canXScroll & sensor anyButtonPressed ifTrue:
[[sensor anyButtonPressed] whileTrue:
[oldMarker _ xMarker.
xMarker _ xMarker translateBy:
((sensor cursorPoint x - xMarker center x min:
xScrollBar inside right - xMarker right) max: xScrollBar inside left - xMarker left) @ 0.
(oldMarker areasOutside: xMarker), (xMarker areasOutside: oldMarker) do:
[:region | Display fill: region rule: Form reverse mask: Form gray]].
self xScrollView.
xScrollBar display.
self moveXMarker]! !
XAxisScrollController subclass: #GraphHolderController
instanceVariableNames: 'scrollBox selection selectionMenu '
classVariableNames: 'YellowButtonMenu '
poolDictionaries: ''
category: 'Grapher'!
GraphHolderController comment:
'As a subclass of XAxisScrollController I provide X and Y axis scrolling. In addition, I provide ''smooth'' scrolling by red button dragging of the mouse. I also am capable of responding to red button clicks to select an element of the display if I have a menu to activate for selections. The menu is initialized by my selectionMenu: message which takes an ActionMenu as its argument. The message selectors included with the ActionMenu must be messages that the objects which make up the graph respond to.
My instance variables:
scrollBox <Rectangle>
My scrollBox represents the area of the display which
is visible on the screen. It is in local view coordinates.
selection <GraphNode>
If an element of the display has been selected by clicking
the mouse red button on it, it is saved here.
selectionMenu <Array of (PopUpMenu, Array of message selectors)>
The yellow button menu to be activated when a selection
has been made and the yellow button is pressed. Menu
messages are sent to the object field of the selected
GraphNode. If selectionMenu is nil the window does not
respond to red button clicks (although red button scrolling
is still available).
'!
!GraphHolderController methodsFor: 'initialize-release'!
initialize
"I use an ActionMenu rather than a PopUpMenu so no
yellowButtonMessages are needed."
yellowButtonMenu _ YellowButtonMenu.
scrollBox _ 0@0 extent: 0@0.
super initialize! !
!GraphHolderController methodsFor: 'accessing'!
scrollBox: aRectangle
"My scrollBox is a Rectangle which pans over the virtual display of
my model. My view looks through my scrollBox at the model. Normally,
my window would perform this function, but windows get scaled and
I required an unscaled scrollBox."
scrollBox _ Rectangle origin: 0@0 extent: aRectangle extent!
selection
^selection!
selectionMenu: anActionMenu
selectionMenu _ anActionMenu! !
!GraphHolderController methodsFor: 'basic control sequence'!
controlInitialize
selection == nil ifFalse: [self darkHighlightSelection].
super controlInitialize!
controlTerminate
selection == nil ifFalse: [self dimHighlightSelection].
super controlTerminate! !
!GraphHolderController methodsFor: 'control defaults'!
controlActivity
| cursorPoint xlate newSelection |
sensor redButtonPressed ifTrue:
[sensor leftShiftDown | (selectionMenu == nil)
ifTrue: [^self xAndYScrollAbsolute].
cursorPoint _ (sensor cursorPoint
translateBy: scrollBox origin
- view displayTransformation translation
- model offset) rounded.
newSelection _ model selectNodeAt: cursorPoint.
self setSelection: newSelection.
newSelection == nil
ifTrue: [self xAndYScrollAbsolute]
ifFalse: [[sensor redButtonPressed & self isControlActive]
whileTrue]].
super controlActivity!
isControlActive
^sensor blueButtonPressed not and: [super isControlActive]! !
!GraphHolderController methodsFor: 'menu messages'!
fileOutGraph
"Produce a PostScript file which will make a hardcopy version of my model."
| aStream |
Cursor write showWhile:
[aStream _ FileStream fileNamed: 'diagps.script'.
model psStoreOn: aStream.
aStream close]!
localMenuItem: aSelector
^ #( #mvcInspect #fileOutGraph ) includes: aSelector!
menuMessageReceiver
selection == nil
ifTrue: [^self]
ifFalse: [sensor leftShiftDown
ifTrue: [^selection]
ifFalse: [^selection object]]!
mvcInspect
self controlTerminate.
sensor leftShiftDown
ifTrue: [view superView inspect]
ifFalse: [view inspect]!
yellowButtonActivity
"Determine which item in the yellow button pop-up menu is selected.
If one is selected, then send the corresponding message to the object
designated as the menu message receiver."
| index selector |
yellowButtonMenu == nil
ifFalse:
[index _ yellowButtonMenu startUpYellowButton.
index ~= 0
ifTrue:
[selector _ yellowButtonMenu selectorAt: index.
(self localMenuItem: selector)
ifTrue: [self perform: selector]
ifFalse: [self controlTerminate.
selector numArgs = 1
ifTrue: [self menuMessageReceiver perform: selector with: model]
ifFalse: [self menuMessageReceiver perform: selector].
self controlInitialize]]]! !
!GraphHolderController methodsFor: 'marker adjustment'!
computeMarkerRegion
^Rectangle
origin: 0 @ 0
extent: 10 @ ((scrollBox height asFloat /
view boundingBox height asFloat *
scrollBar inside height) rounded
min: scrollBar inside height)!
computeXMarkerRegion
^Rectangle
origin: 0 @ 0
extent: ((scrollBox width asFloat /
view boundingBox width asFloat *
xScrollBar inside width) rounded
min: xScrollBar inside width) @ 10!
markerDelta
^marker top
- scrollBar inside top
- (scrollBox top - view boundingBox top asFloat
/ view boundingBox height asFloat *
scrollBar inside height asFloat) rounded!
xMarkerDelta
^xMarker left
- xScrollBar inside left
- (scrollBox left - view boundingBox left asFloat
/ view boundingBox width asFloat
* xScrollBar inside width asFloat) rounded! !
!GraphHolderController methodsFor: 'scrolling'!
scrollAmount
^(sensor cursorPoint - scrollBar inside topCenter) y!
scrollBy: amount
scrollBox _ scrollBox translateBy: amount!
scrollView: anInteger
"If anInteger is not zero, scroll by anInteger amount."
| min max amount |
max _ view boundingBox top - scrollBox top min: 0.
min _ view boundingBox bottom - scrollBox bottom max: 0.
amount _ (anInteger negated max: max) min: min.
amount ~= 0
ifTrue:
[self scrollBy: 0 @ amount.
view clearInside.
view display]!
scrollViewNoDisplay: anInteger
| min max amount |
max _ view boundingBox top - scrollBox top min: 0.
min _ view boundingBox bottom - scrollBox bottom max: 0.
amount _ (anInteger negated max: max) min: min.
amount ~= 0
ifTrue:
[self scrollBy: 0 @ amount]!
scrollViewXY: aPoint
| amount ymax ymin xmax xmin |
ymax _ view boundingBox top - scrollBox top min: 0.
ymin _ view boundingBox bottom - scrollBox bottom max: 0.
xmax _ view boundingBox left - scrollBox left min: 0.
xmin _ view boundingBox right - scrollBox right max: 0.
amount _ Point x: ((aPoint x negated max: xmax) min: xmin) rounded
y: ((aPoint y negated max: ymax) min: ymin) rounded.
amount ~= (0@0)
ifTrue:
[self scrollBy: amount.
view clearInside.
view display]!
viewDelta
"Answer an integer that indicates how much the view should be scrolled.
The scroll bar has been moved and now the view must be so the amount to
scroll is computed as a ratio of the current scroll bar position."
^scrollBox top - view boundingBox top -
((marker top - scrollBar top) asFloat
/ scrollBar height asFloat
* view boundingBox height asFloat) rounded!
viewXDelta
"Answer an integer that indicates how much the view should be scrolled.
The scroll bar has been moved and now the view must be so the amount to
scroll is computed as a ratio of the current scroll bar position."
^scrollBox left - view boundingBox left
- ((xMarker left - xScrollBar left) asFloat
/ xScrollBar width asFloat
* view boundingBox width asFloat) rounded!
xScrollAmount
^(sensor cursorPoint - scrollBar inside leftCenter) x!
xScrollView: anInteger
"If anInteger is not zero, scroll by anInteger amount."
| min max amount |
max _ view boundingBox left - scrollBox left min: 0.
min _ view boundingBox right - scrollBox right max: 0.
amount _ (anInteger negated max: max) min: min.
amount ~= 0
ifTrue:
[self scrollBy: amount @ 0.
view clearInside.
view display]! !
!GraphHolderController methodsFor: 'displaying'!
displayOn: aDisplayMedium transformation: aDisplayTransformation clippingBox: clippingBox rule: ruleInteger mask: halfTone
| location |
location _ aDisplayTransformation applyTo: scrollBox origin x negated @ scrollBox origin y negated.
model form
displayOn: aDisplayMedium
at: location
clippingBox: clippingBox
rule: ruleInteger
mask: halfTone.
selection == nil ifFalse: [self darkHighlightSelection]! !
!GraphHolderController methodsFor: 'private'!
darkHighlightSelection
| selectBox |
selectBox _ (selection boundingBox
translateBy: selection offset +
model offset +
view displayTransformation translation -
scrollBox origin) rounded.
(selection form) displayOn: Display
at: (selectBox origin)
clippingBox: (selectBox intersect: view insetDisplayBox)
rule: 12
mask: Form black!
deHighlightSelection
| selectBox |
selectBox _ (selection boundingBox
translateBy: selection offset +
model offset +
view displayTransformation translation -
scrollBox origin) rounded.
(selection form) displayOn: Display
at: (selectBox origin)
clippingBox: (selectBox intersect: view insetDisplayBox)
rule: Form over
mask: Form black!
dimHighlightSelection
| selectBox newForm |
selectBox _ (selection boundingBox
translateBy: selection offset +
model offset +
view displayTransformation translation -
scrollBox origin) rounded.
newForm _ selection form deepCopy.
newForm fill: (newForm boundingBox)
rule: Form under
mask: Form lightGray.
newForm displayOn: Display
at: (selectBox origin)
clippingBox: (selectBox intersect: view insetDisplayBox)
rule: Form over
mask: Form black!
setSelection: aGraphNode
"Set the currently selected node to aGraphNode and set
the yellowButtonMenu."
selection == nil
ifFalse: [self deHighlightSelection].
selection _ aGraphNode.
selection == nil
ifTrue: [yellowButtonMenu _ YellowButtonMenu]
ifFalse: [self darkHighlightSelection.
yellowButtonMenu _ selectionMenu]!
xAndYScrollAbsolute
| savedCursor oldMarker oldXMarker cursorPoint delta |
((self canXScroll or: [self canScroll])
and: [sensor redButtonPressed]) ifTrue:
[savedCursor _ sensor currentCursor.
self changeCursor: Cursor fourWay.
cursorPoint _ sensor cursorPoint.
[sensor redButtonPressed and: [self isControlActive]] whileTrue:
[[(sensor cursorPoint - cursorPoint) abs < (1@1)
and: [sensor redButtonPressed]] whileTrue.
delta _ cursorPoint.
delta _ (cursorPoint _ sensor cursorPoint) - delta.
self scrollViewXY: delta.
self moveMarker.
self moveXMarker].
savedCursor show]! !
"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
GraphHolderController class
instanceVariableNames: ''!
!GraphHolderController class methodsFor: 'class initialization'!
initialize
"GraphController initialize."
YellowButtonMenu _ ActionMenu
labels: 'inspect\file out' withCRs
selectors: #( #mvcInspect #fileOutGraph )! !
GraphHolderController initialize!
View subclass: #GraphHolderView
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'Grapher'!
GraphHolderView comment:
'I provide a resizable View on graphical objects, without scaling the object. To do this I maintain the standard cooridinate transformations of View, but I use only a transformation with unit scaling for display purposes.
Used as a subview of a StandardSystemView, I should be added via the addSubView:in:borderWidth: message to ensure proper rescaling during a resize operation.
'!
!GraphHolderView methodsFor: 'initialize-release'!
release
"If the #noform change protocol has been used, there is a circularity
in the Graph so release it, too."
model release.
super release! !
!GraphHolderView methodsFor: 'window access'!
defaultWindow
^model boundingBox! !
!GraphHolderView methodsFor: 'controller access'!
defaultControllerClass
^GraphHolderController! !
!GraphHolderView methodsFor: 'display box access'!
computeBoundingBox
^boundingBox _ model boundingBox! !
!GraphHolderView methodsFor: 'displaying'!
display
self isUnlocked ifTrue:
[boundingBox _ nil.
viewport _ nil.
self controller scrollBox: self insetDisplayBox].
super display!
displayView
"We always want to see the Graph at unit scale."
controller
displayOn: Display
transformation: self displayTransformation copy scaleOfOne
clippingBox: self insetDisplayBox
rule: Form over
mask: Form black! !
!GraphHolderView methodsFor: 'updating'!
update: how
"Graph's change protocol includes #form and #noform. #form indicates
that the view is actually displaying a Form and does not need to clear
its inside during scrolling. #noform indicates that the Graph is being
redisplayed each time the View scrolls, and the View must clear its
inside before redisplaying the Graph. The boundingBox is always reset
because the size of the Graph changed."
how == #form ifTrue:
[boundingBox _ nil.
self insideColor: nil.
^self].
how == #noform ifTrue:
[boundingBox _ nil.
self insideColor: Form white.
^self]! !
!GraphHolderView methodsFor: 'model access'!
erase
"I replace the current model with a model constructed of the EmptyGraph."
model isEmpty
ifFalse: [ self replaceModel: (GraphHolder createEmpty)]!
replaceModel: newModel
"I replace the model in the view with a new model."
self model: newModel.
self update: #noform.
self clearInside.
self display! !
"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
GraphHolderView class
instanceVariableNames: ''!
!GraphHolderView class methodsFor: 'instance creation'!
openOn: roots label: labelString
"Create a Graph viewing the DAG rooted in roots. Label the
GraphView with labelString. The default lay out is horizontal.
See the comment in GraphView class.open:label:menu:"
self openOn: roots label: labelString format: #( #horizontal )!
openOn: roots label: labelString format: formatSymbols
"By default, Graph windows do not respond to mouse clicks
(except for the yellow button menu)."
self openOn: roots label: labelString format: formatSymbols menu: nil!
openOn: roots label: labelString format: formatSymbols menu: anActionMenu
"The default messages used to build a graph are #children and
#graphLabel. #children returns a Colleciton of child nodes.
#graphLabel returns a Text to be used as the label in the GraphView."
self openOn: roots
label: labelString
format: formatSymbols
menu: anActionMenu
childrenMsg: #children
labelMsg: #graphLabel!
openOn: roots label: labelString format: formatSymbols menu: actionMenu childrenMsg: childrenMsg labelMsg: labelMsg
self open: (self createModel: roots
children: childrenMsg
label: labelMsg
format: formatSymbols)
label: labelString
menu: actionMenu! !
!GraphHolderView class methodsFor: 'private'!
createModel: roots children: childrenMsg label: labelMsg format: formatSymbols
| aGraph |
aGraph _ GraphHolder createForestWithRoots: roots
children: childrenMsg
label: labelMsg.
aGraph layout: formatSymbols.
^aGraph!
open: aGraph label: labelString menu: anActionMenu
"Open a scrollable, resizeable view displaying the data structure
in aGraph. To make the elements sensitive to mouse clicks anActionMenu
non nil. The message selected from the menu will be sent to the selected
element. If anActionMenu is nil mouse clicks are ignored."
| formView topView |
formView _ self new model: aGraph.
formView controller selectionMenu: anActionMenu.
topView _ StandardSystemView new label: labelString.
topView borderWidth: 1.
topView insideColor: Form white.
"formView is added as follows to ensure proper scaling of
the view when the topView is resized (via 'frame')."
topView addSubView: formView in: (0@0 extent: 1@1) borderWidth: 1.
topView controller open! !
#('FourWay' 'LeftCursor' 'RightCursor' 'XMarkerCursor') do:
[ :var | Cursor addClassVarName: var].!
!Cursor class methodsFor: 'constants'!
fourWay
"Answer the instance of me that is the shape of four connected arrows."
^FourWay! !
!Cursor class methodsFor: 'constants'!
left
"Answer the instance of me that is the shape of an arrow facing to the left."
^LeftCursor! !
!Cursor class methodsFor: 'constants'!
right
"Answer the instance of me that is the shape of an arrow facing to the right."
^RightCursor! !
!Cursor class methodsFor: 'constants'!
xMarker
"Answer the instance of me that is displayed when thumb-scrolling on the x-axis."
^XMarkerCursor! !
!Cursor class methodsFor: 'class initialization'!
initialize
"Create all the standard cursors
Cursor blank
Cursor corner
Cursor crossHair
Cursor down
Cursor execute
Cursor fourWay
Cursor left
Cursor marker
Cursor normal
Cursor origin
Cursor read
Cursor right
Cursor square
Cursor up
Cursor wait
Cursor write
Cursor xMarker"
OriginCursor _
(Cursor
extent: 16@16
fromArray: #(
2r1111111111111111
2r1111111111111111
2r1100000000000000
2r1100000000000000
2r1100000000000000
2r1100000000000000
2r1100000000000000
2r1100000000000000
2r1100000000000000
2r1100000000000000
2r1100000000000000
2r1100000000000000
2r1100000000000000
2r1100000000000000
2r1100000000000000
2r1100000000000000)
offset: -2@-2).
CornerCursor _
(Cursor
extent: 16@16
fromArray: #(
2r0000000000000011
2r0000000000000011
2r0000000000000011
2r0000000000000011
2r0000000000000011
2r0000000000000011
2r0000000000000011
2r0000000000000011
2r0000000000000011
2r0000000000000011
2r0000000000000011
2r0000000000000011
2r0000000000000011
2r0000000000000011
2r1111111111111111
2r1111111111111111)
offset: -14@-14).
ReadCursor _
(Cursor
extent: 16@16
fromArray: #(
2r0000110000000110
2r0001001000001001
2r0001001000001001
2r0010000000010000
2r0100000000100000
2r1111101111100000
2r1000010000100000
2r1000010000100000
2r1011010110100000
2r0111101111000000
2r0
2r0
2r0
2r0
2r0
2r0)
offset: 0@0).
WriteCursor _ (Cursor
extent: 16@16
fromArray: #(
2r0000000000000110
2r0000000000001111
2r0000000000010110
2r0000000000100100
2r0000000001001000
2r0000000010010000
2r0000000100100000
2r0000001001000011
2r0000010010000010
2r0000100100000110
2r0001001000001000
2r0010010000001000
2r0111100001001000
2r0101000010111000
2r0110000110000000
2r1111111100000000)
offset: 0@0).
WaitCursor _
(Cursor
extent: 16@16
fromArray: #(
2r1111111111111111
2r1000000000000001
2r0100000000000010
2r0010000000000100
2r0001110000111000
2r0000111101110000
2r0000011011100000
2r0000001111000000
2r0000001111000000
2r0000010110100000
2r0000100010010000
2r0001000110001000
2r0010001101000100
2r0100111111110010
2r1011111111111101
2r1111111111111111)
offset: 0@0).
BlankCursor _ Cursor new.
XeqCursor _
(Cursor
extent: 16@16
fromArray: #(
2r1000000000010000
2r1100000000010000
2r1110000000111000
2r1111000111111111
2r1111100011000110
2r1111110001000100
2r1111111001111100
2r1111000001101100
2r1101100011000110
2r1001100010000010
2r0000110000000000
2r0000110000000000
2r0000011000000000
2r0000011000000000
2r0000001100000000
2r0000001100000000)
offset: 0@0).
SquareCursor _
(Cursor
extent: 16@16
fromArray: #(
2r0
2r0
2r0
2r0
2r0
2r0000001111000000
2r0000001111000000
2r0000001111000000
2r0000001111000000
2r0
2r0
2r0
2r0
2r0
2r0
2r0)
offset: -8@-8).
NormalCursor _
(Cursor
extent: 16@16
fromArray: #(
2r1000000000000000
2r1100000000000000
2r1110000000000000
2r1111000000000000
2r1111100000000000
2r1111110000000000
2r1111111000000000
2r1111100000000000
2r1111100000000000
2r1001100000000000
2r0000110000000000
2r0000110000000000
2r0000011000000000
2r0000011000000000
2r0000001100000000
2r0000001100000000)
offset: 0@0).
CrossHairCursor _
(Cursor
extent: 16@16
fromArray: #(
2r0000000100000000
2r0000000100000000
2r0000000100000000
2r0000000100000000
2r0000000100000000
2r0000000100000000
2r0000000100000000
2r1111111111111110
2r0000000100000000
2r0000000100000000
2r0000000100000000
2r0000000100000000
2r0000000100000000
2r0000000100000000
2r0000000100000000
2r0)
offset: -7@-7).
MarkerCursor _
Cursor
extent: 16@16
fromArray: #(
2r0
2r0
2r0
2r0000001000000000
2r0000001110000000
2r0000001111100000
2r1111111111111000
2r1111111111111110
2r1111111111111000
2r0000001111100000
2r0000001110000000
2r0000001000000000
2r0
2r0
2r0
2r0)
offset: -7@-7.
UpCursor _
Cursor
extent: 16@16
fromArray: #(
2r1000000000000000
2r1100000000000000
2r1110000000000000
2r1111000000000000
2r1111100000000000
2r1111110000000000
2r1100000000000000
2r1100000000000000
2r1100000000000000
2r1100000000000000
2r1100000000000000
2r1100000000000000
2r1100000000000000
2r1100000000000000
2r1100000000000000
2r1100000000000000)
offset: 0@-7.
DownCursor _
Cursor
extent: 16@16
fromArray: #(
2r0000110000000000
2r0000110000000000
2r0000110000000000
2r0000110000000000
2r0000110000000000
2r0000110000000000
2r0000110000000000
2r0000110000000000
2r0000110000000000
2r0000110000000000
2r1111110000000000
2r0111110000000000
2r0011110000000000
2r0001110000000000
2r0000110000000000
2r0000010000000000)
offset: -5@-7.
LeftCursor _
Cursor
extent: 16@16
fromArray: #(
2r1111111111111111
2r0111111111111111
2r0011110000000000
2r0001110000000000
2r0000110000000000
2r0000010000000000
2r0000000000000000
2r0000000000000000
2r0000000000000000
2r0000000000000000
2r0000000000000000
2r0000000000000000
2r0000000000000000
2r0000000000000000
2r0000000000000000
2r0000000000000000)
offset: -7@0.
RightCursor _
Cursor
extent: 16@16
fromArray: #(
2r0000000000100000
2r0000000000110000
2r0000000000111000
2r0000000000111100
2r1111111111111110
2r1111111111111111
2r0000000000000000
2r0000000000000000
2r0000000000000000
2r0000000000000000
2r0000000000000000
2r0000000000000000
2r0000000000000000
2r0000000000000000
2r0000000000000000
2r0000000000000000)
offset: -7@-5.
XMarkerCursor _
Cursor
extent: 16@16
fromArray: #(
2r0
2r0000000100000000
2r0000000100000000
2r0000001110000000
2r0000001110000000
2r0000011111000000
2r0000011111000000
2r0000111111100000
2r0000111111100000
2r0001111111110000
2r0000001110000000
2r0000001110000000
2r0000001110000000
2r0000001110000000
2r0000001110000000
2r0000001110000000)
offset: -7@-7.
FourWay _
Cursor
extent: 16@16
fromArray: #(
2r0000000100000000
2r0000001110000000
2r0000011111000000
2r0000111111100000
2r0001001110010000
2r0011001110011000
2r0111111111111100
2r1111111111111110
2r0111111111111100
2r0011001110011000
2r0001001110010000
2r0000111111100000
2r0000011111000000
2r0000001110000000
2r0000000100000000
2r0000000000000000)
offset: -7@-7.
"Cursor initialize"! !
Cursor initialize.!
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads