CDInstancesImpl.mesa (part of ChipNDale)
Copyright © 1983, 1985 by Xerox Corporation. All rights reserved.
by Christian Jacobi, May 12, 1983 12:22 pm
last edited by Christian Jacobi, September 20, 1985 3:37:35 pm PDT
--Procedures with vanilla stuff around instances
DIRECTORY
CD,
CDBasics,
CDOrient,
CDInstances,
CDProperties;
CDInstancesImpl: CEDAR PROGRAM
IMPORTS CD, CDInstances, CDOrient, CDBasics, CDProperties
EXPORTS CDInstances =
BEGIN
--be carefull, InstanceList's are lists of pointers, distinguish between:
--procedures which modify the application list, from procedures which don't
--procedures which modify the instances pointed to, from procedures which don't
--procedures which modify an application list, from procedures which modify the instances
--procedures inspecting an application list
PointToI: PUBLIC PROC [pos: CD.Position, inst: CD.Instance] RETURNS [BOOL] =
--returns "pos points to the application inst", using its virtual coordinates
BEGIN
r: CD.Rect = CDBasics.RectAt[pos, [0, 0]];
IF ~CDBasics.InsidePos[pos, r] THEN RETURN [FALSE];
RETURN [HitInstance[inst, r]]
END;
HitInstance: PUBLIC PROC [inst: CD.Instance, hitRect: CD.Rect] RETURNS [BOOL] =
--returns "pos points to the application inst", using its virtual coordinates
BEGIN
RETURN [inst.ob.class.hitInside[
inst.ob,
CDOrient.DeMapRect[
itemInWorld: hitRect,
cellSize: inst.ob.size,
cellInstOrient: inst.orientation,
cellInstPos: inst.location
]
]]
END;
InstRectI: PUBLIC PROC [inst: CD.Instance] RETURNS [CD.Rect] =
BEGIN
RETURN [
CDOrient.MapRect[
itemInCell: CD.InterestRect[inst.ob],
cellSize: inst.ob.size,
cellInstOrient: inst.orientation,
cellInstPos: inst.location
]
]
END;
NewInstance: PUBLIC PROC [ob: CD.Object←NIL, location: CD.Position←[0,0], orientation: CD.Orientation𡤀,
selected: BOOLFALSE, properties: CD.PropList←NIL] RETURNS [CD.Instance] =
BEGIN
off: CD.Position = CDBasics.BaseOfRect[
CDOrient.MapRect[
itemInCell: CD.InterestRect[ob],
cellSize: ob.size,
cellInstOrient: orientation,
cellInstPos: [0, 0]
]];
a: CD.Instance = NEW[CD.InstanceRep ← CD.InstanceRep[
ob: ob,
location: CDBasics.SubPoints[location, off],
orientation: orientation,
selected: selected,
properties: properties
]];
RETURN [a]
END;
BoundingRectO: PUBLIC PROC[list: CD.InstanceList, selectedOnly: BOOLFALSE] RETURNS [CD.Rect] =
BEGIN
bound: CD.Rect ← CDBasics.empty;
FOR tem: LIST OF CD.Instance ← list, tem.rest WHILE tem#NIL DO
IF selectedOnly AND NOT tem.first.selected THEN LOOP;
bound ← CDBasics.Surround[bound, CDInstances.InstRectO[tem.first]]
ENDLOOP;
RETURN [bound]
END;
BoundingRectI: PUBLIC PROC[list: CD.InstanceList, selectedOnly: BOOLFALSE] RETURNS [CD.Rect] =
BEGIN
bound: CD.Rect ← CDBasics.empty;
FOR tem: LIST OF CD.Instance ← list, tem.rest WHILE tem#NIL DO
IF selectedOnly AND NOT tem.first.selected THEN LOOP;
bound ← CDBasics.Surround[bound, InstRectI[tem.first]]
ENDLOOP;
RETURN [bound]
END;
InstanceAt: PUBLIC PROC [il: CD.InstanceList, pos: CD.Position,
selectedOnly: BOOLFALSE] RETURNS [CD.Instance] =
--returns a reference to an application at location pos (or NIL if there is none)
BEGIN
FOR w: CD.InstanceList ← il, w.rest WHILE w#NIL DO
IF (~selectedOnly OR w.first.selected)
AND CDInstances.PointToO[pos, w.first]
AND PointToI[pos, w.first] THEN
RETURN [w.first]
ENDLOOP;
RETURN [NIL]
END;
--procedures which modify the instances referenced by a list
TransformList: PUBLIC PROC[il: CD.InstanceList,
cellRect: CD.Rect, transformation: CD.Orientation] =
BEGIN
FOR t: CD.InstanceList ← il, t.rest WHILE t#NIL DO
Transform[t.first, cellRect, transformation];
ENDLOOP
END;
TranslateList: PUBLIC PROC[il: CD.InstanceList, offset: CD.Position] =
BEGIN
FOR t: CD.InstanceList ← il, t.rest WHILE t#NIL DO
CDInstances.Translate[t.first, offset];
ENDLOOP;
END;
DeSelectList: PUBLIC PROC [list: CD.InstanceList] =
BEGIN
FOR w: CD.InstanceList ← list, w.rest WHILE w#NIL DO
w.first.selected ← FALSE
ENDLOOP;
END;
AppendToList: PUBLIC PROC [inst, to: CD.InstanceList] RETURNS [CD.InstanceList] =
--composes the lists "inst" and "to"
--the original list "to" is destroied and must be replaced by the retuned list
--the original list "inst" is not touched
BEGIN
FOR w: CD.InstanceList ← inst, w.rest WHILE w#NIL DO
to ← CONS[w.first, to];
ENDLOOP;
RETURN [to]
END;
--procedures which handle the application list but don't modify the instances
SplitPointed: PUBLIC PROC [from: CD.InstanceList, pos: CD.Position] RETURNS [pointed, others: CD.InstanceList] =
--copyes the pointed application references from "from" to "pointed"
--copyes the non-pointed application references from "from" to "others"
--does not make copies of the real instances
--finds maximal 1 pointed application
BEGIN
pApp: CD.Instance = InstanceAt[from, pos];
pointed ← NIL;
others ← NIL;
FOR w: CD.InstanceList ← from, w.rest WHILE w#NIL DO
IF w.first=pApp THEN pointed ← LIST[w.first]
ELSE others ← CONS[w.first, others]
ENDLOOP
END;
SplitSelected: PUBLIC PROC [from: CD.InstanceList] RETURNS [selected, others: CD.InstanceList] =
--copyes the selected application references from "from" to "selected"
--copyes the non-selected application references from "from" to "others"
--does not make copies of the real instances
BEGIN
selected←NIL;
others←NIL;
FOR w: CD.InstanceList ← from, w.rest WHILE w#NIL DO
IF w.first.selected THEN selected ← CONS[w.first, selected]
ELSE others ← CONS[w.first, others]
ENDLOOP
END;
OnlySelected: PUBLIC PROC[il: CD.InstanceList] RETURNS [selected: CD.InstanceList←NIL] =
-- returns new list but same instances
BEGIN
FOR l: CD.InstanceList ← il, l.rest WHILE l#NIL DO
IF l.first.selected THEN selected ← CONS[l.first, selected];
ENDLOOP;
END;
--procedures which create a new application list, with new instances
Transform: PUBLIC PROC [inst: CD.Instance, cellRect: CD.Rect, transformation: CD.Orientation] =
--performs "transformation" to "inst"; the transformation occurs to the rect "cellRect".
--"cellRect" and "inst" in the same coordinate system
--WARNING transformation group NOT abelsch
BEGIN
r: CD.Rect ← CDOrient.MapRect[
itemInCell: CDOrient.RectAt[
CDBasics.SubPoints[inst.location, CDBasics.BaseOfRect[cellRect]],
inst.ob.size,
inst.orientation],
cellSize: CDBasics.SizeOfRect[cellRect],
cellInstOrient: transformation,
cellInstPos: CDBasics.BaseOfRect[cellRect]];
inst.location ← CDBasics.BaseOfRect[r];
inst.orientation ← CDOrient.ComposeOrient[
itemOrientInCell: inst.orientation, cellOrientInWorld: transformation];
END;
CopyList: PUBLIC PROC[il: CD.InstanceList] RETURNS [CD.InstanceList] =
--creates a new list with new instances
BEGIN
newList: CD.InstanceList ← NIL;
FOR t: CD.InstanceList ← il, t.rest WHILE t#NIL DO
a: CD.Instance = NEW[CD.InstanceRep ← t.first^];
a.properties ← CDProperties.DangerousCopyProps[a.properties];
newList ← CONS[a, newList]
ENDLOOP;
RETURN [newList]
END;
ComposedCopy: PUBLIC PROC[il: CD.InstanceList,
cellPos, cellSize: CD.Position, cellOrient: CD.Orientation] RETURNS [CD.InstanceList] =
--makes a copy of "il" with world coordinates assumed that "il" has cell coordinates
--cellSize in cell coordinates, cellPos in world cordinates
--the new list points to new instances
BEGIN
r: CD.Rect;
newList: CD.InstanceList ← NIL;
FOR t: CD.InstanceList ← il, t.rest WHILE t#NIL DO
a: CD.Instance ← NEW[CD.InstanceRep ← t.first^];
r ← CDOrient.MapRect[
itemInCell: CDOrient.RectAt[a.location, a.ob.size, a.orientation],
cellSize: cellSize,
cellInstOrient: cellOrient,
cellInstPos: cellPos];
a.location ← CDBasics.BaseOfRect[r];
a.orientation ← CDOrient.ComposeOrient[
itemOrientInCell: a.orientation, cellOrientInWorld: cellOrient];
a.properties ← CDProperties.DangerousCopyProps[t.first.properties];
newList ← CONS[a, newList]
ENDLOOP;
RETURN [newList]
END;
DeComposedCopy: PUBLIC PROC[il: CD.InstanceList,
cellPos, cellSize: CD.Position, cellOrient: CD.Orientation] RETURNS [CD.InstanceList] =
--makes a copy of "il" with cell coordinates assumed il has world coordinates
--cellSize in cell coordinates
--cellPos, cellOrient in world coordinates
--the new list points to new instances
BEGIN
r: CD.Rect;
newList: CD.InstanceList ← NIL;
FOR t: CD.InstanceList ← il, t.rest WHILE t#NIL DO
a: CD.Instance ← NEW[CD.InstanceRep← t.first^];
r ← CDOrient.DeMapRect[
itemInWorld: CDOrient.RectAt[a.location, a.ob.size, a.orientation],
cellSize: cellSize,
cellInstOrient: cellOrient,
cellInstPos: cellPos];
a.location ← CDBasics.BaseOfRect[r];
a.orientation ← CDOrient.DecomposeOrient[
itemOrientInWorld: a.orientation,
cellOrientInWorld: cellOrient];
a.properties ← CDProperties.DangerousCopyProps[t.first.properties];
newList ← CONS[a, newList]
ENDLOOP;
RETURN [newList]
END;
END.