CDVSomeCursors.mesa
Copyright © 1983, 1984 by Xerox Corporation. All rights reserved.
by Christian Jacobi August 5, 1983 11:07 am
last edited by Christian Jacobi October 22, 1984 9:42:09 am PDT
DIRECTORY
CD,
CDDefaults,
CDVPrivate,
CDVScale,
Graphics,
RuntimeError,
TIPUser,
ViewerClasses;
CDVSomeCursors: CEDAR PROGRAM
IMPORTS CDDefaults, CDVPrivate, CDVScale, Graphics, RuntimeError, TIPUser =
BEGIN
ViewerPos2: PROC [me: CDVPrivate.MyGraphicRef] RETURNS [CD.Position] = INLINE {
RETURN [CDVScale.DesignToViewerPosition[me.scale, me.stopVC]];
};
ViewerPos1: PROC [me: CDVPrivate.MyGraphicRef] RETURNS [CD.Position] = INLINE {
RETURN [CDVScale.DesignToViewerPosition[me.scale, me.startVC]];
};
SetModeInvertBlack: PROC[me: CDVPrivate.MyGraphicRef] = INLINE {
Graphics.SetColor[me.viewerContext, Graphics.black];
[] ← Graphics.SetPaintMode[me.viewerContext, invert];
};
XCursor: PUBLIC PROC[me: CDVPrivate.MyGraphicRef] =
BEGIN
p2: CD.Position~ViewerPos2[me];
SetModeInvertBlack[me];
Graphics.SetCP[me.viewerContext, p2.x-8, p2.y-8];
Graphics.DrawTo[me.viewerContext, p2.x+8, p2.y+8];
Graphics.SetCP[me.viewerContext, p2.x+8, p2.y-8];
Graphics.DrawTo[me.viewerContext, p2.x-8, p2.y+8];
END;
PlusCursor: PUBLIC PROC[me: CDVPrivate.MyGraphicRef] =
BEGIN
p2: CD.Position~ViewerPos2[me];
CDVPrivate.InvertArea[me, p2.x-3, p2.y, p2.x+3, p2.y];
CDVPrivate.InvertArea[me, p2.x, p2.y-3, p2.x, p2.y+3];
END;
DefaultCursor: PUBLIC PROC[me: CDVPrivate.MyGraphicRef] =
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.MyGraphicRef] =
BEGIN
p1: CD.Position~ViewerPos1[me];
p2: CD.Position~ViewerPos2[me];
SetModeInvertBlack[me];
Graphics.SetCP[me.viewerContext, p1.x, p1.y];
Graphics.DrawTo[me.viewerContext, p2.x, p2.y];
END;
RectCursor: PUBLIC PROC[me: CDVPrivate.MyGraphicRef] =
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.MyGraphicRef] =
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.y<p1.y OR p2.y>p1.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.y<p1.y THEN { -- L shaped, down
CDVPrivate.InvertArea[me, p1.x, p1.y, xi, p1.y];
CDVPrivate.InvertArea[me, xi, p1.y, xi, p2.y];
CDVPrivate.InvertArea[me, xi, p2.y, xo, p2.y];
CDVPrivate.InvertArea[me, xo, p2.y, xo, p1.y+wireWidth];
CDVPrivate.InvertArea[me, xo, p1.y+wireWidth, p1.x, p1.y+wireWidth];
CDVPrivate.InvertArea[me, p1.x, p1.y+wireWidth, p1.x, p1.y];
RETURN
};
IF p2.y>p1.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.x<p1.x OR p2.x>p1.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.x<p1.x THEN { -- L shaped, left
CDVPrivate.InvertArea[me, p1.x, p1.y, p1.x, yi];
CDVPrivate.InvertArea[me, p1.x, yi, p2.x, yi];
CDVPrivate.InvertArea[me, p2.x, yi, p2.x, yo];
CDVPrivate.InvertArea[me, p2.x, yo, p1.x+wireWidth, yo];
CDVPrivate.InvertArea[me, p1.x+wireWidth, yo, p1.x+wireWidth, p1.y];
CDVPrivate.InvertArea[me, p1.x+wireWidth, p1.y, p1.x, p1.y];
RETURN
};
IF p2.x>p1.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.Level = CDDefaults.CurrentLevel[me.actualDesign];
w: CD.DesignNumber = CDDefaults.LevelWidth[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
};
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: BOOLFALSE] =
INLINE BEGIN
ENABLE RuntimeError.UNCAUGHT => {--must have not yet been initialized-- GOTO deny};
IF CDVPrivate.cursoredCDViewer#NIL THEN
RETURN [NARROW[CDVPrivate.cursoredCDViewer.data, CDVPrivate.MyGraphicRef].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];
CDVPrivate.ImplementACursor[$arrow, UseArrowCursor];
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.