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, March 25, 1986 1:23:13 pm PST
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: BOOL ← FALSE];
RemoveAll:
PUBLIC PROC [v: ViewerClasses.Viewer] =
BEGIN
keyList: LIST OF REF←NIL;
me: CDVPrivate.VRef = NARROW[v.data];
GetThem:
PROC [] =
BEGIN
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;
END;
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] =
BEGIN
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];
};
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.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:
REF←
NIL] =
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:
REF←
NIL, removeOthers:
BOOL←
TRUE, key:
REF←
NIL] =
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] =
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: REF ← NEW[INT];
END.