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, June 11, 1985 10:10:25 am 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: BOOL ← FALSE, properties: CD.Properties←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:
BOOL←
FALSE]
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:
BOOL←
FALSE]
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: BOOL←FALSE] 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.CopyProps[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.CopyProps[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.CopyProps[t.first.properties];
newList ← CONS[a, newList]
ENDLOOP;
RETURN [newList]
END;
END.