CDApplicationsImpl.mesa (part of Chipndale)
Copyright © 1983, 1984 by Xerox Corporation. All rights reserved.
by Christian Jacobi May 12, 1983 12:22 pm
last edited by Christian Jacobi November 5, 1984 10:17:43 am PST
--Procedures with vanilla stuff around applications
DIRECTORY
CD,
CDBasics,
CDOrient,
CDApplications,
CDProperties;
CDApplicationsImpl: CEDAR PROGRAM
IMPORTS CDApplications, CDOrient, CDBasics, 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: BOOLFALSE] 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: BOOLEANFALSE] RETURNS [CD.DesignRect] =
BEGIN
bound: CD.DesignRect�sics.empty;
FOR tem: LIST OF CD.ApplicationPtr ← list, tem.rest WHILE tem#NIL DO
IF selectedOnly AND NOT tem.first.selected THEN LOOP;
bound ← CDBasics.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[
CDBasics.SubPoints[aptr.location, CDBasics.BaseOfRect[cellRect]],
aptr.ob.size,
aptr.orientation],
cellSize: CDBasics.SizeOfRect[cellRect],
cellInstOrient: transformation,
cellInstPos: CDBasics.BaseOfRect[cellRect]];
aptr.location ← CDBasics.BaseOfRect[r];
aptr.orientation ← CDOrient.ComposeOrient[
itemOrientInCell: aptr.orientation, cellOrientInWorld: transformation];
END;
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 ← CDProperties.CopyProps[a.properties];
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 ← CDBasics.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 ← CDBasics.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𡤀,
selected: BOOLEANFALSE, 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: CDBasics.SubPoints[location, off],
orientation: orientation,
selected: selected,
properties: properties
]];
RETURN [a]
END;
END.