{ import: Object } { import: John } " This is an example of a GUI object using the JOHN Planner to handle its constraints " Point : ObjectPlus (x y) Line : ObjectPlus (p1 p2) Pencil : Point (canvas size scale scaleX scaleY) " intializes classes, making a collection to keep track of instanciated objects of each type: " [ Point inits ] [ Line inits ] [ Pencil inits ] Point x: aX y: aY [ x := aX. y := aY ] Point x: aX [ x := aX ] Point y: aY [ y := aY ] Point x [ ^x ] Point y [ ^y ] Point move: dir by: delta [ dir == #x ifTrue: [ John forObj: self assign: #x value: ( x + delta ) ] ifFalse: [ John forObj self assign: #y value: ( y + delta ) ] ] Line p1: aP1 p2: aP2 [ aP1 x < aP2 x ifTrue: [ p1 := aP1. p2 := aP2 ] ifFalse: [ p2 := aP1. p1 := aP2 ] ] Line p1 [ ^p1 ] Line p2 [ ^p2 ] Line slope [ | dx dy | dy := p2 y - p1 y. dx := p2 x - p1 x. ^( dx == 0 ifTrue: [ false ] ifFalse: [ dy / dx ] ) ] Line c1_constraint: aPoint [ John forObj: p1 assign: #x value: (aPoint x - 10) ] Line c2_constraint: aPoint [ John forObj: p1 assign: #y value: (aPoint y + 40) ] Line c3_constraint: aPoint [ John forObj: p2 assign: #x value: (aPoint x + 50) ] Line c4_constraint: aPoint [ John forObj: p2 assign: #y value: (aPoint y - 20) ] Pencil size: aSize scale: aScale x: aX y: aY [ scale := aScale. scaleX := aScale. scaleY := aScale * 2. size := aSize / scale + 1. canvas := Array new: size. 0 to: ( size - 1 ) do: [:r | canvas at: r put: ( Array new: size ) ]. self x: aX y: aY ] Pencil atX: aX atY: aY put: p [ ( canvas at: ( aY / scale ) ) at: ( aX / scale ) put: p ] Pencil drawPoint: p [ | r c | self atX: ( p x ) atY: ( p y ) put: p ] Pencil drawLine: l [ | minDelta numMidPts incrX incrY curX curY a b | a := l p1. b := l p2. minDelta := ( b x - a x ) min: ( a y - b y ). numMidPts := minDelta / scale. curX := a x. curY := a y. incrX := ( b x - a x ) / minDelta * scale. incrY := ( a y - b y ) / minDelta * scale. 0 to: numMidPts do: [:s | self atX: curX atY: curY put: ( ( s == 0 ) ifTrue: [ a ] ifFalse: [ ( s == numMidPts ) ifTrue: [ b ] ifFalse: [ 'x' ] ] ). curX := curX + incrX. curY := curY - incrY ]. ] Pencil draw [ 0 to: ( size - 1 ) do: [:r | canvas at: r put: ( Array new: size ) ]. ( Line instances ) do: [:l | self drawLine: l ]. ( Point instances ) do: [:p | self drawPoint: p ]. 0 to: ( size - 1 ) do: [:r | 0 to: ( size - 1 ) do: [:c | ( ( canvas at: ( size - 1 - r ) ) at: c ) symbol put. ' ' put ]. '' putln ]. '' putln ] UndefinedObject symbol [ ^'.' ] Point symbol [ ^name asString ] String symbol [ ^self ] " Main Program " [ | Pen A B C AB | Pen := Pencil new: #Pen type: Pencil. Pen size: 100 scale: 10 x: 0 y: 100. A := Point new: #A type: Point. A x: 20 y: 80. B := Point new: #B type: Point. B x: 80 y: 20. C := Point new: #C type: Point. C x: 30 y: 40. AB := Line new: #AB type: Line. AB p1: A p2: B. " Line c1_constraint: aPoint [ John forObj: p1 assign: #x value: (aPoint x - 10) ] Line c2_constraint: aPoint [ John forObj: p1 assign: #y value: (aPoint y + 40) ] Line c3_constraint: aPoint [ John forObj: p2 assign: #x value: (aPoint x + 50) ] Line c4_constraint: aPoint [ John forObj: p2 assign: #y value: (aPoint y - 20) ] " AB addConstraint: #c1 selfOnly: false dependency: (Array with: (Array with: C with: #x)). AB addConstraint: #c2 selfOnly: false dependency: (Array with: (Array with: C with: #y)). AB addConstraint: #c3 selfOnly: false dependency: (Array with: (Array with: C with: #x)). AB addConstraint: #c4 selfOnly: false dependency: (Array with: (Array with: C with: #y)). Pen draw. C move: #x by: 10. Pen draw. ] " Sample Output: "