(FILECREATED "14-Mar-84 13:50:35" {INDIGO}<LOOPS>SOURCES>GAUGES.;37 81093  

      changes to:  (VARS GAUGESCOMS GAUGEUTILITYFNS)
		   (METHODS DigiMeter.Update LCD.Reset HorizontalScale.ShowTicks LCD.SmallRegion)
		   (INSTANCES DigiMeter.Update LCD.Reset HorizontalScale.ShowTicks LCD.SmallRegion)
		   (FNS LCD.SmallRegion)

      previous date: " 9-Mar-84 17:24:30" {INDIGO}<LOOPS>SOURCES>GAUGES.;36)


(* Copyright (c) 1983, 1984 by Xerox Corporation)

(PRETTYCOMPRINT GAUGESCOMS)

(RPAQQ GAUGESCOMS ((* Copyright (c)
		      Xerox Corporation 1983)
	(CLASSES * GAUGESCLASSES)
	(METHODS BarChart.DrawInstrument BarChart.Set BarChart.SetParameters BarChart.ShowReading 
		 BarChart.Update BoundedMixin.ComputeDisplayVal BoundedMixin.OutOfBounds 
		 Dial.DrawInstrument Dial.SetParameters Dial.ShowLabels Dial.ShowTicks 
		 DigiMeter.ComputeScale DigiMeter.Set DigiMeter.SetParameters DigiMeter.ShowReading 
		 DigiMeter.Update DigiScale.Set DigiScale.SetParameters DigiScale.ShowReading 
		 Gauge.Attach Gauge.AttachProbe Gauge.Attached? Gauge.Close Gauge.Detach 
		 Gauge.DetachProbe Gauge.MaxCurrentReading Gauge.Reset Gauge.SetScale 
		 Gauge.ShowInstrument Gauge.Update Gauge.Update? 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 MultiValueMixin.AddLabel MultiValueMixin.Attach 
		 MultiValueMixin.DeleteLabel MultiValueMixin.Detach MultiValueMixin.MaxCurrentReading 
		 MultiValueMixin.OutOfBounds MultiValueMixin.SetUp RoundScale.Reset RoundScale.Set 
		 RoundScale.ShowReading SelfScaleMixin.Set VerticalScale.DrawInstrument 
		 VerticalScale.Set VerticalScale.SetParameters VerticalScale.ShowLabels 
		 VerticalScale.ShowReading VerticalScale.ShowTicks)
	(* * 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)
   (InstanceVariables (maxLabelWidth 0 doc                   (* maximum widt of a label string.))
		      (scaleLeft 3)
		      (scaleBottom 30))]

[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)]

[DEFCLASS Dial
   (MetaClass Class doc                                      (* A dial with bounded range, like an auto speedometer)
	      Edited:                                        (* dgb: "22-FEB-83 15:11")
	      )
   (Supers BoundedMixin RoundScale)
   (InstanceVariables (ticks 7)
		      (labels (0 20 40 60 80 100 120))
		      (width 121)
		      (displayVal 120)
		      (inputRange 120)
		      (lower 120)
		      (range -60))]

[DEFCLASS DigiMeter
   (MetaClass Class doc                                      (* A combination Meter and LCD, for both analog and 
							     digital readout.)
	      Edited:                                        (* dgb: "28-OCT-83 11:30")
	      )
   (Supers Meter LCD)
   (InstanceVariables (readingY 100)
		      (width 120)
		      (inputRange 100)
		      (labels (0 10 20 30 40 50 60 70 80 90 doc 
                                                             (* labels for the instrument)))
		      (ticks 10))]

[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)
   (InstanceVariables (ticks NIL tickLength NIL)
		      (scaleHeight 6)
		      (scaleLeft 6)
		      (height 24)
		      (width 70))]

[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)

))]

[DEFCLASS HBarChart
   (MetaClass Class doc                                      (* Horizontally oriented BarChart)
	      Edited:                                        (* dgb: "22-JUL-83 23:19")
	      )
   (Supers MultiValueMixin HorizontalScale)
   (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)))
]

[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)
   (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)))]

[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)
   (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)))]

[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)
				 ))]

[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)
   (InstanceVariables (ticks 10)
		      (lower 90)
		      (displayVal 90)
		      (range -360)
		      (labels (0 10 20 30 40 50 60 70 80 90))
		      (height 120)
		      (width 100))]

[DEFCLASS MultiValueMixin
   (MetaClass Class Edited:                                  (* dgb: "22-JUL-83 16:56"))
   (Supers Object)
   (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)))]

