CDViewHighlightImpl.mesa (part of ChipNDale)
Copyright © 1985 by Xerox Corporation. All rights reserved.
by Christian Jacobi, July 4, 1985 1:34:38 pm PDT
last edited by Christian Jacobi, July 4, 1985 3:38:41 pm PDT
DIRECTORY
Atom,
CD,
CDBasics,
CDDraw,
CDInstances,
CDViewHighlight,
CDVPrivate,
ViewerClasses USING [Viewer];
CDViewHighlightImpl: CEDAR MONITOR
IMPORTS Atom, CDBasics, CDDraw, CDInstances, CDVPrivate
EXPORTS CDViewHighlight =
BEGIN
State: TYPE = RECORD [pr: REF CDVPrivate.PainterRec, included: BOOLFALSE];
RemoveAll: PUBLIC PROC[v: ViewerClasses.Viewer] =
BEGIN
keyList: LIST OF REFNIL;
me: CDVPrivate.MyGraphicRef = NARROW[v.data];
FOR list: Atom.PropList ← me.properties, list.rest WHILE list#NIL DO
IF list.first#NIL THEN
WITH list.first.val SELECT FROM
s: REF State => keyList ← CONS[list.first.key, keyList]
ENDCASE => NULL
ENDLOOP;
FOR list: LIST OF REF ← keyList, list.rest WHILE list#NIL DO
ShowInstance[v, NIL, TRUE, list.first];
ENDLOOP;
END;
GetData: INTERNAL PROC [me: CDVPrivate.MyGraphicRef, key: REF] RETURNS [state: REF State] =
BEGIN
IF key=NIL THEN key ← defaultKey;
WITH Atom.GetPropFromList[me.properties, key] SELECT FROM
s: REF State => state ← s;
ENDCASE => {
state ← NEW[State];
state.pr ← NEW[CDVPrivate.PainterRec ← [rect: CDBasics.empty, proc: PaintIt, data: NIL]];
me.properties ← Atom.PutPropOnList[me.properties, key, state];
};
END;
ToInstList: PROC [x: REF] RETURNS [CD.InstanceList] =
BEGIN
WITH x SELECT FROM
l: CD.InstanceList => RETURN [l];
inst: CD.Instance => RETURN [LIST[inst]];
ENDCASE => RETURN [NIL];
END;
Paint: PROC [me: CDVPrivate.MyGraphicRef, rect: CD.Rect, erase: BOOL] =
INLINE BEGIN
IF CDBasics.NonEmpty[rect] THEN
CDDraw.InsertCommand[me.ct, CDDraw.Comm[cmd: rect, erase: erase, rect: rect, ref: NIL]];
END;
Update: PUBLIC ENTRY PROC [v: ViewerClasses.Viewer, key: REFNIL] =
BEGIN
ENABLE UNWIND => NULL;
me: CDVPrivate.MyGraphicRef = NARROW[v.data];
state: REF State = GetData[me, key];
clearRect: CD.Rect ← state.pr.rect;
paintRect: CD.Rect ← CDInstances.BoundingRectO[ToInstList[state.pr.data]];
state.pr.rect ← paintRect;
Paint[me, paintRect, FALSE];
Paint[me, clearRect, TRUE];
END;
ShowInstance: PUBLIC ENTRY PROC[v: ViewerClasses.Viewer, instOrList: REFNIL, removeOthers: BOOLTRUE, key: REFNIL] =
BEGIN
ENABLE UNWIND => NULL;
me: CDVPrivate.MyGraphicRef = NARROW[v.data];
state: REF State = GetData[me, key];
instL: CD.InstanceList ← ToInstList[instOrList];
clearRect: CD.Rect ← CDBasics.empty;
paintRect: CD.Rect ← CDInstances.BoundingRectO[instL];
IF removeOthers THEN {
clearRect ← state.pr.rect;
state.pr.rect ← CDBasics.empty;
state.pr.data ← NIL;
};
FOR list: CD.InstanceList ← ToInstList[state.pr.data], list.rest WHILE list#NIL DO
instL ← CONS[list.first, instL]
ENDLOOP;
state.pr.data ← instL;
state.pr.rect ← CDBasics.Surround[paintRect, state.pr.rect];
IF state.pr.data#NIL AND ~state.included THEN {
state.included ← TRUE;
CDVPrivate.IncludeAPainterRec[me, state.pr];
}
ELSE IF state.pr.data=NIL THEN {
state.included ← FALSE;
CDVPrivate.RemoveAPainterRec[me, state.pr];
};
Paint[me, paintRect, FALSE];
Paint[me, clearRect, TRUE];
END;
PaintIt: PROC [me: CDVPrivate.MyGraphicRef, paintRef: REF CDVPrivate.PainterRec, interrestRect: CD.Rect] =
BEGIN
WITH paintRef.data SELECT FROM
instL: CD.InstanceList => {
FOR l: CD.InstanceList ← instL, l.rest WHILE l#NIL DO
IF me.stoprequest^ THEN EXIT;
IF CDBasics.Intersect[CDInstances.InstRectO[l.first], interrestRect] THEN
l.first.ob.class.quickDrawMe[l.first, l.first.location, l.first.orientation, me.deviceDrawRef]
ENDLOOP;
};
inst: CD.Instance => {
inst.ob.class.quickDrawMe[inst, inst.location, inst.orientation, me.deviceDrawRef]
};
ENDCASE => NULL;
END;
defaultKey: REFNEW[INT];
END.