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: 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.DesignRectsics.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: 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: CDBasics.SubPoints[location, off],
orientation: orientation,
selected: selected,
properties: properties
]];
RETURN [a]
END;
END.