[DEFCLASS RoundScale
   (MetaClass AbstractClass Edited:                          (* mjs: "28-JAN-83 10:19")
	      doc                                            (* AbstractClass for instrucments with circular 
							     (arc) scales)
	      )
   (Supers Instrument)
   (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)))]

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

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

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

[DEFCLASS SelfScaleMixin
   (MetaClass Class Edited:                                  (* dgb: "10-JUN-83 02:32"))
   (Supers Object)
   (InstanceVariables (lowScaleFactor 5 doc                  (* If maxCurrentReading shrinks so that it will fit more
							     than lowScaleFactor times in inputRange, the gauge 
							     rescales)))]

[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)
   (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)))]

[METH BarChart  DrawInstrument NIL
      (* Print the labels under each bar.)]


[METH BarChart  Set (reading label)
      (* show reading on vertical scale)]


[METH BarChart  SetParameters NIL
      (* Set scale hieght from height)]


[METH BarChart  ShowReading NIL
      (* dgb: " 9-JUN-83 22:14")]


[METH BarChart  Update NIL
      (* Scale internal readings to min and max for update)]


[METH BoundedMixin  ComputeDisplayVal (reading)
      (* dgb: "26-JAN-83 17:09")]


[METH BoundedMixin  OutOfBounds (outFlg)
      (* Print ? if out, space other wise)]


[METH Dial  DrawInstrument NIL
      (* Draw two concentric circles to contain ticks)]


[METH Dial  SetParameters NIL
      (* Set up center of circle for dial and needle, and length of radius.)]


[METH Dial  ShowLabels NIL
      (* If there are any labels, show them on the dial)]


[METH Dial  ShowTicks NIL
      (* Draw ticks in even intervals from angle of 120 down to 60)]


[METH DigiMeter  ComputeScale (min max labelScale)
      (* Compute scale for both dial and alphaDisplay)]


[METH DigiMeter  Set (reading)
      (* set both on dial and on digits)]


[METH DigiMeter  SetParameters NIL
      (* Set all params)]


[METH DigiMeter  ShowReading (reading)
      (* Show displayVal both on dial and on digits)]


[METH DigiMeter  Update NIL
      (*)]


[METH DigiScale  Set (reading)
      (* Combined method for Set)]


[METH DigiScale  SetParameters NIL
      (* Set parameters for unscaled horizontal gauge combined with LCD on bottom)]


[METH DigiScale  ShowReading NIL
      (* dgb: " 9-JUN-83 21:34")]


[METH Gauge  Attach (obj varName selector otherArgs label machine xOrPos y)
      (* Attach a self to obj/varName)]


[METH Gauge  AttachProbe (obj varName selector otherArgs label machine)
      (* Attach a probe to an object, and record attachment here in Gauge. Returns current value of 
	 obj varName)]


[METH Gauge  Attached? (dontPrintFlg)
      (* dgb: "17-FEB-83 13:12")]


[METH Gauge  Close NIL
      (* Detach the gauge and close the window)]


[METH Gauge  Detach NIL
      (* Detach gauge from attachedPlaces it is attached to)]


[METH Gauge  DetachProbe (place)
      (* Detach a probe on a place specified by place, a list of form (objName varName . otherStuff)
	 %. Called by Detach)]


[METH Gauge  MaxCurrentReading NIL
      (* Returns the reading now, since in general there is only one)]


[METH Gauge  Reset (newReading)
      (* set reading to value, and then update gauge so that it shows that reading without going 
	 through intermediate states)]


[METH Gauge  SetScale (min max labelScale)
      (* compute the scale and redisplay if necessary)]


[METH Gauge  ShowInstrument NIL
      (* Cause an error, becuase this should be implemented in subclass)]


[METH Gauge  Update NIL
      (* Set up display window for instrument. Reinitialize to reflect current state)]


[METH Gauge  Update? NIL
      (* Update if there is a window and it is open)]


[METH HBarChart  DrawInstrument NIL
      (* Print the labels next to each bar.)]


[METH HBarChart  Set (reading label)
      (* show reading on vertical scale)]


[METH HBarChart  SetParameters NIL
      (* Set scale hieght from height)]


[METH HBarChart  ShowReading NIL
      (* show the line at initial level. intrnal displayVal is really line heigt)]


[METH HorizontalScale  DrawInstrument NIL
      (* Draw a horizontal tube for instrument)]


[METH HorizontalScale  OutOfBounds NIL
      (* Print "  " or ?? depending on whether reading is out of bounds)]


