CDAbutsImpl.mesa
Copyright © 1983, 1984, 1985 by Xerox Corporation. All rights reversed.
Created by Bertrand Serlet, February 3, 1985 12:49:51 pm PST
Last edited by Bertrand Serlet, May 22, 1985 5:38:03 pm PDT
DIRECTORY
CD, CDAbuts, CDBasics, CDCallSpecific, CDCells, CDDirectory, CDMenus, CDOps, CDProperties, CDSequencer, CDX, Rope, TerminalIO;
CDAbutsImpl: CEDAR PROGRAM
IMPORTS CD, CDBasics, CDCallSpecific, CDCells, CDDirectory, CDMenus, CDOps, CDProperties, CDSequencer, CDX, Rope, TerminalIO
EXPORTS CDAbuts
SHARES CDDirectory =
BEGIN
OPEN CDAbuts;
Is this an Abut?
IsAbutX: PUBLIC IsAbutProc = {
yes ← (ob#NIL) AND (ob.specificRef#NIL) AND ISTYPE [ob.specificRef, LIST OF CD.ObPtr] AND (ob.p=pForAbutX) AND (ob.p.objectType=$AbutX);
}; -- completely redundant
IsAbutY: PUBLIC IsAbutProc = {
yes ← (ob#NIL) AND (ob.specificRef#NIL) AND ISTYPE [ob.specificRef, LIST OF CD.ObPtr] AND (ob.p=pForAbutY) AND (ob.p.objectType=$AbutY);
}; -- completely redundant
IsAbut: PUBLIC IsAbutProc = {
yes ← (ob#NIL) AND (ob.specificRef#NIL) AND ISTYPE [ob.specificRef, LIST OF CD.ObPtr] AND (ob.p=pForAbutX OR ob.p=pForAbutY) AND (ob.p.objectType=$AbutX OR ob.p.objectType=$AbutY);
}; -- completely redundant
Getting subobjects from an Abut.
NARROW error if not an Abut
GetAbutSubObjects: PUBLIC PROC [abut: CD.ObPtr] RETURNS [subObjects: LIST OF CD.ObPtr] = {
subObjects ← NARROW [abut.specificRef];
};
Creating a new Abut object.
CreateNewAbutX: PUBLIC CreateAbutProc = {
newAbut ← NEW [CD.ObjectDefinition ← [p: pForAbutX, specificRef: subObjects]];
newAbut.size ← Expand[newAbut, NIL, NIL].size;
};
CreateNewAbutY: PUBLIC CreateAbutProc = {
newAbut ← NEW [CD.ObjectDefinition ← [p: pForAbutY, specificRef: subObjects]];
newAbut.size ← Expand[newAbut, NIL, NIL].size;
};
Expanding Abuts into cells
Takes an abut and returns the cell which is equivalent to this abut. Cell resulting always belongs to the from design if me belongs to the from design. It is included in the to design if to#NIL
Expand: CDDirectory.AnotherProc -- [me: CD.ObPtr, from: CD.Design, to: CD.Design] RETURNS [CD.ObPtr] -- = {
pos: CD.Position ← [0, 0];
equivalentCell: CD.ObPtr;
IF to=NIL THEN {
ref: REF ← CDProperties.GetPropFromObject[me, $AbutCache];
IF ref#NIL THEN RETURN[NARROW[ref]];
};
equivalentCell ← CDCells.CreateEmptyCell[];
FOR list: LIST OF CD.ObPtr ← GetAbutSubObjects[me], list.rest WHILE list#NIL DO
[] ← CDX.IncludeOb[design: NIL, cell: equivalentCell, ob: list.first, position: pos, cellCSystem: originCoords, obCSystem: interrestCoords, mode: dontPropagate];
SELECT me.p FROM
pForAbutX => pos.x ← pos.x + CDBasics.SizeOfRect[CD.InterestRect[list.first]].x;
pForAbutY => pos.y ← pos.y + CDBasics.SizeOfRect[CD.InterestRect[list.first]].y;
ENDCASE => ERROR;
ENDLOOP;
[] ← CDCells.RepositionCell[equivalentCell, NIL];
IF to#NIL
THEN [] ← CDDirectory.Include[to, equivalentCell, Rope.Cat[CDDirectory.Name[equivalentCell], "-AbutEquivalent"]]
ELSE CDProperties.PutPropOnObject[me, $AbutCache, equivalentCell];
RETURN [equivalentCell];
};
DirectoryProcs applicable to Abuts
EnumerateAbutChildObjects: CDDirectory.EnumerateChildObjectsProc -- [me: CD.ObPtr, p: CDDirectory.EnumerateObjectsProc, x: REF ANY] -- = {
ref: REF ← CDProperties.GetPropFromObject[me, $AbutCache];
IF ref#NIL THEN p[NARROW[ref], x];
FOR w: LIST OF CD.ObPtr ← GetAbutSubObjects[me], w.rest WHILE w#NIL DO
p[w.first, x] ENDLOOP;
};
ReplaceAbutDirectChilds: CDDirectory.ReplaceDChildsProc -- [me: CD.ObPtr, design: CD.Design, replace: CDDirectory.ReplaceList] RETURNS [changed: BOOL ← FALSE] -- =
BEGIN
oldSize: CD.Position ← me.size;
subObjects: LIST OF CD.ObPtr ← GetAbutSubObjects[me];
FOR w: LIST OF CD.ObPtr ← subObjects, w.rest WHILE w#NIL DO
FOR l: CDDirectory.ReplaceList ← replace, l.rest WHILE l#NIL DO
IF l.first.old=w.first THEN {changed ← TRUE; EXIT};
ENDLOOP;
IF changed THEN EXIT;
ENDLOOP;
IF ~changed THEN RETURN;
CDProperties.PutPropOnObject[me, $AbutCache, NIL];
me.size ← CDDirectory.Expand[me, NIL, NIL].size;
changed ← oldSize = me.size;
CDDirectory.RepositionObject[design, me, oldSize];
END;
AnotherAbut: CDDirectory.AnotherProc -- [me: CD.ObPtr, from: CD.Design, to: CD.Design] RETURNS [CD.ObPtr] -- =
BEGIN
newAbut: CD.ObPtr ← IF IsAbutX[me] THEN CreateNewAbutX[GetAbutSubObjects[me]] ELSE CreateNewAbutY[GetAbutSubObjects[me]];
IF to#NIL THEN [] ← CDDirectory.Include[to, newAbut, CDDirectory.Name[me]];
RETURN [newAbut]
END;
Object Procs for Abuts (patch before Christian makes a nice outlineproc)
DrawAbutSelection: PROC [aptr: CD.ApplicationPtr, pos: CD.DesignPosition, orient: CD.Orientation, pr: CD.DrawRef] = {
aptr ← NEW [CD.Application ← [
ob: CDDirectory.Expand[aptr.ob, NIL, NIL],
location: aptr.location, selected: aptr.selected]];
aptr.ob.p.showMeSelected[aptr, pos, orient, pr];
};
InterestRect: CD.RectProc -- [ob: CD.ObPtr] RETURNS [CD.DesignRect] -- = {
rect: CD.Rect ← CD.InterestRect[CDDirectory.Expand[ob, NIL, NIL]];
RETURN [rect];
};
Patch before Christian Generalizes it
TransformToCellS: PROC [comm: CDSequencer.Command] =
BEGIN
n: NAT;
TerminalIO.WriteRope["transform to cell\n"];
n ← CDCallSpecific.CallForSelected[comm.design, $TransformToCell];
TerminalIO.WriteInt[n]; TerminalIO.WriteRope[" objects transformed\n"];
END;
TransformToCell: CDCallSpecific.CallProc
-- PROC [design: CD.Design, aptr: CD.ApplicationPtr, x: REF] RETURNS [done: BOOL←TRUE, removeMe: BOOL�LSE, include: CD.ApplicationList←NIL, repaintMe: BOOL�LSE, repaintInclude: BOOL�LSE] -- =
BEGIN
cob: CD.ObPtr ← NIL;
IF IsAbut[aptr.ob] THEN cob ← CDDirectory.Expand[aptr.ob, design, design];
done ← cob#NIL;
IF done THEN {
removeMe ← TRUE;
repaintMe ← TRUE;
include ← LIST[NEW[CD.Application ← [
ob: cob,
location: aptr.location,
orientation: aptr.orientation,
selected: aptr.selected,
properties: CDProperties.CopyProps[aptr.properties]
]]];
repaintInclude ← TRUE;
}
END;
Another Patch before Christian Generalizes it
ExpandAndPushS: PROC [comm: CDSequencer.Command] =
BEGIN
first: CD.ApplicationPtr;
multiple: BOOL;
[first, multiple] ← CDOps.SelectedApplication[comm.design];
TerminalIO.WriteRope["ExpandAndPush into object "];
IF multiple THEN {TerminalIO.WriteRope["Multiple selected object\n"]; RETURN};
IF first=NIL THEN {TerminalIO.WriteRope["No selected object\n"]; RETURN};
SELECT TRUE FROM
CDCells.IsCell[first.ob] =>
IF CDCells.PushInCellSelected[comm.design] THEN {
TerminalIO.WriteRope[comm.design.actual.first.specific.name];
TerminalIO.WriteLn[]
}
ELSE TerminalIO.WriteRope["not done\n"];
IsAbut[first.ob]    => {
TerminalIO.WriteRope[CDDirectory.Name[first.ob]];
TerminalIO.WriteRope[" expanded into "];
first.ob ← CDDirectory.Expand[first.ob, comm.design, comm.design];
IF CDCells.PushInCellSelected[comm.design] THEN {
TerminalIO.WriteRope[comm.design.actual.first.specific.name];
TerminalIO.WriteLn[]
}
ELSE TerminalIO.WriteRope["not done\n"];
};
ENDCASE      => TerminalIO.WriteRope[" not done\n"];
END;
Start of initialization
pForAbutX: REF CD.ObjectProcs = CD.RegisterObjectType[$AbutX];
dpx: REF CDDirectory.DirectoryProcs = CDDirectory.InstallDirectoryProcs[pForAbutX];
pForAbutY: REF CD.ObjectProcs = CD.RegisterObjectType[$AbutY];
dpy: REF CDDirectory.DirectoryProcs = CDDirectory.InstallDirectoryProcs[pForAbutY];
Everything for AbutX
DirectoryProcs
dpx.enumerateChildObjects ← EnumerateAbutChildObjects;
dpx.replaceDirectChilds ← ReplaceAbutDirectChilds;
dpx.another ← AnotherAbut;
dpx.expand ← Expand;
Object Procs
pForAbutX.showMeSelected ← DrawAbutSelection;
pForAbutX.interestRect ← InterestRect;
Everything for AbutY
DirectoryProcs
dpy.enumerateChildObjects ← EnumerateAbutChildObjects;
dpy.replaceDirectChilds ← ReplaceAbutDirectChilds;
dpy.another ← AnotherAbut;
dpy.expand ← Expand;
Object Procs
pForAbutY.showMeSelected ← DrawAbutSelection;
pForAbutY.interestRect ← InterestRect;
Accelerator (Cache mechanism for the expansion)
[] ← CDProperties.RegisterProperty[$AbutCache, $Abuts];
CDProperties.FetchProcs[$AbutCache].makeCopy ← CDProperties.DontCopy;
Patch waiting clean TransformToCell
CDCallSpecific.Register[$TransformToCell, pForAbutX, TransformToCell];
CDCallSpecific.Register[$TransformToCell, pForAbutY, TransformToCell];
CDSequencer.ImplementCommand[$TransformToCellS, TransformToCellS,, doQueue];
CDMenus.CreateEntry[$SpecialMenu, "Abuts -> Cell", $TransformToCellS];
Patch waiting clean ExpandAndPush
CDSequencer.ImplementCommand[$ExpandAndPushS, ExpandAndPushS,, doQueue];
END.