DIRECTORY CedarProcess, CD, CDBasics, CDDrawQueue, CDProperties, CDValue, CDVArrow, CDViewerBackdoor, CDVPrivate, CDVScale, Imager, Process, ViewerEvents; CDVArrowImpl: CEDAR MONITOR IMPORTS CDBasics, CDDrawQueue, CDProperties, CDValue, CDViewerBackdoor, CDVPrivate, CDVScale, CedarProcess, Imager, Process, ViewerEvents EXPORTS CDVArrow = BEGIN ShowArrow: PUBLIC PROC [design: CD.Design, pos: CD.Position] = { CDValue.Store[boundTo: design, key: $arrow, value: NEW[CD.Position_pos]]; CDDrawQueue.InsertDrawCommand[design, CDDrawQueue.Request[$PutArrowXXX, [pos.x, pos.y, 0, 0]]] }; RemoveArrow: PUBLIC PROC[design: CD.Design] = { CDValue.Store[boundTo: design, key: $arrow, value: NIL]; CDDrawQueue.InsertDrawCommand[design, CDDrawQueue.Request[$RemoveArrowXXX, [0, 0, 0, 0]]]; }; GetAPainterRec: ENTRY PROC [me: CDVPrivate.VRef] RETURNS [pr: REF CDVPrivate.PainterRec] = { ENABLE UNWIND => NULL; x: REF = CDProperties.GetProp[me.properties, $CDxArrowPaintProc]; IF x#NIL THEN pr _ NARROW[x] ELSE { pr _ NEW[CDVPrivate.PainterRec_[proc: PaintArrow]]; CDProperties.PutProp[me.properties, $CDxArrowPaintProc, pr] } }; PaintArrow: CDVPrivate.PainterProc = { vp: CD.Position _ CDVScale.DesignToViewerPosition[me.scale, [paintRef.rect.x1, paintRef.rect.y1]]; vp _ CDBasics.AddPoints[vp, [1, 1]]; Imager.SetColor[me.viewContext, Imager.black]; Imager.MaskVector[me.viewContext, [vp.x+10, vp.y], [vp.x, vp.y]]; Imager.MaskVector[me.viewContext, [vp.x, vp.y], [vp.x, vp.y+10]]; Imager.MaskVector[me.viewContext, [vp.x, vp.y], [vp.x+18, vp.y+18]]; }; PaintTheArrow: CDViewerBackdoor.FurtherPaintProc = { pr: REF CDVPrivate.PainterRec = GetAPainterRec[me]; comm: REF CDDrawQueue.Request = NARROW[key]; arrowSize: CD.Number = MAX[CDVScale.UngriddedViewerToDesignScalar[me.scale, 20], 1]; aRect: CD.Rect _ [x1: comm.rect.x1, y1: comm.rect.y1, x2: comm.rect.x1+arrowSize, y2: comm.rect.y1+arrowSize]; IF pr.data = $on THEN { oldRect: CD.Rect; IF pr.rect=aRect THEN RETURN; oldRect _ pr.rect; pr.rect _ aRect; CDDrawQueue.QueueInsertDrawCommand[me.ct, CDDrawQueue.Request[$redraw, oldRect]]; } ELSE { pr.rect _ aRect; CDVPrivate.IncludeAPainterRec[me, pr]; pr.data _ $on; }; CDDrawQueue.QueueInsertDrawCommand[me.ct, CDDrawQueue.Request[$draw, aRect]]; }; RemoveTheArrow: CDViewerBackdoor.FurtherPaintProc = { pr: REF CDVPrivate.PainterRec = GetAPainterRec[me]; IF pr.data = $on THEN { oldRect: CD.Rect _ pr.rect; pr.rect _ CDBasics.empty; pr.data _ NIL; CDDrawQueue.QueueInsertDrawCommand[me.ct, CDDrawQueue.Request[$redraw, oldRect]]; CDVPrivate.RemoveAPainterRec[me, pr]; } }; CallOnOpenOrCreate: ViewerEvents.EventProc = TRUSTED { Process.Detach[FORK ReInstallTheArrow[NARROW[viewer.data]]]; }; ReInstallTheArrow: PROC [me: CDVPrivate.VRef] = { CedarProcess.SetPriority[CedarProcess.Priority[background]]; Process.Pause[Process.MsecToTicks[500]]; IF me.ct#NIL THEN { -- which now certainly is true WITH CDValue.Fetch[boundTo: me.actualDesign, key: $arrow, propagation: design] SELECT FROM pos: REF CD.Position => { CDDrawQueue.QueueInsertDrawCommand[me.ct, CDDrawQueue.Request[$PutArrowXXX, [pos.x, pos.y, 0, 0]]] }; ENDCASE => { CDDrawQueue.QueueInsertDrawCommand[me.ct, CDDrawQueue.Request[$RemoveArrowXXX, [0, 0, 0, 0]]] }; } }; Init: PROC [] = { CDValue.RegisterKey[$arrow]; CDViewerBackdoor.InstallFurtherPaint[keyValue: $PutArrowXXX, proc: PaintTheArrow]; CDViewerBackdoor.InstallFurtherPaint[keyValue: $RemoveArrowXXX, proc: RemoveTheArrow]; [] _ ViewerEvents.RegisterEventProc[proc: CallOnOpenOrCreate, event: open, filter: $ChipNDale, before: FALSE]; [] _ ViewerEvents.RegisterEventProc[proc: CallOnOpenOrCreate, event: create, filter: $ChipNDale, before: FALSE]; }; Init[]; END. CDVArrowImpl.mesa (part of ChipNDale) Copyright c 1984, 1987 by Xerox Corporation. All rights reserved. by Christian Jacobi, August 30, 1984 10:21:27 am PDT last edited by Christian Jacobi, March 3, 1987 3:50:25 pm PST -- implements arrows on ChipNDale viewers -- we have to distribute the command to the separate viewers because -- arrows have different sizes in design coordinates, depending on scale -- of the viewer. -- we do store the arrow position twice! -- 1: on a per design basis (using CDValue); this is used to reeinstall arrows -- when viewers are opened -- 2: on a per viewer basis (in the PainterRec); this allows erasing the arrows -- however we need a flag in the PainterRec if it is valid ($on) --called from client --called from client --called through ProtectedRepaint only --called in viewers paint proc --called through ProtectedRepaint only --called in viewers paint proc --crazy: we fork, because we want to wait --crazy: we wait, to increase propability of the commandtable beeing initialized Κ„˜codešœ,™,Kšœ Οmœ7™BKšœ5™5Kšœ=™=—K˜šΟk ˜ Kšœ ˜ Kšžœ˜Kšœ ˜ Kšœ ˜ Kšœ ˜ Kšœ˜Kšœ ˜ Kšœ˜Kšœ ˜ Kšœ ˜ Kšœ˜Kšœ˜Kšœ ˜ —K˜šΟn œžœž˜Kšžœ‚˜‰Kšžœ ˜—Kšž˜K™K™)K™KšœE™EKšœI™IKšœ™K™™(K™OK™KšœO™OKšœD™D—K˜š Ÿ œžœžœ žœžœ˜@KšΟc™Kšœ3žœžœ˜IKšœ^˜^Kšœ˜—K˜šŸ œžœžœ žœ ˜/Kšœ™Kšœ3žœ˜8KšœZ˜ZKšœ˜—K˜šŸœž œžœžœ˜\Kšž˜Kšœžœ;˜AKšžœžœžœžœ˜šžœ˜Kšœžœ+˜3Kšœ;˜;Kšœ˜—Kšœ˜—K˜šΟb œ˜&Kšœžœ\˜bKšœ$˜$Kšœ.˜.KšœA˜AKšœA˜AKšœD˜DKšœ˜—K˜š‘ œ'˜4Kšœ œ™&Kšœ  ™Kšœžœ,˜3Kšœžœžœ˜,Kšœ žœ žœ:˜Tšœžœ-˜6Kšœ8˜8—šžœžœ˜Kšœ žœ˜Kšžœžœžœ˜Kšœ˜Kšœ˜KšœQ˜QK˜—šžœ˜Kšœ˜Kšœ&˜&Kšœ˜K˜—KšœM˜MKšœ˜K˜—š‘œ'˜5Kšœ œ™&Kšœ  ™Kšœžœ,˜3šžœžœ˜Kšœ žœ˜Kšœ˜Kšœ žœ˜KšœQ˜QKšœ%˜%K˜—Kšœ˜—K˜šΠbnœžœ˜6Kš *™*Kšœžœžœ˜