<> <> <> <<--Procedures with vanilla stuff around applications>> DIRECTORY CD, CDInline, CDOrient, CDApplications, CDProperties; CDApplicationsImpl: CEDAR PROGRAM IMPORTS CDApplications, CDOrient, CDInline, CDProperties EXPORTS CDApplications = BEGIN <<--be carefull, ApplicationList's are lists of pointers, distinguish between:>> <<--procedures which modify the application list, from procedures which don't>> <<--procedures which modify the applications pointed to, from procedures which don't>> <<--procedures which modify an application list, from procedures which modify the applications>> <<--procedures inspecting an application list>> AplicationAt: PUBLIC PROC [al: CD.ApplicationList, pos: CD.DesignPosition, selectedOnly: BOOL_FALSE] RETURNS [CD.ApplicationPtr] = <<--returns a reference to an application at location pos (or NIL if there is none)>> BEGIN FOR w: CD.ApplicationList _ al, w.rest WHILE w#NIL DO IF (~selectedOnly OR w.first.selected) AND CDApplications.PointToO[pos, w.first] AND CDApplications.PointToI[pos, w.first] THEN RETURN [w.first] ENDLOOP; RETURN [NIL] END; BoundingRect: PUBLIC PROC[list: CD.ApplicationList, selectedOnly: BOOLEAN_FALSE] RETURNS [CD.DesignRect] = BEGIN bound: CD.DesignRect_CDInline.empty; FOR tem: LIST OF CD.ApplicationPtr _ list, tem.rest WHILE tem#NIL DO IF selectedOnly AND NOT tem.first.selected THEN LOOP; bound _ CDInline.Surround[bound, CDApplications.ARectO[tem.first]] ENDLOOP; RETURN [bound] END; <<--procedures which modify the applications referenced by a list>> TransformList: PUBLIC PROC[al: CD.ApplicationList, cellRect: CD.DesignRect, transformation: CD.Orientation] = BEGIN FOR t: CD.ApplicationList _ al, t.rest WHILE t#NIL DO Transform[t.first, cellRect, transformation]; ENDLOOP END; TranslateList: PUBLIC PROC[al: CD.ApplicationList, offset: CD.DesignPosition] = BEGIN FOR t: CD.ApplicationList _ al, t.rest WHILE t#NIL DO CDApplications.Translate[t.first, offset]; ENDLOOP; END; DeSelectList: PUBLIC PROC [list: CD.ApplicationList] = BEGIN FOR w: CD.ApplicationList _ list, w.rest WHILE w#NIL DO w.first.selected _ FALSE ENDLOOP; END; AppendToList: PUBLIC PROC [app, to: CD.ApplicationList] RETURNS [CD.ApplicationList] = <<--composes the lists "app" and "to">> <<--the original list "to" is destroied and must be replaced by the retuned list>> <<--the original list "app" is not touched >> BEGIN FOR w: CD.ApplicationList _ app, 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 applications>> SplitPointed: PUBLIC PROC [from: CD.ApplicationList, pos: CD.DesignPosition] RETURNS [pointed, others: CD.ApplicationList] = <<--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 applications>> <<--finds maximal 1 pointed application>> BEGIN pApp: CD.ApplicationPtr = AplicationAt[from, pos]; pointed _ NIL; others _ NIL; FOR w: CD.ApplicationList _ 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.ApplicationList] RETURNS [selected, others: CD.ApplicationList] = <<--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 applications>> BEGIN selected_NIL; others_NIL; FOR w: CD.ApplicationList _ 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[al: CD.ApplicationList] RETURNS [selected: CD.ApplicationList_NIL] = <<-- returns new list but same applications>> BEGIN FOR l: CD.ApplicationList _ al, 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 applications>> Transform: PUBLIC PROC [aptr: CD.ApplicationPtr, cellRect: CD.DesignRect, transformation: CD.Orientation] = <<--performs "transformation" to "aptr"; the transformation occurs to the rect "cellRect".>> <<--"cellRect" and "aptr" in the same coordinate system>> <<--WARNING transformation group NOT abelsch>> BEGIN r: CD.DesignRect _ CDOrient.MapRect[ itemInCell: CDOrient.RectAt[ CDInline.SubPoints[aptr.location, CDInline.BaseOfRect[cellRect]], aptr.ob.size, aptr.orientation], cellSize: CDInline.SizeOfRect[cellRect], cellInstOrient: transformation, cellInstPos: CDInline.BaseOfRect[cellRect]]; aptr.location _ CDInline.BaseOfRect[r]; aptr.orientation _ CDOrient.ComposeOrient[ itemOrientInCell: aptr.orientation, cellOrientInWorld: transformation]; END; <<--XXXXX CopyList+ComposedCopy+DeComposedCopy: copy properties and selection ??>> CopyList: PUBLIC PROC[al: CD.ApplicationList] RETURNS [CD.ApplicationList] = <<--creates a new list with new applications>> BEGIN newList: CD.ApplicationList _ NIL; FOR t: CD.ApplicationList _ al, t.rest WHILE t#NIL DO a: CD.ApplicationPtr _ NEW[CD.Application _ t.first^]; a.properties _ NIL; newList _ CONS[a, newList] ENDLOOP; RETURN [newList] END; ComposedCopy: PUBLIC PROC[al: CD.ApplicationList, cellPos, cellSize: CD.DesignPosition, cellOrient: CD.Orientation] RETURNS [CD.ApplicationList] = <<--makes a copy of "al" with world coordinates assumed that "al" has cell coordinates>> <<--cellSize in cell coordinates, cellPos in world cordinates>> <<--the new list points to new applications>> BEGIN r: CD.DesignRect; newList: CD.ApplicationList _ NIL; FOR t: CD.ApplicationList _ al, t.rest WHILE t#NIL DO a: CD.ApplicationPtr _ NEW[CD.Application _ t.first^]; r _ CDOrient.MapRect[ itemInCell: CDOrient.RectAt[a.location, a.ob.size, a.orientation], cellSize: cellSize, cellInstOrient: cellOrient, cellInstPos: cellPos]; a.location _ CDInline.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[al: CD.ApplicationList, cellPos, cellSize: CD.DesignPosition, cellOrient: CD.Orientation] RETURNS [CD.ApplicationList] = <<--makes a copy of "al" with cell coordinates assumed al has world coordinates>> <<--cellSize in cell coordinates>> <<--cellPos, cellOrient in world coordinates>> <<--the new list points to new applications>> BEGIN r: CD.DesignRect; newList: CD.ApplicationList _ NIL; FOR t: CD.ApplicationList _ al, t.rest WHILE t#NIL DO a: CD.ApplicationPtr _ NEW[CD.Application_ t.first^]; r _ CDOrient.DeMapRect[ itemInWorld: CDOrient.RectAt[a.location, a.ob.size, a.orientation], cellSize: cellSize, cellInstOrient: cellOrient, cellInstPos: cellPos]; a.location _ CDInline.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; NewApplicationI: PUBLIC PROC [ob: CD.ObPtr_NIL, location: CD.DesignPosition_[0,0], orientation: CD.Orientation_0, selected: BOOLEAN _ FALSE, properties: CD.Properties_NIL] RETURNS [CD.ApplicationPtr] = <<--creates a new application, does neither draw nor include it into any world>> <<--modifies location such that ob...insideRect is at original location>> BEGIN inr: CD.DesignRect _ ob.p.insideRect[ob]; off: CD.DesignPosition _ CDOrient.MapPosition[ itemInCell: inr, cellSize: ob.size, cellInstOrient: orientation, cellInstPos: [0, 0] ]; a: CD.ApplicationPtr _ NEW[CD.Application _ CD.Application[ ob: ob, location: CDInline.SubPoints[location, off], orientation: orientation, selected: selected, properties: properties ]]; RETURN [a] END; END.