<> <> <> <> DIRECTORY CD, CDBasics, 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 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; DesignOf: PUBLIC PROC[viewer: ViewerClasses.Viewer] RETURNS [isDesign: BOOL_FALSE, design: CD.Design_NIL, rect: CD.DesignRect_CDBasics.empty] = BEGIN IF viewer#NIL AND viewer.data#NIL AND ISTYPE[viewer.data, CDVPrivate.MyGraphicRef] THEN { me: CDVPrivate.MyGraphicRef = NARROW[viewer.data]; design _ me.actualDesign; IF me.deviceDrawRef#NIL THEN rect _ me.deviceDrawRef.worldClip; isDesign_TRUE; }; 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.worldClip] 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] = { RETURN [CDVPrivate.CreateViewer[design]] }; ShowArrow: PUBLIC PROC [design: CD.Design, pos: CD.DesignPosition] = { CDVArrow.ShowArrow[design, pos] }; <<>> RemoveArrow: PUBLIC PROC[design: CD.Design] = { CDVArrow.RemoveArrow[design] }; FindDesign: PUBLIC PROC[name: Rope.ROPE, case: BOOL _ TRUE] 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; END.