CDRepetitionsImpl.mesa (part of ChipNDale)
Copyright © 1983, 1986 by Xerox Corporation. All rights reserved.
Created by Christian Jacobi, October 27, 1983 3:36 pm
Last Edited by: Christian Jacobi, December 17, 1986 3:08:11 pm PST
DIRECTORY
CD,
CDBasics,
CDDirectory,
CDIO,
CDProperties,
CDRepetitions,
IO,
Rope,
TokenIO;
CDRepetitionsImpl:
CEDAR
PROGRAM
IMPORTS CD, CDBasics, CDDirectory, CDIO, CDProperties, IO, TokenIO, Rope
EXPORTS CDRepetitions
SHARES CDDirectory =
BEGIN
RepSpecific: TYPE = CDRepetitions.RepSpecific;
RepRec: TYPE = CDRepetitions.RepRec;
pForRepetitions:
CD.ObjectClass =
CD.RegisterObjectClass[$Repetitions, [
drawMe: DrawMeForRepetitions,
quickDrawMe: QuickDrawMeForRepetitions,
internalRead: ReadRepetition,
internalWrite: WriteRepetition,
describe: Describe
]];
Describe:
PROC [me:
CD.Object]
RETURNS [Rope.
ROPE] = {
rp: RepSpecific = NARROW[me.specific];
RETURN [
IO.PutFR[
"repetition [%g] ""%g""",
[integer[rp.count]],
[rope[CDDirectory.Name[me]]]
]]
};
Adjust:
PROC [repOb:
CD.Object, rp: RepSpecific] = {
or: CD.Rect ← CDBasics.MapRect[rp.ob.bbox, [[0,0], rp.orientation]];
ir: CD.Rect ← CDBasics.MapRect[CD.InterestRect[rp.ob], [[0,0], rp.orientation]];
totalOffset: CD.Position ← [(rp.count-1)*rp.offset.x, (rp.count-1)*rp.offset.y];
repOb.bbox ← CDBasics.Surround[or, CDBasics.MoveRect[or, totalOffset]];
rp.ir ← CDBasics.Surround[ir, CDBasics.MoveRect[ir, totalOffset]];
};
InternalCreateRepetition:
PROC [ob:
CD.Object, count:
NAT, offset:
CD.Position, orientation:
CD.Orientation]
RETURNS [
CD.Object] = {
rp: RepSpecific =
NEW[RepRec←[
ob: ob,
ir: [0, 0, 0, 0],
orientation: orientation,
offset: offset,
count: MAX[1, MIN[count, 512]]
]];
repOb:
CD.Object =
NEW[
CD.ObjectRep←[
class: pForRepetitions,
specific: rp
]];
Adjust[repOb, rp];
RETURN [repOb];
};
CreateRepetition:
PUBLIC
PROC [design:
CD.Design, ob:
CD.Object, count:
NAT, offset:
CD.Position, orientation:
CD.Orientation]
RETURNS [
CD.Object] = {
repOb: CD.Object = InternalCreateRepetition[ob, count, offset, orientation];
[] ← CDDirectory.Include[design, repOb, Rope.Cat["=rep-", CDDirectory.Name[ob]]];
RETURN [repOb];
};
DrawMeForRepetitions:
PROC [inst:
CD.Instance, trans:
CD.Transformation, pr:
CD.DrawRef] = {
rptr: RepSpecific ← NARROW[inst.ob.specific];
dummyInstance: CD.Instance ← NEW[CD.InstanceRep←[ob: rptr.ob]];
t1: CD.Transformation ← CDBasics.ComposeTransform[[[0,0], rptr.orientation], trans];
off: CD.Position ← CDBasics.MapPoint[rptr.offset, [[0,0], trans.orient]];
FOR i:
INT
IN [0..rptr.count)
DO
IF pr.stopFlag^ THEN EXIT;
pr.drawChild[dummyInstance, t1, pr];
t1.off ← CDBasics.AddPoints[t1.off, off]
ENDLOOP;
};
QuickDrawMeForRepetitions:
PROC [inst:
CD.Instance, trans: CD.Transformation, pr:
CD.DrawRef] = {
rptr: RepSpecific ← NARROW[inst.ob.specific];
t1: CD.Transformation ← CDBasics.ComposeTransform[[[0,0], rptr.orientation], trans];
off: CD.Position ← CDBasics.MapPoint[rptr.offset, [[0,0], trans.orient]];
IF pr.dummyInst=NIL THEN pr.dummyInst ← NEW[CD.InstanceRep←[ob: rptr.ob]];
FOR i:
INT
IN [0..rptr.count)
DO
IF pr.stopFlag^ THEN EXIT;
pr.dummyInst.ob ← rptr.ob;
rptr.ob.class.quickDrawMe[pr.dummyInst, t1, pr];
t1.off ← CDBasics.AddPoints[t1.off, off]
ENDLOOP;
};
Another:
PROC [me:
CD.Object, fromOrNil:
CD.Design, into:
CD.Design
, friendly:
BOOL]
RETURNS [new:
CD.Object, topMode: CDDirectory.InclOrReady←ready, childMode: CDDirectory.ImmOrIncl←immutable] = {
rp: RepSpecific = NARROW[me.specific];
new ← InternalCreateRepetition[rp.ob, rp.count, rp.offset, rp.orientation];
CDProperties.AppendProps[winner: new.properties, looser: me.properties, putOnto: new];
IF ~rp.ob.class.inDirectory
OR (fromOrNil#
NIL
AND fromOrNil=into)
THEN
childMode ← included
};
EnumerateRepeatedObjects:
PROC [me:
CD.Object, p: CDDirectory.EnumerateObjectsProc, x:
REF] = {
rptr: RepSpecific = NARROW[me.specific];
p[rptr.ob, x];
};
ReadRepetition:
CD.InternalReadProc = {
ob: CD.Object = CDIO.ReadObject[h];
count: NAT = TokenIO.ReadInt[h];
offset: CD.Position = CDIO.ReadPos[h];
orientation: CD.Orientation = CDIO.ReadOrientation[h];
rep: CD.Object ← InternalCreateRepetition[ob: ob, count: count, offset: offset, orientation: orientation];
?? IF CDIO.VersionKey[h]<=15 THEN not necessary; I can't believe it but I tested it
RETURN [rep];
};
WriteRepetition:
CD.InternalWriteProc = {
specific: RepSpecific = NARROW[ob.specific];
CDIO.WriteObject[h, specific.ob];
TokenIO.WriteInt[h, specific.count];
CDIO.WritePos[h, specific.offset];
CDIO.WriteOrientation[h, specific.orientation];
};
ReplaceDirectChildForReps: CDDirectory.ReplaceDChildsProc = {
rp: CDRepetitions.RepSpecific = NARROW[me.specific];
bbox: CD.Rect ← me.bbox;
ir: CD.Rect ← rp.ir;
FOR replaceList: CDDirectory.ReplaceList ← replace, replaceList.rest
WHILE replaceList#
NIL
DO
rep: REF CDDirectory.ReplaceRec ← replaceList.first;
IF rep.old=rp.ob
THEN {
trans:
CD.Transformation ← CDBasics.ComposeTransform[
itemInCell: rep.trans,
cellInWorld: [[0, 0], rp.orientation]
].itemInWorld;
rp.ob ← rep.new;
rp.orientation ← trans.orient;
Adjust[me, rp];
IF trans.off#[0, 0]
THEN
CDDirectory.ReplaceObject[design: design, old: me, new: me, trans: [trans.off, original]]
ELSE
IF me.bbox#bbox
OR rp.ir#ir
THEN
CDDirectory.PropagateResize[design, me];
changed ← TRUE;EXIT;
};
ENDLOOP;
};
InitRepetitions:
PROC [] = {
rp:
REF CDDirectory.DirectoryProcs = CDDirectory.InstallDirectoryProcs[pForRepetitions, [
enumerateChildObjects: EnumerateRepeatedObjects,
replaceDirectChilds: ReplaceDirectChildForReps,
another: Another
]];
};
InitRepetitions[];
END.