CDInstancesImpl.mesa (part of ChipNDale)
Copyright © 1983, 1986 by Xerox Corporation. All rights reserved.
by Christian Jacobi, May 12, 1983 12:22 pm
last edited by Christian Jacobi, March 14, 1986 2:08:42 pm PST
--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;
NewInst: PUBLIC PROC [ob: CD.Object, location: CD.Position, orientation: CD.Orientation, selected: BOOL, properties: CD.PropList] RETURNS [inst: CD.Instance] =
BEGIN
inst ← NEW[CD.InstanceRep ← CD.InstanceRep[ob: ob, location: location, orientation: orientation, selected: selected, properties: properties]];
END;
Copy: PUBLIC PROC [inst: CD.Instance] RETURNS [CD.Instance] =
BEGIN
RETURN [ NEW[CD.InstanceRep ← CD.InstanceRep[ob: inst.ob, location: inst.location, orientation: inst.orientation, selected: inst.selected, properties: CDProperties.DCopyProps[inst.properties]]] ];
END;
NewInstI: PUBLIC PROC [ob: CD.Object, location: CD.Position, orientation: CD.Orientation, selected: BOOL, properties: CD.PropList] RETURNS [inst: CD.Instance] =
BEGIN
off: CD.Position = CDBasics.BaseOfRect[
CDOrient.MapRect[
itemInCell: CD.InterestRect[ob],
cellSize: ob.size,
cellInstOrient: orientation,
cellInstPos: [0, 0]
]];
inst ← NewInst[ob, CDBasics.SubPoints[location, off], orientation, selected, properties];
END;
BoundingRectO: PUBLIC PROC[list: CD.InstanceList, selectedOnly: BOOL] RETURNS [bound: CD.Rect ← CDBasics.empty] =
BEGIN
FOR l: LIST OF CD.Instance ← list, l.rest WHILE l#NIL DO
IF selectedOnly AND NOT l.first.selected THEN LOOP;
bound ← CDBasics.Surround[bound, CDInstances.InstRectO[l.first]]
ENDLOOP;
END;
BoundingRectI: PUBLIC PROC[list: CD.InstanceList, selectedOnly: BOOL] RETURNS [bound: CD.Rect ← CDBasics.empty] =
BEGIN
FOR l: LIST OF CD.Instance ← list, l.rest WHILE l#NIL DO
IF selectedOnly AND NOT l.first.selected THEN LOOP;
bound ← CDBasics.Surround[bound, InstRectI[l.first]]
ENDLOOP;
END;
InstanceAt: PUBLIC PROC [il: CD.InstanceList, pos: CD.Position, selectedOnly: BOOL] RETURNS [CD.Instance] =
--returns a reference to an application at location pos (or NIL if there is none)
BEGIN
FOR l: CD.InstanceList ← il, l.rest WHILE l#NIL DO
IF (~selectedOnly OR l.first.selected)
AND CDInstances.PointToO[pos, l.first]
AND PointToI[pos, l.first] THEN
RETURN [l.first]
ENDLOOP;
RETURN [NIL]
END;
--procedures which modify the instances referenced by a list
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
SplitSelected: PUBLIC PROC [il: CD.InstanceList] RETURNS [selected, others: CD.InstanceList ← NIL] =
BEGIN
FOR w: CD.InstanceList ← il, 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
CopyList: PUBLIC PROC[il: CD.InstanceList] RETURNS [nl: CD.InstanceList←NIL] =
--creates a new list with new instances
BEGIN
FOR l: CD.InstanceList ← il, l.rest WHILE l#NIL DO
nl ← CONS[Copy[l.first], nl];
ENDLOOP;
END;
Composed: PUBLIC PROC[inst: CD.Instance, cellPos, cellSize: CD.Position, cellOrient: CD.Orientation] RETURNS [c: CD.Instance] =
BEGIN
c ← Copy[inst];
c.location ← CDBasics.BaseOfRect[CDOrient.MapRect[
itemInCell: CDOrient.RectAt[inst.location, inst.ob.size, inst.orientation],
cellSize: cellSize,
cellInstOrient: cellOrient,
cellInstPos: cellPos
]];
c.orientation ← CDOrient.ComposeOrient[itemOrientInCell: inst.orientation, cellOrientInWorld: cellOrient];
END;
DeComposed: PUBLIC PROC[inst: CD.Instance, cellPos, cellSize: CD.Position, cellOrient: CD.Orientation] RETURNS [dc: CD.Instance] =
BEGIN
dc ← Copy[inst];
dc.location ← CDBasics.BaseOfRect[CDOrient.DeMapRect[
itemInWorld: CDOrient.RectAt[inst.location, inst.ob.size, inst.orientation],
cellSize: cellSize,
cellInstOrient: cellOrient,
cellInstPos: cellPos
]];
dc.orientation ← CDOrient.DecomposeOrient[itemOrientInWorld: inst.orientation, cellOrientInWorld: cellOrient];
END;
ComposedList: PUBLIC PROC[il: CD.InstanceList, cellPos, cellSize: CD.Position, cellOrient: CD.Orientation] RETURNS [cl: CD.InstanceList ← NIL] =
BEGIN
FOR l: CD.InstanceList ← il, l.rest WHILE l#NIL DO
cl ← CONS[Composed[l.first, cellPos, cellSize, cellOrient], cl];
ENDLOOP;
END;
DeComposedList: PUBLIC PROC[il: CD.InstanceList, cellPos, cellSize: CD.Position, cellOrient: CD.Orientation] RETURNS [dcl: CD.InstanceList ← NIL] =
BEGIN
FOR l: CD.InstanceList ← il, l.rest WHILE l#NIL DO
dcl ← CONS[DeComposed[l.first, cellPos, cellSize, cellOrient], dcl];
ENDLOOP;
END;
END.