(FILECREATED "22-SEP-83 15:27:02" {INDIGO}<LOOPS>SOURCES>GAUGES.;28 84475  

      changes to:  (CLASSES MultiValueMixin)

      previous date: "20-SEP-83 18:21:43" {INDIGO}<LOOPS>SOURCES>GAUGES.;27)


(PRETTYCOMPRINT GAUGESCOMS)

(RPAQQ GAUGESCOMS ((* Copyright (c)
		      Xerox Corporation 1983)
		   (CLASSES * GAUGESCLASSES)
		   (* * Functions to implement GAUGES)
		   (FNS * GAUGEFNS)
		   (* * Utility functions for Gauges)
		   (FNS * GAUGEUTILITYFNS)
		   (VARS GB)))



(* Copyright (c) Xerox Corporation 1983)


(RPAQQ GAUGESCLASSES (BarChart BoundedMixin Dial DigiMeter DigiScale Gauge HBarChart HorizontalScale 
			       Instrument LCD Meter MultiValueMixin RoundScale SSBarChart SSDigiMeter 
			       SSHBarChart SelfScaleMixin VerticalScale))
(DEFCLASSES BarChart BoundedMixin Dial DigiMeter DigiScale Gauge HBarChart HorizontalScale Instrument 
	    LCD Meter MultiValueMixin RoundScale SSBarChart SSDigiMeter SSHBarChart SelfScaleMixin 
	    VerticalScale)
[DEFCLASS BarChart
   (MetaClass Class doc                                      (* A gauge with multiple vertical scales.)
	      Edited:                                        (* dgb: "22-JUL-83 15:50")
	      )
   (Supers MultiValueMixin VerticalScale)
   (ClassVariables)
   (InstanceVariables (maxLabelWidth 0 doc                   (* maximum widt of a label string.))
		      (scaleLeft 3)
		      (scaleBottom 30))
   (Methods (DrawInstrument BarChart.DrawInstrument doc      (* Print the labels under each bar.))
	    (Set BarChart.Set args (reading label))
	    (SetParameters BarChart.SetParameters doc        (* show the line at initial level.
							     intrnal displayVal is really line heigt))
	    (ShowReading BarChart.ShowReading args NIL doc 
                                                             (* dgb: " 9-JUN-83 22:14"))
	    (Update BarChart.Update doc                      (* Scale internal readings to min and max for update)
		    args NIL))]

[DEFCLASS BoundedMixin
   (MetaClass Class Edited:                                  (* dgb: " 9-JUN-83 23:04")
	      doc

          (* * For use as a mixin for Instruments. Computes a bounded scale for displayVal)


	      )
   (Supers Object)
   (ClassVariables)
   (InstanceVariables)
   (Methods (ComputeDisplayVal BoundedMixin.ComputeDisplayVal doc 
                                                             (* dgb: "26-JAN-83 17:09")
			       args
			       (reading))
	    (OutOfBounds BoundedMixin.OutOfBounds args (outFlg)
			 doc                                 (* Print ? if out, space other wise)
			 ))]

[DEFCLASS Dial
   (MetaClass Class doc                                      (* A dial with bounded range, like an auto speedometer)
	      Edited:                                        (* dgb: "22-FEB-83 15:11")
	      )
   (Supers BoundedMixin RoundScale)
   (ClassVariables)
   (InstanceVariables (ticks 7)
		      (labels (0 20 40 60 80 100 120))
		      (width 121)
		      (displayVal 120)
		      (inputRange 120)
		      (lower 120)
		      (range -60))
   (Methods (DrawInstrument Dial.DrawInstrument args NIL doc 
                                                             (* Draw two concentric circles to contain ticks)
			    )
	    (SetParameters Dial.SetParameters args NIL doc 
                                                             (* dgb: "26-JAN-83 16:54"))
	    (ShowLabels Dial.ShowLabels args NIL doc         (* If there are any labels, show them on the dial)
			)
	    (ShowTicks Dial.ShowTicks args (xc yc)))]

[DEFCLASS DigiMeter
   (MetaClass Class doc                                      (* A combination Meter and LCD, for both analog and 
							     digital readout.)
	      Edited:                                        (* edited: "10-JUL-83 14:05")
	      )
   (Supers Meter LCD)
   (ClassVariables)
   (InstanceVariables (readingY 100)
		      (width 120)
		      (inputRange 100)
		      (labels (0 10 20 30 40 50 60 70 80 90))
		      (ticks 10))
   (Methods (ComputeScale DigiMeter.ComputeScale doc         (* Compute scale for both dial and alphaDisplay)
			  )
	    (Set DigiMeter.Set doc                           (* set both on dial and on digits))
	    (SetParameters DigiMeter.SetParameters doc       (* Set all params))
	    (ShowReading DigiMeter.ShowReading args (reading)
			 doc                                 (* dgb: " 9-JUN-83 22:14")
			 ))]

[DEFCLASS DigiScale
   (MetaClass Class doc                                      (* Combines a numeric display with an unlabelled 
							     proportional horizontal scale)
	      Edited:                                        (* dgb: " 6-JUN-83 17:55")
	      )
   (Supers HorizontalScale LCD)
   (ClassVariables)
   (InstanceVariables (ticks NIL tickLength NIL)
		      (scaleHeight 6)
		      (scaleLeft 6)
		      (height 24)
		      (width 70))
   (Methods (Set DigiScale.Set doc                           (* Combined method for Set))
	    (SetParameters DigiScale.SetParameters doc       (* Set parameters for unscaled horizontal gauge combined
							     with LCD on bottom))
	    (ShowReading DigiScale.ShowReading doc           (* dgb: " 9-JUN-83 21:34")))]

