PieViewersImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Michael Plass, November 2, 1982 10:56 am
Last Edited by: Beach, May 24, 1983 9:13 am
Doug Wyatt, April 10, 1985 9:16:02 pm PST
DIRECTORY
Imager USING [black, MaskFill, SetColor, TranslateT, white],
ImagerPath USING [PathProc, VEC],
PieViewers USING [PieViewer],
Real USING [RoundI],
RealFns USING [CosDeg, SinDeg],
ViewerClasses USING [PaintProc, Viewer, ViewerClass, ViewerClassRec],
ViewerOps USING [CreateViewer, PaintViewer, RegisterViewerClass];
PieViewersImpl: CEDAR PROGRAM
IMPORTS Imager, Real, RealFns, ViewerOps
EXPORTS PieViewers
~ BEGIN
PieViewer: TYPE ~ PieViewers.PieViewer;
Data: TYPE ~ REF DataRec;
DataRec: TYPE ~ RECORD [
total: REAL, -- what the entire circle is worth
amount: REAL, -- what amount is currently on
granularity: REAL -- display will not change if the new amount is of the same grain
];
Create: PUBLIC PROC [parent: ViewerClasses.Viewer, x, y: INTEGER ← 0, diameter: INTEGER ← 16, total: REAL ← 100, divisions: NAT ← 25] RETURNS [pieViewer: PieViewer] ~ {
data: REF DataRec ← NEW[DataRec];
data.total ← total;
data.granularity ← total/divisions;
pieViewer ← ViewerOps.CreateViewer[flavor: $PieViewer, info: [parent: parent, wx: x, wy: y, ww: diameter, wh: diameter, data: data, border: FALSE], paint: FALSE];
Set[pieViewer, 0];
};
Set: PUBLIC PROC [pieViewer: PieViewer, amount: REAL] ~ {
d: Data ~ NARROW[pieViewer.data];
IF d=NIL THEN RETURN;
IF amount=d.total OR amount=0 OR Real.RoundI[d.amount/d.granularity] # Real.RoundI[amount/d.granularity] THEN {
d.amount ← amount;
ViewerOps.PaintViewer[pieViewer, client, FALSE, $Update];
};
};
VEC: TYPE ~ ImagerPath.VEC;
PieViewerPaint: ViewerClasses.PaintProc ~ {
d: Data ~ NARROW[self.data];
delta: REAL ~ 360*(d.amount/d.total);
radius: REALMIN[self.cw, self.ch]*0.5;
Loc: PROC [a: REAL] RETURNS [VEC] ~ { RETURN[[radius*RealFns.CosDeg[a], radius*RealFns.SinDeg[a]]] };
MaskSector: PROC [a0, a2: REAL] ~ {
path: ImagerPath.PathProc ~ {
moveTo[[0, 0]];
lineTo[Loc[a0]];
arcTo[Loc[(a0+a2)/2], Loc[a2]]
};
Imager.MaskFill[context, path];
};
Imager.TranslateT[context, [self.cw*0.5, self.ch*0.5]];
Imager.SetColor[context, Imager.black];
MaskSector[90, 90+delta];
Imager.SetColor[context, Imager.white];
radius ← radius+1; -- mask white with larger radius to avoid black garbage
MaskSector[90, 90-(360-delta)];
};
pieViewer: ViewerClasses.ViewerClass ← NEW[ViewerClasses.ViewerClassRec ← [
paint: PieViewerPaint,
tipTable: NIL
]];
ViewerOps.RegisterViewerClass[$PieViewer, pieViewer]; -- plug in to Viewers
END.