<> <> <> <> <<--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.