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

  1.  
  2. 'Smalltalk Textbook Appendix 20'!
  3.  
  4.  
  5.  
  6.  
  7.  
  8. View subclass: #EngiClockView
  9.     instanceVariableNames: 'cacheImage cacheTime '
  10.     classVariableNames: ''
  11.     poolDictionaries: ''
  12.     category: 'Engi-Clock'!
  13. EngiClockView comment:
  14. '
  15.  
  16. Engi 0.06 (19 March 1994)
  17. Copyright (C) 1994 by Atsushi Aoki
  18.  
  19. '!
  20.  
  21.  
  22. !EngiClockView methodsFor: 'controller accessing'!
  23.  
  24. defaultControllerClass
  25.     ^EngiClockController! !
  26.  
  27. !EngiClockView methodsFor: 'display box accessing'!
  28.  
  29. bounds
  30.     (self topComponent width isNil or: [self topComponent height isNil])
  31.         ifTrue: [^nil].
  32.     ^super bounds!
  33.  
  34. bounds: ignore 
  35.     cacheImage := nil! !
  36.  
  37. !EngiClockView methodsFor: 'displaying'!
  38.  
  39. displayBackgroundImageOn: graphicsContext 
  40.     | center radius rect paragraph degree x y |
  41.     graphicsContext paint: self backgroundColor.
  42.     graphicsContext displayRectangle: self bounds.
  43.     graphicsContext paint: self foregroundColor.
  44.     center := self bounds center.
  45.     radius := self bounds extent // 2 - 12.
  46.     rect := 0 @ 0 extent: 2 @ 2.
  47.     1 to: 12
  48.         do: 
  49.             [:number | 
  50.             paragraph := number printString asText asComposedText.
  51.             degree := number - 3 * 30.
  52.             x := degree degreesToRadians cos.
  53.             y := degree degreesToRadians sin.
  54.             paragraph displayOn: graphicsContext at: center + 1 + (x @ y * radius) - (paragraph extent // 2).
  55.             graphicsContext displayRectangle: rect at: center + (x @ y * (radius - 10))]!
  56.  
  57. displayLongHandOn: graphicsContext 
  58.     | center radius minute x y points |
  59.     center := self bounds center.
  60.     radius := self bounds extent // 2 - 20.
  61.     minute := cacheTime minutes.
  62.     x := (minute * 6 - 90) degreesToRadians cos.
  63.     y := (minute * 6 - 90) degreesToRadians sin.
  64.     points := Array new: 5.
  65.     points at: 1 put: center + (self rotateBlock value: x @ y * 3 asPoint value: -180).
  66.     points at: 2 put: center + (self rotateBlock value: x @ y * 3 asPoint value: -90).
  67.     points at: 3 put: center + (x @ y * (radius * 9 // 10) asPoint).
  68.     points at: 4 put: center + (self rotateBlock value: x @ y * 3 asPoint value: 90).
  69.     points at: 5 put: points first copy.
  70.     points := points collect: [:p | p rounded].
  71.     graphicsContext capStyle: GraphicsContext capButt.
  72.     graphicsContext joinStyle: GraphicsContext joinMiter.
  73.     graphicsContext paint: self selectionForegroundColor.
  74.     graphicsContext lineWidth: 1.
  75.     graphicsContext displayPolygon: points.
  76.     graphicsContext paint: self selectionBackgroundColor.
  77.     graphicsContext displayPolyline: points!
  78.  
  79. displayOn: graphicsContext 
  80.     self bounds notNil ifTrue: [self displayTimeOn: graphicsContext]!
  81.  
  82. displayPivotOn: graphicsContext 
  83.     graphicsContext capStyle: GraphicsContext capButt.
  84.     graphicsContext joinStyle: GraphicsContext joinMiter.
  85.     graphicsContext paint: self backgroundColor.
  86.     graphicsContext lineWidth: 1.
  87.     graphicsContext
  88.         displayWedgeBoundedBy: ((self bounds center extent: Point zero)
  89.                 expandedBy: 3)
  90.         startAngle: 0
  91.         sweepAngle: 360.
  92.     graphicsContext paint: self foregroundColor.
  93.     graphicsContext
  94.         displayArcBoundedBy: ((self bounds center extent: Point zero)
  95.                 expandedBy: 3)
  96.         startAngle: 0
  97.         sweepAngle: 360!
  98.  
  99. displayShortHandOn: graphicsContext 
  100.     | center radius minute x y hour points |
  101.     center := self bounds center.
  102.     radius := self bounds extent // 2 - 20.
  103.     minute := cacheTime minutes.
  104.     hour := cacheTime hours * 5 + (minute / 12) asFloat.
  105.     x := (hour * 6 - 90) degreesToRadians cos.
  106.     y := (hour * 6 - 90) degreesToRadians sin.
  107.     points := Array new: 5.
  108.     points at: 1 put: center + (self rotateBlock value: x @ y * 3 asPoint value: -180).
  109.     points at: 2 put: center + (self rotateBlock value: x @ y * 3 asPoint value: -90).
  110.     points at: 3 put: center + (x @ y * (radius * 7 // 10) asPoint).
  111.     points at: 4 put: center + (self rotateBlock value: x @ y * 3 asPoint value: 90).
  112.     points at: 5 put: points first copy.
  113.     points := points collect: [:p | p rounded].
  114.     graphicsContext capStyle: GraphicsContext capButt.
  115.     graphicsContext joinStyle: GraphicsContext joinMiter.
  116.     graphicsContext paint: self selectionForegroundColor.
  117.     graphicsContext lineWidth: 1.
  118.     graphicsContext displayPolygon: points.
  119.     graphicsContext paint: self selectionBackgroundColor.
  120.     graphicsContext displayPolyline: points!
  121.  
  122. displayTickHandOn: graphicsContext 
  123.     | center radius length seconds x y |
  124.     center := self bounds center.
  125.     radius := self bounds extent // 2 - 20.
  126.     length := radius * 10 // 10.
  127.     seconds := cacheTime seconds.
  128.     x := (seconds * 6 - 90) degreesToRadians cos.
  129.     y := (seconds * 6 - 90) degreesToRadians sin.
  130.     graphicsContext capStyle: GraphicsContext capButt.
  131.     graphicsContext joinStyle: GraphicsContext joinMiter.
  132.     graphicsContext paint: self selectionBackgroundColor.
  133.     graphicsContext lineWidth: 1.
  134.     graphicsContext displayLineFrom: center to: center + (x @ y * length)!
  135.  
  136. displayTimeOn: graphicsContext 
  137.     | aPixmap pixmapContext |
  138.     ((cacheImage isNil or: [cacheTime isNil])
  139.         or: [self model currentTime minutes ~= cacheTime minutes])
  140.         ifTrue: 
  141.             [cacheTime := self model currentTime.
  142.             aPixmap := Pixmap extent: self bounds extent.
  143.             pixmapContext := aPixmap graphicsContext.
  144.             self displayBackgroundImageOn: pixmapContext.
  145.             self displayShortHandOn: pixmapContext.
  146.             self displayLongHandOn: pixmapContext.
  147.             self displayPivotOn: pixmapContext.
  148.             cacheImage := aPixmap asImage.
  149.             aPixmap close]
  150.         ifFalse: [cacheTime := self model currentTime].
  151.     cacheImage displayOn: graphicsContext.
  152.     self displayTickHandOn: graphicsContext! !
  153.  
  154. !EngiClockView methodsFor: 'updating'!
  155.  
  156. update: ignore 
  157.     self updateCheck ifFalse: [^nil].
  158.     self displayOn: self graphicsContext!
  159.  
  160. updateCheck
  161.     | topWindow topController |
  162.     topWindow := self topComponent.
  163.     (topWindow isKindOf: DisplaySurface)
  164.         ifFalse: [^false].
  165.     self isOpen ifFalse: [^false].
  166.     topController := topWindow controller.
  167.     (ScheduledControllers scheduledControllers includes: topController)
  168.         ifFalse: [^false].
  169.     ^true! !
  170.  
  171. !EngiClockView methodsFor: 'private'!
  172.  
  173. rotateBlock
  174.     | block |
  175.     block := 
  176.             [:p :d | 
  177.             | radians sin cos x y |
  178.             radians := d negated degreesToRadians.
  179.             sin := radians sin.
  180.             cos := radians cos.
  181.             x := p x * cos + (p y * sin).
  182.             y := p x * sin negated + (p y * cos).
  183.             x @ y].
  184.     ^block! !
  185. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  186.  
  187. EngiClockView class
  188.     instanceVariableNames: ''!
  189.  
  190.  
  191. !EngiClockView class methodsFor: 'instance creation'!
  192.  
  193. openOn: aClock 
  194.     | topWindow clockView edgeDecorator |
  195.     topWindow := ScheduledWindow
  196.                 model: aClock
  197.                 label: 'Clock'
  198.                 minimumSize: 100 @ 100.
  199.     clockView := self new model: aClock.
  200.     edgeDecorator := LookPreferences edgeDecorator on: clockView.
  201.     edgeDecorator noMenuBar.
  202.     edgeDecorator noVerticalScrollBar.
  203.     edgeDecorator noHorizontalScrollBar.
  204.     topWindow component: edgeDecorator.
  205.     topWindow open! !
  206.  
  207.  
  208.  
  209.  
  210.  
  211. Controller subclass: #EngiClockController
  212.     instanceVariableNames: ''
  213.     classVariableNames: ''
  214.     poolDictionaries: ''
  215.     category: 'Engi-Clock'!
  216. EngiClockController comment:
  217. '
  218.  
  219. Engi 0.06 (19 March 1994)
  220. Copyright (C) 1994 by Atsushi Aoki
  221.  
  222. '!
  223.  
  224.  
  225. !EngiClockController methodsFor: 'control defaults'!
  226.  
  227. controlActivity
  228.     (PopUpMenu labels: self model currentDateString) startUp!
  229.  
  230. isControlActive
  231.     ^self viewHasCursor and: [self sensor redButtonPressed or: [self sensor yellowButtonPressed]]! !
  232.  
  233.  
  234.  
  235.  
  236.  
  237. Model subclass: #EngiClockModel
  238.     instanceVariableNames: 'clockProcess '
  239.     classVariableNames: ''
  240.     poolDictionaries: ''
  241.     category: 'Engi-Clock'!
  242. EngiClockModel comment:
  243. '
  244.  
  245. Engi 0.06 (19 March 1994)
  246. Copyright (C) 1994 by Atsushi Aoki
  247.  
  248. '!
  249.  
  250.  
  251. !EngiClockModel methodsFor: 'initialize-release'!
  252.  
  253. initialize
  254.     EngiSystem soleEngiSystem addDependent: self.
  255.     self resumeClockProcess!
  256.  
  257. release
  258.     self terminateClockProcess.
  259.     EngiSystem soleEngiSystem removeDependent: self! !
  260.  
  261. !EngiClockModel methodsFor: 'accessing'!
  262.  
  263. currentDate
  264.     ^Date today!
  265.  
  266. currentDateString
  267.     | today stream |
  268.     today := self currentDate.
  269.     stream := WriteStream on: (String new: 20).
  270.     stream nextPutAll: ' '.
  271.     stream nextPutAll: today monthIndex printString.
  272.     stream nextPutAll: '/'.
  273.     stream nextPutAll: today dayOfMonth printString.
  274.     stream nextPutAll: ' ('.
  275.     stream nextPutAll: (today weekday copyFrom: 1 to: 3).
  276.     stream nextPutAll: ')'.
  277.     stream nextPutAll: ', '.
  278.     stream nextPutAll: today year printString.
  279.     stream nextPutAll: ' '.
  280.     ^stream contents!
  281.  
  282. currentTime
  283.     ^Time now!
  284.  
  285. currentTimeString
  286.     | now stream |
  287.     now := self