<> <> <> <> DIRECTORY CD, CDLayers, CDVPrivate, CDVScale, Imager, ImagerBackdoor, RuntimeError, PrincOpsUtils, TIPUser, ViewerClasses; CDVSomeCursors: CEDAR PROGRAM IMPORTS CDLayers, CDVPrivate, CDVScale, Imager, ImagerBackdoor, PrincOpsUtils, RuntimeError, TIPUser = BEGIN ViewerPos2: PROC [me: CDVPrivate.VRef] RETURNS [CD.Position] = INLINE { RETURN [CDVScale.DesignToViewerPosition[me.scale, me.stopVC]]; }; ViewerPos1: PROC [me: CDVPrivate.VRef] RETURNS [CD.Position] = INLINE { RETURN [CDVScale.DesignToViewerPosition[me.scale, me.startVC]]; }; DefaultCursor: PUBLIC PROC[me: CDVPrivate.VRef] = BEGIN p2: CD.Position = ViewerPos2[me]; CDVPrivate.InvertArea[me, p2.x-8, p2.y, p2.x+8, p2.y]; CDVPrivate.InvertArea[me, p2.x, p2.y-8, p2.x, p2.y+8]; END; ArrowCursor: PUBLIC PROC[me: CDVPrivate.VRef] = BEGIN p1: CD.Position = ViewerPos1[me]; p2: CD.Position = ViewerPos2[me]; Imager.SetColor[me.viewContext, ImagerBackdoor.invert]; Imager.MaskVector[me.viewContext, [p1.x, p1.y], [p2.x, p2.y]]; END; PseudoArrowCursor: PUBLIC PROC[me: CDVPrivate.VRef] = BEGIN ENABLE RuntimeError.UNCAUGHT => { IF CDVPrivate.catchAnyWhichDeadlock THEN GOTO SomeError ELSE REJECT; }; p1: CD.Position = ViewerPos1[me]; p2: CD.Position = ViewerPos2[me]; CDVPrivate.InvertArea[me, p1.x, p1.y, p1.x, p2.y]; CDVPrivate.InvertArea[me, p1.x, p2.y, p2.x, p2.y]; EXITS SomeError => NULL; END; RectCursor: PUBLIC PROC[me: CDVPrivate.VRef] = BEGIN ENABLE RuntimeError.UNCAUGHT => { IF CDVPrivate.catchAnyWhichDeadlock THEN GOTO SomeError ELSE REJECT; }; p1: CD.Position = ViewerPos1[me]; p2: CD.Position = ViewerPos2[me]; CDVPrivate.InvertArea[me, p1.x, p1.y, p1.x, p2.y]; CDVPrivate.InvertArea[me, p1.x, p2.y, p2.x, p2.y]; CDVPrivate.InvertArea[me, p2.x, p2.y, p2.x, p1.y]; CDVPrivate.InvertArea[me, p2.x, p1.y, p1.x, p1.y]; EXITS SomeError => NULL; END; LCursor: PUBLIC PROC[me: CDVPrivate.VRef] = BEGIN ENABLE RuntimeError.UNCAUGHT => { IF CDVPrivate.catchAnyWhichDeadlock THEN GOTO SomeError ELSE REJECT; }; yi, yo, xi, xo: INT; --i=inner, o=outer, if p1 considered center wireWidth: CD.Number = MAX[CDVScale.DesignToViewerScalar[me.scale, me.defaultWidthVC], 1]; p1: CD.Position = ViewerPos1[me]; p2: CD.Position = ViewerPos2[me]; IF me.firstHorizontalVC THEN { IF p2.x<=p1.x AND p2.x>=p1.x-wireWidth AND (p2.yp1.y+wireWidth) THEN { -- sorry, only vertical, p2.x ignored CDVPrivate.InvertArea[me, p1.x, p2.y, p1.x, p1.y]; CDVPrivate.InvertArea[me, p1.x, p1.y, p1.x+wireWidth, p1.y]; CDVPrivate.InvertArea[me, p1.x+wireWidth, p1.y, p1.x+wireWidth, p2.y]; CDVPrivate.InvertArea[me, p1.x+wireWidth, p2.y, p1.x, p2.y]; RETURN }; IF p2.x>=p1.x THEN {xi _ p2.x; xo _ xi+wireWidth} ELSE {xo _ p2.x; xi _ xo+wireWidth}; IF p2.yp1.y+wireWidth THEN { -- L shaped, up CDVPrivate.InvertArea[me, p1.x, p1.y, xo, p1.y]; CDVPrivate.InvertArea[me, xo, p1.y, xo, p2.y]; CDVPrivate.InvertArea[me, xo, p2.y, xi, p2.y]; CDVPrivate.InvertArea[me, xi, p2.y, xi, p1.y+wireWidth]; CDVPrivate.InvertArea[me, xi, p1.y+wireWidth, p1.x, p1.y+wireWidth]; CDVPrivate.InvertArea[me, p1.x, p1.y+wireWidth, p1.x, p1.y]; RETURN }; <<-- only horizontal>> CDVPrivate.InvertArea[me, p1.x, p1.y, p2.x, p1.y]; CDVPrivate.InvertArea[me, p2.x, p1.y, p2.x, p1.y+wireWidth]; CDVPrivate.InvertArea[me, p2.x, p1.y+wireWidth, p1.x, p1.y+wireWidth]; CDVPrivate.InvertArea[me, p1.x, p1.y+wireWidth, p1.x, p1.y]; } ELSE -- NOT me.firstHorizontalVC -- { IF p2.y<=p1.y AND p2.y>=p1.y-wireWidth AND (p2.xp1.x+wireWidth) THEN { -- sorry, only horizontal, p2.y ignored CDVPrivate.InvertArea[me, p2.x, p1.y, p1.x, p1.y]; CDVPrivate.InvertArea[me, p1.x, p1.y, p1.x, p1.y+wireWidth]; CDVPrivate.InvertArea[me, p1.x, p1.y+wireWidth, p2.x, p1.y+wireWidth]; CDVPrivate.InvertArea[me, p2.x, p1.y+wireWidth, p2.x, p1.y]; RETURN }; IF p2.y>=p1.y THEN {yi _ p2.y; yo _ yi+wireWidth} ELSE {yo _ p2.y; yi _ yo+wireWidth}; IF p2.xp1.x+wireWidth THEN { -- L shaped, right CDVPrivate.InvertArea[me, p1.x, p1.y, p1.x, yo]; CDVPrivate.InvertArea[me, p1.x, yo, p2.x, yo]; CDVPrivate.InvertArea[me, p2.x, yo, p2.x, yi]; CDVPrivate.InvertArea[me, p2.x, yi, p1.x+wireWidth, yi]; CDVPrivate.InvertArea[me, p1.x+wireWidth, yi, p1.x+wireWidth, p1.y]; CDVPrivate.InvertArea[me, p1.x+wireWidth, p1.y, p1.x, p1.y]; RETURN }; -- only vertical CDVPrivate.InvertArea[me, p1.x, p1.y, p1.x, p2.y]; CDVPrivate.InvertArea[me, p1.x, p2.y, p1.x+wireWidth, p2.y]; CDVPrivate.InvertArea[me, p1.x+wireWidth, p2.y, p1.x+wireWidth, p1.y]; CDVPrivate.InvertArea[me, p1.x+wireWidth, p1.y, p1.x, p1.y]; }; EXITS SomeError => NULL; END; UseWireCursor: CDVPrivate.CursorModeProc = { l: CD.Layer = CDLayers.CurrentLayer[me.actualDesign]; w: CD.Number = CDLayers.LayerWidth[me.actualDesign, l]; me.designRec.outlineProcLC _ IF w>0 THEN LCursor ELSE RectCursor; me.designRec.usedCursor _ $wire; }; UseRectCursor: CDVPrivate.CursorModeProc = { me.designRec.usedCursor _ mode; me.designRec.outlineProcLC _ RectCursor }; UseArrowCursor: CDVPrivate.CursorModeProc = { me.designRec.usedCursor _ mode; me.designRec.outlineProcLC _ ArrowCursor }; UsePseudoArrowCursor: CDVPrivate.CursorModeProc = { me.designRec.usedCursor _ mode; me.designRec.outlineProcLC _ PseudoArrowCursor }; UseDefaultCursor: CDVPrivate.CursorModeProc = { me.designRec.usedCursor _ NIL; me.designRec.outlineProcLC _ DefaultCursor }; DoThePartialAdvance: CDVPrivate.CursorModeProc = { UseWireCursor[me, $wire]; IF me.designRec.firstHLC THEN me.designRec.startLC.x _ me.designRec.stopLC.x ELSE me.designRec.startLC.y _ me.designRec.stopLC.y; me.designRec.firstHLC _ NOT me.designRec.firstHLC; me.designRec.startLCValid _ TRUE; }; DoFlipCursor: CDVPrivate.CursorModeProc = { UseWireCursor[me, $wire]; me.designRec.firstHLC _ NOT me.designRec.firstHLC }; IsTheCursor: PROC [usedCursor: REF] RETURNS [yes: BOOL_FALSE] = INLINE BEGIN ENABLE RuntimeError.UNCAUGHT => {--must have not yet been initialized-- GOTO deny}; IF CDVPrivate.cursoredCDViewer#NIL THEN RETURN [NARROW[CDVPrivate.cursoredCDViewer.data, CDVPrivate.VRef].designRec.usedCursor=usedCursor]; EXITS deny => RETURN [FALSE] END; IsWire: PROC RETURNS [BOOL] = {RETURN [IsTheCursor[$wire]]}; IsRect: PROC RETURNS [BOOL] = {RETURN [IsTheCursor[$rect]]}; IsArrow: PROC RETURNS [BOOL] = {RETURN [IsTheCursor[$arrow]]}; IsDefault: PROC RETURNS [BOOL] = {RETURN [IsTheCursor[NIL]]}; CDVPrivate.ImplementACursor[NIL, UseDefaultCursor]; --overwrites the default CDVPrivate.ImplementACursor[$wire, UseWireCursor]; CDVPrivate.ImplementACursor[$rect, UseRectCursor]; IF PrincOpsUtils.VERSION[].machineType=dorado THEN CDVPrivate.ImplementACursor[$arrow, UseArrowCursor] ELSE CDVPrivate.ImplementACursor[$arrow, UsePseudoArrowCursor]; CDVPrivate.ImplementACursor[$default, UseDefaultCursor]; CDVPrivate.ImplementACursor[$PartialWireAdvance, DoThePartialAdvance]; CDVPrivate.ImplementACursor[$FlipWire, DoFlipCursor]; TIPUser.RegisterTIPPredicate[key: $ChipndaleWireCursor, p: IsWire]; TIPUser.RegisterTIPPredicate[key: $ChipndaleRectCursor, p: IsRect]; TIPUser.RegisterTIPPredicate[key: $ChipndaleArrowCursor, p: IsArrow]; TIPUser.RegisterTIPPredicate[key: $ChipndaleDefaultCursor, p: IsDefault]; END.