[METH HorizontalScale  Set (newReading)
      (* show reading on horizontal scale)]


[METH HorizontalScale  SetParameters NIL
      (* Set scale width from width)]


[METH HorizontalScale  ShowLabels NIL
      (* Put labels next to ticks)]


[METH HorizontalScale  ShowReading NIL
      (* dgb: " 9-JUN-83 22:37")]


[METH HorizontalScale  ShowTicks NIL
      (* Show ticks along bottom edge of scale)]


[METH Instrument  ComputeDisplayVal (reading)
      (* Computes displayVal of instrument in bounded range)]


[METH Instrument  ComputeScale (min max labelScale)
      (* DECLARATIONS: MIXED)]


[METH Instrument  PrintLabelScale NIL
      (* Print the scale of labelling on instrument)]


[METH Instrument  SetParameters NIL
      (* Set scale hieght from height)]


[METH Instrument  ShowInstrument NIL
      (* show the instrument including the current displayVal)]


[METH LCD  ComputeScale (min max)
      (* Sets the precision based on the width of min and max)]


[METH LCD  PrintReading NIL
      (* dgb: " 9-JUN-83 22:15")]


[METH LCD  Reset (newReading)
      (* set reading to value. Same as Set since there is no special way to do this)]


[METH LCD  Set (newReading)
      (* Put number in box)]


[METH LCD  SetParameters NIL
      (* Set the font for the window)]


[METH LCD  ShowInstrument NIL
      (* Nothing needed)]


[METH LCD  ShowReading NIL
      (* dgb: " 9-JUN-83 22:15")]


[METH LCD  SmallRegion NIL
      (* Create small LCD region for mixin display)]


[METH Meter  ComputeScale NIL
      (* dgb: "29-JAN-83 01:48")]


[METH Meter  DrawInstrument NIL
      (*)]


[METH Meter  SetParameters NIL
      (* Compute center and radius for meters)]


[METH Meter  Shape NIL
      (*)]


[METH Meter  ShowLabels NIL
      (* If there are any labels, show them on the dial)]


[METH Meter  ShowTicks NIL
      (* *Draw ticks at even intervals around the circle starting from 90)]


[METH MultiValueMixin  AddLabel (label labelReading)
      (* add to the list of bars on the chart)]


[METH MultiValueMixin  Attach (obj varName selector label machine xOrPos y)
      (* Attach to obj varName and label it in chart with label)]


[METH MultiValueMixin  DeleteLabel (label updateFlg)
      (* Remove a bar from a chart)]


[METH MultiValueMixin  Detach (label)
      (* Detach gauge from attachedPlaces it is attached to)]


[METH MultiValueMixin  MaxCurrentReading NIL
      (* return the max readinr in (@ reading))]


[METH MultiValueMixin  OutOfBounds (outFlg)
      (* Print ? if out, space other wise)]


[METH MultiValueMixin  SetUp (listOfObjects ivName chartTitle maxScale path)
      (* 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.)]


[METH RoundScale  Reset (newReading)
      (* set reading to value, and then update gauge so that it shows that reading without going 
	 through intermediate states)]


[METH RoundScale  Set (newReading)
      (* dgb: "27-JAN-83 11:34")]


[METH RoundScale  ShowReading NIL
      (* dgb: "26-JAN-83 23:43")]


[METH SelfScaleMixin  Set (reading otherArg1 otherArg2)
      (* Check if reading is too high or too low, and if so see if gauge needs to rescale)]


[METH VerticalScale  DrawInstrument NIL
      (* Draw a vertical tube for instrument)]


[METH VerticalScale  Set (reading)
      (* show reading on vertical scale)]


[METH VerticalScale  SetParameters NIL
      (* Set scale hieght from height)]


[METH VerticalScale  ShowLabels NIL
      (* Put labels next to ticks)]


[METH VerticalScale  ShowReading NIL
      (* dgb: " 9-JUN-83 22:37")]


[METH VerticalScale  ShowTicks NIL
      (* Show ticks along right edge of scale)]


(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])

