<> <> <> <> <<--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_0] = { FOR list: CD.InstanceList _ il, list.rest WHILE list#NIL DO leng _ leng+1; ENDLOOP; }; END.