CDViewHighlightImpl.mesa (part of ChipNDale)
Copyright © 1985 by Xerox Corporation. All rights reserved.
Created by Christian Jacobi, July 4, 1985 1:34:38 pm PDT
Last edited by: Christian Jacobi, September 23, 1986 11:25:26 am PDT
DIRECTORY
CD,
CDBasics,
CDDrawQueue,
CDInstances,
CDProperties,
CDViewHighlight,
CDVPrivate,
ViewerClasses USING [Viewer];
CDViewHighlightImpl: CEDAR MONITOR
IMPORTS CDBasics, CDDrawQueue, CDInstances, CDProperties, CDVPrivate
EXPORTS CDViewHighlight
SHARES CDProperties =
BEGIN
State: TYPE = RECORD [pr: REF CDVPrivate.PainterRec, included: BOOLFALSE];
RemoveAll: PUBLIC PROC [v: ViewerClasses.Viewer] =
BEGIN
keyList: LIST OF REFNIL;
me: CDVPrivate.VRef = NARROW[v.data];
GetThem: PROC [] = {
FOR list: CD.PropList ← me.properties^, list.rest WHILE list#NIL DO
WITH list.first.val SELECT FROM
s: REF State => keyList ← CONS[list.first.key, keyList];
ENDCASE => NULL;
ENDLOOP;
};
CDProperties.DoWithinLock[GetThem];
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.VRef, key: REF] RETURNS [state: REF State] = {
IF key=NIL THEN key ← defaultKey;
WITH CDProperties.GetListProp[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]];
CDProperties.PutProp[me.properties, key, state];
};
};
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.VRef, rect: CD.Rect, erase: BOOL] =
INLINE BEGIN
IF CDBasics.NonEmpty[rect] THEN
CDDrawQueue.QueueInsertDrawCommand[me.ct, CDDrawQueue.Request[(IF erase THEN $redraw ELSE $draw), rect]];
END;
Update: PUBLIC ENTRY PROC [v: ViewerClasses.Viewer, key: REFNIL] =
BEGIN
ENABLE UNWIND => NULL;
me: CDVPrivate.VRef = 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.VRef = 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.VRef, paintRef: REF CDVPrivate.PainterRec, interrestRect: CD.Rect] = {
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[me.deviceDrawRef, l.first.ob, l.first.trans, l.first.properties]
ENDLOOP;
};
inst: CD.Instance => {
inst.ob.class.quickDrawMe[me.deviceDrawRef, inst.ob, inst.trans, inst.properties]
};
ENDCASE => NULL;
};
defaultKey: REFNEW[INT];
END.