DIRECTORY Basics USING [DIVMOD], Convert USING [IntFromRope, RopeFromInt], Graphics USING [ black, Color, Context, DrawBox, DrawChar, DrawRope, FontRef, SetColor, SetCP, SetStipple, white], Labels USING [Label], NumberLabels USING [], Rope USING [ROPE], VFonts USING [CharWidth, defaultFont, Font, FontHeight, GraphicsFont, StringWidth], ViewerClasses USING [ GetProc, PaintProc, SetProc, Viewer, ViewerClass, ViewerClassRec, ViewerRec], ViewerOps USING [CreateViewer, PaintViewer, RegisterViewerClass]; LabelsImpl: CEDAR PROGRAM IMPORTS Basics, Convert, Graphics, VFonts, ViewerOps EXPORTS Labels, NumberLabels = BEGIN OPEN ViewerClasses, Labels, Rope; bottomOffset: INTEGER = 3; -- for painting leftOffset: INTEGER = 3; LabelData: TYPE = REF LabelDataRec; LabelDataRec: TYPE = RECORD [ font: VFonts.Font, displayStyle: DisplayStyle ]; DisplayStyle: TYPE = {blackOnWhite, whiteOnBlack, blackOnGrey} ; Create: PUBLIC PROC [info: ViewerRec _ [], font: VFonts.Font _ VFonts.defaultFont, paint: BOOL _ TRUE] RETURNS [label: Label] = BEGIN data: LabelData _ NEW[LabelDataRec _ [font, blackOnWhite]]; IF info.parent=NIL THEN ERROR; IF info.ww=0 THEN info.ww _ VFonts.StringWidth[info.name, font]+leftOffset+leftOffset; IF info.wh=0 THEN info.wh _ VFonts.FontHeight[font]+bottomOffset; info.data _ data; label _ ViewerOps.CreateViewer[$Label, info, paint]; END; LabelPaint: PaintProc = BEGIN OPEN Graphics; data: LabelData _ NARROW[self.data]; myGrey: CARDINAL = 001010B; borderFudge: INTEGER = IF self.border THEN 0 ELSE 1; IF data = NIL THEN RETURN; IF ~clear OR data.displayStyle#blackOnWhite THEN BEGIN SELECT data.displayStyle FROM whiteOnBlack => Graphics.SetColor[context, Graphics.black]; blackOnGrey => Graphics.SetStipple[context, myGrey]; blackOnWhite => Graphics.SetColor[context, Graphics.white]; ENDCASE; DrawBox[context, [1, 1, self.cw-1, self.ch-1]]; END; IF self.name=NIL THEN RETURN; SetColor[context, SELECT data.displayStyle FROM whiteOnBlack => white, ENDCASE => black]; SetCP[context, leftOffset+borderFudge, bottomOffset+borderFudge]; DrawRope[self: context, rope: self.name, font: VFonts.GraphicsFont[data.font]]; END; LabelGet: GetProc = BEGIN RETURN[self.name]; END; LabelSet: SetProc = BEGIN IF op=NIL THEN self.name _ NARROW[data] ELSE BEGIN myData: LabelData _ NARROW[self.data]; IF myData = NIL THEN RETURN; SELECT data FROM $BlackOnWhite => myData.displayStyle _ blackOnWhite; $WhiteOnBlack => myData.displayStyle _ whiteOnBlack; $BlackOnGrey => myData.displayStyle _ blackOnGrey; ENDCASE; END; IF finalise THEN ViewerOps.PaintViewer[self, all]; END; NumberLabel: TYPE = ViewerClasses.Viewer; NumberLabelData: TYPE = REF NumberLabelDataRec; NumberLabelDataRec: TYPE = RECORD [ font: VFonts.Font, displayStyle: DisplayStyle, currentValue: INT _ 0, lastDisplayed: INT _ 0 ]; -- The following material is to support NumberLabels CreateNumber: PUBLIC PROC [info: ViewerClasses.ViewerRec _ [], chars: NAT _ 0, initialValue: INT _ 0, font: VFonts.Font _ VFonts.defaultFont, paint: BOOL _ TRUE] RETURNS [nl: NumberLabel _ NIL] = { data: NumberLabelData _ NEW [ NumberLabelDataRec _ [font, blackOnWhite, initialValue, initialValue + 1]]; IF info.parent=NIL THEN ERROR; IF info.ww=0 THEN info.ww _ chars*VFonts.CharWidth['0, font]+leftOffset+leftOffset; IF info.wh=0 THEN info.wh _ VFonts.FontHeight[font]+bottomOffset; info.data _ data; nl _ ViewerOps.CreateViewer[$NumberLabel, info, paint]; }; NumberLabelPaint: ViewerClasses.PaintProc = { data: NumberLabelData _ NARROW[self.data]; myGrey: CARDINAL = 001010B; borderFudge: INTEGER = IF self.border THEN 0 ELSE 1; chars: ARRAY [0..11] OF CHAR; pos: NAT _ 0; card: LONG CARDINAL; scard: CARDINAL; font: Graphics.FontRef = VFonts.GraphicsFont[data.font]; IF data = NIL THEN RETURN; IF ~clear OR data.displayStyle # blackOnWhite THEN BEGIN SELECT data.displayStyle FROM whiteOnBlack => Graphics.SetColor[context, Graphics.black]; blackOnGrey => Graphics.SetStipple[context, myGrey]; blackOnWhite => Graphics.SetColor[context, Graphics.white]; ENDCASE; Graphics.DrawBox[context, [1, 1, self.cw-1, self.ch-1]]; whatChanged _ NIL; END; IF whatChanged = $Update AND data.currentValue = data.lastDisplayed THEN RETURN; data.lastDisplayed _ data.currentValue; Graphics.SetColor[context, SELECT data.displayStyle FROM whiteOnBlack => Graphics.white, ENDCASE => Graphics.black]; Graphics.SetCP[context, leftOffset+borderFudge, bottomOffset+borderFudge]; card _ LOOPHOLE[data.currentValue]; IF data.currentValue < 0 THEN { Graphics.DrawChar[context, '-, font]; card _ - card; }; WHILE card > LAST[CARDINAL] DO chars[pos] _ '0 + (card MOD 10); card _ card / 10; pos _ pos + 1; ENDLOOP; scard _ card; WHILE scard > 9 DO mod: CARDINAL; [scard,mod] _ Basics.DIVMOD[scard, 10]; chars[pos] _ '0 + mod; pos _ pos + 1; ENDLOOP; Graphics.DrawChar[context, '0 + scard, font]; WHILE pos > 0 DO pos _ pos - 1; Graphics.DrawChar[context, chars[pos], font]; ENDLOOP; }; NumberLabelGet: ViewerClasses.GetProc = { myData: NumberLabelData _ NARROW[self.data]; IF myData = NIL THEN RETURN [NIL]; IF op = NIL THEN RETURN[Convert.RopeFromInt[myData.currentValue]] ELSE RETURN [NEW[INT _ myData.currentValue]]; }; NumberLabelSet: ViewerClasses.SetProc = { myData: NumberLabelData _ NARROW[self.data]; IF myData = NIL THEN RETURN; WITH data SELECT FROM rope: ROPE => myData.currentValue _ Convert.IntFromRope[rope]; atom: ATOM => SELECT data FROM $BlackOnWhite => myData.displayStyle _ blackOnWhite; $WhiteOnBlack => myData.displayStyle _ whiteOnBlack; $BlackOnGrey => myData.displayStyle _ blackOnGrey; ENDCASE; refInt: REF INT => myData.currentValue _ refInt^; ENDCASE => RETURN; IF finalise THEN ViewerOps.PaintViewer[self, all]; }; NumberLabelUpdate: PUBLIC PROC [nl: NumberLabel, new: INT _ 0] = { myData: NumberLabelData _ NARROW[nl.data]; IF myData = NIL THEN RETURN; myData.currentValue _ new; IF new # myData.lastDisplayed THEN ViewerOps.PaintViewer[nl, all, FALSE, $Update]; }; NumberLabelQuery: PUBLIC PROC [nl: NumberLabel] RETURNS [current: INT _ 0] = { myData: NumberLabelData _ NARROW[nl.data]; IF myData = NIL THEN RETURN; RETURN [myData.currentValue]; }; labelClass: ViewerClasses.ViewerClass _ NEW[ViewerClasses.ViewerClassRec _ [ paint: LabelPaint, get: LabelGet, set: LabelSet ]]; numberLabelClass: ViewerClasses.ViewerClass _ NEW[ViewerClasses.ViewerClassRec _ [ paint: NumberLabelPaint, get: NumberLabelGet, set: NumberLabelSet ]]; ViewerOps.RegisterViewerClass[$Label, labelClass]; -- plug in to Viewers ViewerOps.RegisterViewerClass[$NumberLabel, numberLabelClass]; -- plug in to Viewers END. ΠLabelsImpl.mesa McGregor, October 28, 1982 11:17 am Maxwell, May 23, 1983 2:57 pm Russ Atkinson, September 27, 1983 1:14 pm borderFudge is so labels line up whether they have borders or not borderFudge is so labels line up whether they have borders or not while we have to stay in 32 bits, do so at this point, it is faster to do this in 16 bits unconditionally output the leading character finally, output the remaining characters that we have stored Κ\– "Mesa" style˜šΟc™Jšœ#™#Jšœ™Jšœ)™)—J˜šΟk ˜ Jšœžœžœ˜Jšœžœ˜)šœ žœ˜Jšœa˜a—Jšœžœ ˜Jšœ žœ˜Jšœžœžœ˜JšœžœG˜Sšœžœ˜J˜M—Jšœ žœ2˜A—J˜JšΟb œžœž˜J˜Jšžœ-˜4Jšžœ˜J˜Jšžœžœ˜'J˜Jšœžœ˜*Jšœ žœ˜J˜Jšœ žœžœ˜#šœžœžœ˜J˜J˜J˜J˜—Jšœžœ.˜@J˜šΟnœžœžœ?˜RJšœžœžœžœž˜2Jšœžœ&˜;Jšžœ žœžœžœ˜Jšžœ žœE˜VJšžœ žœ0˜AJ˜J˜4Jšžœ˜J˜—šœžœžœ ˜,JšA™AJšœžœ ˜$Jšœžœ ˜Jš œ žœžœ žœžœ˜4Jšžœžœžœžœ˜šžœžœ žœž˜6šžœž˜Jšœ;˜;—šœ5˜5Jšœ;˜;Jšžœ˜—J˜/Jšžœ˜—Jšžœ žœžœžœ˜šœžœž˜/J˜Jšžœ ˜—J˜AJ˜OJšžœ˜J˜—šœž˜Jšžœ ˜Jšžœ˜J˜—šœž˜Jšžœžœžœ žœ˜'šžœž˜ Jšœžœ ˜&Jšžœ žœžœžœ˜šžœž˜J˜4J˜4J˜2Jšžœ˜—Jšžœ˜—Jšžœ žœ"˜2Jšžœ˜J˜—Jšœ žœ˜)J˜Jšœžœžœ˜/šœžœžœ˜#J˜J˜Jšœžœ˜Jšœžœ˜J˜J˜—Jš5˜5š  œžœž˜Jš œ,žœžœ5žœžœžœžœ˜«šœžœ˜JšœK˜K—Jšžœ žœžœžœ˜Jšžœ žœB˜SJšžœ žœ0˜AJ˜Jšœ7˜7Jšœ˜J˜—šœ,ž˜-JšA™AJšœžœ ˜*Jšœžœ ˜Jš œ žœžœ žœžœ˜4Jšœžœ žœžœ˜Jšœžœ˜ Jšœžœžœ˜Jšœžœ˜Jšœ8˜8Jšžœžœžœžœ˜šžœžœ"žœž˜8šžœž˜Jšœ;˜;—šœ5˜5Jšœ;˜;Jšžœ˜—Jšœ8˜8Jšœžœ˜Jšžœ˜—Jšžœžœ(žœžœ˜PJšœ'˜'šœžœž˜8J˜Jšžœ˜—J˜JJšœžœ˜#šžœ˜šžœ˜Jšœ%˜%J˜J˜——J™Jšœ'™'šžœžœžœž˜Jšœžœ˜ J˜J˜Jšžœ˜—J™Jšœ1™1J˜ šžœ ž˜Jšœžœ˜Jšœžœ ˜'Jšœ˜J˜Jšžœ˜—J™Jšœ,™,Jšœ-˜-J™Jšœ<™<šžœ ž˜J˜Jšœ-˜-Jšžœ˜—Jšžœ˜J˜—šœ(ž˜)Jšœžœ ˜,Jš žœ žœžœžœžœ˜"šžœž˜ Jšžœžœ*˜5Jšžœžœžœžœ˜-—Jšžœ˜J˜—šœ)˜)Jšœžœ ˜,Jšžœ žœžœžœ˜šžœžœž˜šœžœ˜ Jšœ0˜0—šœžœ˜šžœž˜J˜4J˜4J˜2Jšžœ˜——šœžœžœ˜Jšœ˜—Jšžœžœ˜—Jšžœ žœ"˜2Jšœ˜J˜—š œžœžœžœ ˜BJšœžœ ˜*Jšžœ žœžœžœ˜Jšœ˜Jšžœžœ žœ ˜RJšœ˜J˜—š  œžœžœžœ žœ ˜NJšœžœ ˜*Jšžœ žœžœžœ˜Jšžœ˜Jšœ˜J˜—šœ(žœ!˜LJ˜J˜J˜ J˜J˜—šœ.žœ!˜RJ˜J˜J˜J˜J˜—Jšœ3˜HJšœ?˜TJ˜Jšžœ˜J˜—…—Ά#β