home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
BURKS 2
/
BURKS_AUG97.ISO
/
BURKS
/
LANGUAGE
/
SMALTALK
/
TEXTBOOK
/
AP17.ST
(
.txt
)
< prev
next >
Wrap
Text File
|
1997-04-22
|
23KB
|
780 lines
'Smalltalk Textbook Appendix 17'!
EngiDisplayModel subclass: #EngiFreehandModel
instanceVariableNames: 'polylines changed element trace '
classVariableNames: 'FileMenu FreehandMenu '
poolDictionaries: ''
category: 'Engi-Figure'!
EngiFreehandModel comment:
'
Engi 0.05 (3 March 1994)
Copyright (C) 1994 by Atsushi Aoki
'!
!EngiFreehandModel methodsFor: 'initialize-release'!
initialize
self value: OrderedCollection new.
self fresh.
self windowLabel: 'Freehand'.
changed := false.
trace := false! !
!EngiFreehandModel methodsFor: 'accessing'!
element
^element!
element: freehandElement
element := freehandElement.
element notNil ifTrue: [self polylines: freehandElement polylines].
changed := false!
polylines
^polylines!
polylines: collectionOfPolylines
polylines := collectionOfPolylines asOrderedCollection.
self flushBounds.
changed := true!
trace
^trace = true!
trace: aBoolean
trace := aBoolean = true! !
!EngiFreehandModel methodsFor: 'bounds accessing'!
computeBounds
| bounds |
bounds := nil.
self element isNil
ifTrue: [(self polylines isNil or: [self polylines isEmpty])
ifTrue: [bounds := Point zero extent: Point zero]
ifFalse: [self polylines do: [:polyline | polyline do: [:point | bounds isNil
ifTrue: [bounds := point extent: Point zero]
ifFalse: [bounds := bounds merge: (point extent: Point zero)]]]]]
ifFalse: [bounds := self element bounds].
bounds := bounds expandedBy: self expandedRectangle.
bounds := bounds merge: (Point zero corner: Point zero).
displayOrigin := Point zero - bounds origin.
^Point zero extent: bounds extent!
expandedRectangle
| expandWidth |
(self polylines isNil or: [self polylines isEmpty])
ifTrue: [^Point zero corner: Point zero].
expandWidth := self defaultLineWidth + 1 // 2.
^expandWidth @ expandWidth corner: expandWidth @ expandWidth! !
!EngiFreehandModel methodsFor: 'displaying'!
displayAxesOn: graphicsContext at: aPoint!
displayValueOn: graphicsContext at: aPoint
displayOrigin isNil ifTrue: [self bounds].
self element isNil
ifTrue:
[graphicsContext capStyle: GraphicsContext capRound.
graphicsContext joinStyle: GraphicsContext joinRound.
graphicsContext lineWidth: self defaultLineWidth.
self polylines do: [:each | graphicsContext displayPolyline: each at: aPoint + displayOrigin]]
ifFalse: [self element displayOn: graphicsContext at: aPoint]! !
!EngiFreehandModel methodsFor: 'viewing'!
open
| displayView edgeDecorator topView freshButton analyzeButton registerButton recognizeButton |
displayView := self defaultViewClass model: self.
edgeDecorator := LookPreferences edgeDecorator on: displayView.
edgeDecorator noMenuBar.
edgeDecorator useVerticalScrollBar.
edgeDecorator useHorizontalScrollBar.
freshButton := Button trigger model: ((PluggableAdaptor on: self)
getBlock: [:m | false]
putBlock: [:m :v | m fresh: displayView controller]
updateBlock: [:m :a :p | false]).
freshButton label: 'fresh'.
analyzeButton := Button trigger model: ((PluggableAdaptor on: self)
getBlock: [:m | false]
putBlock: [:m :v | m analyze: displayView controller]
updateBlock: [:m :a :p | false]).
analyzeButton label: 'analyze'.
registerButton := Button trigger model: ((PluggableAdaptor on: self)
getBlock: [:m | false]
putBlock: [:m :v | m register: displayView controller]
updateBlock: [:m :a :p | false]).
registerButton label: 'register'.
recognizeButton := Button trigger model: ((PluggableAdaptor on: self)
getBlock: [:m | false]
putBlock: [:m :v | m recognize: displayView controller]
updateBlock: [:m :a :p | false]).
recognizeButton label: 'recognize'.
topView := EngiTopView
model: nil
label: self windowLabel
minimumSize: 300 @ 320.
topView add: freshButton in: (topView frameFraction: (0 @ 0 corner: 0.25 @ 0)
offset: (0 @ 0 corner: 0 @ 20)).
topView add: analyzeButton in: (topView frameFraction: (0.25 @ 0 corner: 0.5 @ 0)
offset: (0 @ 0 corner: 0 @ 20)).
topView add: registerButton in: (topView frameFraction: (0.5 @ 0 corner: 0.75 @ 0)
offset: (0 @ 0 corner: 0 @ 20)).
topView add: recognizeButton in: (topView frameFraction: (0.75 @ 0 corner: 1 @ 0)
offset: (0 @ 0 corner: 0 @ 20)).
topView add: edgeDecorator in: (topView frameFraction: (0 @ 0 corner: 1 @ 1)
offset: (0 @ 20 corner: 0 @ 0)).
topView open! !
!EngiFreehandModel methodsFor: 'controlling'!
redButtonActivity: aController
| aSensor graphicsContext pointCollection previousPoint currentPoint |
aSensor := aController sensor.
graphicsContext := aController view graphicsContext.
graphicsContext capStyle: GraphicsContext capRound.
graphicsContext joinStyle: GraphicsContext joinRound.
graphicsContext lineWidth: self defaultLineWidth.
pointCollection := OrderedCollection new.
currentPoint := previousPoint := aSensor cursorPoint.
pointCollection add: currentPoint.
[aSensor redButtonPressed]
whileTrue:
[aController poll.
currentPoint := aSensor cursorPoint.
currentPoint = previousPoint
ifFalse:
[graphicsContext displayLineFrom: previousPoint to: currentPoint.
pointCollection add: currentPoint.
previousPoint := currentPoint]].
pointCollection size > 1
ifTrue:
[self polylines isNil ifTrue: [self fresh].
self polylines add: pointCollection asArray.
changed := true]!
yellowButtonActivity: aController
| aMenu aSymbol |
aMenu := self yellowButtonMenu.
aMenu isNil ifTrue: [^nil].
aSymbol := aMenu startUp.
aSymbol = 0
ifFalse:
[aSymbol numArgs = 0 ifTrue: [self perform: aSymbol].
aSymbol numArgs = 1 ifTrue: [self perform: aSymbol with: aController]]! !
!EngiFreehandModel methodsFor: 'menu messages'!
analyze: aController
| freehandElement |
self polylines isEmpty ifTrue: [^nil].
changed = true
ifTrue:
[freehandElement := EngiFreehandElement new.
freehandElement polylines: self polylines.
self element: freehandElement.
self changed: #value].
changed := false!
debug: aController
| bool |
bool := self confirm: 'Do you want to trace?' default: self trace.
self trace: bool!
fileMenu
"EngiFreehandModel flushMenus."
FileMenu isNil
ifTrue:
[| collection |
collection := OrderedCollection new.
collection add: 'new' -> #new:.
collection add: 'open' -> #open:.
collection add: nil.
collection add: 'save' -> #save:.
FileMenu := EngiMenuMaker fromCollection: collection].
^FileMenu!
fresh: aController
self fresh.
self changed: #value!
new: aController
self class new open!
open: aController
| fileName fileStream binaryObjectStorage readBlockClosure className freehandModel |
fileName := self request: 'file name?' default: String new.
(fileName isNil or: [fileName isEmpty])
ifTrue: [^nil].
(self class errorSignal
handle:
[:exception |
Transcript cr; show: 'file not found'.
exception returnWith: nil]
do: [fileStream := fileName asFilename readStream]) isNil ifTrue: [^nil].
(self class errorSignal
handle:
[:exception |
Transcript cr; show: 'can not read boss'.
exception returnWith: nil]
do: [binaryObjectStorage := BinaryObjectStorage onOldNoScan: fileStream]) isNil ifTrue: [^nil].
readBlockClosure :=
[className := binaryObjectStorage next.
className = self class name ifTrue: [freehandModel := binaryObjectStorage next]].
Cursor read showWhile: [[readBlockClosure value]
valueNowOrOnUnwindDo: [binaryObjectStorage close]].
className = self class name ifFalse: [^nil].
freehandModel open.
^freehandModel!
recognize: aController
| result index |
self polylines isEmpty ifTrue: [^nil].
self analyze: aController.
result := self recognize0: self element with: self value.
result isEmpty
ifTrue:
[(PopUpMenu labelArray: #('can not recognize' )) startUp.
^nil].
index := (PopUpMenu labelArray: (result collect: [:item | item value])) startUp.
index > 0 ifTrue: [(result at: index) open]!
register: aController
| figure shape opaque answer message |
self polylines isEmpty ifTrue: [^nil].
self analyze: aController.
figure := self element image.
shape := figure copy.
shape palette: CoveragePalette monoMaskPalette.
opaq