CDRepetitionCommands.mesa (part of ChipNDale)
Copyright © 1983, 1984 by Xerox Corporation. All rights reserved.
by Christian Jacobi, July 11, 1983 3:42 pm
last edited Christian Jacobi, June 3, 1985 2:05:26 pm PDT
DIRECTORY
CD,
CDInstances,
CDCallSpecific,
CDCells,
CDCommandOps,
CDDirectory,
CDOps,
CDOrient,
CDProperties,
CDRepetitions,
CDSequencer,
Rope,
TerminalIO;
CDRepetitionCommands: CEDAR PROGRAM
IMPORTS CDInstances, CDCallSpecific, CDCells, CDCommandOps, CDDirectory, CDOps, CDOrient, CDProperties, CDRepetitions, CDSequencer, TerminalIO =
BEGIN
MakeRepetition: PROC [comm: CDSequencer.Command] =
BEGIN
sel: CD.InstanceList;
ob: CD.Object;
offset, location: CD.Position;
count: INT;
first: CD.Instance;
multiple: BOOL;
TerminalIO.WriteRope["make a repetition "];
[first, multiple] ← CDOps.SelectedInstance[comm.design];
IF first=NIL THEN {TerminalIO.WriteRope["no selected object\n"]; RETURN};
count ← TerminalIO.RequestInt["number: "];
IF count<1 OR count>=LAST[NAT] THEN
{TerminalIO.WriteRope["bad number\n"]; RETURN};
IF count>=257 THEN
{TerminalIO.WriteRope["don't exagerate\n"]; RETURN};
IF multiple THEN {
[done: multiple, cellOb: ob] ← CDCells.CreateCellSelected[comm.design, "-dummy"];
IF NOT multiple THEN {TerminalIO.WriteRope["not done\n"]; RETURN};
};
[selected: sel, others: comm.design.actual.first.specific.contents] ←
CDInstances.SplitSelected[comm.design.actual.first.specific.contents];
IF sel.first=NIL OR sel.rest#NIL THEN ERROR; -- therefore sel#NIL !
offset ← [comm.pos.x-comm.sPos.x, comm.pos.y-comm.sPos.y];
ob ← CDRepetitions.CreateRepetition[comm.design, sel.first.ob, count, offset, sel.first.orientation];
location ← sel.first.location;
IF offset.x<0 THEN location.x ← location.x+(count-1)*offset.x;
IF offset.y<0 THEN location.y ← location.y+(count-1)*offset.y;
CDOps.AddAnObject[comm.design, ob, location, CDOrient.original];
END;
ChangeRepetition: PROC [comm: CDSequencer.Command] =
BEGIN
inst: CD.Instance = CDCommandOps.TheInstance[comm, "change a repetition "];
IF inst#NIL THEN
IF ~ISTYPE[inst.ob.specificRef, CDRepetitions.RepPtr] THEN
TerminalIO.WriteRope["selected ob not a repetition"]
ELSE {
offset: CD.Position = [comm.pos.x-comm.sPos.x, comm.pos.y-comm.sPos.y];
rp: CDRepetitions.RepPtr = NARROW[inst.ob.specificRef];
CDCommandOps.RedrawInstance[comm.design, inst];
inst.ob ← CDRepetitions.CreateRepetition[comm.design, rp.ob, rp.count, offset, CDOrient.ComposeOrient[rp.orientation, inst.orientation]];
inst.orientation ← CDOrient.original;
CDCommandOps.RedrawInstance[comm.design, inst, FALSE];
TerminalIO.WriteRope[" done\n"]
};
END;
TransformToCellS: PROC [comm: CDSequencer.Command] =
BEGIN
n: NAT;
TerminalIO.WriteRope["transform to cell\n"];
n ← CDCallSpecific.CallForSelected[design: comm.design, objectSpecific: $TransformToCell, whatElse: TransformOthers];
TerminalIO.WriteInt[n]; TerminalIO.WriteRope[" objects transformed\n"];
END;
TransformOthers: PROC [design: CD.Design, inst: CD.Instance, x: REF]
RETURNS [done: BOOLTRUE, removeMe: BOOLFALSE, include: CD.InstanceList←NIL,
repaintMe: BOOLFALSE, repaintInclude: BOOLFALSE] =
BEGIN
IF inst.ob.class.inDirectory AND ~CDCells.IsCell[inst.ob] THEN {
cob: CD.Object ← CDDirectory.Expand[inst.ob, design, design];
done ← cob#NIL;
IF done THEN {
removeMe ← TRUE;
repaintMe ← TRUE;
include ← LIST[NEW[CD.InstanceRep ← [
ob: cob,
location: inst.location,
orientation: inst.orientation,
selected: inst.selected,
properties: CDProperties.CopyProps[inst.properties]
]]];
repaintInclude ← TRUE;
}
};
END;
AllRepetitionsToCells: PROC [comm: CDSequencer.Command] =
BEGIN
n: NAT ← 0;
repList: LIST OF CD.Object ← NIL;
--we make a list first, otherwise: directory changes while the enumeration
FindRepetitions: CDDirectory.EachEntryAction =
-- PROC [name: Rope.ROPE, ob: CD.Object] RETURNS [quit: BOOL�LSE]
BEGIN
WITH ob.specificRef SELECT FROM
rp: CDRepetitions.RepPtr => repList ← CONS[ob, repList];
ENDCASE => NULL
END;
TerminalIO.WriteRope["transform all repetitions to cells\n"];
[] ← CDDirectory.Enumerate[design: comm.design, action: FindRepetitions];
FOR list: LIST OF CD.Object ← repList, list.rest WHILE list#NIL DO
name: Rope.ROPE ← CDDirectory.Name[list.first];
rCell: CD.Object ← CDDirectory.Expand[list.first, comm.design, comm.design];
IF rCell=NIL THEN
TerminalIO.WriteRope[Rope.Cat["** ", name, " not transformed\n"]]
ELSE {
[] ← CDDirectory.Remove[design: comm.design, name: name, expectObject: list.first];
[] ← CDDirectory.Rename[design: comm.design, object: rCell, newName: name];
n ← n+1;
CDDirectory.ReplaceObject[design: comm.design, old: list.first, new: rCell];
TerminalIO.WriteRope[Rope.Cat[" cell ", CDDirectory.Name[rCell], " generated\n"]]
};
ENDLOOP;
TerminalIO.WriteInt[n]; TerminalIO.WriteRope[" repetitions transformed\n"];
END;
CDSequencer.ImplementCommand[$DrawRepetition, MakeRepetition];
CDSequencer.ImplementCommand[$ChangeRepetition, ChangeRepetition];
CDSequencer.ImplementCommand[$TransformToCellS, TransformToCellS];
END.