CDViewerImpl.mesa (part of Chipndale)
Copyright © 1983, 1985 by Xerox Corporation. All rights reserved.
by Christian Jacobi, October 13, 1983 3:07 pm
last edited by Christian Jacobi, February 16, 1985 5:11:45 pm PST
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: BOOLFALSE] 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.