[DEFCLASS Gauge
   (MetaClass Class doc                                      (* An object which presents a dynamic graphical image of
							     a Loops value)
	      Edited:                                        (* dgb: "22-JUL-83 16:24")
	      )
   (Supers Window)
   [ClassVariables (LeftButtonItems ((Update (QUOTE Update)
					     "Update gauge to show all labels")
				     ("Save in IT" (QUOTE SaveInIT)
						   "Save Gauge as value of variable IT")))
		   (MiddleButtonItems ((Attached? (QUOTE Attached?)
						  "Print where gauge attached")
				       (Detach (QUOTE Detach)
					       "Detach gauge"]
   (InstanceVariables (reading 0 doc                         (* external value of reading))
		      (attachedTo NIL ivName NIL machine NIL doc 

          (* value is object this gauge is attached to. ivName tells the name of iv. machine is NIL if local, else is 
	  ETHERHOSTNUMBER or name of remote machine)

))
   (Methods (Attach Gauge.Attach args (obj varName selector otherArgs label machine)
		    doc                                      (* Attach a self to obj/varName)
		    )
	    (Attached? Gauge.Attached? args (printFlg)
		       doc                                   (* dgb: "17-FEB-83 13:12")
		       )
	    (Close Gauge.Close doc                           (* Detach the gauge and close the window)
		   )
	    (Detach Gauge.Detach args NIL doc                (* Detach gauge from attachedPlaces it is attached to)
		    )
	    (SetScale Gauge.SetScale args (min max labelScale)
		      doc                                    (* compute the scale and redisplay if necessary)
		      )
	    (ShowInstrument SubclassResponsibility args NIL doc 
                                                             (*))
	    (Update Gauge.Update doc                         (* Set up display window for instrument.
							     Reinitialize to reflect current state)
		    args NIL)
	    (Reset Gauge.Reset args (newReading)
		   doc                                       (* set reading to value, and then update gauge so that 
							     it shows that reading without going through intermediate
							     states)
		   )
	    (DetachProbe Gauge.DetachProbe args (place)
			 doc                                 (* Detach a probe on a place specified by place, a list 
							     of form (objName varName . otherStuff). Called by 
							     Detach)
			 )
	    (AttachProbe Gauge.AttachProbe args (obj varName selector otherArgs label machine)
			 doc                                 (* Attach a probe to an object, and record attachment 
							     here in Gauge. Returns current value of obj varName)
			 )
	    (MaxCurrentReading Gauge.MaxCurrentReading args NIL doc 
                                                             (* Returns the reading now, since in general there is 
							     only one))
	    (Update? Gauge.Update? args NIL doc              (* Update if there is a window and it is open)
		     ))]

[DEFCLASS HBarChart
   (MetaClass Class doc                                      (* Horizontally oriented BarChart)
	      Edited:                                        (* dgb: "22-JUL-83 23:19")
	      )
   (Supers MultiValueMixin HorizontalScale)
   (ClassVariables)
   (InstanceVariables (width 250 doc                         (* Inside width of entire window))
		      (scaleLeft 40 doc                      (* position From left of names))
		      (width 250 doc                         (* Inside width of entire window))
		      (maxLabelWidth 0 doc                   (* maxSize in dots of the widest label)))
   (Methods (Set HBarChart.Set args (reading label)
		 doc                                         (* show reading on vertical scale)
		 )
	    (ShowReading HBarChart.ShowReading doc           (* show the line at initial level.
							     intrnal displayVal is really line heigt)
			 args NIL)
	    (SetParameters HBarChart.SetParameters doc       (* Set scale hieght from height))
	    (DrawInstrument HBarChart.DrawInstrument doc     (* Print the labels next to each bar.)))]

[DEFCLASS HorizontalScale
   (MetaClass Class doc                                      (* A labelled bounded scale with a bar which fills to 
							     the right)
	      Edited:                                        (* dgb: "22-FEB-83 15:13")
	      )
   (Supers BoundedMixin Instrument)
   (ClassVariables)
   (InstanceVariables (labels (0 10 20 30 40 50 60 70 80 90 100))
		      (ticks 11)
		      (height 57 doc                         (* a window high enough for 11 labels))
		      (width 208)
		      (scaleWidth 120 doc                    (* width of inside of scale))
		      (scaleHeight 15 doc                    (* height of scale))
		      (scaleLeft 12 doc                      (* left edge of scale))
		      (scaleBottom 10 doc                    (* bottom edge of scale)))
   (Methods (DrawInstrument HorizontalScale.DrawInstrument args NIL doc 
                                                             (* Draw a horizontal tube for instrument)
			    )
	    (OutOfBounds HorizontalScale.OutOfBounds doc     (* Print "  " or ?? depending on whether reading is out 
							     of bounds))
	    (Set HorizontalScale.Set args (reading)
		 doc                                         (* show reading on horizontal scale)
		 )
	    (SetParameters HorizontalScale.SetParameters doc 
                                                             (* Set scale width from width))
	    (ShowLabels HorizontalScale.ShowLabels args NIL doc 
                                                             (* Put labels next to ticks))
	    (ShowReading HorizontalScale.ShowReading args NIL doc 
                                                             (* dgb: " 9-JUN-83 22:37")))]

[DEFCLASS Instrument
   (MetaClass AbstractClass doc                              (* A numeric gauge scaled externally by inputLower and 
							     inputRange, and internally by lower and range)
	      Edited:                                        (* dgb: "22-FEB-83 15:03")
	      )
   (Supers Gauge)
   (ClassVariables)
   (InstanceVariables (displayVal 0 doc                      (* Internal value relative to instrument)
				  )
		      (ticks 5 tickLength 9 smallTicks 1 doc 

          (* * ticks on the instrument; value is number or NIL; smallTicks is number between each large tick)

)
		      (labels NIL doc                        (* labels for the instrument))
		      (labelScale 1 doc                      (* scaleFactor for labels e.g. value 1000 means 3000 is 
							     indicated by 3))
		      (lower 0 doc                           (* lower bound for internal displayVal))
		      (inputLower 0 doc                      (* lower bound for external reading))
		      (range 100 doc                         (* range for internal displayVal))
		      (inputRange 100 doc                    (* range for external reading)))
   (Methods (ComputeScale Instrument.ComputeScale args (min max labelScale)
			  doc                                (* DECLARATIONS: MIXED)
			  )
	    (ComputeDisplayVal Instrument.ComputeDisplayVal args (reading)
			       doc                           (* Computes displayVal of instrument in bounded range)
			       )
	    (PrintLabelScale Instrument.PrintLabelScale args NIL doc 
                                                             (* Print the scale of labelling on instrument)
			     )
	    (SetParameters Instrument.SetParameters args NIL doc 
                                                             (* Set scale hieght from height))
	    (ShowInstrument Instrument.ShowInstrument args NIL doc 
                                                             (* show the instrument including the current displayVal)
			    ))]

[DEFCLASS LCD
   (MetaClass Class doc                                      (* A gauge which gives an alphanumeric display of a 
							     value)
	      Edited:                                        (* dgb: "13-JUN-83 10:42")
	      )
   (Supers Gauge)
   (ClassVariables (Font (GACHA 12 BOLD)))
   (InstanceVariables (height 14)
		      (width 30)
		      (readingY 7 doc                        (* y position of center of reading))
		      (precision 5 readingRegion NIL doc     (* value= num chars in reading.
							     readingRegion is derived from precision and rading)
				 ))
   (Methods (ComputeScale LCD.ComputeScale args (min max)
			  doc                                (* Sets the precision based on the width of min and max)
			  )
	    (Set LCD.Set args (reading)
		 doc                                         (* Put number in box)
		 )
	    (SetParameters LCD.SetParameters args NIL doc    (* Set the font for the window))
	    (ShowInstrument LCD.ShowInstrument doc           (* Nothing needed))
	    (ShowReading LCD.ShowReading args NIL doc        (* dgb: " 9-JUN-83 22:15"))
	    (PrintReading LCD.PrintReading args NIL doc      (* dgb: " 9-JUN-83 22:15")))]

[DEFCLASS Meter
   (MetaClass Class doc                                      (* A circular instrument that will wrap around any 
							     number of times)
	      Edited:                                        (* dgb: "22-FEB-83 15:10")
	      )
   (Supers RoundScale)
   (ClassVariables)
   (InstanceVariables (ticks 10)
		      (lower 90)
		      (displayVal 90)
		      (range -360)
		      (labels (0 10 20 30 40 50 60 70 80 90))
		      (height 120)
		      (width 100))
   (Methods (ComputeScale Meter.ComputeScale doc             (* dgb: "29-JAN-83 01:48"))
	    (DrawInstrument Meter.DrawInstrument args NIL doc 
                                                             (*))
	    (SetParameters Meter.SetParameters args NIL doc 
                                                             (* Compute center and radius for meters))
	    (Shape Meter.Shape doc                           (*))
	    (ShowLabels Meter.ShowLabels doc                 (* If there are any labels, show them on the dial)
			)
	    (ShowTicks Meter.ShowTicks args NIL doc          (* *Draw ticks at even intervals around the circle 
							     starting from 90)))]

[DEFCLASS MultiValueMixin
   (MetaClass Class Edited:                                  (* dgb: "22-JUL-83 16:56"))
   (Supers Object)
   (ClassVariables)
   (InstanceVariables (displayVal NIL doc 

          (* List of participants. Each elementof displayVal is a triple (Label xPos YValue) where label is an atom, and 
	  will be used both to identify the column, and label it on the bottom. xPos is the horizontal position, and Ypos is
	  the vertical height starting at scaleBottom+1)

)
		      (barWidth 10 doc                       (* standard width of the bar))
		      (scaleBottom 30 doc                    (* Bottom edge of scale)))
   (Methods (Attach MultiValueMixin.Attach args (obj varName selector label machine xOrPos y)
		    doc                                      (* Attach to obj varName and label it in chart with 
							     label)
		    )
	    (Detach MultiValueMixin.Detach args (label)
		    doc                                      (* Detach gauge from attachedPlaces it is attached to)
		    )
	    (SetUp MultiValueMixin.SetUp args (listOfObjects ivName chartTitle maxScale path)
		   doc

          (* Attach a bar chart to the iv of specified by the object in the list, and the path. path can be an atom, meaning
	  that IV, or it can be a list of atoms to be followed, each an iv name. Each bar on the chart will be labelled with
	  the name of the object on listOfObjects. title will be used for the BarChart.)


		   )
	    (OutOfBounds MultiValueMixin.OutOfBounds args (outFlg)
			 doc                                 (* Print ? if out, space other wise)
			 )
	    (MaxCurrentReading MultiValueMixin.MaxCurrentReading args NIL doc 
                                                             (* return the max readinr in 
							     (@ reading)))
	    (AddLabel MultiValueMixin.AddLabel doc           (* add to the list of bars on the chart)
		      args
		      (label labelReading))
	    (DeleteLabel MultiValueMixin.DeleteLabel args (label updateFlg)
			 doc                                 (* Remove a bar from a chart)
			 ))]

[DEFCLASS RoundScale
   (MetaClass AbstractClass Edited:                          (* mjs: "28-JAN-83 10:19")
	      doc                                            (* AbstractClass for instrucments with circular 
							     (arc) scales)
	      )
   (Supers Instrument)
   (ClassVariables)
   (InstanceVariables (needleLength 15 doc                   (* radius of needle))
		      (radius 10 doc                         (* radius of arc in instrument))
		      (xc 0 doc                              (* x center of arc))
		      (yc 0 doc                              (* y center of arc)))
   (Methods (Set RoundScale.Set args (reading)
		 doc                                         (* dgb: "27-JAN-83 11:34")
		 )
	    (ShowReading RoundScale.ShowReading args NIL doc 
                                                             (* dgb: "26-JAN-83 23:43"))
	    (Reset RoundScale.Reset args (newReading)
		   doc                                       (* set reading to value, and then update gauge so that 
							     it shows that reading without going through intermediate
							     states)
		   ))]

[DEFCLASS SSBarChart
   (MetaClass Class doc                                      (* Self-scaling BarChart)
	      Edited:                                        (* edited: "10-JUL-83 14:03")
	      )
   (Supers SelfScaleMixin BarChart)
   (ClassVariables)
   (InstanceVariables)
   (Methods)]

[DEFCLASS SSDigiMeter
   (MetaClass Class doc                                      (* Self-scaling DigiMeter.)
	      Edited:                                        (* edited: "10-JUL-83 14:04")
	      )
   (Supers SelfScaleMixin DigiMeter)
   (ClassVariables)
   (InstanceVariables)
   (Methods)]

[DEFCLASS SSHBarChart
   (MetaClass Class doc                                      (* This is a self scaling Horizontally oriented 
							     barChart)
	      Edited:                                        (* dgb: "23-JUL-83 00:46")
	      )
   (Supers SelfScaleMixin HBarChart)
   (ClassVariables)
   (InstanceVariables)
   (Methods)]

[DEFCLASS SelfScaleMixin
   (MetaClass Class Edited:                                  (* dgb: "10-JUN-83 02:32"))
   (Supers Object)
   (ClassVariables)
   (InstanceVariables (lowScaleFactor 5 doc                  (* If maxCurrentReading shrinks so that it will fit more
							     than lowScaleFactor times in inputRange, the gauge 
							     rescales)))
   (Methods (Set SelfScaleMixin.Set args (reading otherArg1 otherArg2)
		 doc                                         (* Check if reading is too high or too low, and if so 
							     see if gauge needs to rescale)
		 ))]

[DEFCLASS VerticalScale
   (MetaClass Class doc                                      (* A labelled bounded scale with a black bar which rises
							     proportional to its reading)
	      Edited:                                        (* dgb: "23-JUN-83 16:38")
	      )
   (Supers BoundedMixin Instrument)
   (ClassVariables)
   (InstanceVariables (labels (0 10 20 30 40 50 60 70 80 90 100))
		      (ticks 11 tickLength 7)
		      (height 160 doc                        (* a window high enough for 11 labels))
		      (width 77)
		      (scaleWidth 15 doc                     (* width of inside of scale))
		      (scaleHeight 120 doc                   (* height of scale))
		      (scaleLeft 15 doc                      (* left edge of scale))
		      (scaleBottom 12 doc                    (* bottom edge of scale)))
   (Methods (DrawInstrument VerticalScale.DrawInstrument args NIL doc 
                                                             (* Draw a vertical tube for instrument))
	    (Set VerticalScale.Set args (reading)
		 doc                                         (* show reading on vertical scale)
		 )
	    (SetParameters VerticalScale.SetParameters doc 
                                                             (* Set scale hieght from height))
	    (ShowLabels VerticalScale.ShowLabels args NIL doc 
                                                             (* Put labels next to ticks))
	    (ShowTicks VerticalScale.ShowTicks args NIL doc 
                                                             (* Show ticks along right edge of scale))
	    (ShowReading VerticalScale.ShowReading args NIL doc 
                                                             (* dgb: " 9-JUN-83 22:37")))]

(* * Functions to implement GAUGES)


(RPAQQ GAUGEFNS (BarChart.DrawInstrument BarChart.Set BarChart.SetParameters BarChart.ShowReading 
					 BarChart.Update BoundedMixin.ComputeDisplayVal 
					 BoundedMixin.OutOfBounds ChangeHorizontalSetting 
					 ChangeVerticalSetting ComputeLabels Dial.DrawInstrument 
					 Dial.SetParameters Dial.ShowLabels Dial.ShowTicks 
					 DigiMeter.ComputeScale DigiMeter.Set DigiMeter.SetParameters 
					 DigiMeter.ShowReading DigiMeter.Update DigiScale.Set 
					 DigiScale.SetParameters DigiScale.ShowReading DrawLines 
					 DrawVTick Gauge.Attach Gauge.AttachProbe Gauge.Attached? 
					 Gauge.Close Gauge.Detach Gauge.DetachProbe 
					 Gauge.MaxCurrentReading Gauge.Reset Gauge.SetScale 
					 Gauge.Update Gauge.Update? GetPathObj 
					 HBarChart.DrawInstrument HBarChart.Set 
					 HBarChart.SetParameters HBarChart.ShowReading 
					 HorizontalScale.DrawInstrument HorizontalScale.OutOfBounds 
					 HorizontalScale.Set HorizontalScale.SetParameters 
					 HorizontalScale.ShowLabels HorizontalScale.ShowReading 
					 HorizontalScale.ShowTicks Instrument.ComputeDisplayVal 
					 Instrument.ComputeScale Instrument.PrintLabelScale 
					 Instrument.SetParameters Instrument.ShowInstrument 
					 LCD.ComputeScale LCD.PrintReading LCD.Reset LCD.Set 
					 LCD.SetParameters LCD.ShowInstrument LCD.ShowReading 
					 LCD.SmallRegion Meter.ComputeScale Meter.DrawInstrument 
					 Meter.SetParameters Meter.Shape Meter.ShowLabels 
					 Meter.ShowTicks MoveImageRight MultiValueMixin.AddLabel 
					 MultiValueMixin.Attach MultiValueMixin.DeleteLabel 
					 MultiValueMixin.Detach MultiValueMixin.MaxCurrentReading 
					 MultiValueMixin.OutOfBounds MultiValueMixin.SetUp 
					 RoundScale.Reset RoundScale.Set RoundScale.ShowReading 
					 SelfScaleMixin.Set SetUpBarChart SubclassResponsibility 
					 VerticalScale.DrawInstrument VerticalScale.Set 
					 VerticalScale.SetParameters VerticalScale.ShowLabels 
					 VerticalScale.ShowReading VerticalScale.ShowTicks))
(DEFINEQ

(BarChart.DrawInstrument
  [LAMBDA (self)                                             (* dgb: " 9-JUN-83 22:14")
                                                             (* Print the labels under each bar.)
    (for triple in (@ displayVal) bind [labelY ←(IPLUS (@ scaleBottom)
						       (DSPLINEFEED NIL (@ window]
       do (MOVETO (IPLUS (CADR triple)
			 (IQUOTIENT [IDIFFERENCE (@ maxLabelWidth)
						 (STRINGWIDTH (CAR triple)
							      (DSPFONT NIL (@ window]
				    2))
		  labelY
		  (@ window))
	  (PRIN1 (CAR triple)
		 (@ window])

(BarChart.Set
  [LAMBDA (self reading label)                               (* dgb: "10-JUN-83 11:07")
                                                             (* show reading on vertical scale)
    (PROG ((quad (FASSOC label (@ displayVal)))
	   (newSetting (← self ComputeDisplayVal reading)))
          (COND
	    ((NULL quad)
	      (ERROR label "not in this BarChart")))
          (RPLACA (CDDDR quad)
		  reading)
          (ChangeVerticalSetting (IPLUS (CADR quad)
					(IQUOTIENT (IDIFFERENCE (@ maxLabelWidth)
								(@ barWidth))
						   2))
				 (CADDR quad)
				 newSetting
				 (@ window)
				 (@ barWidth))
          (RPLACA (CDDR quad)
		  newSetting])

(BarChart.SetParameters
  [LAMBDA (self)                                             (* dgb: " 9-JUN-83 22:14")
                                                             (* Set scale hieght from height)
    [←@
      range
      (←@
	scaleHeight
	(IDIFFERENCE (@ height)
		     (IPLUS 8 (@ scaleBottom]
    [for triple in (@ displayVal) finally (←@
					    maxLabelWidth w)
       bind (w ← 0)
	    (wf ←(DSPFONT NIL (@ window)))
       do (SETQ w (IMAX w (STRINGWIDTH (CAR triple)
				       wf]
    (for triple in (@ displayVal) bind (totalW ← 0)
       do                                                    (* Now set up the xPosition of the bar)
	  (RPLACA (CDR triple)
		  (IPLUS (@ scaleLeft)
			 totalW))
	  (SETQ totalW (IPLUS totalW (@ maxLabelWidth)))
       finally (←@
		 scaleWidth totalW))
    (←@
      lower
      (@ scaleBottom))
    (←@
      width
      (IPLUS (@ scaleLeft)
	     (@ scaleWidth)
	     (COND
	       ((@ ticks)
		 (IPLUS (@ ticks:,tickLength)
			30))
	       (T 0])

(BarChart.ShowReading
  [LAMBDA (self)                                             (* dgb: "10-JUN-83 02:02")
                                                             (* dgb: " 9-JUN-83 22:14")
                                                             (* show the line at initial level.
							     intrnal displayVal is really line heigt)
    (for triple in (@ displayVal) bind (c ←(IQUOTIENT (IDIFFERENCE (@ maxLabelWidth)
								   (@ barWidth))
						      2))
       do (ChangeVerticalSetting (IPLUS c (CADR triple))
				 (@ scaleBottom)
				 (CADDR triple)
				 (@ window)
				 (@ barWidth])

(BarChart.Update
  [LAMBDA (self)                                             (* dgb: "22-JUL-83 17:32")
                                                             (* Scale internal readings to min and max for update)
    [for quad in (@ displayVal) do (RPLACA (CDDR quad)
					   (← self ComputeDisplayVal (CADDDR quad]
    (←Super
      self Update])

(BoundedMixin.ComputeDisplayVal
  [LAMBDA (self reading)                                     (* dgb: " 9-JUN-83 22:57")
                                                             (* dgb: "26-JAN-83 17:09")
                                                             (*)
    (PROG [(boundedReading (PinnedSetting reading (@ inputLower)
					  (PLUS (@ inputLower)
						(@ inputRange]
                                                             (* Set up indicator in upper left if out of bounds)
          (← self OutOfBounds (NEQ reading boundedReading))
          (RETURN (FIX (←Super
			 self ComputeDisplayVal boundedReading])

(BoundedMixin.OutOfBounds
  [LAMBDA (self outFlg)                                      (* dgb: "27-JAN-83 00:10")
                                                             (* Print ? if out, space other wise)
    (MOVETOUPPERLEFT (%@ window))
    (PRIN1 (COND
	     (outFlg "??")
	     (T "  "))
	   (%@ window])

(ChangeHorizontalSetting
  [LAMBDA (yPos oldXPos newXPos window settingWidth)         (* dgb: "22-JUL-83 23:29")
                                                             (* Move a bar to left or right as needed)
    (COND
      ((GREATERP oldXPos newXPos)
	(LineLeft oldXPos newXPos yPos (@ window)
		  settingWidth))
      ((GREATERP newXPos oldXPos)
	(LineRight oldXPos newXPos yPos (@ window)
		   settingWidth])

(ChangeVerticalSetting
  [LAMBDA (xPos oldYPos newYPos window settingWidth)         (* dgb: "25-MAR-83 16:57")
    (COND
      ((GREATERP oldYPos newYPos)
	(LineLower xPos oldYPos newYPos (%@ window)
		   settingWidth))
      ((GREATERP newYPos oldYPos)
	(LineRaise xPos oldYPos newYPos (%@ window)
		   settingWidth])

(ComputeLabels
  [LAMBDA (goodMinVal goodIncr goodmaxVal labelScale)        (* sm: "14-JUN-83 11:49")
    (PROG (incr labelList endPtr lab1 lab)
          [SETQ lab (COND
	      ((GREATERP 1 (ABS goodIncr))
		goodMinVal)
	      (T                                             (* for increments greater than 1, set the base to be a 
							     fixed number)
		 (FIX goodMinVal]                            (* For ranges greater than 10, set the increment to a 
							     fixed number)
          (OR (GREATERP 10 (DIFFERENCE goodmaxVal goodMinVal))
	      (SETQ goodIncr (FIX goodIncr)))
      LP  (COND
	    ([AND incr (OR (EQP 0 incr)
			   (COND
			     ((MINUSP incr)
			       (LESSP lab goodMaxVal))
			     (T (GREATERP lab goodMaxVal]
	      (GO OUT)))
          (SETQ lab1 (QUOTIENT lab labelScale))
          [COND
	    [endPtr (FRPLACD endPtr (SETQ endPtr (LIST lab1]
	    (T (SETQ labelList (SETQ endPtr (LIST lab1]
          (SETQ lab (PLUS lab (SETQ incr goodIncr)))
          (GO LP)
      OUT (RETURN labelList])

(Dial.DrawInstrument
  [LAMBDA (self)                                             (* dgb: "21-FEB-83 09:54")
                                                             (* Draw two concentric circles to contain ticks)
    (DRAWCIRCLE (%@ xc)
		(%@ yc)
		(%@ radius)
		2 NIL (%@ window))
    (DRAWCIRCLE (%@ xc)
		(%@ yc)
		(IDIFFERENCE (%@ radius)
			     (%@ ticks:,tickLength))
		2 NIL (%@ window))
    (DrawTick self 60 20 -20 1)
    (DrawTick self 120 20 20 1])

(Dial.SetParameters
  [LAMBDA (self)                                             (* dgb: "21-FEB-83 16:27")
                                                             (* Set up center of circle for dial and needle, and 
							     length of radius.)
    (PROG [xc [twoLines (ITIMES 2 (DSPLINEFEED NIL (%@ window]
	      (ms (MAXSTRINGWIDTH (%@ labels]
          (←%@
	    xc
	    (SETQ xc (IQUOTIENT (%@ width)
				2)))
          (←%@
	    radius
	    (IDIFFERENCE (%@ width)
			 (IPLUS 5 ms)))
          [←%@
	    needleLength
	    (IDIFFERENCE (%@ radius)
			 (IPLUS 4 (%@ ticks:,tickLength]
          (←%@
	    height
	    (%@ xc))
          (←%@
	    yc
	    (IPLUS (%@ height)
		   (IMINUS (%@ radius))
		   twoLines])

(Dial.ShowLabels
  [LAMBDA (self)                                             (* dgb: "21-FEB-83 10:01")
                                                             (* If there are any labels, show them on the dial)
    (COND
      ((%@ labels)
	(DSPRIGHTMARGIN (IPLUS (%@ width)
			       50)
			(%@ window))                         (* so that labels on the right won't go to the next 
							     line)
	(PROG [(nl (SUB1 (LENGTH (%@ labels]
	      (for lab in (%@ labels) as i from 0 by 1 do (ShowRayLabel self
									(PLUS 120
									      (QUOTIENT (TIMES i -60)
											nl))
									lab])

(Dial.ShowTicks
  [LAMBDA (self)                                             (* dgb: "21-FEB-83 11:01")
                                                             (* Draw ticks in even intervals from angle of 120 down 
							     to 60)
    (for a in (EvenIntervals 120 -60 (SUB1 (%@ ticks))) bind [incr ←(IQUOTIENT -60
									       (SUB1 (%@ ticks]
       do (DrawTick self a (%@ ticks:,smallTicks)
		    incr .7)
       finally (DrawTick self 60])

(DigiMeter.ComputeScale
  [LAMBDA (self min max labelScale)                          (* dgb: "10-JUN-83 11:53")
                                                             (* Compute scale for both dial and alphaDisplay)
    (←SuperFringe
      self ComputeScale min max labelScale])

(DigiMeter.Set
  [LAMBDA (self reading)                                     (* dgb: "10-JUN-83 11:53")
                                                             (* set both on dial and on digits)
    (←SuperFringe
      self Set reading])

(DigiMeter.SetParameters
  [LAMBDA (self)                                             (* dgb: "21-FEB-83 14:59")
                                                             (* Set all params)
    (PROG [(lf (FONTHEIGHT (%@%@ Font]
          (DSPFONT (%@%@ Font)
		   (%@ window))
          (DoMethod self (QUOTE SetParameters)
		    (%$ Meter))                              (* first determine height for meter, then add to it the 
							     height for the LCD)
          (←%@
	    readingY
	    (IPLUS (%@ height)
		   lf))
          (←%@
	    height
	    (IPLUS (%@ height)
		   (ITIMES 2 lf)))                           (* set up small reding region)
          (LCD.SmallRegion self])

(DigiMeter.ShowReading
  [LAMBDA (self reading)                                     (* dgb: "10-JUN-83 11:53")
                                                             (* dgb: " 9-JUN-83 22:14")
                                                             (* Show displayVal both on dial and on digits)
    (←SuperFringe
      self ShowReading reading])

(DigiMeter.Update
  [LAMBDA (self)                                             (* dgb: "10-JUN-83 11:54")
                                                             (*)
    (←SuperFringe
      self Update])

(DigiScale.Set
  [LAMBDA (self reading)                                     (* dgb: "10-JUN-83 11:54")
                                                             (* Combined method for Set)
    (←SuperFringe
      self Set reading])

(DigiScale.SetParameters
  [LAMBDA (self)                                             (* dgb: "21-FEB-83 15:38")
                                                             (* Set parameters for unscaled horizontal gauge combined
							     with LCD on bottom)
    (PROG [(lf (FONTHEIGHT (%@%@ Font]
          (DSPFONT (%@%@ Font)
		   (%@ window))
          (←%@
	    scaleBottom
	    (IPLUS 4 lf))
          (←%@
	    readingY
	    (ADD1 (IQUOTIENT lf 2)))
          (DoMethod self (QUOTE SetParameters)
		    (%$ HorizontalScale))
          (LCD.SmallRegion self])

(DigiScale.ShowReading
  [LAMBDA (self)                                             (* dgb: "10-JUN-83 11:54")
                                                             (* dgb: " 9-JUN-83 21:34")
                                                             (* Combined method for ShowReading)
    (←SuperFringe
      self ShowReading])

(DrawLines
  [LAMBDA (pointList window fromPointN toPointN width operation color)
                                                             (* dgb: "25-MAR-83 19:35")
    (OR fromPointN (SETQ fromPointN 1))
    (OR toPointN (SETQ toPointN (LENGTH pointList)))
    (PROG ((pointTail (NTH pointList fromPointN)))
          (OR pointTail (RETURN))
          (MOVETO (fetch XCOORD of (CAR pointTail))
		  (fetch YCOORD of (CAR pointTail))
		  window)
          (for i from (ADD1 fromPointN) by 1 to toPointN as point in (CDR pointTail)
	     do (BLOCK)
		(DRAWTO (fetch XCOORD of point)
			(fetch YCOORD of point)
			width operation window color])

(DrawVTick
  [LAMBDA (self x y incr)                                    (* dgb: "21-FEB-83 12:13")
                                                             (* Draw a horizontal line for a tick)
    (DRAWLINE x y x (IPLUS y (%@ ticks:,tickLength))
	      2
	      (QUOTE PAINT)
	      (%@ window))
    (AND incr (%@ ticks:,smallTicks)
	 (PROG [(xsmall (IPLUS x 1 (IQUOTIENT incr 2]
	       (DRAWLINE xsmall y xsmall (IPLUS y (IQUOTIENT (%@ ticks:,tickLength)
							     2))
			 1
			 (QUOTE PAINT)
			 (%@ window])

(Gauge.Attach
  [LAMBDA (self obj varName selector otherArgs label machine xOrPos y)
                                                             (* dgb: "23-JUN-83 15:05")
                                                             (* Attach a self to obj/varName)
    (OR (@ title)
	(←@
	  title varName))
    (← self Set (← self AttachProbe obj varName selector otherArgs label machine))
    (← self Update)                                          (* Move if not attached before)
    (OR (CDR (@ attachedTo))
	(← self Move xOrPos y))
    self])

(Gauge.AttachProbe
  [LAMBDA (self obj varName selector otherArgs label machine)
                                                             (* dgb: "10-JUN-83 01:50")
                                                             (* Attach a probe to an object, and record attachment 
							     here in Gauge. Returns current value of obj varName)
    (←@
      attachedTo
      (CONS [CONS obj (CONS varName (COND
			      ((OR machine label)
				(LIST machine label]
	    (@ attachedTo)))                                 (* AttachListAP returns current value of obj varName)
    (COND
      (machine (REMOTEVAL (BQUOTE (AttachListAP ($ , obj)
						(QUOTE , varName)
						(QUOTE RemoteSend)
						(QUOTE remoteCalls)
						(QUOTE , (LIST (UID self)
							       (ETHERHOSTNUMBER)))
						(QUOTE , (OR selector (QUOTE Set)))
						(QUOTE , otherArgs)))
			  machine 1))
      (T (AttachListAP obj varName (QUOTE SendAVMessage)
		       (QUOTE avMessages)
		       self
		       (OR selector (QUOTE Set))
		       otherArgs])

(Gauge.Attached?
  [LAMBDA (self printFlg)                                    (* dgb: "22-JUL-83 16:59")
                                                             (* dgb: "17-FEB-83 13:12")
                                                             (*)
    (COND
      ((NULL printFlg)
	(@ attachedTo))
      [(@ attachedTo)
	(for place machine in (@ attachedTo) first (CLEARW PROMPTWINDOW)
	   do (COND
		((SETQ machine (CADDR place))
		  (printout PROMPTWINDOW "Remotely Attached to " (CAR place)
			    " "
			    (CADR place)
			    " on " machine T))
		(T (printout PROMPTWINDOW "Locally Attached to " (← (CAR place)
								    NameString)
			     " "
			     (CADR place)
			     T]
      (T (CLEARW PROMPTWINDOW)
	 (printout PROMPTWINDOW (CHARACTER 7)
		   "Not attached"])

(Gauge.Close
  [LAMBDA (self)                                             (* dgb: "22-JUL-83 17:00")
                                                             (* Detach the gauge and close the window)
    (AND (← self Attached?)
	 (← self Detach))
    (←Super
      self Close])

(Gauge.Detach
  [LAMBDA (self)                                             (* dgb: "10-JUN-83 00:16")
                                                             (* Detach gauge from attachedPlaces it is attached to)
    (COND
      ((NULL (@ attachedTo))
	(← self Attached?))
      (T (← self Attached?)
	 (printout PROMPTWINDOW "Detaching" T)
	 (for place in (@ attachedTo) finally (←@
						attachedTo NIL)
	    do (← self DetachProbe place])

(Gauge.DetachProbe
  [LAMBDA (self place)                                       (* dgb: "23-JUN-83 14:13")
                                                             (* Detach a probe on a place specified by place, a list 
							     of form (objName varName . otherStuff). Called by 
							     Detach)
    (PROG (machine)
          (COND
	    ((SETQ machine (CADDR place))                    (* remote attachment)
	      (REMOTEVAL [BQUOTE (RemoveListAP ($ , (CAR place))
					       (QUOTE , (CADR place))
					       (QUOTE RemoteSend)
					       (QUOTE remoteCalls)
					       (QUOTE , (LIST (UID self)
							      (ETHERHOSTNUMBER]
			 machine 0))
	    (T                                               (* local gauge)
	       (RemoveListAP (CAR place)
			     (CADR place)
			     (QUOTE SendAVMessage)
			     (QUOTE avMessages)
			     self T])

(Gauge.MaxCurrentReading
  [LAMBDA (self)                                             (* dgb: "10-JUN-83 02:17")
                                                             (* Returns the reading now, since in general there is 
							     only one)
    (@ reading])

(Gauge.Reset
  [LAMBDA (self newReading)                                  (* dgb: " 6-JUN-83 17:43")
                                                             (* set reading to value, and then update gauge so that 
							     it shows that reading without going through intermediate
							     states)
    (←%@
      reading newReading)
    (← self Update])

(Gauge.SetScale
  [LAMBDA (self min max labelScale)                          (* dgb: "23-JUN-83 15:50")
                                                             (* compute the scale and redisplay if necessary)
    (← self ComputeScale min max labelScale)
    (← self Update?])

(Gauge.Update
  [LAMBDA (self)                                             (* dgb: " 9-JUN-83 23:26")
                                                             (* Set up display window for instrument.
							     Reinitialize to reflect current state)
    (← self Clear)
    (← self SetParameters)
    (←Super
      self Update)
    (← self ShowInstrument)
    (← self ShowReading)
    self])

(Gauge.Update?
  [LAMBDA (self)                                             (* dgb: "23-JUN-83 16:00")
                                                             (* Update if there is a window and it is open)
    (AND [NOT (NotSetValue (GetIVHere self (QUOTE window]
	 (ACTIVEWP (GetValue self (QUOTE window)))
	 (← self Update])

(GetPathObj
  [LAMBDA (obj path)                                         (* sm: "12-MAY-83 15:37")
    (COND
      ((NULL path)
	obj)
      (T (GetPathObj (GetValue obj (CAR path))
		     (CDR path])

(HBarChart.DrawInstrument
  [LAMBDA (self)                                             (* dgb: "23-JUL-83 00:16")
                                                             (* Print the labels next to each bar.)
    (for quad in (@ displayVal) first (MOVETO 1 (IPLUS (@ scaleBottom)
						       (@ scaleHeight)
						       (DSPLINEFEED NIL (@ window)))
					      (@ window))
       do (PRINT (CAR quad)
		 (@ window])

(HBarChart.Set
  [LAMBDA (self reading label)                               (* dgb: "22-JUL-83 23:28")
                                                             (* show reading on vertical scale)
    (PROG ((quad (FASSOC label (@ displayVal)))
	   (newSetting (← self ComputeDisplayVal reading)))
          (COND
	    ((NULL quad)
	      (ERROR label "not in this BarChart")))
          (RPLACA (CDDDR quad)
		  reading)
          (ChangeHorizontalSetting (CADR quad)
				   (CADDR quad)
				   newSetting
				   (@ window)
				   (@ barWidth))
          (RPLACA (CDDR quad)
		  newSetting])

(HBarChart.SetParameters
  [LAMBDA (self)                                             (* dgb: "23-JUL-83 00:36")
                                                             (* Set scale hieght from height)
    (PROG [linePos (lf (IMINUS (DSPLINEFEED NIL (@ window]
          (←@
	    barWidth
	    (IPLUS lf -3))                                   (* barWidth is height of font -3.0 height of gauge is 3 
							     lines heigher than number of entries)
          (←@
	    scaleBottom lf)
          [←@
	    scaleHeight
	    (ITIMES lf (LENGTH (@ displayVal]
          (←@
	    height
	    (IPLUS (@ scaleBottom)
		   (@ scaleHeight)
		   (@ ticks:,tickLength)
		   lf 6))
          [for quad in (@ displayVal) finally (←@
						maxLabelWidth w)
	     bind (w ← 0)
		  (wf ←(DSPFONT NIL (@ window)))
	     do (SETQ w (IMAX w (STRINGWIDTH (CAR quad)
					     wf]
          [←@
	    lower
	    (←@
	      scaleLeft
	      (IPLUS 8 (@ maxLabelWidth]
          [←@
	    range
	    (←@
	      scaleWidth
	      (IDIFFERENCE (@ width)
			   (IPLUS (@ scaleLeft)
				  16]
          (SETQ linePos (IPLUS (@ scaleBottom)
			       (@ scaleHeight)))
          (for quad in (@ displayVal)
	     do (SETQ linePos (IDIFFERENCE linePos lf))
		(RPLACA (CDR quad)
			linePos)                             (* Compute position of bar, and then its internal value)
		(RPLACA (CDDR quad)
			(← self ComputeDisplayVal (CADDDR quad])

(HBarChart.ShowReading
  [LAMBDA (self)                                             (* dgb: "23-JUL-83 00:26")
                                                             (* show the line at initial level.
							     intrnal displayVal is really line heigt)
    (for quad in (@ displayVal) bind (c ←(@ scaleLeft)) do (ChangeHorizontalSetting (CADR quad)
										    c
										    (CADDR quad)
										    (@ window)
										    (@ barWidth])

(HorizontalScale.DrawInstrument
  [LAMBDA (self)                                             (* dgb: "21-FEB-83 11:39")
                                                             (* Draw a horizontal tube for instrument)
    (DrawBox (%@ scaleLeft)
	     (%@ scaleBottom)
	     (ADD1 (%@ scaleWidth))
	     (%@ scaleHeight)
	     1
	     (QUOTE PAINT)
	     (%@ window])

(HorizontalScale.OutOfBounds
  [LAMBDA (self outFlg)                                      (* dgb: "21-FEB-83 13:26")
                                                             (* Print "  " or ?? depending on whether reading is out 
							     of bounds)
    (MOVETO (IPLUS (%@ scaleLeft)
		   (%@ scaleWidth))
	    1
	    (%@ window))
    (PRIN1 (COND
	     (outFlg "??")
	     (T "  "))
	   (%@ window])

(HorizontalScale.Set
  [LAMBDA (self reading)                                     (* dgb: " 9-JUN-83 22:57")
                                                             (* show reading on horizontal scale)
    (←@
      reading reading)
    (PROG ((y (ADD1 (@ scaleBottom)))
	   (w (SUB1 (@ scaleHeight)))
	   (displayVal (@ displayVal))
	   (newSetting (← self ComputeDisplayVal reading)))
          (←@
	    displayVal newSetting)
          (COND
	    ((GREATERP displayVal newSetting)
	      (LineLeft displayVal newSetting y (@ window)
			w))
	    ((GREATERP newSetting displayVal)
	      (LineRight displayVal newSetting y (@ window)
			 w])

(HorizontalScale.SetParameters
  [LAMBDA (self)                                             (* dgb: " 9-JUN-83 22:14")
                                                             (* Set scale width from width)
    [←@
      range
      (←@
	scaleWidth
	(IPLUS (@ width)
	       -2
	       (ITIMES -2 (@ scaleLeft]
    [←@
      displayVal
      (←@
	lower
	(ADD1 (@ scaleLeft]
    (←@
      height
      (IMAX (@ height)
	    (IPLUS (@ scaleBottom)
		   (@ scaleHeight)
		   (COND
		     ((@ ticks)
		       (IPLUS (@ ticks:,tickLength)
			      12))
		     (T 3])

(HorizontalScale.ShowLabels
  [LAMBDA (self)                                             (* dgb: "22-FEB-83 11:10")
                                                             (* Put labels next to ticks)
    (AND (%@ ticks)
	 (PROG (xpos (ylabel (IPLUS (%@ scaleBottom)
				    (%@ scaleHeight)
				    (%@ ticks:,tickLength)
				    6)))
	       (SETQ xpos (EvenIntervals (IDIFFERENCE (%@ scaleLeft)
						      3)
					 (%@ scaleWidth)
					 (SUB1 (%@ ticks))
					 T))
	       (for x in xpos as lab in (%@ labels) bind (font ←(DSPFONT NIL (%@ window)))
		  do (MOVETO (IDIFFERENCE (IPLUS x 3)
					  (IQUOTIENT (STRINGWIDTH lab font)
						     2))
			     ylabel
			     (%@ window))
		     (PRIN1 lab (%@ window])

(HorizontalScale.ShowReading
  [LAMBDA (self)                                             (* dgb: "14-JUN-83 00:49")
                                                             (* dgb: " 9-JUN-83 22:37")
                                                             (* show the line at initial level.
							     intrnal displayVal is really line heigt)
    (LineRight (ADD1 (@ scaleLeft))
	       (←@
		 displayVal
		 (← self ComputeDisplayVal (@ reading)))
	       (ADD1 (@ scaleBottom))
	       (@ window)
	       (SUB1 (@ scaleHeight])

(HorizontalScale.ShowTicks
  [LAMBDA (self)                                             (* dgb: "23-JUL-83 00:03")
                                                             (* Show ticks along bottom edge of scale)
    (AND (@ ticks)
	 (PROG ((tickY (IPLUS (@ scaleBottom)
			      (@ scaleHeight)
			      4))
		(tickXs (EvenIntervals (@ scaleLeft)
				       (@ scaleWidth)
				       (SUB1 (@ ticks))
				       T)))
	       (for XT on tickXs do (DrawVTick self (CAR XT)
					       tickY
					       (AND (CDR XT)
						    (IDIFFERENCE (CADR XT)
								 (CAR XT])

(Instrument.ComputeDisplayVal
  [LAMBDA (self reading)                                     (* dgb: " 9-JUN-83 22:15")
                                                             (* Computes displayVal of instrument in bounded range)
    (PLUS (@ lower)
	  (QUOTIENT (TIMES (DIFFERENCE reading (@ inputLower))
			   (@ range))
		    (@ inputRange])

(Instrument.ComputeScale
  [LAMBDA (self min max labelScale)                          (* dgb: "13-JUN-83 23:41")
                                                             (* DECLARATIONS: MIXED)

          (* Compute a scale covering min and max, with ticks and labels at multiples of one of the appropriate multiples of
	  either .2 .25 .5 or 1.0)


    (PROG ((maxTicks (@ ticks))
	   (scalingFactor 1)
	   estIncr goodIncr goodMinVal goodMaxVal range)     (* Don't bother for no ticks)
          (COND
	    ((OR (NULL maxTicks)
		 (EQ maxTicks 0))
	      (←@
		inputLower min)
	      (←@
		inputRange
		(IDIFFERENCE max min))
	      (RETURN)))
          (AND labelScale (←@
		 labelScale labelScale))
          (SETQ estIncr (QUOTIENT (FDIFFERENCE max min)
				  (MIN 10 maxTicks)))
          (while (GREATERP estIncr 1)
	     do (SETQ scalingFactor (TIMES 10 scalingFactor))
		(SETQ estIncr (QUOTIENT estIncr 10)))
          (COND
	    ((EQUAL estIncr 0.0)
	      (ERROR "No range for scale")))
          (while (GREATERP .1 estIncr)
	     do (SETQ scalingFactor (QUOTIENT scalingFactor 10))
		(SETQ estIncr (TIMES estIncr 10)))
          [SETQ goodIncr (TIMES scalingFactor (COND
				  ((GREATERP estIncr .5)
				    1)
				  ((GREATERP estIncr .25)
				    .5)
				  ((GREATERP estIncr .2)
				    .25)
				  ((GREATERP estIncr .1)
				    .2)
				  (T .1]
          [SETQ goodMinVal (TIMES goodIncr (FIX (QUOTIENT min goodIncr]
          [SETQ goodMaxVal (TIMES goodIncr (FIX (QUOTIENT max goodIncr]

          (* * Comput labelScale if not given one)


          (OR labelScale (bind (t1 ← 1)
			       (m1 ← goodMaxVal) while (GREATERP m1 100)
			    do (SETQ m1 (FQUOTIENT m1 10))
			       (SETQ t1 (ITIMES t1 10))
			    finally (SETQ labelScale t1)))
          (←@
	    labelScale labelScale)

          (* * Now compute labels)


          (COND
	    ((GREATERP max goodMaxVal)
	      (SETQ goodMaxVal (FPLUS goodMaxVal goodIncr)
		goodIncr)))
          (←@
	    labels
	    (ComputeLabels goodMinVal goodIncr goodMaxVal labelScale))
          (←@
	    ticks
	    (LENGTH (@ labels)))
          (←@
	    inputLower goodMinVal)
          (←@
	    inputRange
	    (IDIFFERENCE goodMaxVal goodMinVal])

(Instrument.PrintLabelScale
  [LAMBDA (self)                                             (* dgb: "21-FEB-83 13:28")
                                                             (* Print the scale of labelling on instrument)
    (AND (%@ ticks)
	 (COND
	   ((NEQ 1 (%@ labelScale))
	     (MOVETO 1 1 (%@ window))
	     (PRIN1 (QUOTE X)
		    (%@ window))
	     (PRIN1 (%@ labelScale)
		    (%@ window])

(Instrument.SetParameters
  [LAMBDA (self)                                             (* dgb: "27-JAN-83 01:03")
                                                             (* Dummy function where default values are appropriate)
    self])

(Instrument.ShowInstrument
  [LAMBDA (self)                                             (* dgb: " 9-JUN-83 22:15")
                                                             (* show the instrument including the current displayVal)
    (← self DrawInstrument)
    (AND (@ ticks)
	 (PROGN (← self ShowTicks)
		(← self ShowLabels)))
    (← self PrintLabelScale])

(LCD.ComputeScale
  [LAMBDA (self min max)                                     (* dgb: "29-JAN-83 01:56")
                                                             (* Sets the precision based on the width of min and max)
    (←%@
      precision
      (IMAX (NCHARS min)
	    (NCHARS max])

(LCD.PrintReading
  [LAMBDA (self)                                             (* dgb: "14-JUL-83 22:23")
                                                             (* dgb: " 9-JUN-83 22:15")
                                                             (* Print the displayVal in the readingRegion by painting
							     black and then inverting)
    (AND (← self HasLispWindow)
	 (PROG (w n op rdString)
	       [SETQ rdString (COND
		   ((Object? (@ reading))
		     (← (@ reading)
			NameString))
		   (T (@ reading]
	       (SETQ w (NCHARS rdString))
	       (COND
		 ((IGREATERP 0 (SETQ n (IDIFFERENCE (@ precision)
						    w)))

          (* * String too long, change precison and make window grow if necessary)


		   (←@
		     precision w)
		   (← self Update)))
	       (DSPFILL (@ precision:,readingRegion)
			BLACKSHADE
			(QUOTE PAINT)
			(@ window))
	       (SETQ op (DSPOPERATION (QUOTE INVERT)
				      (@ window)))
	       (CENTERPRINTINREGION rdString (@ precision:,readingRegion)
				    (@ window))
	       (DSPOPERATION op (@ window])

(LCD.Reset
  [LAMBDA (self newReading)                                  (* dgb: "13-JUN-83 11:18")
                                                             (* set reading to value. Same as Set since there is no 
							     special way to do this)
    (← self Set newReading])

(LCD.Set
  [LAMBDA (self reading)                                     (* dgb: "10-JUN-83 00:30")
                                                             (* Put number in box)
    (←@
      reading reading)
    (← self PrintReading])

(LCD.SetParameters
  [LAMBDA (self)                                             (* dgb: "21-FEB-83 15:02")
                                                             (* Set the font for the window)
    (PROG [(readingHeight (IPLUS 4 (FONTHEIGHT (%@%@ Font]
          (DSPFONT (%@%@ Font)
		   (%@ window))
          [←%@
	    width
	    (MAX (TitleWidth (%@ title))
		 (%@ width)
		 (PLUS 2 (TIMES (%@ precision)
				(CHARWIDTH 65 (%@%@ Font]
          [←%@
	    height
	    (MAX (%@ height)
		 (IPLUS 2 (FONTHEIGHT (%@%@ Font]
          (←%@
	    readingY
	    (MAX (%@ readingY)
		 (IQUOTIENT (%@ height)
			    2)))
          (←%@
	    precision:,readingRegion
	    (create REGION
		    LEFT ← 1
		    BOTTOM ←(IPLUS (%@ readingY)
				   -1
				   (IQUOTIENT readingHeight -2))
		    WIDTH ←(IDIFFERENCE (%@ width)
					2)
		    HEIGHT ← readingHeight])

(LCD.ShowInstrument
  [LAMBDA (self)                                             (* dgb: "28-JAN-83 14:29")
                                                             (* Nothing needed)
    self])

(LCD.ShowReading
  [LAMBDA (self)                                             (* dgb: " 9-JUN-83 23:47")
                                                             (* dgb: " 9-JUN-83 22:15")
                                                             (* Put the displayVal up on the instrument)
    (← self PrintReading])

(LCD.SmallRegion
  [LAMBDA (self)                                             (* dgb: "21-FEB-83 14:56")
    (←%@
      precision:,readingRegion
      (PROG [(readingHeight (FONTHEIGHT (%@%@ Font)))
	     (readingWidth (IPLUS 4 (ITIMES (%@ precision)
					    (CHARWIDTH 65 (%@%@ Font]
	    (RETURN (create REGION
			    LEFT ←(IQUOTIENT (IDIFFERENCE (%@ width)
							  readingWidth)
					     2)
			    BOTTOM ←(IPLUS (%@ readingY)
					   (IQUOTIENT readingHeight -2))
			    WIDTH ← readingWidth
			    HEIGHT ← readingHeight])

(Meter.ComputeScale
  [LAMBDA (self min max labelScale)                          (* dgb: "21-FEB-83 09:26")
                                                             (* ordinary computation, followed by adjustment of 
							     numTicks and labels)
    (←Super
      self ComputeScale min max labelScale)
    (←%@
      ticks
      (SUB1 (%@ ticks)))                                     (* Remove last label and subtract one from number of 
							     ticks)
    [←%@
      labels
      (DREVERSE (CDR (DREVERSE (%@ labels]
    T])

(Meter.DrawInstrument
  [LAMBDA (self)                                             (* dgb: "21-FEB-83 10:53")
                                                             (*)
    (DRAWCIRCLE (%@ xc)
		(%@ yc)
		(%@ radius)
		2 NIL (%@ window])

(Meter.SetParameters
  [LAMBDA (self)                                             (* dgb: "10-JUN-83 11:44")
                                                             (* Compute center and radius for meters)
                                                             (* Height leaves room for extra line at top)
    [←@
      height
      (←@
	width
	(MIN (@ height)
	     (@ width]                                       (* radius leaves room for lavels around sides)
    (←@
      yc
      (←@
	xc
	(IQUOTIENT (@ width)
		   2)))
    [←@
      radius
      (IDIFFERENCE (@ yc)
		   (IMIN 18 (IPLUS 6 (MAXSTRINGWIDTH (@ labels]
    (←@
      needleLength
      (IDIFFERENCE (@ radius)
		   (@ ticks:,tickLength])

(Meter.Shape
  [LAMBDA (self newRegion)                                   (* dgb: "28-JAN-83 13:09")
                                                             (*)
    (PROG ((reg (←Super
		  self Shape newRegion)))
          (←%@
	    width
	    (IMIN (fetch WIDTH of reg)
		  (fetch HEIGHT of reg])

(Meter.ShowLabels
  [LAMBDA (self)                                             (* dgb: "21-FEB-83 09:32")
                                                             (* If there are any labels, show thenm on the dial)
    (COND
      ((%@ labels)
	(DSPRIGHTMARGIN (IPLUS (%@ width)
			       50)
			(%@ window))                         (* so that labels on the right won't go to the next 
							     line)
	(for lab in (%@ labels) as a in (EvenIntervals 90 -360 (%@ ticks))
	   do (ShowRayLabel self a lab])

(Meter.ShowTicks
  [LAMBDA (self)                                             (* dgb: "21-FEB-83 10:54")
                                                             (* *Draw ticks at even intervals around the circle 
							     starting from 90)
    (for a in (EvenIntervals 90 -360 (%@ ticks)) bind (incr ←(IQUOTIENT -360 (%@ ticks)))
       do (DrawTick self a (%@ ticks:,smallTicks)
		    incr .5])

(MoveImageRight
  [LAMBDA (WINDOW XDELTA)                                    (* dgb: "11-JAN-83 10:54")
                                                             (* scrolling function that scrolls by blting existing 
							     bits and then filling with background the newly exposed 
							     bits. Copied from SCROLLBYREPAINTFN)
    (PROG ((DSP (WINDOWPROP WINDOW (QUOTE DSP)))
	   (EXTENT (WINDOWPROP WINDOW (QUOTE EXTENT)))
	   CLIPREG)
          (SETQ CLIPREG (DSPCLIPPINGREGION NIL DSP))
          (COND
	    ((AND (NEQ XDELTA 0)
		  (COND
		    ((AND EXTENT (NEQ (fetch (REGION WIDTH) of EXTENT)
				      -1))                   (* limit amount by the extent)
                                                             (* for now limit right extent to right of window to keep
							     it always visible.)
		      (SETQ XDELTA (IMIN (IDIFFERENCE (fetch (REGION LEFT) of CLIPREG)
						      (fetch (REGION LEFT) of EXTENT))
					 (IMAX (IDIFFERENCE (fetch (REGION PRIGHT) of CLIPREG)
							    (fetch (REGION PRIGHT) of EXTENT))
					       XDELTA)))     (* make sure it is still not 0)
		      (NEQ XDELTA 0))
		    (T T)))
	      (BITBLT WINDOW (WTODSX 0 WINDOW)
		      (WTODSY 0 WINDOW)
		      WINDOW
		      (WTODSX XDELTA WINDOW)
		      (WTODSY 0 WINDOW)
		      (fetch (REGION WIDTH) of CLIPREG)
		      (fetch (REGION HEIGHT) of CLIPREG))
	      (WXOFFSET XDELTA DSP)
	      (FILLWITHBACKGROUND WINDOW (COND
				    ((IGREATERP XDELTA 0)    (* moving to right, create new region on left for 
							     repaintfn)
				      (create REGION
					      LEFT ←(WTODSX 0 WINDOW)
					      BOTTOM ←(WTODSY 0 WINDOW)
					      WIDTH ←(IMIN XDELTA (fetch (REGION WIDTH) of CLIPREG))
					      HEIGHT ←(fetch (REGION HEIGHT) of CLIPREG)))
				    (T                       (* moving to left.)
				       (create REGION
					       LEFT ←(IMAX (WTODSX (IPLUS (fetch (REGION WIDTH)
									     of CLIPREG)
									  XDELTA)
								   WINDOW)
							   (fetch (REGION LEFT) of CLIPREG))
					       BOTTOM ←(WTODSY 0 WINDOW)
					       WIDTH ←(IMIN (IMINUS XDELTA)
							    (fetch (REGION WIDTH) of CLIPREG))
					       HEIGHT ←(fetch (REGION HEIGHT) of CLIPREG])

(MultiValueMixin.AddLabel
  [LAMBDA (self label labelReading)                          (* mjs: "22-JUL-83 11:42")
                                                             (* add to the list of bars on the chart)
    (←@
      displayVal
      (CONS (LIST label 0 (← self ComputeDisplayVal labelReading)
		  labelReading)
	    (LISTP (@ displayVal])

(MultiValueMixin.Attach
  [LAMBDA (self obj varName selector label machine xOrPos y)
                                                             (* dgb: "20-SEP-83 17:09")
                                                             (* Attach to obj varName and label it in chart with 
							     label)
    (PROG NIL
          (OR label (SETQ label (PromptRead 
		     "Label needed to attach 
on MultiValue Gauges.  Type label or NIL to abort:"))
	      (RETURN NIL))
          (COND
	    ((FASSOC label (@ displayVal))
	      (ERROR label "is already in use in MultiValueMixin")))
          (← self AddLabel label (← self AttachProbe obj varName (QUOTE Set)
				    (LIST label)
				    label machine))
          (← self Update)                                    (* Move if not attached before)
          (OR (CDR (@ attachedTo))
	      (← self Move xOrPos y))
      self])

(MultiValueMixin.DeleteLabel
  [LAMBDA (self label updateFlg)                             (* mjs: "22-JUL-83 11:43")
                                                             (* Remove a bar from a chart)
    (COND
      [label (←@
	       displayVal
	       (DELASSOC label (@ displayVal]
      (T (←@
	   displayVal NIL)))
    (AND updateFlg (← self Update])

(MultiValueMixin.Detach
  [LAMBDA (self label)                                       (* dgb: "22-JUL-83 16:45")
                                                             (* Detach gauge from attachedPlaces it is attached to)
    (COND
      ((NULL label)                                          (* If no label is specified, iterate thru labels and 
							     detach them all.)
	(for (dv lab) in (@ displayVal)
	   do (SETQ lab (CAR dv))
	      (← self Detach lab)))
      ([OR (NULL (@ attachedTo))
	   (NULL (FASSOC label (@ displayVal]
	(← self Attached?))
      (T (← self DeleteLabel label)
	 (← self Attached?)
	 (printout PROMPTWINDOW "Detaching" T)
	 (←@
	   attachedTo
	   (for place in (@ attachedTo) join (COND
					       ((OR (NULL label)
						    (EQ label (CADDDR place)))
						 (← self DetachProbe place)
						 NIL)
					       (T            (* Keep this place)
						  (LIST place])

(MultiValueMixin.MaxCurrentReading
  [LAMBDA (self)                                             (* mjs: "22-JUL-83 11:43")
                                                             (* return the max readinr in 
							     (@ reading))
    (for quad in (@ displayVal) bind (max ←(@ inputLower)) do (SETQ max (IMAX (CADDDR quad)
									      max))
       finally (RETURN max])

(MultiValueMixin.OutOfBounds
  [LAMBDA (self outFlg)                                      (* mjs: "22-JUL-83 11:43")
                                                             (* Print ? if out, space other wise)
    (MOVETO (IDIFFERENCE (fetch WIDTH of (WINDOWPROP (@ window)
						     (QUOTE REGION)))
			 24)
	    2
	    (@ window))
    (PRIN1 (COND
	     (outFlg "??")
	     (T "  "))
	   (@ window])

(MultiValueMixin.SetUp
  [LAMBDA (self listOfObjects ivName chartTitle maxScale path machine xOrPos y)
                                                             (* dgb: "22-JUL-83 16:47")

          (* Attach a bar chart to the iv of specified by the object in the list, and the path. path can be an atom, meaning
	  that IV, or it can be a list of atoms to be followed, each an iv name. Each bar on the chart will be labelled with
	  the name of the object on listOfObjects. title will be used for the BarChart.)


    (bind gaugedObj first (←@
			    self title chartTitle)
       for obj in listOfObjects bind label
       do (SETQ gaugedObj (GetPathObj obj path))
	  (SETQ label (OR (GetObjectName obj)
			  obj))
	  (← self AddLabel label (← self AttachProbe gaugedObj ivName (QUOTE Set)
				    (LIST label)
				    label machine))
       finally (AND maxScale (← self SetScale 0 maxScale))
	       (← self Update)
	       (← self Move xOrPos y)
	       (RETURN self])

(RoundScale.Reset
  [LAMBDA (self newReading)                                  (* dgb: "13-JUN-83 10:57")
                                                             (* set reading to value, and then update gauge so that 
							     it shows that reading without going through intermediate
							     states)
    (← self ShowReading)
    (←@
      reading newReading)
    (← self ShowReading])

(RoundScale.Set
  [LAMBDA (self reading)                                     (* edited: "14-JUL-83 10:21")
                                                             (* dgb: "27-JAN-83 11:34")
                                                             (* Move the setting on a RoundScale instrument from 
							     current setting to taht specified by input.)
    (PROG ((newVal (← self ComputeDisplayVal reading)))
          (COND
	    ((IGREATERP (IABS (IDIFFERENCE newVal (@ displayVal)))
			540)                                 (* Don't spin more than one and a half revolutions.
							     Just reset)
	      (← self Reset reading))
	    (T (←@
		 reading reading)
	       (AND (← self HasLispWindow)
		    (RotateLine (@ xc)
				(@ yc)
				(@ needleLength)
				(@ displayVal)
				(←@
				  displayVal newVal)
				(@ window)
				2])

(RoundScale.ShowReading
  [LAMBDA (self)                                             (* dgb: " 9-JUN-83 23:38")
                                                             (* dgb: "26-JAN-83 23:43")
                                                             (*)
    (DrawRay (@ xc)
	     (@ yc)
	     (@ needleLength)
	     (←@
	       displayVal
	       (← self ComputeDisplayVal (@ reading)))
	     2
	     (QUOTE INVERT)
	     (@ window])

(SelfScaleMixin.Set
  [LAMBDA (self reading otherArg1 otherArg2)                 (* dgb: "13-JUN-83 21:06")
                                                             (* Check if reading is too high or too low, and if so 
							     see if gauge needs to rescale)
    (←Super
      self Set reading otherArg1 otherArg2)
    (PROG (maxDiff (max (← self MaxCurrentReading)))
          (COND
	    [(IGREATERP (SETQ maxDiff (IDIFFERENCE max (@ inputLower)))
			(@ inputRange))                      (* If max is greater than previous max then change range
							     to make current max be 4/5 of full scale)
	      (← self SetScale (@ inputLower)
		 (IPLUS (@ inputLower)
			(IQUOTIENT (ITIMES 5 maxDiff)
				   4]
	    ((AND (IGREATERP (@ inputRange)
			     (ITIMES maxDiff (@ lowScaleFactor)))
		  (IGREATERP @inputRange 10))

          (* If max is less than lowScaleFactor times range, and newMax would not be less than 10, then change range to make
	  current max be 4/5 of full scale)


	      (← self SetScale (@ inputLower)
		 (IPLUS (@ inputLower)
			(IMAX 10 (IQUOTIENT (ITIMES 5 maxDiff)
					    4])

(SetUpBarChart
  [LAMBDA (listOfObjects ivName chartTitle maxScale path)    (* sm: "12-MAY-83 15:32")

          (* Attach a bar chart to the iv of specified by the object in the list, and the path. path can be an atom, meaning
	  that IV, or it can be a list of atoms to be followed, each an iv name. Each bar on the chart will be labelled with
	  the name of the object on listOfObjects. title will be used for the BarChart.)


    (bind gaugedObj bc first (←%@(SETQ bc (← (%$ BarChart)
					     New))
			       title chartTitle)
       for obj in listOfObjects
       do (SETQ gaugedObj (GetPathObj obj path))
	  (← bc Attach gaugedObj ivName (QUOTE Set)
	     (OR (GetObjectName obj)
		 obj))
	  (AND maxScale (← bc SetScale 0 maxScale))
       finally (RETURN bc])

(SubclassResponsibility
  [LAMBDA (self)                                             (* dgb: "21-FEB-83 10:12")
                                                             (* Error. Should be implemented in subclass)
    (HELPCHECK "Should have been implemented in subclass"])

(VerticalScale.DrawInstrument
  [LAMBDA (self)                                             (* dgb: "30-JAN-83 12:40")
                                                             (* Draw a vertical tube for instrument)
    (DrawBox (%@ scaleLeft)
	     (%@ scaleBottom)
	     (%@ scaleWidth)
	     (ADD1 (%@ scaleHeight))
	     1
	     (QUOTE PAINT)
	     (%@ window])

(VerticalScale.Set
  [LAMBDA (self reading)                                     (* dgb: " 9-JUN-83 22:57")
                                                             (* show reading on vertical scale)
    (←@
      reading reading)
    (PROG ((x (ADD1 (@ scaleLeft)))
	   (w (SUB1 (@ scaleWidth)))
	   (displayVal (@ displayVal))
	   (newSetting (← self ComputeDisplayVal reading)))
          (←@
	    displayVal newSetting)
          (ChangeVerticalSetting x displayVal newSetting (@ window)
				 w])

(VerticalScale.SetParameters
  [LAMBDA (self)                                             (* dgb: " 9-JUN-83 22:15")
                                                             (* Set scale hieght from height)
    [←@
      range
      (←@
	scaleHeight
	(IDIFFERENCE (@ height)
		     (IPLUS 8 (@ scaleBottom]
    [←@
      displayVal
      (←@
	lower
	(ADD1 (@ scaleBottom]
    (←@
      width
      (IMAX (@ width)
	    (IPLUS (@ scaleLeft)
		   (@ scaleWidth)
		   (COND
		     ((@ ticks)
		       (IPLUS (@ ticks:,tickLength)
			      30))
		     (T 0])

(VerticalScale.ShowLabels
  [LAMBDA (self)                                             (* dgb: "21-FEB-83 10:58")
                                                             (* Put labels next to ticks)
    (AND (%@ ticks)
	 (PROG (ypos (xlabel (IPLUS (%@ scaleLeft)
				    (%@ scaleWidth)
				    (%@ ticks:,tickLength)
				    6)))
	       (SETQ ypos (EvenIntervals (IDIFFERENCE (%@ scaleBottom)
						      3)
					 (%@ scaleHeight)
					 (SUB1 (%@ ticks))
					 T))
	       (for y in ypos as lab in (%@ labels)
		  do (MOVETO xlabel y (%@ window))
		     (PRIN1 lab (%@ window])

(VerticalScale.ShowReading
  [LAMBDA (self)                                             (* dgb: "13-JUN-83 10:53")
                                                             (* dgb: " 9-JUN-83 22:37")
                                                             (* show the line at initial level.
							     intrnal displayVal is really line heigt)
    (ChangeVerticalSetting (ADD1 (@ scaleLeft))
			   (ADD1 (@ scaleBottom))
			   (←@
			     displayVal
			     (← self ComputeDisplayVal (@ reading)))
			   (@ window)
			   (SUB1 (@ scaleWidth])

(VerticalScale.ShowTicks
  [LAMBDA (self)                                             (* dgb: "21-FEB-83 09:34")
                                                             (* Show ticks along right edge of scale)
    (PROG ((tickX (IPLUS (%@ scaleLeft)
			 (%@ scaleWidth)
			 4))
	   (tickYs (EvenIntervals (%@ scaleBottom)
				  (%@ scaleHeight)
				  (SUB1 (%@ ticks))
				  T)))
          (for YT on tickYs do (DrawHTick self tickX (CAR YT)
					  (AND (CDR YT)
					       (IDIFFERENCE (CADR YT)
							    (CAR YT])
)
(* * Utility functions for Gauges)


(RPAQQ GAUGEUTILITYFNS (CenterPrint ConcatNSpaces DrawBox DrawHTick DrawRay DrawTick EvenIntervals 
				    LineLeft LineLower PinnedSetting PrintLabelScale LineRaise 
				    LineRight RotateLine ShowRayLabel TellInstrument TitleWidth))
(DEFINEQ

(CenterPrint
  [LAMBDA (string xpos ypos window)                          (* dgb: "25-JAN-83 16:22")
                                                             (* Print string centered around xpos at height ypos)
    (MOVETO (IDIFFERENCE xpos (LRSH (STRINGWIDTH string (DSPFONT NIL window))
				    1))
	    ypos window)
    (PRIN1 string window])

(ConcatNSpaces
  [LAMBDA (N string)                                         (* dgb: "25-JAN-83 16:23")
                                                             (* Put N Spaces on the front of a string.
							     Good for making fixed width strings)
    (CONCAT (SELECTQ N
		     (0 "")
		     (1 " ")
		     (2 "  ")
		     (3 "   ")
		     (4 "    ")
		     "     ")
	    (COND
	      ((IGREATERP N 5)
		(ConcatNSpaces (IDIFFERENCE N 5)
			       string))
	      (T string])

(DrawBox
  [LAMBDA (left bottom width height lineWidth operation window)
                                                             (* dgb: "29-JAN-83 01:01")
    (PROG ((topy (IPLUS bottom height))
	   (topx (IPLUS left width)))                        (* left)
          (DRAWLINE left bottom left topy lineWidth operation window)
                                                             (* bottom)
          (DRAWLINE left bottom topx bottom lineWidth operation window)
                                                             (* right)
          (DRAWLINE topx bottom topx topy lineWidth operation window)
                                                             (* top)
          (DRAWLINE left topy topx topy lineWidth operation window])

(DrawHTick
  [LAMBDA (self x y incr)                                    (* dgb: "21-FEB-83 09:36")
                                                             (* Draw a horizontal line for a tick)
    (DRAWLINE x y (IPLUS x (%@ ticks:,tickLength))
	      y 2 (QUOTE PAINT)
	      (%@ window))
    (AND incr (%@ ticks:,smallTicks)
	 (PROG [(ysmall (IPLUS y 1 (IQUOTIENT incr 2]
	       (DRAWLINE x ysmall (IPLUS x (IQUOTIENT (%@ ticks:,tickLength)
						      2))
			 ysmall 1 (QUOTE PAINT)
			 (%@ window])

(DrawRay
  [LAMBDA (x y length angle width operation window color invisLength)
                                                             (* dgb: "11-JAN-83 13:12")

          (* Draw a ray from center xy y at angle of length. If invisLength is given, only draw the end of the ray that is 
	  visible)


    (PROG ((s (SIN angle))
	   (c (COS angle)))
          (DRAWLINE (COND
		      (invisLength (PLUS x (TIMES invisLength c)))
		      (T x))
		    (COND
		      (invisLength (PLUS y (TIMES invisLength s)))
		      (T y))
		    (PLUS x (TIMES length c))
		    (PLUS y (TIMES length s))
		    width operation window color])

(DrawTick
  [LAMBDA (self angle numExtraTicks incr smallSizeFactor)    (* dgb: "21-FEB-83 09:38")
                                                             (* Draw a tick and potentially some small ticks)
    (PROG ((tickLength (%@ ticks:,tickLength))
	   invisLength)
          (DrawRay (%@ xc)
		   (%@ yc)
		   (%@ radius)
		   angle 2 (QUOTE PAINT)
		   (%@ window)
		   NIL
		   (IDIFFERENCE (%@ radius)
				tickLength))
          (OR numExtraTicks (RETURN))                        (* Go on only if there are extra small ticks)
          [SETQ invisLength (IDIFFERENCE (%@ radius)
					 (COND
					   (smallSizeFactor (TIMES tickLength smallSizeFactor))
					   (T tickLength]
          (for i from 1 to numExtraTicks bind (nt1 ←(ADD1 numExtraTicks))
	     do (DrawRay (%@ xc)
			 (%@ yc)
			 (%@ radius)
			 (IPLUS angle (IQUOTIENT (TIMES i incr)
						 nt1))
			 2
			 (QUOTE PAINT)
			 (%@ window)
			 NIL invisLength])

(EvenIntervals
  [LAMBDA (lower range numIntervals includeLastFlg)          (* dgb: "29-JAN-83 00:17")
                                                             (* Produces a list of integers in best approximation of 
							     an integer linear scale between ower and lower+range.
							     Include lower+range only if includeLastFlg=T.)
    (for i from 0 to numIntervals when (OR includeLastFlg (NEQ i numIntervals))
       collect (IPLUS lower (IQUOTIENT (ITIMES i range)
				       numIntervals])

(LineLeft
  [LAMBDA (XA XB Y window height wait shade)                 (* dgb: "10-JUL-83 21:19")
                                                             (* Draw a thick line, reducing the size from XB to XA.
							     XA>XB to work)
    (for I from 1 to (IDIFFERENCE XA XB)
       do (WAITMS (OR wait 2))
	  (BITBLT NIL NIL NIL window (IDIFFERENCE XA I)
		  Y 1 (OR height 4)
		  (QUOTE TEXTURE)
		  (QUOTE INVERT)
		  (OR shade BLACKSHADE])

(LineLower
  [LAMBDA (X YA YB window width wait shade)                  (* dgb: "10-JUL-83 21:19")
    (for I from 1 to (IABS (IDIFFERENCE YB YA))
       do (WAITMS (OR wait 2))
	  (BITBLT NIL NIL NIL window X (IDIFFERENCE (IMAX YA YB)
						    I)
		  (OR width 4)
		  1
		  (QUOTE TEXTURE)
		  (QUOTE INVERT)
		  (OR shade BLACKSHADE])

(PinnedSetting
  [LAMBDA (reading minSetting maxSetting)                    (* dgb: "25-JAN-83 16:31")
                                                             (* Returns the value of reading if it is between 
							     minSetting and maxSetting, else the "pinned" value)
    (COND
      ((GREATERP minSetting reading)
	minSetting)
      ((GREATERP reading maxSetting)
	maxSetting)
      (T reading])

(PrintLabelScale
  [LAMBDA (self)                                             (* dgb: "28-JAN-83 18:38")
    (COND
      ((NEQ 1 (%@ labelScale))
	(MOVETO 1 1 (%@ window))
	(PRIN1 (QUOTE X)
	       (%@ window))
	(PRIN1 (%@ labelScale)
	       (%@ window])

(LineRaise
  [LAMBDA (X YA YB window width wait shade)                  (* dgb: "10-JUL-83 21:19")
    (for I from 0 to (SUB1 (IABS (IDIFFERENCE YB YA)))
       do (WAITMS (OR wait 2))
	  (BITBLT NIL NIL NIL window X (IPLUS I (IMIN YA YB))
		  (OR width 4)
		  1
		  (QUOTE TEXTURE)
		  (QUOTE PAINT)
		  (OR shade BLACKSHADE])

(LineRight
  [LAMBDA (XA XB Y window height wait shade)                 (* dgb: "10-JUL-83 21:19")
    (for I from 0 to (SUB1 (IDIFFERENCE XB XA))
       do (WAITMS (OR wait 2))
	  (BITBLT NIL NIL NIL window (IPLUS I XA)
		  Y 1 (OR height 4)
		  (QUOTE TEXTURE)
		  (QUOTE PAINT)
		  (OR shade BLACKSHADE])

(RotateLine
  [LAMBDA (xorg yorg length angle newAngle window width deltaAngle color)
                                                             (* dgb: "11-JUL-83 14:16")
    (PROG (incr (diff (IDIFFERENCE newAngle angle)))
          (COND
	    ((EQUAL angle newAngle)
	      (RETURN)))                                     (* First erase the current needle)
          (DrawRay xorg yorg length angle width (QUOTE INVERT)
		   window color)
          [SETQ incr (COND
	      ((IGREATERP -5 diff)
		(IMINUS (OR deltaAngle 5)))
	      [(IGREATERP diff 5)
		(OR deltaAngle (IMAX 5 (IQUOTIENT diff 8]
	      (T (GO end]
          (for a from (IPLUS angle incr) to (IDIFFERENCE newAngle incr) by incr
	     do (DrawRay xorg yorg length a width (QUOTE INVERT)
			 window color)                       (* Draw and then erase a line)
		(DrawRay xorg yorg length a width (QUOTE INVERT)
			 window color))
      end                                                    (* Now draw final needle)
          (DrawRay xorg yorg length newAngle width (QUOTE INVERT)
		   window color])

(ShowRayLabel
  [LAMBDA (self angle string)                                (* dgb: "10-JUN-83 11:47")

          (* Draw a ray from center xy y at angle of length. If invisLength is given, only draw the end of the ray that is 
	  visible)


    (PROG ((length (IPLUS (@ radius)
			  3
			  (IQUOTIENT (MAXSTRINGWIDTH (@ labels))
				     2)))
	   (s (SIN angle))
	   (c (COS angle)))
          (CenterPrint string (PLUS (@ xc)
				    (TIMES length c))
		       (PLUS (@ yc)
			     3
			     (IQUOTIENT (DSPLINEFEED NIL (@ window))
					2)
			     (TIMES length s))
		       (@ window])

(TellInstrument
  [LAMBDA (self varName newValue propName activeVal type)    (* mjs: "17-FEB-83 15:11")
                                                             (* This is a putFn for changing attached instruments)
    (PROG ((temp (PutLocalState activeVal newValue self varName propName type)))
          (for instrument in (GetIt self varName (QUOTE myGauges)
				    type)
	     do (← instrument Set newValue))
          (RETURN temp])

(TitleWidth
  [LAMBDA (str)                                              (* dgb: "21-JAN-83 14:44")
    (STRINGWIDTH str (DSPFONT NIL WindowTitleDisplayStream])
)

(RPAQQ GB (MultiValueMixin SelfScaleMixin SelfScaleBarChart BoundedMixin VerticalScale BarChart 
			   RoundScale HorizontalScale DigiScale LCD Gauge DigiMeter Instrument Meter 
			   Dial))
(DECLARE: DONTCOPY
  (FILEMAP (NIL (24468 75027 (BarChart.DrawInstrument 24478 . 25060) (BarChart.Set 25062 . 25750) (
BarChart.SetParameters 25752 . 26812) (BarChart.ShowReading 26814 . 27459) (BarChart.Update 27461 . 
27839) (BoundedMixin.ComputeDisplayVal 27841 . 28499) (BoundedMixin.OutOfBounds 28501 . 28828) (
ChangeHorizontalSetting 28830 . 29269) (ChangeVerticalSetting 29271 . 29605) (ComputeLabels 29607 . 
30658) (Dial.DrawInstrument 30660 . 31146) (Dial.SetParameters 31148 . 31890) (Dial.ShowLabels 31892
 . 32542) (Dial.ShowTicks 32544 . 33047) (DigiMeter.ComputeScale 33049 . 33345) (DigiMeter.Set 33347
 . 33600) (DigiMeter.SetParameters 33602 . 34319) (DigiMeter.ShowReading 34321 . 34694) (
DigiMeter.Update 34696 . 34916) (DigiScale.Set 34918 . 35164) (DigiScale.SetParameters 35166 . 35755) 
(DigiScale.ShowReading 35757 . 36111) (DrawLines 36113 . 36827) (DrawVTick 36829 . 37359) (
Gauge.Attach 37361 . 37926) (Gauge.AttachProbe 37928 . 38977) (Gauge.Attached? 38979 . 39809) (
Gauge.Close 39811 . 40104) (Gauge.Detach 40106 . 40584) (Gauge.DetachProbe 40586 . 41473) (
Gauge.MaxCurrentReading 41475 . 41758) (Gauge.Reset 41760 . 42142) (Gauge.SetScale 42144 . 42436) (
Gauge.Update 42438 . 42849) (Gauge.Update? 42851 . 43194) (GetPathObj 43196 . 43407) (
HBarChart.DrawInstrument 43409 . 43859) (HBarChart.Set 43861 . 44471) (HBarChart.SetParameters 44473
 . 45942) (HBarChart.ShowReading 45944 . 46431) (HorizontalScale.DrawInstrument 46433 . 46821) (
HorizontalScale.OutOfBounds 46823 . 47247) (HorizontalScale.Set 47249 . 47916) (
HorizontalScale.SetParameters 47918 . 48495) (HorizontalScale.ShowLabels 48497 . 49257) (
HorizontalScale.ShowReading 49259 . 49822) (HorizontalScale.ShowTicks 49824 . 50428) (
Instrument.ComputeDisplayVal 50430 . 50790) (Instrument.ComputeScale 50792 . 53075) (
Instrument.PrintLabelScale 53077 . 53490) (Instrument.SetParameters 53492 . 53745) (
Instrument.ShowInstrument 53747 . 54120) (LCD.ComputeScale 54122 . 54426) (LCD.PrintReading 54428 . 
55513) (LCD.Reset 55515 . 55811) (LCD.Set 55813 . 56062) (LCD.SetParameters 56064 . 56942) (
LCD.ShowInstrument 56944 . 57154) (LCD.ShowReading 57156 . 57496) (LCD.SmallRegion 57498 . 58041) (
Meter.ComputeScale 58043 . 58604) (Meter.DrawInstrument 58606 . 58861) (Meter.SetParameters 58863 . 
59600) (Meter.Shape 59602 . 59932) (Meter.ShowLabels 59934 . 60491) (Meter.ShowTicks 60493 . 60936) (
MoveImageRight 60938 . 63289) (MultiValueMixin.AddLabel 63291 . 63655) (MultiValueMixin.Attach 63657
 . 64556) (MultiValueMixin.DeleteLabel 64558 . 64933) (MultiValueMixin.Detach 64935 . 65894) (
MultiValueMixin.MaxCurrentReading 65896 . 66312) (MultiValueMixin.OutOfBounds 66314 . 66741) (
MultiValueMixin.SetUp 66743 . 67772) (RoundScale.Reset 67774 . 68190) (RoundScale.Set 68192 . 69068) (
RoundScale.ShowReading 69070 . 69534) (SelfScaleMixin.Set 69536 . 70680) (SetUpBarChart 70682 . 71500)
 (SubclassResponsibility 71502 . 71791) (VerticalScale.DrawInstrument 71793 . 72177) (
VerticalScale.Set 72179 . 72698) (VerticalScale.SetParameters 72700 . 73270) (VerticalScale.ShowLabels
 73272 . 73892) (VerticalScale.ShowReading 73894 . 74468) (VerticalScale.ShowTicks 74470 . 75025)) (
75312 84257 (CenterPrint 75322 . 75683) (ConcatNSpaces 75685 . 76186) (DrawBox 76188 . 76968) (
DrawHTick 76970 . 77489) (DrawRay 77491 . 78135) (DrawTick 78137 . 79111) (EvenIntervals 79113 . 79660
) (LineLeft 79662 . 80143) (LineLower 80145 . 80506) (PinnedSetting 80508 . 80930) (PrintLabelScale 
80932 . 81195) (LineRaise 81197 . 81548) (LineRight 81550 . 81881) (RotateLine 81883 . 83008) (
ShowRayLabel 83010 . 83617) (TellInstrument 83619 . 84085) (TitleWidth 84087 . 84255)))))
STOP