(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: " 4-OCT-83 17:01")
                                                             (* 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 10 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: "13-OCT-83 22:06")
                                                             (* Set all params)
    (PROG [(lf (FONTHEIGHT (@@ Font]
          (DSPFONT (@@ Font)
		   (@ window))
          (←Super
	    self SetParameters)                              (* 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: "28-OCT-83 11:30")
                                                             (* 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])

(Gauge.Attach
  [LAMBDA (self obj varName selector otherArgs label machine xOrPos y)
                                                             (* dgb: "13-OCT-83 22:06")
                                                             (* 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: "13-OCT-83 22:06")
                                                             (* Attach a probe to an object, and record attachment 
							     here in Gauge. Returns current value of obj varName)
    [COND
      ((NOT (type? instance obj))
	(ERROR obj " not an instance -- cannot attach a gauge"))
      ((NOT (← obj HasIV varName))
	(ERROR varName (CONCAT " not an IV of " obj "
Cannot attach"]
    (←@
      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 dontPrintFlg)                                (* dgb: "13-OCT-83 22:06")
                                                             (* dgb: "17-FEB-83 13:12")
                                                             (*)
    (COND
      (dontPrintFlg (@ 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 dontDetachFlg)                               (* dgb: " 6-Mar-84 15:32")
                                                             (* Detach the gauge and close the window)
    (AND (NULL dontDetachFlg)
	 (← self Attached? T)
	 (← self Detach))
    (←Super
      self Close])

(Gauge.Detach
  [LAMBDA (self)                                             (* dgb: "13-OCT-83 22:06")
                                                             (* Detach gauge from attachedPlaces it is attached to)
    (COND
      ((@ attachedTo)
	(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.ShowInstrument
  [LAMBDA (self)                                             (* edited: "13-NOV-83 18:22")
                                                             (* Cause an error, becuase this should be implemented in
							     subclass)
    (ERROR "ShowInstrument should be implemented in " (Class self])

(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])

(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 newReading)                                  (* dgb: "13-OCT-83 22:06")
                                                             (* show reading on horizontal scale)
    (←@
      reading newReading)
    (PROG ((y (ADD1 (@ scaleBottom)))
	   (w (SUB1 (@ scaleHeight)))
	   (displayVal (@ displayVal))
	   (newSetting (← self ComputeDisplayVal newReading)))
          (←@
	    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 newReading)                                  (* dgb: "13-OCT-83 22:06")
                                                             (* Put number in box)
    (←@
      reading newReading)
    (← self PrintReading])

(LCD.SetParameters
  [LAMBDA (self)                                             (* dgb: "13-OCT-83 22:06")
                                                             (* 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: "14-Mar-84 13:46")
                                                             (* Create small LCD region for mixin display)
    (←@
      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])

(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: "13-OCT-83 22:06")
                                                             (* 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)
	 (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 newReading)                                  (* dgb: "13-OCT-83 22:06")
                                                             (* 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 newReading)))
          (COND
	    ((IGREATERP (IABS (IDIFFERENCE newVal (@ displayVal)))
			540)                                 (* Don't spin more than one and a half revolutions.
							     Just reset)
	      (← self Reset newReading))
	    (T (←@
		 reading newReading)
	       (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])

(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: " 5-OCT-83 09:21")
                                                             (* Set scale hieght from height)
    (←@
      height
      (IMAX (@ height)
	    130))
    [←@
      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 ChangeHorizontalSetting ChangeVerticalSetting ComputeLabels 
				    ConcatNSpaces DrawBox DrawHTick DrawLines DrawRay DrawTick 
				    DrawVTick EvenIntervals GetPathObj LineLeft LineLower LineRaise 
				    LineRight MoveImageRight PinnedSetting PrintLabelScale RotateLine 
				    SetUpBarChart 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])

(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])

(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])

(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])

(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])

(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])

(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])

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

(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])

(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])

(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])

(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])

(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])

(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])

(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))
(PUTPROPS GAUGES COPYRIGHT ("Xerox Corporation" 1983 1984))
(DECLARE: DONTCOPY
  (FILEMAP (NIL (20674 64983 (BarChart.DrawInstrument 20684 . 21266) (BarChart.Set 21268 . 21956) (
BarChart.SetParameters 21958 . 23018) (BarChart.ShowReading 23020 . 23665) (BarChart.Update 23667 . 
24045) (BoundedMixin.ComputeDisplayVal 24047 . 24705) (BoundedMixin.OutOfBounds 24707 . 25034) (
Dial.DrawInstrument 25036 . 25522) (Dial.SetParameters 25524 . 26253) (Dial.ShowLabels 26255 . 26905) 
(Dial.ShowTicks 26907 . 27410) (DigiMeter.ComputeScale 27412 . 27708) (DigiMeter.Set 27710 . 27963) (
DigiMeter.SetParameters 27965 . 28651) (DigiMeter.ShowReading 28653 . 28934) (DigiMeter.Update 28936
 . 29156) (DigiScale.Set 29158 . 29404) (DigiScale.SetParameters 29406 . 29995) (DigiScale.ShowReading
 29997 . 30351) (Gauge.Attach 30353 . 30918) (Gauge.AttachProbe 30920 . 32173) (Gauge.Attached? 32175
 . 33001) (Gauge.Close 33003 . 33321) (Gauge.Detach 33323 . 33748) (Gauge.DetachProbe 33750 . 34637) (
Gauge.MaxCurrentReading 34639 . 34922) (Gauge.Reset 34924 . 35306) (Gauge.SetScale 35308 . 35600) (
Gauge.ShowInstrument 35602 . 35938) (Gauge.Update 35940 . 36351) (Gauge.Update? 36353 . 36696) (
HBarChart.DrawInstrument 36698 . 37148) (HBarChart.Set 37150 . 37760) (HBarChart.SetParameters 37762
 . 39231) (HBarChart.ShowReading 39233 . 39720) (HorizontalScale.DrawInstrument 39722 . 40110) (
HorizontalScale.OutOfBounds 40112 . 40536) (HorizontalScale.Set 40538 . 41211) (
HorizontalScale.SetParameters 41213 . 41790) (HorizontalScale.ShowLabels 41792 . 42552) (
HorizontalScale.ShowReading 42554 . 43117) (HorizontalScale.ShowTicks 43119 . 43723) (
Instrument.ComputeDisplayVal 43725 . 44085) (Instrument.ComputeScale 44087 . 46370) (
Instrument.PrintLabelScale 46372 . 46785) (Instrument.SetParameters 46787 . 47040) (
Instrument.ShowInstrument 47042 . 47415) (LCD.ComputeScale 47417 . 47721) (LCD.PrintReading 47723 . 
48808) (LCD.Reset 48810 . 49106) (LCD.Set 49108 . 49360) (LCD.SetParameters 49362 . 50219) (
LCD.ShowInstrument 50221 . 50431) (LCD.ShowReading 50433 . 50773) (LCD.SmallRegion 50775 . 51421) (
Meter.ComputeScale 51423 . 51984) (Meter.DrawInstrument 51986 . 52241) (Meter.SetParameters 52243 . 
52980) (Meter.Shape 52982 . 53312) (Meter.ShowLabels 53314 . 53871) (Meter.ShowTicks 53873 . 54316) (
MultiValueMixin.AddLabel 54318 . 54682) (MultiValueMixin.Attach 54684 . 55583) (
MultiValueMixin.DeleteLabel 55585 . 55960) (MultiValueMixin.Detach 55962 . 56900) (
MultiValueMixin.MaxCurrentReading 56902 . 57318) (MultiValueMixin.OutOfBounds 57320 . 57747) (
MultiValueMixin.SetUp 57749 . 58778) (RoundScale.Reset 58780 . 59196) (RoundScale.Set 59198 . 60080) (
RoundScale.ShowReading 60082 . 60546) (SelfScaleMixin.Set 60548 . 61692) (VerticalScale.DrawInstrument
 61694 . 62078) (VerticalScale.Set 62080 . 62599) (VerticalScale.SetParameters 62601 . 63226) (
VerticalScale.ShowLabels 63228 . 63848) (VerticalScale.ShowReading 63850 . 64424) (
VerticalScale.ShowTicks 64426 . 64981)) (65406 80815 (CenterPrint 65416 . 65777) (
ChangeHorizontalSetting 65779 . 66218) (ChangeVerticalSetting 66220 . 66554) (ComputeLabels 66556 . 
67607) (ConcatNSpaces 67609 . 68110) (DrawBox 68112 . 68892) (DrawHTick 68894 . 69413) (DrawLines 
69415 . 70129) (DrawRay 70131 . 70775) (DrawTick 70777 . 71751) (DrawVTick 71753 . 72283) (
EvenIntervals 72285 . 72832) (GetPathObj 72834 . 73045) (LineLeft 73047 . 73528) (LineLower 73530 . 
73891) (LineRaise 73893 . 74244) (LineRight 74246 . 74577) (MoveImageRight 74579 . 76930) (
PinnedSetting 76932 . 77354) (PrintLabelScale 77356 . 77619) (RotateLine 77621 . 78746) (SetUpBarChart
 78748 . 79566) (ShowRayLabel 79568 . 80175) (TellInstrument 80177 . 80643) (TitleWidth 80645 . 80813)
))))
STOP