'Smalltalk Express Test Meter'! 'Terrence Ma'! 'Modified from On To Smalltalk'! ViewManager subclass: #GuiViewManager instanceVariableNames: '' classVariableNames: '' poolDictionaries: 'ColorConstants WBConstants' ! !GuiViewManager methods! decrementMeter: theButton | meter | meter := self paneNamed: 'the meter'. meter setValue: meter getValue - 1; event: #display ! ! !GuiViewManager methods! incrementMeter: theButton | meter | meter := self paneNamed: 'the meter'. meter setValue: meter getValue + 1; event: #display ! ! !GuiViewManager methods! initializeMeter: theMeter theMeter setMin: 0; setMax: 10; setValue: 5; setTitle: 'Test Meter'; event: #display ! ! !GuiViewManager methods! callDrawMeter: theMeter theMeter drawMeter ! ! !GuiViewManager methods! createViews "WARNING! This method was automatically generated by WindowBuilder. Code you add here which does not conform to the WindowBuilder API will probably be lost the next time you save your layout definition." | v | self addView: ( v := self topPaneClass new owner: self; labelWithoutPrefix: 'Test Meter'; noSmalltalkMenuBar; viewName: 'mainView'; framingBlock: ( FramingParameters new iDUE: 677 @ 416; xC; yC; cRDU: (9 @ 408 rightBottom: 667 @ 46)); pStyle: #(sysmenu sizable titlebar minimize maximize); addSubpane: ( Button new owner: self; framingBlock: ( FramingParameters new iDUE: 210 @ 56; lDU: 64 r: #left; rDU: 274 r: #left; tDU: 40 r: #top; bDU: 96 r: #top); startGroup; when: #clicked perform: #decrementMeter:; contents: 'Decrement'; yourself ); addSubpane: ( Button new owner: self; framingBlock: ( FramingParameters new iDUE: 210 @ 56; lDU: 384 r: #left; rDU: 594 r: #left; tDU: 40 r: #top; bDU: 96 r: #top); startGroup; when: #clicked perform: #incrementMeter:; contents: 'Increment'; yourself ); addSubpane: ( MeterGraphPane new owner: self; framingBlock: ( FramingParameters new iDUE: 530 @ 192; lDU: 64 r: #left; rDU: 594 r: #left; tDU: 120 r: #top; bDU: 312 r: #top); paneName: 'the meter'; noScrollBars; startGroup; when: #getContents perform: #initializeMeter:; when: #display perform: #callDrawMeter:; yourself ); yourself ). ! ! GraphPane subclass: #MeterGraphPane instanceVariableNames: 'min max value title' classVariableNames: '' poolDictionaries: 'ColorConstants' ! !MeterGraphPane methods! setMin: aNumber min := aNumber ! ! !MeterGraphPane methods! setMax: aNumber max := aNumber ! ! !MeterGraphPane methods! setValue: aNumber value := aNumber ! ! !MeterGraphPane methods! getValue ^ value ! ! !MeterGraphPane methods! setTitle: aString title := aString ! ! !MeterGraphPane methods! drawMeter | thePen meterWidth meterHeight xLft yBot xPointer yPointer ptrHeight ptrHalfWidth oldBackColor dialArray range step tics tickPlace tickHeight| self erase. thePen := self pen. meterHeight := 30. meterWidth := self width * 3 // 4. ptrHeight := 10. ptrHalfWidth := 5. xLft := self width - meterWidth // 2. yBot := self height * 3 // 8. "Draw frame for meter" thePen drawRectangle: ((xLft - ptrHalfWidth) @ yBot extent: (meterWidth + (ptrHalfWidth * 2)) @ meterHeight). "Draw tick marks. Adaped from code provided by Richard Lyon. Works well for all min and max values" range := max - min. range = 0 ifTrue: [self error: 'Cannot put tics in an interval of width zero']. range < 0 ifTrue: [step := -1. range := range negated] ifFalse: [step := 1]. [range <= 15] whileTrue: [range := range*10. step := step/10]. [range > 150] whileTrue: [range := range/10. step := step*10]. range <= 30 ifTrue: [tics := #(1 5 10)] ifFalse: [(range <= 60) ifTrue: [tics := #(2 10 20)] ifFalse: [tics := #(5 10 50)] ]. step := step * (tics at: 1). (((min // (step negated)) negated) to: (max // step)) do: [:k | (k \\ ((tics at: 3) / (tics at: 1)) = 0) ifTrue: [tickHeight := meterHeight * 3 // 4] ifFalse: [(k \\ ((tics at: 2) / (tics at: 1)) = 0) ifTrue: [tickHeight := meterHeight // 2] ifFalse: [tickHeight := meterHeight * 3 // 8]]. tickPlace := xLft + (k * meterWidth * step // max) - (min * meterWidth // range). thePen lineFrom: (tickPlace @ yBot) to: (tickPlace @ (yBot + tickHeight))]. "Write title" title notNil ifTrue: [thePen centerText: title at: ((self width) // 2) @ (yBot + meterHeight + (2 * thePen font height))]. "Write scale minimum, middle, and maximum" min notNil & max notNil ifTrue: [thePen centerText: min printString at: xLft @ yBot. thePen centerText: (max - min // 2 + min) printString at: (xLft + (meterWidth // 2)) @ yBot. thePen centerText: max printString at: (xLft + meterWidth) @ yBot]. "Draw pointer, if values set" min notNil & max notNil & value notNil ifTrue: [xPointer := (value - min) * meterWidth // (max - min) + xLft. yPointer := yBot + meterHeight - 1. oldBackColor := thePen backColor. thePen backColor: ClrBlack. dialArray := Array with: ((xPointer + ptrHalfWidth) @ yPointer) with: (xPointer @ (yPointer - ptrHeight)) with: ((xPointer - ptrHalfWidth) @ yPointer). thePen polygonFilled: dialArray. thePen backColor: oldBackColor] ! !