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.