<> <> <> <> <<>> DIRECTORY CD, CDBasics, CDCells, CDCellsInteractions, CDDefaultProcs, CDDirectory, CDEnvironment, CDImports, CDInstances, CDOps, CDSatellites, CDSequencer, CDSequencerExtras, CDViewer, CDViewHighlight, List, Pipal, PipalCD, PipalInt, PipalIO, PipalMos, PipalOps, PipalUI, PW, RefTab, SymTab, TerminalIO, ViewerClasses, ViewerOps; PipalUIImpl: CEDAR PROGRAM IMPORTS CD, CDBasics, CDCells, CDCellsInteractions, CDDefaultProcs, CDDirectory, CDEnvironment, CDImports, CDInstances, CDOps, CDSatellites, CDSequencerExtras, CDViewer, CDViewHighlight, List, Pipal, PipalCD, PipalInt, PipalIO, PipalMos, PipalOps, PW, RefTab, SymTab, TerminalIO, ViewerOps EXPORTS PipalUI SHARES CDImports = BEGIN OPEN PipalUI; <> stupidCDProps: LIST OF REF _ LIST [$GeneratorProc, $CDxDrawSymbolics, $layerOfPin, $CDSatellitesGroupId, $CDBringoverLibraryName, $CDSatellitesOGroup, $OwnerDesign, $SatellitesCounter, $FileVersion, $CDSatellitesMax, $WireIconsConvertedFrom23, $FiddleKey]; otherProps: LIST OF REF _ LIST [$X, $PinOrder, $InstanceName, $DontFlatten, $Export, $MintDiscardMe]; UnknownProp: SIGNAL [key: ATOM, val: REF] = CODE; DesignRoot: PUBLIC PROC [design: Design] RETURNS [root: Pipal.Object] = { Each: CDDirectory.EachEntryAction = { [] _ SymTab.Store[directory, name, PipalCD.CDToPObject[ob]]; }; top: Pipal.Object _ PipalCD.CDToPObject[CDOps.RealTopCell[design]]; satellites: Pipal.Objects _ NIL; directory: SymTab.Ref _ SymTab.Create[]; FOR props: CD.PropList _ design.properties^, props.rest WHILE props#NIL DO key: REF _ props.first.key; val: REF _ props.first.val; IF ISTYPE [key, ATOM] THEN SELECT TRUE FROM List.Memb[key, stupidCDProps] => {}; List.Memb[key, otherProps] => top _ Pipal.CreateAnnotation[top, NARROW [key], val]; ENDCASE => { SIGNAL UnknownProp[NARROW [key], val]; otherProps_ CONS [key, otherProps]; }; ENDLOOP; FOR list: CD.InstanceList _ CDSatellites.GetSatellites[design], list.rest WHILE list#NIL DO satellites _ CONS [PipalCD.CDToPInstance[list.first], satellites]; ENDLOOP; [] _ CDDirectory.Enumerate[design, Each]; root _ PipalIO.CreateDirectory[design.name, PipalMos.CreateStar[top, satellites], directory]; }; <> highlightClass: CD.ObjectClass _ PW.RegisterClass[ objectType: $PipalHighlight, expand: ExpandHighlight, interestRect: CDDefaultProcs.InterestRect, drawMe: HighlightDrawMe, quickDrawMe: HighlightDrawMe, showMeSelected: CDDefaultProcs.ShowMeSelected ]; <> <<>> ExpandHighlight: CDDirectory.ExpandProc = {ERROR}; HighlightDrawMe: CD.DrawProc = { pr _ NEW [CD.DrawInformation _ pr^]; pr.drawRect _ HighlightDrawRect; pr.drawChild[pr, NARROW [ob.specific], trans]; }; HighlightDrawRect: CD.DrawRectProc = { CDDefaultProcs.DrawRect[pr, r, CD.shadeLayer]; }; CreateHighlight: PROC [cdobj: CD.Object] RETURNS [ob: CD.Object] = { ob _ NEW [CD.ObjectRep _ [ bbox: cdobj.bbox, class: highlightClass, immutable: TRUE, specific: cdobj ]]; }; HighlightDesign: PUBLIC PROC [design: Design, transformation: PipalInt.Transformation _ [], object: Pipal.Object _ NIL, viewer: ViewerClasses.Viewer _ NIL, label: Pipal.ROPE _ NIL, rescale: BOOL _ TRUE] = { bbox: CD.Rect; cdhighlight: CD.Instance; IF viewer=NIL THEN viewer _ FindViewer[design, label]; IF object=NIL THEN { CDViewHighlight.ShowInstance[v: viewer, instOrList: NIL]; RETURN; }; cdhighlight _ CDInstances.NewInst[ CreateHighlight[PipalCD.PToCDObject[object].cdobj], PipalCD.PToCDTrans[transformation] ]; bbox _ CDInstances.InstRectO[cdhighlight]; CDViewHighlight.ShowInstance[v: viewer, instOrList: cdhighlight]; ViewerOps.OpenIcon[viewer]; IF NOT CDBasics.NonEmpty[bbox] THEN RETURN; IF CDBasics.NonEmpty[bbox] AND rescale THEN CDViewer.ShowAndScale[viewer, bbox]; CDOps.ImmediateRedraw[design, bbox, FALSE]; }; FindViewer: PUBLIC PROC [design: Design, label: Pipal.ROPE _ NIL] RETURNS [viewer: ViewerClasses.Viewer] = { viewer _ CDViewer.LastViewer[]; IF CDViewer.DesignOf[viewer]#design THEN { viewers: CDViewer.ViewerList _ CDViewer.ViewersOf[design]; IF viewers=NIL THEN { viewer _ CDViewer.CreateViewer[design]; IF label#NIL THEN ViewerOps.SetViewer[viewer: viewer, data: label, op: $Label]; } ELSE viewer _ viewers.first; }; }; <> SearchDesignRootPath: PRIVATE PROC [design: Design] RETURNS [pushPath: PipalOps.Path] = { found: BOOL; root: Pipal.Object _ DesignRoot[design]; top: Pipal.Object _ PipalCD.CDToPObject[CDOps.RealTopCell[design]]; IF top=Pipal.void THEN RETURN [NIL]; -- serious yogourt here if that value gets used! ... Think of all consequences for example in ReplaceInDesign [pushPath, found] _ PipalOps.FindOpsPath[root, top]; <<-- We do not deal here with pushed cell path WRONG>> IF NOT found THEN ERROR; }; EnumerateSelectedObjects: PUBLIC PROC [design: Design, each: EachSelectedProc] RETURNS [quit: BOOL _ FALSE] = { pushPath: PipalOps.Path; ThisInstance: CDCells.InstEnumerator = { path: PipalOps.Path; trans: PipalInt.Transformation; child: Pipal.Object; subPath: PipalOps.Path; found: BOOL; cdtrans: CD.Transformation; IF NOT inst.selected THEN RETURN; IF design.actual.first.mightReplace=NIL THEN cdtrans _ inst.trans ELSE { cdaux: CD.Transformation _ design.actual.first.mightReplace.trans; cdtrans _ [ CDBasics.DeMapPoint[inst.trans.off, cdaux], CDBasics.DecomposeOrient[itemInWorld: inst.trans.orient, cellInWorld: cdaux.orient] ]; }; trans _ PipalCD.CDToPTrans[cdtrans]; child _ PipalCD.CDToPObject[inst.ob]; [subPath, found] _ PipalOps.FindIntPath[ [], pushed, -- We do not deal here with pushed cell path WRONG trans, child ]; IF NOT found THEN ERROR; path _ PipalOps.ConcatPath[pushPath, subPath]; quit _ each[path, trans, child] }; pushed: Pipal.Object _ PipalCD.CDToPObject[CDOps.PushedTopCell[design]]; IF pushed=Pipal.void THEN RETURN; pushPath _ SearchDesignRootPath[design]; quit _ CDCells.EnumerateInstances[CDOps.PushedTopCell[design], ThisInstance]; }; TheSelectedObject: PUBLIC PROC [design: Design] RETURNS [thePath: PipalOps.Path, theTrans: PipalInt.Transformation, theChild: Pipal.Object _ NIL] = { Each: EachSelectedProc = { IF theChild=NIL THEN {thePath _ path; theTrans _ trans; theChild _ child} ELSE quit _ TRUE; }; IF EnumerateSelectedObjects[design, Each] THEN theChild _ NIL; IF theChild=NIL THEN TerminalIO.PutF["*** Several selected objects: cannot do it.\n"]; }; <<>> <> <> <> <> <> <> <<] THEN {worldInstance.selected _ TRUE; done _ TRUE; EXIT};>> < done _ FALSE; >> <> <<};>> <> <> <> <> <> <> <> <<] THEN {done _ CDCellsInteractions.PushInCellInstance[design, worldInstance]; EXIT};>> < done _ FALSE; >> <> <<};>> <> cdCommandDispatch: RefTab.Ref _ RefTab.Create[]; -- maps keys to CommandProcs cdCommandData: RefTab.Ref _ RefTab.Create[]; -- maps keys to registration data (if any!) CDCommandDispatcher: PROC [comm: CDSequencer.Command] = { proc: REF CommandProc _ NARROW [RefTab.Fetch[cdCommandDispatch, comm.key].val]; IF proc=NIL THEN ERROR; -- command not registered! proc^[ comm.design, [comm.pos.x, comm.pos.y], [comm.sPos.x, comm.sPos.y], RefTab.Fetch[cdCommandData, comm.key].val, comm.ref ]; }; RegisterCommand: PUBLIC PROC [key: ATOM, proc: CommandProc, queue, markChanged: BOOL _ TRUE, data: REF _ NIL] = { CDSequencerExtras.RegisterCommand[key, CDCommandDispatcher, NIL, IF queue THEN IF markChanged THEN doQueueAndMark ELSE doQueue ELSE IF markChanged THEN ERROR ELSE dontQueue]; [] _ RefTab.Store[cdCommandDispatch, key, NEW [CommandProc _ proc]]; IF data#NIL THEN [] _ RefTab.Store[cdCommandData, key, data]; }; <> Contains: PUBLIC PROC [object: Pipal.Object, candidateTrans: PipalInt.Transformation, candidateObject: Pipal.Object] RETURNS [BOOL] = { ContainsChild: PipalInt.EachChildProc = { IF transformation=candidateTrans AND child=candidateObject THEN RETURN [TRUE]; IF NOT PipalInt.IsInsideRectangle[PipalInt.BBox[child, transformation], PipalInt.BBox[candidateObject, candidateTrans]] THEN RETURN [FALSE]; quit _ PipalInt.HasEnumerate[child] AND PipalInt.Enumerate[child, ContainsChild, transformation]; }; SubCandidateNotContained: PipalInt.EachChildProc = { quit _ NOT Contains[object, transformation, child]; }; IF ContainsChild[[], object] THEN RETURN [TRUE]; IF NOT PipalInt.HasEnumerate[candidateObject] THEN RETURN [FALSE]; RETURN [NOT PipalInt.Enumerate[candidateObject, SubCandidateNotContained, candidateTrans]]; }; SameInstances: PUBLIC PROC [trans1: PipalInt.Transformation, object1: Pipal.Object, trans2: PipalInt.Transformation, object2: Pipal.Object] RETURNS [BOOL] = { RETURN [Contains[PipalInt.TransformObject[trans1, object1], trans2, object2] AND Contains[PipalInt.TransformObject[trans2, object2], trans1, object1]]; }; <> GetTopInstances: PUBLIC PROC [design: Design] RETURNS [topInstances: TopInstanceLists _ NIL] = { GetInstances: PROC [design: Design] = { thisTops: Pipal.Objects _ NIL; stack: LIST OF CD.PushRec _ NIL; trail: LIST OF CD.PushRec _ NIL; FOR stack _ design.actual, stack.rest UNTIL stack.rest=NIL DO trail _ stack; ENDLOOP; thisTops _ LIST [PipalCD.CDToPObject[stack.first.dummyCell.ob]]; -- old code used to be slightly different here! (BS) IF trail#NIL THEN thisTops _ CONS [PipalCD.CDToPInstance[trail.first.mightReplace], thisTops]; FOR cl: LIST OF CDImports.Cache _ CDImports.GetCacheList[design].list, cl.rest UNTIL cl=NIL DO IF RefTab.Insert[processedDesigns, cl.first.importee, $Done] THEN GetInstances[cl.first.importee]; ENDLOOP; topInstances _ CONS[[design, thisTops], topInstances]; }; processedDesigns: RefTab.Ref _ RefTab.Create[]; GetInstances[design]; }; <> schematicLambda: PUBLIC INT _ CD.FetchTechnology[$cmosB].lambda; schematicFudge: PUBLIC INT _ schematicLambda / 2; FetchKeyLine: PUBLIC PROC [fileName, key: Pipal.ROPE] RETURNS [entry: Pipal.ROPE _ NIL] = { entry _ CDEnvironment.FetchKeyLine[fileName, key]; }; ExecuteInTerminal: PUBLIC PROC [entry: Pipal.ROPE] = { [] _ CDEnvironment.StuffToCommandTool[entry]; }; <> Draw: PUBLIC PROC [object: Pipal.Object] RETURNS [design: Design] = { design _ PW.Draw[PipalCD.PToCDObject[object].cdobj]; }; <> END.