DIRECTORY CD, CDInstances, CDBasics, CDCallSpecific, CDSequencer, CDOps, CDOrient, CDProperties, CDValue, IO, TerminalIO; CDStretchCommands: CEDAR PROGRAM IMPORTS CDInstances, CDBasics, CDOps, CDOrient, CDProperties, CDSequencer, CDValue, IO, TerminalIO = BEGIN StretchApplication: PROC [design: CD.Design, inst: CD.Instance, orientInPlane: CD.Orientation, amount: CD.Number] RETURNS [include: CD.InstanceList_NIL, removeMe: BOOL_FALSE] = BEGIN CallSpecific: PROC [design: CD.Design, inst: CD.Instance, x: REF, objectSpecific: REF] RETURNS [done: BOOL_FALSE, removeMe: BOOL_FALSE, include: CD.InstanceList_NIL, repaintMe: BOOL_FALSE, repaintInclude: BOOL_FALSE] = BEGIN IF objectSpecific#NIL THEN BEGIN class: REF = CDProperties.GetProp[inst.ob.class.properties, objectSpecific]; IF class#NIL AND ISTYPE[class, REF CDCallSpecific.CallProc] THEN BEGIN [done: done, removeMe: removeMe, include: include, repaintMe: repaintMe, repaintInclude: repaintInclude] _ NARROW[class, REF CDCallSpecific.CallProc]^[design, inst, x] END; END; END; appOrient, orientInObject: CD.Orientation; done, repaintMe, repaintInclude: BOOL; offset: REF CD.Position _ NEW[CD.Position_[0, 0]]; orientInPlane _ CDOrient.ConcentrateOnRotate90[orientInPlane]; appOrient _ CDOrient.ConcentrateOnRotate90[inst.orientation]; orientInObject _ CDOrient.DecomposeOrient[ itemOrientInWorld: orientInPlane, cellOrientInWorld: appOrient ]; IF CDOrient.IncludesOddRot90[orientInObject] THEN offset.x_amount ELSE offset.y_amount; CDOps.DelayedRedraw[design, CDInstances.InstRectO[inst]]; [done, removeMe, include, repaintMe, repaintInclude] _ CallSpecific[design, inst, offset , $Lengthen]; IF done THEN { SELECT CDOrient.ConcentrateOnRotate90[orientInPlane] FROM CDOrient.original => { inst.location.y _ inst.location.y-amount; IF include#NIL THEN CDInstances.TranslateList[include, [0, -amount]] }; CDOrient.rotate90 => NULL; CDOrient.rotate180 => NULL; CDOrient.rotate270 => { inst.location.x _ inst.location.x-amount; IF include#NIL THEN CDInstances.TranslateList[include, [-amount, 0]] }; ENDCASE => ERROR; CDOps.DelayedRedraw[design, CDInstances.InstRectO[inst]]; }; END; SelectBorder: PROC [r: CD.Rect, pos: CD.Position] RETURNS [orient: CD.Orientation] = BEGIN dx1, dx2, dy1, dy2: CD.Number; 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.Instance, from, to: CD.Position] RETURNS [amount: CD.Number, orientInPlane: CD.Orientation] = BEGIN r: CD.Rect = CDInstances.InstRectI[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.Rect, pos: CD.Position, dir: CD.Orientation, dirAmount: CD.Number] RETURNS [amount: CD.Number, 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.Position, growAsToX: BOOL_FALSE, edgeInOrient: BOOL_FALSE, orient: CD.Orientation_CD.original] = BEGIN pointedAp: CD.Instance; orientInPlane: CD.Orientation; amount: CD.Number; include: CD.InstanceList; removeMe: BOOL; removeList, includeList: CD.InstanceList_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 _ CDInstances.InstanceAt[il: CDOps.InstList[design], pos: from, selectedOnly: TRUE]; IF pointedAp=NIL THEN { TerminalIO.WriteRope[" no selected object pointed\n"]; RETURN }; IF growAsToX THEN { amount_to.x; orientInPlane _ SelectBorder[CDInstances.InstRectI[pointedAp], from] } ELSE IF edgeInOrient THEN [amount, orientInPlane] _ FixDirection[CDInstances.InstRectI[pointedAp], from, orient, to.x] ELSE [amount, orientInPlane] _ DetermineDirection[pointedAp, from, to]; FOR list: CD.InstanceList _ CDOps.InstList[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 _ CDInstances.AppendToList[include, includeList]; } ENDLOOP; RemoveAppList[design, removeList]; CDOps.IncludeInstanceList[design, includeList]; TerminalIO.WriteF1["%g objects tried to stretch\n", IO.int[count]]; END; RemoveAppList: PROC [design: CD.Design, appList: CD.InstanceList, draw: BOOL_TRUE] = BEGIN FOR list: CD.InstanceList _ appList, list.rest WHILE list#NIL DO CDOps.RemoveInstance[design, list.first, draw]; ENDLOOP; END; StretchCommandS: PROC [comm: CDSequencer.Command] = BEGIN TerminalIO.WriteRope["Stretch selected"]; DoAStretch[design: comm.design, from: comm.sPos, to: comm.pos] END; StepValue: PROC [comm: CDSequencer.Command] RETURNS [n: CD.Number] = BEGIN n _ CDValue.FetchInt[boundTo: comm.design, key: $CDxStepValue, propagation: global]; IF n<=0 THEN n _ comm.design.technology.lambda END; GrowStepSCommand: PROC [comm: CDSequencer.Command] = BEGIN TerminalIO.WriteRope["grow selected"]; DoAStretch[design: comm.design, from: comm.pos, to: [StepValue[comm], 0], growAsToX: TRUE ] END; ShrinkStepSCommand: PROC [comm: CDSequencer.Command] = BEGIN TerminalIO.WriteRope["shrink selected"]; DoAStretch[design: comm.design, from: comm.pos, to: [-StepValue[comm], 0], 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], 0], 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], 0], 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], 0], 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], 0], edgeInOrient: TRUE, orient: CDOrient.original] END; CDSequencer.ImplementCommand[$StretchS, StretchCommandS]; CDSequencer.ImplementCommand[$GrowStepS, GrowStepSCommand]; CDSequencer.ImplementCommand[$ShrinkStepS, ShrinkStepSCommand]; CDSequencer.ImplementCommand[$StretchStepLeftS, StretchStepLeftCommandS]; CDSequencer.ImplementCommand[$StretchStepRightS, StretchStepRightCommandS]; CDSequencer.ImplementCommand[$StretchStepUpS, StretchStepUpCommandS]; CDSequencer.ImplementCommand[$StretchStepDownS, StretchStepDownCommandS]; END. rCDStretchCommands.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, November 12, 1985 11:00:42 am PST -- 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 Κ ;˜codešœ,™,Kšœ Οmœ1™˜>Kšœ=˜=šœ*˜*Kšœ"˜"Kšœ˜Kšœ˜—Kšžœ+žœžœž˜WKšœ9˜9Kšœf˜fšžœžœ˜šžœ/ž˜9šœ˜Kšœ)˜)Kšžœ žœžœ1˜DK˜—Kšœžœ˜Kšœžœ˜šœ˜Kšœ)˜)Kšžœ žœžœ1˜DK˜—Kšžœžœ˜—Kšœ9˜9Kšœ˜—Kšžœ˜—K˜š   œžœžœ žœ žœ žœ˜TKšž˜Kšœžœ˜K˜Kšœžœ ˜Kšœžœ ˜Kšœžœ ˜Kšœžœ ˜š žœžœžœžœžœ˜;šžœ žœΟc˜šžœ žœ‘˜Kšžœ žœ˜,Kšžœ˜—šžœ‘˜ Kšžœ žœ˜,Kšžœ˜ ——šžœ‘˜ šžœ žœ‘˜Kšžœ žœ˜+Kšžœ˜—šžœ‘˜ Kšžœ žœ˜+Kšžœ˜ ——K˜—šžœ‘œ˜Kšœ˜K˜—Kšžœ˜—K˜š œžœ žœžœ žœ žœžœ˜…Kšœ\™\Kšœ™Kšœ™Kšž˜Kšœžœ)˜.š žœžœžœžœ‘˜Gš žœžœžœžœ‘ ˜:Kšœ˜Kšœ"˜"K˜—šžœ‘˜Kšœ˜Kšœ!˜!K˜—K˜—šžœ‘˜ š žœžœžœžœ‘ ˜MKšœ˜Kšœ!˜!K˜—šžœ‘˜%Kšœ˜Kšœ"˜"K˜—K˜—Kšžœ˜—K˜š  œžœžœ žœžœžœ žœ žœžœ˜™Kšœ™Kšž˜š œžœ˜Kšœ˜KšœJ˜JKšœ˜—Kšœ žœžœžœ ˜5Kšœ žœžœžœ ˜2Kšœ˜Kšœ˜šžœž˜Kšœ‘œžœ žœ ˜˜QK˜—Kšžœ˜—Kšœ"˜"Kšœ/˜/Kšœ4žœ ˜CKšžœ˜—K˜š   œžœ žœžœžœžœ˜TKšž˜š žœžœ#žœžœž˜@Kšœ/˜/Kšžœ˜—Kšžœ˜—Kšœ˜K˜K˜š œžœ˜3Kšž˜K˜)Kšœ>˜>Kšžœ˜—K˜š  œžœžœžœ ˜DKšž˜KšœT˜TKšžœžœ"˜.Kšžœ˜K˜—š œžœ˜4Kšž˜K˜&KšœUžœ˜[Kšžœ˜K˜—š œžœ˜6Kšž˜K˜(KšœVžœ˜\Kšžœ˜K˜—š œžœ˜;Kšž˜K˜3KšœYžœ˜zKšžœ˜—K˜š œžœ˜