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.