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 [
BOOL ←
FALSE] = {
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.