CDStretchCommands.mesa (part of Chipndale)
by Christian Jacobi July 11, 1983 3:42 pm
last edited Christian Jacobi February 14, 1984 4:05 pm
DIRECTORY
CD,
CDApplications,
CDSequencer,
CDCallSpecific,
CDInline,
CDObjectProcs,
CDOps,
CDOrient,
TerminalIO;
CDStretchCommands:
CEDAR
PROGRAM
IMPORTS CDApplications, CDInline, CDObjectProcs, CDOps, CDOrient, CDSequencer, TerminalIO =
BEGIN
StretchApplication:
PROC [design:
CD.Design, aptr:
CD.ApplicationPtr, orientInPlane:
CD.Orientation, amount:
CD.DesignNumber]
RETURNS [include:
CD.ApplicationList←
NIL, removeMe:
BOOL←
FALSE] =
-- orientInPlane:
-- at position "original" the bottom edge [(0, 0), (1, 0)] is streched
-- mirroring is ignored
-- amount>0 ==> grow in direction orientInPlane
-- amount<0 ==> shrink on edge orientInPlane
BEGIN
CallSpecific:
PROC [design:
CD.Design, aptr:
CD.ApplicationPtr, x:
REF, objectSpecific:
REF]
RETURNS [done:
BOOL←
FALSE, removeMe:
BOOL←
FALSE, include:
CD.ApplicationList←
NIL,
repaintMe: BOOL←FALSE, repaintInclude: BOOL←FALSE] =
BEGIN
IF objectSpecific#
NIL
THEN
BEGIN
p: REF = CDObjectProcs.FetchFurther [aptr.ob.p, objectSpecific];
IF p#
NIL
AND
ISTYPE[p,
REF CDCallSpecific.CallProc]
THEN
BEGIN
[done: done,
removeMe: removeMe,
include: include,
repaintMe: repaintMe,
repaintInclude: repaintInclude] ← NARROW[p, REF CDCallSpecific.CallProc]^[design, aptr, x]
END;
END;
END;
appOrient, orientInObject: CD.Orientation;
done, repaintMe, repaintInclude: BOOL;
offset: REF CD.DesignPosition ← NEW[CD.DesignPosition←[0, 0]];
--ignore mirroring and 45 degrees
orientInPlane ← CDOrient.ConcentrateOnRotate90[orientInPlane];
appOrient ← CDOrient.ConcentrateOnRotate90[aptr.orientation];
orientInObject ← CDOrient.DecomposeOrient[
itemOrientInWorld: orientInPlane,
cellOrientInWorld: appOrient
];
IF CDOrient.IncludesOddRot90[orientInObject] THEN offset.x𡤊mount ELSE offset.y𡤊mount;
CDOps.DelayedRedraw[design, CDApplications.ApplicationRect[aptr]];
[done, removeMe, include, repaintMe, repaintInclude] ← CallSpecific[design, aptr, offset , $Lengthen];
IF done
THEN {
SELECT CDOrient.ConcentrateOnRotate90[orientInPlane]
FROM
CDOrient.original => {
aptr.location.y ← aptr.location.y-amount;
IF include#NIL THEN MoveAppList[include, [0, -amount]]
};
CDOrient.rotate90 => NULL;
CDOrient.rotate180 => NULL;
CDOrient.rotate270 => {
aptr.location.x ← aptr.location.x-amount;
IF include#NIL THEN MoveAppList[include, [-amount, 0]]
};
ENDCASE => ERROR;
CDOps.DelayedRedraw[design, CDApplications.ApplicationRect[aptr]];
};
END;
DoAStretch:
PROC [design:
CD.Design, from, to:
CD.DesignPosition, pointed:
BOOL←
FALSE] =
-- ~pointed: stretch selected
-- pointed: stretch pointed
BEGIN
r: CD.DesignRect;
pointedAp: CD.ApplicationPtr;
orientInPlane: CD.Orientation;
amount: CD.DesignNumber;
include: CD.ApplicationList;
removeMe: BOOL;
removeList, includeList: CD.ApplicationList←NIL;
count: NAT ← 0;
IF from=to
THEN {
TerminalIO.WriteRope[" null stretch\n"];
RETURN
};
pointedAp ← CDOps.PointedApplication[design, from];
IF pointedAp=
NIL
THEN {
TerminalIO.WriteRope[" no object pointed\n"];
RETURN
};
r ← CDApplications.ApplicationRect[pointedAp];
IF
ABS[to.x-from.x]>
ABS[to.y-from.y]
THEN {
--horizontal
IF
ABS[r.x1-from.x] <
ABS[r.x2-from.x]
THEN {
--left--
amount ← from.x-to.x;
orientInPlane ← CDOrient.rotate270
}
ELSE {
--right--
amount ← to.x-from.x;
orientInPlane ← CDOrient.rotate90
}
}
ELSE {
--vertical
IF
ABS[r.y1-from.y] <
ABS[r.y2-from.y]
THEN {
--near to origin--
amount ← from.y-to.y;
orientInPlane ← CDOrient.original
}
ELSE {
--far from origin--
amount ← to.y-from.y;
orientInPlane ← CDOrient.rotate180
}
};
IF pointed
THEN {
-- use pointed
count ← 1;
[includeList, removeMe] ← StretchApplication[design, pointedAp, orientInPlane, amount];
IF removeMe THEN removeList ← LIST[pointedAp];
}
ELSE {
-- use selected
FOR list:
CD.ApplicationList ← CDOps.AppList[design], list.rest
WHILE list#
NIL
DO
IF list.first.selected
THEN {
count ← count+1;
[include, removeMe] ← StretchApplication[design, list.first, orientInPlane, amount];
IF removeMe THEN removeList ← CONS[list.first, removeList];
IF include#NIL THEN includeList ← CDApplications.AppendToList[include, includeList];
}
ENDLOOP;
};
RemoveAppList[design, removeList];
CDOps.IncludeApplicationList[design, includeList];
TerminalIO.WriteInt[count];
TerminalIO.WriteRope[" objects tried to stretch\n"];
END;
RemoveAppList:
PROC [design:
CD.Design, appList:
CD.ApplicationList, draw:
BOOL←
TRUE] =
BEGIN
FOR list:
CD.ApplicationList ← appList, list.rest
WHILE list#
NIL
DO
CDOps.RemoveApplication[design, list.first, draw];
ENDLOOP;
END;
MoveAppList:
PROC [appList:
CD.ApplicationList, offset:
CD.DesignPosition] =
BEGIN
FOR list:
CD.ApplicationList ← appList, list.rest
WHILE list#
NIL
DO
list.first.location ← CDInline.AddPoints[list.first.location, offset];
ENDLOOP;
END;
StretchCommandP:
PROC [comm: CDSequencer.Command] =
BEGIN
TerminalIO.WriteRope["Stretch pointed"];
DoAStretch[design: comm.design, from: comm.sPos, to: comm.pos, pointed: TRUE]
END;
StretchCommandS:
PROC [comm: CDSequencer.Command] =
BEGIN
TerminalIO.WriteRope["Stretch selected"];
DoAStretch[design: comm.design, from: comm.sPos, to: comm.pos, pointed: FALSE]
END;
CDSequencer.ImplementCommand[$StretchPS, StretchCommandS];
CDSequencer.ImplementCommand[$StretchP, StretchCommandP];
CDSequencer.ImplementCommand[$StretchS, StretchCommandS];
END.