<> <> <> 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_amount ELSE offset.y_amount; 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.