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: BOOLLSE, include: CD.ApplicationList←NIL, repaintMe: BOOLLSE, repaintInclude: BOOLLSE] -- =
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.