DIRECTORY CD, CDApplications, CDBasics, CDCallSpecific, CDSequencer, CDObjectProcs, CDOps, CDOrient, CDValue, TerminalIO; CDStretchCommands: CEDAR PROGRAM IMPORTS CDApplications, CDBasics, CDObjectProcs, CDOps, CDOrient, CDSequencer, CDValue, TerminalIO = BEGIN StretchApplication: PROC [design: CD.Design, aptr: CD.ApplicationPtr, orientInPlane: CD.Orientation, amount: CD.DesignNumber] RETURNS [include: CD.ApplicationList_NIL, removeMe: BOOL_FALSE] = 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]]; 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.ARectO[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 CDApplications.TranslateList[include, [0, -amount]] }; CDOrient.rotate90 => NULL; CDOrient.rotate180 => NULL; CDOrient.rotate270 => { aptr.location.x _ aptr.location.x-amount; IF include#NIL THEN CDApplications.TranslateList[include, [-amount, 0]] }; ENDCASE => ERROR; CDOps.DelayedRedraw[design, CDApplications.ARectO[aptr]]; }; END; SelectBorder: PROC [r: CD.DesignRect, pos: CD.DesignPosition] RETURNS [orient: CD.Orientation] = BEGIN dx1, dx2, dy1, dy2: CD.DesignNumber; r _ CDBasics.Extend[r, 200]; dx1 _ ABS[r.x1-pos.x]; dx2 _ ABS[r.x2-pos.x]; dy1 _ ABS[r.y1-pos.y]; dy2 _ ABS[r.y2-pos.y]; IF (pos.x IN [r.x1..r.x2]) OR pos.y IN [r.y1..r.y2] THEN { IF dx1<=dx2 THEN --left IF dy1<=dy2 THEN --down IF dx1<=dy1 THEN orient _ CDOrient.rotate270 ELSE orient _ CDOrient.original ELSE --top IF dx1<=dy2 THEN orient _ CDOrient.rotate270 ELSE orient _ CDOrient.rotate180 ELSE --right IF dy1<=dy2 THEN --down IF dx2<=dy1 THEN orient _ CDOrient.rotate90 ELSE orient _ CDOrient.original ELSE --top IF dx2<=dy2 THEN orient _ CDOrient.rotate90 ELSE orient _ CDOrient.rotate180 } ELSE --outside enough-- { orient _ CDOrient.original } END; DetermineDirection: PROC [sampleApp: CD.ApplicationPtr, from, to: CD.DesignPosition] RETURNS [amount: CD.DesignNumber, orientInPlane: CD.Orientation] = BEGIN r: CD.DesignRect = CDApplications.ARectI[sampleApp]; IF ABS[to.x-from.x]>ABS[to.y-from.y] THEN { --horizontal stretch vector IF ABS[r.x1-from.x] < ABS[r.x2-from.x] THEN {--left edge-- amount _ from.x-to.x; orientInPlane _ CDOrient.rotate270 } ELSE { --right edge-- amount _ to.x-from.x; orientInPlane _ CDOrient.rotate90 } } ELSE { --vertical stretch vector IF ABS[r.y1-from.y] < ABS[r.y2-from.y] THEN {--near to origin (bottom) edge-- amount _ from.y-to.y; orientInPlane _ CDOrient.original } ELSE { --far from origin (top) edge-- amount _ to.y-from.y; orientInPlane _ CDOrient.rotate180 } }; END; FixDirection: PROC [r: CD.DesignRect, pos: CD.DesignPosition, dir: CD.Orientation, dirAmount: CD.DesignNumber] RETURNS [amount: CD.DesignNumber, orientInPlane: CD.Orientation] = BEGIN Fiddle: PROC [] = { amount _ -amount; orientInPlane _ CDOrient.ComposeOrient[orientInPlane, CDOrient.rotate180]; }; mouseRight: BOOL = ABS[r.x1-pos.x] > ABS[r.x2-pos.x]; mouseUp: BOOL = ABS[r.y1-pos.y] > ABS[r.y2-pos.y]; amount _ dirAmount; orientInPlane _ dir; SELECT dir FROM CDOrient.rotate270 --left-- => IF mouseRight THEN Fiddle[]; CDOrient.rotate90 --right-- => IF ~mouseRight THEN Fiddle[]; CDOrient.original --down-- =>IF mouseUp THEN Fiddle[]; CDOrient.rotate180 --up-- => IF ~mouseUp THEN Fiddle[]; ENDCASE => ERROR; END; DoAStretch: PROC [design: CD.Design, from, to: CD.DesignPosition, pointed: BOOL_FALSE, growAsToX: BOOL_FALSE, edgeInOrient: BOOL_FALSE, orient: CD.Orientation_CD.original] = BEGIN pointedAp: CD.ApplicationPtr; orientInPlane: CD.Orientation; amount: CD.DesignNumber; include: CD.ApplicationList; removeMe: BOOL; removeList, includeList: CD.ApplicationList_NIL; count: NAT _ 0; IF growAsToX AND edgeInOrient THEN ERROR; IF ~growAsToX AND ~edgeInOrient AND from=to THEN { TerminalIO.WriteRope[" null stretch\n"]; RETURN }; pointedAp _ CDApplications.AplicationAt[al: CDOps.AppList[design], pos: from, selectedOnly: ~pointed]; IF pointedAp=NIL THEN { IF pointed THEN TerminalIO.WriteRope[" no object pointed\n"] ELSE TerminalIO.WriteRope[" no selected object pointed\n"]; RETURN }; IF growAsToX THEN { amount_to.x; orientInPlane _ SelectBorder[CDApplications.ARectI[pointedAp], from] } ELSE IF edgeInOrient THEN [amount, orientInPlane] _ FixDirection[CDApplications.ARectI[pointedAp], from, orient, to.x] ELSE [amount, orientInPlane] _ DetermineDirection[pointedAp, from, to]; 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; 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; StepValue: PROC[design: CD.Design] RETURNS [CD.DesignNumber] = BEGIN RETURN [CD.lambda*MAX[CDValue.FetchInt[boundTo: design, key: $CDxStepValue, propagation: global], 1]] END; GrowStepSCommand: PROC [comm: CDSequencer.Command] = BEGIN TerminalIO.WriteRope["grow selected"]; DoAStretch[design: comm.design, from: comm.pos, to: [StepValue[comm.design], 0], pointed: FALSE, growAsToX: TRUE ] END; GrowStepPCommand: PROC [comm: CDSequencer.Command] = BEGIN TerminalIO.WriteRope["grow pointed"]; DoAStretch[design: comm.design, from: comm.pos, to: [StepValue[comm.design], 0], pointed: TRUE, growAsToX: TRUE ] END; ShrinkStepSCommand: PROC [comm: CDSequencer.Command] = BEGIN TerminalIO.WriteRope["shrink selected"]; DoAStretch[design: comm.design, from: comm.pos, to: [-StepValue[comm.design], 0], pointed: FALSE, growAsToX: TRUE ] END; ShrinkStepPCommand: PROC [comm: CDSequencer.Command] = BEGIN TerminalIO.WriteRope["shrink pointed"]; DoAStretch[design: comm.design, from: comm.pos, to: [-StepValue[comm.design], 0], pointed: TRUE, growAsToX: TRUE ] END; StretchStepLeftCommandS: PROC [comm: CDSequencer.Command] = BEGIN TerminalIO.WriteRope["Stretch step selected left"]; DoAStretch[design: comm.design, from: comm.sPos, to: [StepValue[comm.design], 0], pointed: FALSE, edgeInOrient: TRUE, orient: CDOrient.rotate270] END; StretchStepRightCommandS: PROC [comm: CDSequencer.Command] = BEGIN TerminalIO.WriteRope["Stretch step selected right"]; DoAStretch[design: comm.design, from: comm.sPos, to: [StepValue[comm.design], 0], pointed: FALSE, edgeInOrient: TRUE, orient: CDOrient.rotate90] END; StretchStepUpCommandS: PROC [comm: CDSequencer.Command] = BEGIN TerminalIO.WriteRope["Stretch step selected up"]; DoAStretch[design: comm.design, from: comm.sPos, to: [StepValue[comm.design], 0], pointed: FALSE, edgeInOrient: TRUE, orient: CDOrient.rotate180] END; StretchStepDownCommandS: PROC [comm: CDSequencer.Command] = BEGIN TerminalIO.WriteRope["Stretch step selected down"]; DoAStretch[design: comm.design, from: comm.sPos, to: [StepValue[comm.design], 0], pointed: FALSE, edgeInOrient: TRUE, orient: CDOrient.original] END; StretchStepLeftCommandP: PROC [comm: CDSequencer.Command] = BEGIN TerminalIO.WriteRope["Stretch step pointed left"]; DoAStretch[design: comm.design, from: comm.sPos, to: [StepValue[comm.design], 0], pointed: TRUE, edgeInOrient: TRUE, orient: CDOrient.rotate270] END; StretchStepRightCommandP: PROC [comm: CDSequencer.Command] = BEGIN TerminalIO.WriteRope["Stretch step pointed right"]; DoAStretch[design: comm.design, from: comm.sPos, to: [StepValue[comm.design], 0], pointed: TRUE, edgeInOrient: TRUE, orient: CDOrient.rotate90] END; StretchStepUpCommandP: PROC [comm: CDSequencer.Command] = BEGIN TerminalIO.WriteRope["Stretch step pointed up"]; DoAStretch[design: comm.design, from: comm.sPos, to: [StepValue[comm.design], 0], pointed: TRUE, edgeInOrient: TRUE, orient: CDOrient.rotate180] END; StretchStepDownCommandP: PROC [comm: CDSequencer.Command] = BEGIN TerminalIO.WriteRope["Stretch step pointed down"]; DoAStretch[design: comm.design, from: comm.sPos, to: [StepValue[comm.design], 0], pointed: TRUE, edgeInOrient: TRUE, orient: CDOrient.original] END; CDSequencer.ImplementCommand[$StretchP, StretchCommandP]; CDSequencer.ImplementCommand[$StretchS, StretchCommandS]; CDSequencer.ImplementCommand[$GrowStepS, GrowStepSCommand]; CDSequencer.ImplementCommand[$GrowStepP, GrowStepPCommand]; CDSequencer.ImplementCommand[$ShrinkStepS, ShrinkStepSCommand]; CDSequencer.ImplementCommand[$ShrinkStepP, ShrinkStepPCommand]; CDSequencer.ImplementCommand[$StretchStepLeftS, StretchStepLeftCommandS]; CDSequencer.ImplementCommand[$StretchStepRightS, StretchStepRightCommandS]; CDSequencer.ImplementCommand[$StretchStepUpS, StretchStepUpCommandS]; CDSequencer.ImplementCommand[$StretchStepDownS, StretchStepDownCommandS]; CDSequencer.ImplementCommand[$StretchStepLeftP, StretchStepLeftCommandP]; CDSequencer.ImplementCommand[$StretchStepRightP, StretchStepRightCommandP]; CDSequencer.ImplementCommand[$StretchStepUpP, StretchStepUpCommandP]; CDSequencer.ImplementCommand[$StretchStepDownP, StretchStepDownCommandP]; END. ¤CDStretchCommands.mesa (part of Chipndale) Copyright c 1984 by Xerox Corporation. All rights reserved. by Christian Jacobi July 11, 1983 3:42 pm last edited Christian Jacobi February 14, 1984 4:05 pm -- 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 --ignore mirroring and 45 degrees --given a sample application and a vector, determine in what absolute direction and how much --a stretch should be --must: sampleApp#NIL --must: sampleApp#NIL -- ~pointed: stretch selected -- pointed: stretch pointed Ê O˜šœ,™,Jšœ Ïmœ1™Jšœ!™!Jšœ>˜>Jšœ=˜=šœ*˜*Jšœ"˜"Jšœ˜Jšœ˜—Jšžœ+žœžœž˜WJšœ9˜9Jšœf˜fšžœžœ˜šžœ/ž˜9šœ˜Jšœ)˜)Jšžœ žœžœ4˜GJ˜—Jšœžœ˜Jšœžœ˜šœ˜Jšœ)˜)Jšžœ žœžœ4˜GJ˜—Jšžœžœ˜—Jšœ9˜9Jšœ˜—Jšžœ˜—J˜š   œžœžœžœžœ žœ˜`Jšž˜Jšœžœ˜$J˜Jšœžœ ˜Jšœžœ ˜Jšœžœ ˜Jšœžœ ˜š žœžœžœžœžœ˜;šžœ žœÏc˜šžœ žœ¡˜Jšžœ žœ˜,Jšžœ˜—šžœ¡˜ Jšžœ žœ˜,Jšžœ˜ ——šžœ¡˜ šžœ žœ¡˜Jšžœ žœ˜+Jšžœ˜—šžœ¡˜ Jšžœ žœ˜+Jšžœ˜ ——J˜—šžœ¡œ˜Jšœ˜J˜—Jšžœ˜—J˜š œžœ žœžœžœ žœžœ˜—Jšœ\™\Jšœ™Jšœ™Jšž˜Jšœžœ/˜4š žœžœžœžœ¡˜Gš žœžœžœžœ¡ ˜:Jšœ˜Jšœ"˜"J˜—šžœ¡˜Jšœ˜Jšœ!˜!J˜—J˜—šžœ¡˜ š žœžœžœžœ¡ ˜MJšœ˜Jšœ!˜!J˜—šžœ¡˜%Jšœ˜Jšœ"˜"J˜—J˜—Jšžœ˜—J˜š  œžœžœžœžœžœžœ žœžœ˜±Jšœ™Jšž˜š œžœ˜Jšœ˜JšœJ˜JJšœ˜—Jšœ žœžœžœ ˜5Jšœ žœžœžœ ˜2Jšœ˜Jšœ˜šžœž˜Jšœ¡œžœ žœ ˜Jšžœ8˜Jšž˜JšžœžœžœP˜eJšžœ˜J˜—š œžœ˜4Jšž˜J˜&JšœZžœ žœ˜rJšžœ˜J˜—š œžœ˜4Jšž˜J˜%JšœZžœ žœ˜qJšžœ˜J˜—š œžœ˜6Jšž˜J˜(Jšœ[žœ žœ˜sJšžœ˜J˜—š œžœ˜6Jšž˜J˜'Jšœ[žœ žœ˜rJšžœ˜J˜J˜—š œžœ˜;Jšž˜J˜3Jšœ[žœžœ˜‘Jšžœ˜—J˜š œžœ˜