home *** CD-ROM | disk | FTP | other *** search
/ BURKS 2 / BURKS_AUG97.ISO / BURKS / LANGUAGE / SMALTALK / TEXTBOOK / AP04.ST (.txt) < prev    next >
Text File  |  1997-04-22  |  8KB  |  314 lines

  1.  
  2. 'Smalltalk Textbook Appendix 04'!
  3.  
  4.  
  5.  
  6.  
  7.  
  8. EngiVariable subclass: #EngiDisplayModel
  9.     instanceVariableNames: 'displayBounds displayOrigin windowLabel '
  10.     classVariableNames: ''
  11.     poolDictionaries: ''
  12.     category: 'Engi-Interface'!
  13. EngiDisplayModel comment:
  14. '
  15.  
  16. Engi 0.01 (10 January 1994)
  17. Copyright (C) 1994 by Atsushi Aoki
  18.  
  19. '!
  20.  
  21.  
  22. !EngiDisplayModel methodsFor: 'accessing'!
  23.  
  24. value: anObject 
  25.     self setValue: anObject.
  26.     self flushBounds.
  27.     self changed: #value! !
  28.  
  29. !EngiDisplayModel methodsFor: 'point accessing'!
  30.  
  31. convertToMyPoint: aPoint 
  32.     ^aPoint - displayOrigin! !
  33.  
  34. !EngiDisplayModel methodsFor: 'bounds accessing'!
  35.  
  36. bounds
  37.     displayBounds isNil ifTrue: [displayBounds := self computeBounds].
  38.     ^displayBounds!
  39.  
  40. computeBounds
  41.     | bounds |
  42.     self canBeDisplayed
  43.         ifTrue: [bounds := self value bounds]
  44.         ifFalse: [bounds := self convertComposedText bounds].
  45.     (bounds origin x > 0 and: [bounds origin y > 0])
  46.         ifTrue: 
  47.             [bounds := (Point zero corner: bounds corner)
  48.                         expandedBy: self expandedRectangle.
  49.             displayOrigin := Point zero - bounds origin.
  50.             ^Point zero extent: bounds extent].
  51.     (bounds origin x > 0 and: [bounds corner y < 0])
  52.         ifTrue: 
  53.             [bounds := ((bounds topRight extent: Point zero)
  54.                         merge: (Point zero extent: Point zero))
  55.                         expandedBy: self expandedRectangle.
  56.             displayOrigin := Point zero - bounds origin.
  57.             ^Point zero extent: bounds extent].
  58.     (bounds origin x < 0 and: [bounds corner y > 0])
  59.         ifTrue: 
  60.             [bounds := ((bounds bottomLeft extent: Point zero)
  61.                         merge: (Point zero extent: Point zero))
  62.                         expandedBy: self expandedRectangle.
  63.             displayOrigin := Point zero - bounds origin.
  64.             ^Point zero extent: bounds extent].
  65.     (bounds corner x < 0 and: [bounds corner y < 0])
  66.         ifTrue: 
  67.             [bounds := (bounds origin corner: Point zero)
  68.                         expandedBy: self expandedRectangle.
  69.             displayOrigin := Point zero - bounds origin.
  70.             ^Point zero extent: bounds extent].
  71.     bounds := bounds expandedBy: self expandedRectangle.
  72.     displayOrigin := Point zero - bounds origin.
  73.     ^Point zero extent: bounds extent!
  74.  
  75. expandedRectangle
  76.     ^0 @ 0 corner: 0 @ 0!
  77.  
  78. flushBounds
  79.     displayBounds := nil.
  80.     (self value notNil and: [self value respondsTo: #flushBounds])
  81.         ifTrue: [self value flushBounds]! !
  82.  
  83. !EngiDisplayModel methodsFor: 'label accessing'!
  84.  
  85. windowLabel
  86.     windowLabel isNil ifTrue: [windowLabel := self defaultWindowLabel].
  87.     ^windowLabel!
  88.  
  89. windowLabel: aStringOrNil 
  90.     | topWindow |
  91.     windowLabel := aStringOrNil.
  92.     self dependedViews do: [:view | (view respondsTo: #topComponent)
  93.             ifTrue: 
  94.                 [topWindow := view topComponent.
  95.                 (topWindow isKindOf: ScheduledWindow)
  96.                     ifTrue: [topWindow label: windowLabel]]]! !
  97.  
  98. !EngiDisplayModel methodsFor: 'displaying'!
  99.  
  100. displayAxesOn: graphicsContext at: aPoint 
  101.     | bounds displayContext |
  102.     bounds := self bounds.
  103.     displayContext := graphicsContext copy.
  104.     displayContext paint: ColorValue veryLightGray.
  105.     displayContext displayLineFrom: displayOrigin x @ 0 to: displayOrigin x @ bounds bottom.
  106.     displayContext displayLineFrom: 0 @ displayOrigin y to: bounds right @ displayOrigin y!
  107.  
  108. displayOn: graphicsContext 
  109.     self displayOn: graphicsContext at: Point zero!
  110.  
  111. displayOn: graphicsContext at: aPoint 
  112.     self displayAxesOn: graphicsContext at: aPoint.
  113.     self displayValueOn: graphicsContext at: aPoint!
  114.  
  115. displayValueOn: graphicsContext at: aPoint 
  116.     self canBeDisplayed
  117.         ifTrue: [self value displayOn: graphicsContext at: aPoint + displayOrigin]
  118.         ifFalse: [self convertComposedText displayOn: graphicsContext at: aPoint + displayOrigin]! !
  119.  
  120. !EngiDisplayModel methodsFor: 'viewing'!
  121.  
  122. open
  123.     | displayView edgeDecorator topView |
  124.     displayView := self defaultViewClass model: self.
  125.     edgeDecorator := LookPreferences edgeDecorator on: displayView.
  126.     edgeDecorator noMenuBar.
  127.     edgeDecorator useVerticalScrollBar.
  128.     edgeDecorator useHorizontalScrollBar.
  129.     topView := EngiTopView
  130.                 model: nil
  131.                 label: self windowLabel
  132.                 minimumSize: 100 @ 100.
  133.     topView add: edgeDecorator in: (topView frameFraction: (0 @ 0 corner: 1 @ 1)).
  134.     topView open! !
  135.  
  136. !EngiDisplayModel methodsFor: 'controlling'!
  137.  
  138. redButtonActivity: aController 
  139.     | aPoint |
  140.     aPoint := self convertToMyPoint: aController sensor cursorPoint.
  141.     Transcript cr; show: aPoint printString!
  142.  
  143. yellowButtonActivity: aController 
  144.     | aMenu aResult |
  145.     aMenu := EngiMenuMaker fromCollection: (Array with: 'inspect' -> [self value inspect]).
  146.     aResult := aMenu startUp.
  147.     aResult = 0 ifFalse: [aResult value]! !
  148.  
  149. !EngiDisplayModel methodsFor: 'updating'!
  150.  
  151. dependedViews
  152.     ^self dependents select: [:view | view isKindOf: self defaultViewClass]!
  153.  
  154. dependentsDo: aBlock 
  155.     self dependedViews do: [:view | aBlock value: view]! !
  156.  
  157. !EngiDisplayModel methodsFor: 'defaults'!
  158.  
  159. defaultViewClass
  160.     ^EngiDisplayView!
  161.  
  162. defaultWindowLabel
  163.     ^'Display'! !
  164.  
  165. !EngiDisplayModel methodsFor: 'private'!
  166.  
  167. canBeDisplayed
  168.     ^((self value respondsTo: #displayOn:)
  169.         and: [self value respondsTo: #displayOn:at:])
  170.         and: [self value respondsTo: #bounds]!
  171.  
  172. convertComposedText
  173.     | aComposedText maxCompositionWidth compositionWidth |
  174.     aComposedText := self value printString asComposedText.
  175.     maxCompositionWidth := (Screen default bounds width / 2) asInteger.
  176.     compositionWidth := (aComposedText bounds width / 2) asInteger.
  177.     compositionWidth > maxCompositionWidth ifTrue: [aComposedText := ComposedText
  178.                     withText: self value printString
  179.                     style: TextAttributes default
  180.                     compositionWidth: maxCompositionWidth].
  181.     ^aComposedText! !
  182. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  183.  
  184. EngiDisplayModel class
  185.     instanceVariableNames: ''!
  186.  
  187.  
  188. !EngiDisplayModel class methodsFor: 'instance creation'!
  189.  
  190. on: anObject 
  191.     ^super new value: anObject! !
  192.  
  193. !EngiDisplayModel class methodsFor: 'view creation'!
  194.  
  195. openOn: anObject 
  196.     ^self openOn: anObject label: nil!
  197.  
  198. openOn: anObject label: labelString 
  199.     | displayModel |
  200.     displayModel := self on: anObject.
  201.     displayModel windowLabel: labelString.
  202.     displayModel open.
  203.     ^displayModel! !
  204.  
  205. !EngiDisplayModel class methodsFor: 'examples'!
  206.  
  207. example1
  208.     "EngiDisplayModel example1."
  209.     "EngiDisplayModel openOn: Image fromUser label: 'Image'."
  210.  
  211.     | displayObject displayModel |
  212.     displayObject := Image fromUser.
  213.     displayModel := EngiDisplayModel on: displayObject.
  214.     displayModel windowLabel: 'Image'.
  215.     displayModel open.
  216.     ^displayModel!
  217.  
  218. example2
  219.     "EngiDisplayModel example2."
  220.     "EngiDisplayModel openOn: Time now label: 'Time'."
  221.  
  222.     | displayObject displayModel |
  223.     displayObject := Time now.
  224.     displayModel := EngiDisplayModel on: displayObject.
  225.     displayModel windowLabel: 'Time'.
  226.     displayModel open.
  227.     ^displayModel! !
  228.  
  229.  
  230.  
  231.  
  232.  
  233. AutoScrollingView subclass: #EngiDisplayView
  234.     instanceVariableNames: ''
  235.     classVariableNames: ''
  236.     poolDictionaries: ''
  237.     category: 'Engi-Interface'!
  238. EngiDisplayView comment:
  239. '
  240.  
  241. Engi 0.01 (10 January 1994)
  242. Copyright (C) 1994 by Atsushi Aoki
  243.  
  244. '!
  245.  
  246.  
  247. !EngiDisplayView methodsFor: 'initialize-release'!
  248.  
  249. initialize
  250.     super initialize.
  251.     self scrollOffsetHolder: ScrollValueHolder new!
  252.  
  253. scrollOffsetHolder: aValueHolder 
  254.     scrollOffset := aValueHolder.
  255.     scrollOffset grid: self scrollGrid! !
  256.  
  257. !EngiDisplayView methodsFor: 'controller accessing'!
  258.  
  259. defaultControllerClass
  260.     ^EngiDisplayController! !
  261.  
  262. !EngiDisplayView methodsFor: 'bounds accessing'!
  263.  
  264. preferredBounds
  265.     (model notNil and: [model respondsTo: #bounds])
  266.         ifTrue: [^model bounds]
  267.         ifFalse: [^Point zero corner: Point zero]! !
  268.  
  269. !EngiDisplayView methodsFor: 'displaying'!
  270.  
  271. displayOn: graphicsContext 
  272.     (model notNil and: [model respondsTo: #displayOn:])
  273.         ifTrue: [model displayOn: graphicsContext]! !
  274.  
  275. !EngiDisplayView methodsFor: 'scrolling'!
  276.  
  277. scrollGrid
  278.     ^1 @ 1! !
  279.  
  280. !EngiDisplayView methodsFor: 'updating'!
  281.  
  282. update: aSymbol 
  283.     self positionTo: Point zero.
  284.     self clearInside.
  285.     self displayOn: self graphicsContext! !
  286.  
  287.  
  288.  
  289.  
  290.  
  291. ControllerWithMenu subclass: #EngiDisplayController
  292.     instanceVariableNames: ''
  293.     classVariableNames: ''
  294.     poolDictionaries: ''
  295.     category: 'Engi-Interface'!
  296. EngiDisplayController comment:
  297. '
  298.  
  299. Engi 0.01 (10 January 1994)
  300. Copyright (C) 1994 by Atsushi Aoki
  301.  
  302. '!
  303.  
  304.  
  305. !EngiDisplayController methodsFor: 'control defaults'!
  306.  
  307. redButtonActivity
  308.     (model notNil and: [model respondsTo: #redButtonActivity:])
  309.         ifTrue: [model redButtonActivity: self]!
  310.  
  311. yellowButtonActivity
  312.     (model notNil and: [model respondsT