CDMoveCopyCommands.mesa (part of ChipNDale)
Copyright © 1983, 1985, 1987 by Xerox Corporation. All rights reserved.
Created by Christian Jacobi, July 11, 1983 3:42 pm
Last edited by: Christian Jacobi, February 17, 1987 6:27:42 pm PST
DIRECTORY
CD,
CDBasics,
CDInstances,
CDOps,
CDSequencer,
CDValue,
PopUpSelection,
Rope,
TerminalIO;
CDMoveCopyCommands:
CEDAR PROGRAM
IMPORTS CDBasics, CDInstances, CDOps, CDSequencer, CDValue, PopUpSelection, TerminalIO =
BEGIN
RedrawMoved:
PROC [design:
CD.Design, r:
CD.Rect, offset:
CD.Position] = {
moved: CD.Rect ← CDBasics.MoveRect[r, offset];
IF CDBasics.Intersect[r, moved]
THEN
CDOps.Redraw[design, CDBasics.Surround[r, moved], TRUE]
ELSE {
CDOps.Redraw[design, r];
CDOps.Redraw[design, moved]; -- use eraseFirst because also used by copy
}
};
OrientSelected:
PROC [design:
CD.Design, transform:
CD.Orientation, base:
CD.Rect←[0,0,-1,-1]] = {
--Orientates the selection such that:
--takes the base rectangle, transforms orientation and translates the transformed rectangle
--to fit its lower left point [after transformation] to be at the same point as the lower left
--point of the base rectangle before the transformation.
--If base is empty, use bbox of selection.
ib, is, orientOff: CD.Position; r, oldbb: CD.Rect; oldPseudoCellT, newPseudoCellT: CD.Transformation;
sel: CD.InstanceList = CDInstances.OnlySelected[CDOps.InstList[design]];
IF sel=NIL THEN RETURN;
oldbb ← CDInstances.BoundingRectO[sel];
IF ~CDBasics.NonEmpty[base] THEN base ← CDInstances.BoundingRectI[sel];
ib ← CDBasics.BaseOfRect[base];
is ← CDBasics.SizeOfRect[base];
oldPseudoCellT ← [ib, original];
r ← CDBasics.MapRect[CDBasics.RectAt[[0,0], is], [[0,0], transform]];
orientOff ← CDBasics.BaseOfRect[r];
newPseudoCellT ← [CDBasics.SubPoints[ib, orientOff], transform];
FOR w:
CD.InstanceList ← sel, w.rest
WHILE w#
NIL DO
pseudoCellRel: CD.Transformation ← CDBasics.DecomposeTransform[w.first.trans, oldPseudoCellT];
w.first.trans ← CDBasics.ComposeTransform[pseudoCellRel, newPseudoCellT]
ENDLOOP;
CDOps.Redraw[design, oldbb];
CDOps.Redraw[design, CDBasics.MapRect[CDBasics.DeMapRect[oldbb, oldPseudoCellT], newPseudoCellT]]
};
MoveSelected:
PROC [design:
CD.Design, offset:
CD.Position] = {
sel: CD.InstanceList = CDInstances.OnlySelected[CDOps.InstList[design]];
bounding: CD.Rect ← CDBasics.empty;
FOR w:
CD.InstanceList ← sel, w.rest
WHILE w#
NIL DO
inst: CD.Instance ← w.first;
bounding ← CDBasics.Surround[bounding, CDInstances.InstRectO[inst]];
inst.trans.off ← CDBasics.AddPoints[inst.trans.off, offset];
ENDLOOP;
RedrawMoved[design, bounding, offset]
};
CopySelected:
PUBLIC PROC [design:
CD.Design, offset:
CD.Position] = {
new: CD.InstanceList←NIL;
sel: CD.InstanceList = CDInstances.OnlySelected[CDOps.InstList[design]];
bounding: CD.Rect ← CDInstances.BoundingRectO[sel];
FOR w:
CD.InstanceList ← sel, w.rest
WHILE w#
NIL DO
inst: CD.Instance ← CDInstances.Copy[w.first];
inst.trans.off ← CDBasics.AddPoints[inst.trans.off, offset];
inst.selected ← TRUE;
new ← CONS[inst, new];
w.first.selected ← FALSE;
ENDLOOP;
CDOps.IncludeInstanceList[design, new, FALSE];
RedrawMoved[design, bounding, offset];
};
TransformS:
PROC [comm: CDSequencer.Command] = {
n: CARDINAL;
TerminalIO.PutRope["transform: "];
n ← PopUpSelection.Request[
header: "transform",
choice: LIST["mirror x", "mirror y", "rot 90", "rot 180", "rot 270"]];
SELECT n
FROM
1 => {TerminalIO.PutRope["mirror x\n"];
OrientSelected[comm.design, mirrorX]};
2 => {TerminalIO.PutRope["mirror y\n"];
OrientSelected[comm.design, rotate180];
OrientSelected[comm.design, mirrorX]};
3 => {TerminalIO.PutRope["rot 90\n"];
OrientSelected[comm.design, rotate90]};
4 => {TerminalIO.PutRope["rot 180\n"];
OrientSelected[comm.design, rotate180]};
5 => {TerminalIO.PutRope["rot 270\n"];
OrientSelected[comm.design, rotate270]};
ENDCASE => TerminalIO.PutRope["Skipped\n"];
};
RotS:
PROC [comm: CDSequencer.Command] = {
TerminalIO.PutRope["rotate counterclockwise\n"];
OrientSelected[comm.design, rotate90]
};
MirrorS:
PROC [comm: CDSequencer.Command] = {
TerminalIO.PutRope["mirror on x axis\n"];
OrientSelected[comm.design, mirrorX]
};
MirrorYS:
PROC [comm: CDSequencer.Command] = {
TerminalIO.PutRope["mirror on y axis\n"];
OrientSelected[comm.design, CD.mirrorY];
};
SimpleMoveSCommand:
PROC [comm: CDSequencer.Command] = {
TerminalIO.PutRope["move (no stretch)\n"];
MoveSelected[design: comm.design, offset: CD.Position[comm.pos.x-comm.sPos.x, comm.pos.y-comm.sPos.y]]
};
CopySCommand:
PROC [comm: CDSequencer.Command] = {
IF comm.pos.x#comm.sPos.x
OR comm.pos.y#comm.sPos.y
THEN {
IF comm.data#
NIL AND comm.data#comm.design
AND ISTYPE[comm.data,
CD.Design]
THEN {
--we dont want to import fancy imports; copy is logically deeper in hierachy
p: CDSequencer.CommandProc ← CDSequencer.FetchCommand[$UnqueuedCopyInterDesign].proc;
IF p=
NIL
THEN TerminalIO.PutRope["failed, command issued in other design\n"]
ELSE CDSequencer.ExecuteProc[p, comm.design, dontQueue, comm];
RETURN
};
TerminalIO.PutRope["copy\n"];
CopySelected[comm.design, CD.Position[comm.pos.x-comm.sPos.x, comm.pos.y-comm.sPos.y]]
}
ELSE TerminalIO.PutRope["no copy in place\n"];
};
StepSize:
PROC [comm: CDSequencer.Command]
RETURNS [n:
CD.Number] = {
design: CD.Design ← comm.design;
n ← CDValue.FetchInt[boundTo: design, key: $CDxStepValue, propagation: design];
IF n<=0
THEN {
n ← CDOps.GetGrid[design, comm];
IF n<=0 THEN n ← design.technology.lambda
}
};
LambdaUpS:
PROC [comm: CDSequencer.Command] = {
TerminalIO.PutRope["step move up\n"];
MoveSelected[comm.design, [0, StepSize[comm]]]
};
LambdaDownS:
PROC [comm: CDSequencer.Command] = {
TerminalIO.PutRope["step move down\n"];
MoveSelected[comm.design, [0, -StepSize[comm]]]
};
LambdaLeftS:
PROC [comm: CDSequencer.Command] = {
TerminalIO.PutRope["step move left\n"];
MoveSelected[comm.design, [-StepSize[comm], 0]]
};
LambdaRightS:
PROC [comm: CDSequencer.Command] = {
TerminalIO.PutRope["step move right\n"];
MoveSelected[comm.design, [StepSize[comm], 0]]
};
RenameDesign:
PROC [comm: CDSequencer.Command] = {
name: Rope.ROPE; done: BOOL;
TerminalIO.PutRopes["rename design ", comm.design.name, "\n"];
name ← TerminalIO.RequestRope["enter name: "];
done ← CDOps.RenameDesign[comm.design, name];
IF done THEN TerminalIO.PutRope["done\n"] ELSE TerminalIO.PutRope["not done\n"];
};
CDValue.StoreInt[boundTo: NIL, key: $CDxStepValue, value: 0];
CDSequencer.ImplementCommand[$MoveS, SimpleMoveSCommand];
CDSequencer.ImplementCommand[$CopyS, CopySCommand];
CDSequencer.ImplementCommand[$LambdaUpS, LambdaUpS];
CDSequencer.ImplementCommand[$LambdaDownS, LambdaDownS];
CDSequencer.ImplementCommand[$LambdaLeftS, LambdaLeftS];
CDSequencer.ImplementCommand[$LambdaRightS, LambdaRightS];
CDSequencer.ImplementCommand[$RotS, RotS];
CDSequencer.ImplementCommand[$MirrorYS, MirrorYS];
CDSequencer.ImplementCommand[$MirrorS, MirrorS];
CDSequencer.ImplementCommand[$TransformS, TransformS];
CDSequencer.ImplementCommand[$RenameDesign, RenameDesign];
END.