<> <> <> <> DIRECTORY CD, CDBasics, CDSequencer, CDVArrow, CDViewer, CDVPrivate, CDVScale, Rope USING [ROPE, Equal], ViewerClasses USING [Viewer], ViewerOps; CDViewerImpl: CEDAR PROGRAM IMPORTS CDVArrow, CDVPrivate, CDVScale, CDBasics, Rope, ViewerOps EXPORTS CDViewer SHARES CDVPrivate = BEGIN ViewerList: TYPE = LIST OF ViewerClasses.Viewer; ViewersOf: PUBLIC PROC[design: REF] RETURNS [vl: ViewerList_NIL] = BEGIN WITH design SELECT FROM me: CDVPrivate.MyGraphicRef => IF me.viewer#NIL THEN RETURN [LIST[me.viewer]]; comm: CDSequencer.Command => RETURN [ViewersOf[comm.ref]]; ENDCASE => NULL; FOR l: CDVPrivate.MyGraphicRef _ CDVPrivate.linkBase, l.link WHILE l#NIL DO IF design=l.actualDesign OR design=l.actualDesign.technology THEN vl _ CONS[l.viewer, vl]; ENDLOOP END; VisibleRect: PUBLIC PROC [viewer: ViewerClasses.Viewer] RETURNS [r: CD.DesignRect _ CDBasics.empty] = <<--undefined if viewer not open or not ChipNDale design>> BEGIN IF viewer#NIL THEN WITH viewer.data SELECT FROM me: CDVPrivate.MyGraphicRef => IF me.deviceDrawRef#NIL THEN r _ me.deviceDrawRef.interestClip; ENDCASE => NULL; END; DesignOf: PUBLIC PROC [viewer: ViewerClasses.Viewer] RETURNS [design: CD.Design _ NIL] = <<--NIL if not a ChipNDale design>> BEGIN IF viewer#NIL THEN WITH viewer.data SELECT FROM me: CDVPrivate.MyGraphicRef => design _ me.actualDesign ENDCASE => NULL; END; ShowPosition: PUBLIC PROC[viewer: ViewerClasses.Viewer, pos: CD.DesignPosition] = <<--moves viewer such that pos is in visible area (does not open closed viewer)>> <<--approximative only>> BEGIN IF viewer#NIL AND viewer.data#NIL AND ISTYPE[viewer.data, CDVPrivate.MyGraphicRef] THEN { viewerCenterOffset: CD.Position _ [viewer.cw/2, viewer.ch/2]; designCenterOffset: CD.Position; me: CDVPrivate.MyGraphicRef = NARROW[viewer.data]; dscale: CDVScale.ScaleRec _ CDVScale.MakeScale[nscale: me.scale.nscale, grid: me.scale.grid]; IF CDBasics.InsidePos[pos, me.deviceDrawRef.interestClip] THEN RETURN; designCenterOffset _ CDVScale.ViewerToDesignPosition[dscale, viewerCenterOffset]; dscale _ CDVScale.MakeScale[nscale: me.scale.nscale, grid: me.scale.grid, off: CDBasics.SubPoints[pos, designCenterOffset]]; me.scale _ dscale; ViewerOps.PaintViewer[viewer, client, FALSE, NIL]; }; END; ShowAndScale: PUBLIC PROC[viewer: ViewerClasses.Viewer, rect: CD.DesignRect] = <<--moves and scales viewer such that rect is in visible area (does not open closed viewer)>> <<--approximative only>> BEGIN IF viewer#NIL AND viewer.data#NIL AND ISTYPE[viewer.data, CDVPrivate.MyGraphicRef] THEN { me: CDVPrivate.MyGraphicRef = NARROW[viewer.data]; dscale: CDVScale.ScaleRec; off: CD.DesignPosition _ CDBasics.Center[rect]; s: CARDINAL _ 0; FOR j: CARDINAL IN [0..CDVScale.scaleNum) DO s _ j; dscale _ CDVScale.MakeScale[nscale: s, grid: 1]; IF CDVScale.ViewerToDesignScalar[dscale, viewer.cw]>(rect.x2-rect.x1) AND CDVScale.ViewerToDesignScalar[dscale, viewer.ch]>(rect.y2-rect.y1) THEN EXIT; ENDLOOP; dscale _ CDVScale.MakeScale[nscale: s, grid: 1]; off.x _ off.x - CDVScale.ViewerToDesignScalar[dscale, viewer.cw]/2; off.y _ off.y - CDVScale.ViewerToDesignScalar[dscale, viewer.ch]/2; dscale _ CDVScale.MakeScale[nscale: s, grid: me.scale.grid, off: off]; me.scale _ dscale; ViewerOps.PaintViewer[viewer, client, FALSE, NIL]; }; END; CreateViewer: PUBLIC PROC [design: CD.Design] RETURNS [ViewerClasses.Viewer] = BEGIN RETURN [CDVPrivate.CreateViewer[design]] END; ShowArrow: PUBLIC PROC [design: CD.Design, pos: CD.DesignPosition] = BEGIN CDVArrow.ShowArrow[design, pos] END; <<>> RemoveArrow: PUBLIC PROC[design: CD.Design] = BEGIN CDVArrow.RemoveArrow[design] END; FindDesign: PUBLIC PROC[name: Rope.ROPE, case: BOOL _ FALSE] RETURNS [CD.Design] = <<--only designs with viewers can be found;>> <<--if multiple designs have the same name, find arbitrary one>> BEGIN FOR l: CDVPrivate.MyGraphicRef _ CDVPrivate.linkBase, l.link WHILE l#NIL DO IF Rope.Equal[l.actualDesign.name, name, case] THEN RETURN[l.actualDesign]; ENDLOOP; RETURN [NIL] END; GetViewer: PUBLIC PROC [comm: CDSequencer.Command] RETURNS [v: ViewerClasses.Viewer _ NIL] = BEGIN IF comm#NIL THEN WITH comm.ref SELECT FROM my: CDVPrivate.MyGraphicRef => RETURN [my.viewer] ENDCASE => NULL END; LastViewer: PUBLIC PROC[] RETURNS [ViewerClasses.Viewer]= BEGIN RETURN [CDVPrivate.LastViewer[]] END; END.