DIRECTORY Atom USING [PutPropOnList], CedarProcess, CD, CDBasics, CDDraw, CDProperties, CDValue, CDVArrow, CDVPrivate, CDVScale, CDVFurtherPainters, Imager, Process, ViewerEvents; CDVArrowImpl: CEDAR MONITOR IMPORTS CedarProcess, CDDraw, CDBasics, CDProperties, CDValue, CDVPrivate, CDVScale, CDVFurtherPainters, Imager, Process, ViewerEvents EXPORTS CDVArrow = BEGIN ShowArrow: PUBLIC PROC [design: CD.Design, pos: CD.Position] = BEGIN CDValue.Store[boundTo: design, key: $arrow, value: NEW[CD.Position_pos]]; CDDraw.InsertCommandAll[design, CDDraw.Comm[cmd: ref, erase: FALSE, rect: [pos.x, pos.y, 0, 0], ref: $PutArrowXXX]] END; RemoveArrow: PUBLIC PROC[design: CD.Design] = BEGIN CDValue.Store[boundTo: design, key: $arrow, value: NIL]; CDDraw.InsertCommandAll[design, CDDraw.Comm[cmd: ref, erase: FALSE, rect: [0, 0, 0, 0], ref: $RemoveArrowXXX]] END; GetAPainterRec: ENTRY PROC [me: CDVPrivate.MyGraphicRef] RETURNS [pr: REF CDVPrivate.PainterRec] = BEGIN ENABLE UNWIND => NULL; x: REF = CDProperties.GetPropFromList[me.properties, $CDxArrowPaintProc]; IF x#NIL THEN pr _ NARROW[x] ELSE { pr _ NEW[CDVPrivate.PainterRec_[proc: PaintArrow]]; me.properties _ Atom.PutPropOnList[me.properties, $CDxArrowPaintProc, pr] } END; PaintArrow: CDVPrivate.PainterProc = BEGIN 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]]; END; PaintTheArrow: CDVFurtherPainters.FurtherPaintProc = BEGIN pr: REF CDVPrivate.PainterRec = GetAPainterRec[me]; comm: REF CDDraw.Comm = 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; CDDraw.InsertCommand[me.ct, CDDraw.Comm[cmd: rect, erase: TRUE, rect: oldRect, ref: NIL]]; } ELSE { pr.rect _ aRect; CDVPrivate.IncludeAPainterRec[me, pr]; pr.data _ $on; }; CDDraw.InsertCommand[me.ct, CDDraw.Comm[cmd: rect, erase: FALSE, rect: aRect, ref: NIL]]; END; RemoveTheArrow: CDVFurtherPainters.FurtherPaintProc = BEGIN pr: REF CDVPrivate.PainterRec = GetAPainterRec[me]; IF pr.data = $on THEN { oldRect: CD.Rect _ pr.rect; pr.rect _ CDBasics.empty; pr.data _ NIL; CDDraw.InsertCommand[me.ct, CDDraw.Comm[cmd: rect, erase: TRUE, rect: oldRect, ref: NIL]]; CDVPrivate.RemoveAPainterRec[me, pr]; } END; CallOnOpenOrCreate: ViewerEvents.EventProc = TRUSTED BEGIN Process.Detach[FORK ReInstallTheArrow[NARROW[viewer.data]]]; END; ReInstallTheArrow: PROC [me: CDVPrivate.MyGraphicRef] = BEGIN 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 => { CDDraw.InsertCommand[me.ct, CDDraw.Comm[cmd: ref, erase: FALSE, rect: [pos.x, pos.y, 0, 0], ref: $PutArrowXXX]] }; ENDCASE => { CDDraw.InsertCommand[me.ct, CDDraw.Comm[cmd: ref, erase: FALSE, rect: [0, 0, 0, 0], ref: $RemoveArrowXXX]] }; } END; Init: PROC [] = BEGIN CDValue.EnregisterKey[$arrow]; CDVFurtherPainters.InstallFurtherPaint[keyValue: $PutArrowXXX, proc: PaintTheArrow]; CDVFurtherPainters.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]; END; Init[]; END. XCDVArrowImpl.mesa (part of ChipNDale) Copyright c 1984 by Xerox Corporation. All rights reserved. by Christian Jacobi, August 30, 1984 10:21:27 am PDT last edited by Christian Jacobi, June 11, 1985 9:26:06 pm PDT -- 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 -- PROC [me: MyGraphicRef, paintRef: REF PainterRec, interrestRect: CD.Rect]; --PROC [me: CDVPrivate.MyGraphicRef, key: REF] --eg. former paints ticks --called through ProtectedRepaint only --called in viewers paint proc --PROC [me: CDVPrivate.MyGraphicRef, key: REF] --eg. former paints ticks --called through ProtectedRepaint only --called in viewers paint proc -- PROC [viewer: ViewerClasses.Viewer, event: ViewerEvent, before: BOOL] RETURNS[abort: BOOL _ FALSE] --crazy: we fork, because we want to wait --crazy: we wait, to increase propability of the commandtable beeing initialized ÊV˜šœ,™,Jšœ Ïmœ1™Jšœ™Jšž˜Jšœ3žœžœ˜I˜ Jšœžœ1˜S—Jšžœ˜—J˜š  œžœžœ žœ ˜-Jšœ™Jšž˜Jšœ3žœ˜8˜ Jšœžœ,˜N—Jšžœ˜—J˜š œž œ˜9Jšžœžœ˜)Jšž˜JšœžœC˜IJšžœžœžœžœ˜šžœ˜Jšœžœ+˜3JšœI˜IJšœ˜—Jšžœ˜—J˜šŸ œ˜$JšœM™MJšž˜Jšœžœ\˜bJšœ$˜$Jšœ.˜.JšœA˜AJšœA˜AJšœD˜DJšžœ˜—J˜šŸ œ(˜5Jšœ.™.Jšœ™JšœÏcœ™&Jšœ ¡™Jšž˜Jšœžœ,˜3Jšœžœžœ˜$Jšœ žœ žœ:˜Tšœžœ-˜6Jšœ8˜8—šžœžœ˜Jšœ žœ˜Jšžœžœžœ˜Jšœ˜Jšœ˜Jšœ:žœžœ˜ZJ˜—šžœ˜Jšœ˜Jšœ&˜&Jšœ˜J˜—Jšœ:žœžœ˜YJšžœ˜J˜—šŸœ(˜6Jšœ.™.Jšœ™Jšœ¡œ™&Jšœ ¡™Jšž˜Jšœžœ,˜3šžœžœ˜Jšœ žœ˜Jšœ˜Jšœ žœ˜Jšœ:žœžœ˜ZJšœ%˜%J˜—Jšžœ˜—J˜šŸœ˜,Jš œžœ<žœžœžœžœ™eJšžœž˜ Jšœ*™*Jšœžœžœ˜