CDInstancesImpl.mesa (part of ChipNDale)
Copyright © 1983, 1986 by Xerox Corporation. All rights reserved.
Created by Christian Jacobi, May 12, 1983 12:22 pm
Last edited by: Christian Jacobi, October 30, 1986 10:31:28 am PST
--Procedures with vanilla stuff around instances
DIRECTORY
CD,
CDBasics,
CDInstances,
CDProperties;
CDInstancesImpl: CEDAR PROGRAM
IMPORTS CD, CDInstances, 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
PointToO: PUBLIC PROC [pos: CD.Position, inst: CD.Instance] RETURNS [BOOL] = {
--returns "pos points to inst"
RETURN [CDBasics.InsidePos[pos, CDInstances.InstRectO[inst]]];
};
PointToI: PUBLIC PROC [pos: CD.Position, inst: CD.Instance] RETURNS [BOOL] = {
--returns "pos points to inst", using internal knowledge
IF ~PointToO[pos, inst] THEN RETURN [FALSE];
RETURN [HitInstance[inst, [x1: pos.x, y1: pos.y, x2: pos.x, y2: pos.y]]]
};
HitInstance: PUBLIC PROC [inst: CD.Instance, hitRect: CD.Rect] RETURNS [BOOL] = {
--returns "pos points to inst", using its virtual coordinates
RETURN [inst.ob.class.hitInside[inst.ob, CDBasics.DeMapRect[hitRect, inst.trans]]]
};
InstRectO: PUBLIC PROC [inst: CD.Instance] RETURNS [CD.Rect] = {
RETURN [CDBasics.MapRect[inst.ob.bbox, inst.trans]]
};
InstRectI: PUBLIC PROC [inst: CD.Instance] RETURNS [CD.Rect] = {
RETURN [CDBasics.MapRect[CD.InterestRect[inst.ob], inst.trans]]
};
NewInst: PUBLIC PROC [ob: CD.Object, trans: CD.Transformation, properties: CD.PropList, selected: BOOL] RETURNS [inst: CD.Instance] = {
inst ← NEW[CD.InstanceRep ← CD.InstanceRep[ob: ob, trans: trans, selected: selected, properties: properties]];
};
Copy: PUBLIC PROC [inst: CD.Instance] RETURNS [CD.Instance] = {
RETURN [ NEW[CD.InstanceRep ← CD.InstanceRep[ob: inst.ob, trans: inst.trans, selected: inst.selected, properties: CDProperties.DCopyProps[inst.properties]]] ];
};
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 instance 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
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
FOR l: CD.InstanceList ← il, l.rest WHILE l#NIL DO
nl ← CONS[Copy[l.first], nl];
ENDLOOP;
};
Composed: PUBLIC PROC[inst: CD.Instance, trans: CD.Transformation] RETURNS [c: CD.Instance] = {
c ← Copy[inst];
c.trans.off ← CDBasics.MapPoint[inst.trans.off, trans];
c.trans.orient ← CDBasics.ComposeOrient[itemInCell: inst.trans.orient, cellInWorld: trans.orient];
};
DeComposed: PUBLIC PROC[inst: CD.Instance, trans: CD.Transformation] RETURNS [dc: CD.Instance] = {
dc ← Copy[inst];
dc.trans.off ← CDBasics.DeMapPoint[inst.trans.off, trans];
dc.trans.orient ← CDBasics.DecomposeOrient[itemInWorld: inst.trans.orient, cellInWorld: trans.orient];
};
ComposedList: PUBLIC PROC[il: CD.InstanceList, trans: CD.Transformation] RETURNS [cl: CD.InstanceList ← NIL] = {
FOR l: CD.InstanceList ← il, l.rest WHILE l#NIL DO
cl ← CONS[Composed[l.first, trans], cl];
ENDLOOP;
};
DeComposedList: PUBLIC PROC[il: CD.InstanceList, trans: CD.Transformation] RETURNS [dcl: CD.InstanceList ← NIL] = {
FOR l: CD.InstanceList ← il, l.rest WHILE l#NIL DO
dcl ← CONS[DeComposed[l.first, trans], dcl];
ENDLOOP;
};
Member: PUBLIC PROC [inst: CD.Instance, il: CD.InstanceList] RETURNS [BOOLFALSE] = {
WHILE il#NIL DO
IF il.first=inst THEN RETURN[TRUE]; il ← il.rest;
ENDLOOP;
};
Length: PUBLIC PROC [il: CD.InstanceList] RETURNS [leng: INT𡤀] = {
FOR list: CD.InstanceList ← il, list.rest WHILE list#NIL DO
leng ← leng+1;
ENDLOOP;
};
END.