DIRECTORY CD, CDBasics, CDEvents, CDInstances, CDOps, CDProperties, CDSimpleOps, Rope USING [IsEmpty, ROPE], TerminalIO; CDSimpleOpsImpl: CEDAR PROGRAM IMPORTS CD, CDBasics, CDEvents, CDInstances, CDOps, CDProperties, Rope, TerminalIO EXPORTS CDSimpleOps SHARES CD = BEGIN renameEvent: CDEvents.EventRegistration _ CDEvents.RegisterEventType[$RenameDesign]; RenameDesign: PUBLIC PROC [design: CD.Design, name: Rope.ROPE] RETURNS [done: BOOL] = { dont: BOOL; oldName: Rope.ROPE _ design.name; IF Rope.IsEmpty[name] THEN RETURN [FALSE]; design.name _ name; dont _ CDEvents.ProcessEvent[renameEvent, design, oldName, TRUE]; IF dont THEN { design.name _ oldName; [] _ CDEvents.ProcessEvent[renameEvent, design, oldName, FALSE]; }; done _ ~dont }; Select: PUBLIC PROC [design: CD.Design, pos: CD.Position, verbose: BOOL] = { sel: CD.Instance _ NIL; FOR w: CD.InstanceList _ CDOps.InstList[design], w.rest WHILE w#NIL DO IF ~w.first.selected THEN { IF CDInstances.PointToI[pos, w.first] THEN {sel _ w.first; EXIT} }; ENDLOOP; IF sel#NIL THEN { sel.selected _ TRUE; CDOps.ReOrderInstance[design, sel]; CDOps.RedrawInstance[design, sel]; IF verbose THEN TerminalIO.PutRope[CDOps.InstRope[sel]]; } ELSE IF verbose THEN { FOR w: CD.InstanceList _ CDOps.InstList[design], w.rest WHILE w#NIL DO IF w.first.selected THEN { IF CDInstances.PointToI[pos, w.first] THEN { TerminalIO.PutRopes[CDOps.InstRope[w.first], " again"]; RETURN } }; ENDLOOP; TerminalIO.PutRope[" no pointed object"]; } }; DeSelect: PUBLIC PROC [design: CD.Design, pos: CD.Position, verbose: BOOL] = { inst: CD.Instance _ CDInstances.InstanceAt[CDOps.InstList[design], pos, TRUE]; IF inst#NIL THEN { IF ~inst.selected THEN ERROR; inst.selected _ FALSE; CDOps.RedrawInstance[design, inst]; CDOps.ReOrderInstance[design, inst]; }; IF verbose THEN TerminalIO.PutRope[CDOps.InstRope[inst]]; }; BoundingRectAndCount: PROC [list: CD.InstanceList, selectedOnly: BOOLEAN_FALSE] RETURNS [bound: CD.Rect_CDBasics.empty, cnt: INT_0] = { FOR tem: LIST OF CD.Instance _ list, tem.rest WHILE tem#NIL DO IF selectedOnly AND NOT tem.first.selected THEN LOOP; cnt _ cnt+1; bound _ CDBasics.Surround[bound, CDInstances.InstRectO[tem.first]] ENDLOOP; }; DeselectAll: PUBLIC PROC [design: CD.Design] = { doItSingleWise: NAT = 4; sel: CD.InstanceList = CDInstances.OnlySelected[CDOps.InstList[design]]; b: CD.Rect; cnt: INT; [b, cnt] _ BoundingRectAndCount[list: sel]; CDInstances.DeSelectList[sel]; IF cnt<=doItSingleWise THEN FOR l: CD.InstanceList _ sel, l.rest WHILE l#NIL DO CDOps.RedrawInstance[design, l.first] ENDLOOP ELSE CDOps.Redraw[design, b]; }; SelectAll: PUBLIC PROC [design: CD.Design] = { b: CD.Rect _ CDInstances.BoundingRectO[list: CDOps.InstList[design], selectedOnly: FALSE]; FOR w: CD.InstanceList _ CDOps.InstList[design], w.rest WHILE w#NIL DO w.first.selected _ TRUE ENDLOOP; CDOps.Redraw[design, b, FALSE]; }; AreaSelectTouched: PROC [design: CD.Design, area: CD.Rect] = { FOR w: CD.InstanceList _ CDOps.InstList[design], w.rest WHILE w#NIL DO IF NOT w.first.selected AND CDBasics.Intersect[area, CDInstances.InstRectI[w.first]] THEN { w.first.selected _ TRUE; CDOps.RedrawInstance[design, w.first, FALSE]; }; ENDLOOP; }; AreaDeSelectTouched: PROC [design: CD.Design, area: CD.Rect] = { FOR w: CD.InstanceList _ CDOps.InstList[design], w.rest WHILE w#NIL DO IF w.first.selected AND CDBasics.Intersect[area, CDInstances.InstRectI[w.first]] THEN { w.first.selected _ FALSE; CDOps.RedrawInstance[design, w.first]; }; ENDLOOP; }; AreaSelectContained: PROC [design: CD.Design, area: CD.Rect] = { FOR w: CD.InstanceList _ CDOps.InstList[design], w.rest WHILE w#NIL DO IF CDBasics.Inside[CDInstances.InstRectI[w.first], area] THEN w.first.selected _ TRUE ENDLOOP; CDOps.Redraw[design, area, FALSE]; }; AreaDeSelectContained: PROC [design: CD.Design, area: CD.Rect] = { FOR w: CD.InstanceList _ CDOps.InstList[design], w.rest WHILE w#NIL DO IF CDBasics.Inside[CDInstances.InstRectI[w.first], area] THEN w.first.selected _ FALSE ENDLOOP; CDOps.Redraw[design, area]; }; AreaSelect: PUBLIC PROC [design: CD.Design, area: CD.Rect, includePartial: BOOL] = { IF includePartial THEN AreaSelectTouched[design, area] ELSE AreaSelectContained[design, area]; }; AreaDeSelect: PUBLIC PROC [design: CD.Design, area: CD.Rect, includePartial: BOOL] = { IF includePartial THEN AreaDeSelectTouched[design, area] ELSE AreaDeSelectContained[design, area]; }; DeleteSelected: PUBLIC PROC [design: CD.Design, verbose: BOOL] = { count: INT _ 0; toDelete, newContents: CD.InstanceList; [selected: toDelete, others: newContents] _ CDInstances.SplitSelected[CDOps.InstList[design]]; CDOps.SetInstList[design, newContents]; FOR w: CD.InstanceList _ toDelete, w.rest WHILE w#NIL DO count _ count+1; CDOps.RedrawInstance[design, w.first, TRUE]; ENDLOOP; IF verbose THEN { IF count#1 THEN TerminalIO.PutF1["%g objects", [integer[count]]] ELSE TerminalIO.PutRope[CDOps.InstRope[toDelete.first]] }; RememberShortTime[design, toDelete]; }; RedrawMoved: PROC [design: CD.Design, r: CD.Rect, offset: CD.Position] = { moved: CD.Rect _ CDBasics.MoveRect[r, offset]; IF CDBasics.Intersect[r, moved] THEN CDOps.Redraw[design, CDBasics.Surround[r, moved], TRUE] ELSE { CDOps.Redraw[design, r]; CDOps.Redraw[design, moved]; -- use eraseFirst because also used by copy } }; MoveSelected: PUBLIC PROC [design: CD.Design, offset: CD.Position] = { sel: CD.InstanceList = CDInstances.OnlySelected[CDOps.InstList[design]]; bounding: CD.Rect _ CDBasics.empty; FOR w: CD.InstanceList _ sel, w.rest WHILE w#NIL DO inst: CD.Instance _ w.first; bounding _ CDBasics.Surround[bounding, CDInstances.InstRectO[inst]]; inst.trans.off _ CDBasics.AddPoints[inst.trans.off, offset]; ENDLOOP; RedrawMoved[design, bounding, offset] }; CopySelected: PUBLIC PROC [design: CD.Design, offset: CD.Position] = { new: CD.InstanceList_NIL; sel: CD.InstanceList = CDInstances.OnlySelected[CDOps.InstList[design]]; bounding: CD.Rect _ CDInstances.BoundingRectO[sel]; FOR w: CD.InstanceList _ sel, w.rest WHILE w#NIL DO inst: CD.Instance _ CDInstances.Copy[w.first]; inst.trans.off _ CDBasics.AddPoints[inst.trans.off, offset]; inst.selected _ TRUE; new _ CONS[inst, new]; w.first.selected _ FALSE; ENDLOOP; CDOps.IncludeInstanceList[design, new, FALSE]; RedrawMoved[design, bounding, offset]; }; TransformSelected: PUBLIC PROC [design: CD.Design, transform: CD.Orientation, base: CD.Rect] = { ib, is, orientOff: CD.Position; r, oldbb: CD.Rect; oldPseudoCellT, newPseudoCellT: CD.Transformation; sel: CD.InstanceList = CDInstances.OnlySelected[CDOps.InstList[design]]; IF sel=NIL THEN RETURN; oldbb _ CDInstances.BoundingRectO[sel]; IF ~CDBasics.NonEmpty[base] THEN base _ CDInstances.BoundingRectI[sel]; ib _ CDBasics.BaseOfRect[base]; is _ CDBasics.SizeOfRect[base]; oldPseudoCellT _ [ib, original]; r _ CDBasics.MapRect[CDBasics.RectAt[[0,0], is], [[0,0], transform]]; orientOff _ CDBasics.BaseOfRect[r]; newPseudoCellT _ [CDBasics.SubPoints[ib, orientOff], transform]; FOR w: CD.InstanceList _ sel, w.rest WHILE w#NIL DO pseudoCellRel: CD.Transformation _ CDBasics.DecomposeTransform[w.first.trans, oldPseudoCellT]; w.first.trans _ CDBasics.ComposeTransform[pseudoCellRel, newPseudoCellT] ENDLOOP; CDOps.Redraw[design, oldbb]; CDOps.Redraw[design, CDBasics.MapRect[CDBasics.DeMapRect[oldbb, oldPseudoCellT], newPseudoCellT]] }; -- -- -- -- -- -- -- -- -- -- -- -- remSize: CARDINAL = 20; RememberBuffer: TYPE = RECORD[ a: ARRAY [0..remSize) OF REF _ ALL[NIL], next: CARDINAL_0]; Forgett: PROC[class: REF] = { WITH class SELECT FROM il: CD.InstanceList => FOR l: CD.InstanceList _ il, l.rest WHILE l#NIL DO Forgett[l.first] ENDLOOP; inst: CD.Instance => {inst.properties _ NIL; inst.ob _ NIL}; ENDCASE => NULL; }; GetDeletedList: PROC [d: CD.Design] RETURNS [REF RememberBuffer] = { WITH CDProperties.GetListProp[d.unDoBuffers^, $delete] SELECT FROM dl: REF RememberBuffer => RETURN [dl]; ENDCASE => { dl: REF RememberBuffer _ NEW[RememberBuffer]; CDProperties.PutProp[d.unDoBuffers, $delete, dl]; RETURN [dl] }; }; RememberShortTime: PROC [d: CD.Design, what: REF] = { dl: REF RememberBuffer _ GetDeletedList[d]; Forgett[dl.a[dl.next]]; dl.a[dl.next] _ what; dl.next _ (dl.next+1) MOD remSize; }; GiveRemembered: PROC [d: CD.Design] RETURNS [REF] = { x: REF; dl: REF RememberBuffer _ GetDeletedList[d]; IF dl=NIL THEN RETURN [NIL]; dl.next _ (dl.next+remSize-1) MOD remSize; x _ dl.a[dl.next]; dl.a[dl.next] _ NIL; RETURN [x]; }; Undelete: PUBLIC PROC [design: CD.Design, n: INT_0] = { del: REF _ GiveRemembered[design]; IF del=NIL THEN RETURN; WITH del SELECT FROM il: CD.InstanceList => CDOps.IncludeInstanceList[design, il]; inst: CD.Instance => CDOps.IncludeInstance[design, inst] ENDCASE => NULL; }; FlushDeletedCache: PUBLIC PROC [design: CD.Design] = { dl: REF RememberBuffer _ GetDeletedList[design]; IF dl#NIL THEN{ dl.next _ (dl.next+remSize-1) MOD remSize; DO dl.next _ (dl.next+remSize-1) MOD remSize; IF dl.a[dl.next]=NIL THEN EXIT; Forgett[dl.a[dl.next]]; dl.a[dl.next] _ NIL; ENDLOOP; }; design.unDoBuffers _ CD.InitPropRef[]; }; END. CDSimpleOpsImpl.mesa (part of ChipNDale) Copyright c 1983, 1985 by Xerox Corporation. All rights reserved. Created by Christian Jacobi, July 12, 1983 10:56 am Last edited by: Christian Jacobi, October 30, 1986 10:30:04 am PST --is only local name --reorder list, future select selects next lower application --reorder list, future select op finds next lower application --dont care about redrawing too much --helps the garbage collector, --special may prevent circularities through properties Κ β˜codešœ.™.Kšœ Οmœ8™CKšœ4™4K™B—K˜šΟk ˜ Kšžœ˜Kšœ ˜ K˜ K˜ K˜K˜ Kšœ ˜ Kšœžœ žœ˜K˜ —K˜šΟnœžœžœ˜KšžœžœH˜RKšžœ ˜Kšžœžœ˜ —Kšž˜K˜TK˜šŸ œžœžœ žœžœžœžœ˜WKšœ™Kšœžœ˜ Kšœžœ˜!Kšžœžœžœžœ˜*Kšœ˜Kšœ;žœ˜Ašžœžœ˜Kšœ˜Kšœ9žœ˜@K˜—Kšœ ˜ Kšœ˜—K˜š Ÿœžœžœ žœžœžœ˜LKšœžœ žœ˜š žœžœ/žœžœž˜Fšžœžœ˜Kšžœ$žœžœ˜@K˜—Kšžœ˜—šžœžœžœ˜Kšœžœ˜Kšœ=™=Kšœ#˜#Kšœ"˜"Kšžœ žœ)˜8Kšœ˜—šžœžœ žœ˜š žœžœ/žœžœž˜Fšžœžœ˜šžœ$žœ˜,Kšœ7˜7Kšž˜Kšœ˜—K˜—Kšžœ˜—Kšœ)˜)K˜—Kšœ˜K˜—š Ÿœžœžœ žœžœžœ˜NKšœžœ@žœ˜Nšžœžœžœ˜Kšžœžœžœ˜Kšœžœ˜Kšœ#˜#Kšœ>™>Kšœ$˜$Kšœ˜—Kšžœ žœ*˜9Kšœ˜K˜—šŸœžœžœžœžœžœ žœžœ˜‡š žœžœžœžœžœžœž˜>Kš žœžœžœžœžœ˜5K˜ KšœB˜BKšžœ˜—Kšœ˜—K˜šŸ œžœžœ žœ ˜0Kšœžœ˜KšœžœA˜HKšœžœ˜ Kšœžœ˜ Kšœ+˜+Kšœ˜šžœžœ˜š žœžœžœžœž˜3Kšœ%˜%Kšž˜——Kšžœ˜Kšœ˜K˜—šŸ œžœžœ žœ ˜.Kšœ$™$KšœžœNžœ˜Zš žœžœ/žœžœž˜FKšœž˜Kšžœ˜—Kšœžœ˜Kšœ˜K˜—šŸœžœ žœžœ ˜>š žœžœ/žœžœž˜Fšžœžœ˜Kšžœ:žœ˜CKšœžœ˜Kšœ&žœ˜-K˜—Kšžœ˜—Kšœ˜K˜—šŸœžœ žœžœ ˜@š žœžœ/žœžœž˜Fšžœ˜Kšžœ:žœ˜CKšœžœ˜Kšœ&˜&K˜—Kšžœ˜—Kšœ˜K˜—šŸœžœ žœžœ ˜@š žœžœ/žœžœž˜FKšžœ7žœž˜UKšžœ˜—Kšœžœ˜"Kšœ˜K˜—šŸœžœ žœžœ ˜Bš žœžœ/žœžœž˜FKšžœ7žœž˜VKšžœ˜—Kšœ˜Kšœ˜K˜—š Ÿ œžœžœ žœžœžœ˜TKšžœžœ!˜7Kšžœ#˜'Kšœ˜K˜—š Ÿ œžœžœ žœžœžœ˜VKšžœžœ"ž˜9Kšžœ$˜)Kšœ˜K˜—š Ÿœžœžœ žœžœ˜BKšœžœ˜Kšœžœ˜'Kšœ^˜^Kšœ'˜'š žœžœ!žœžœž˜8Kšœ˜Kšœ&žœ˜,Kšžœ˜—šžœ žœ˜Kšžœ žœ1˜@Kšžœ3˜7Kšœ˜—K˜$Kšœ˜K˜—š Ÿ œžœ žœ žœžœ˜JKšœžœ%˜.šžœž˜$Kšœ2žœ˜7—šžœ˜Kšœ˜KšœΟc+˜HKšœ˜—Kšœ˜—K˜š Ÿ œžœžœ žœžœ˜FKšœžœA˜HKšœ žœ˜#š žœžœžœžœž˜3Kšœžœ˜KšœD˜DKšœ<˜