Home Segments Index Top Previous Next

874: Mainline

THE METER GRAPH PANE

MeterGraphPane class definition 
GraphPane subclass: #MeterGraphPane 
  instanceVariableNames: 'min max value title' 
  classVariableNames: '' 
  poolDictionaries: 'ColorConstants' 
MeterGraphPane method definition • instance 
setMin: aNumber 
  min := aNumber 
MeterGraphPane method definition • instance 
setMax: aNumber 
  max := aNumber 
MeterGraphPane method definition • instance 
setValue: aNumber 
  value := aNumber 
MeterGraphPane method definition • instance 
getValue 
  ^ value 
MeterGraphPane method definition • instance 
setTitle: aString 
  title := aString 
MeterGraphPane method definition • instance 
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 
             & (value >= min) & (value <= max) 
    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]