-- BoundaryAdjustImpl.mesa; Edited by McGregor on September 1, 1982 4:07 pm
DIRECTORY
Cursors USING [SetCursor],
Graphics USING [Context, DrawBox, SetPaintMode],
InputFocus USING [CaptureButtons, ReleaseButtons],
TIPUser USING [InstantiateNewTIPTable, TIPScreenCoords],
ViewerClasses,
ViewerOps USING [AcquireContext, CreateViewer, EnumerateViewers, EnumProc,
MoveBoundary, MoveViewer, ReleaseContext, RegisterViewerClass, XYWH2Box],
ViewerSpecs,
WindowManager USING [RestoreCursor];
BoundaryAdjustImpl: PROGRAM
IMPORTS Cursors, Graphics, InputFocus, TIPUser, ViewerSpecs,
ViewerOps, WindowManager
SHARES ViewerOps =
BEGIN OPEN ViewerClasses, ViewerSpecs;
width: INTEGER = 7; -- size of adjustment box on screen
height: INTEGER = 5;
inProgress: BOOLEAN ← FALSE;
lastX, lastY: INTEGER ← LAST[INTEGER];
context: Graphics.Context;
BoundaryAdjustPaint: PaintProc = BEGIN OPEN self;
hiddenIcon: BOOLEAN ← FALSE;
IconHidden: ViewerOps.EnumProc = BEGIN
IF v.iconic AND v.wy+v.wh > ViewerSpecs.openBottomY THEN BEGIN
hiddenIcon ← TRUE;
RETURN[FALSE];
END;
END;
ViewerOps.EnumerateViewers[IconHidden];
IF hiddenIcon THEN Graphics.DrawBox[context, ViewerOps.XYWH2Box[0, 0, cw, ch]]
ELSE BEGIN
Graphics.DrawBox[context, ViewerOps.XYWH2Box[0, 0, cw, 1]];
Graphics.DrawBox[context, ViewerOps.XYWH2Box[0, 0, 1, ch]];
Graphics.DrawBox[context, ViewerOps.XYWH2Box[cw-1, 0, 1, ch]];
Graphics.DrawBox[context, ViewerOps.XYWH2Box[0, ch-1, cw, 1]];
END;
END;
BoundaryAdjustNotify: PRIVATE NotifyProc = BEGIN
ENABLE UNWIND => {InputFocus.ReleaseButtons[]; ViewerOps.ReleaseContext[context]};
mouseX, mouseY: INTEGER;
Start: PROC = BEGIN
inProgress ← TRUE;
Cursors.SetCursor[scrollLeftRight];
InputFocus.CaptureButtons[BoundaryAdjustNotify, boundaryAdjustClass.tipTable, self];
context ← ViewerOps.AcquireContext[NIL];
[] ← Graphics.SetPaintMode[context, invert];
END;
FOR list: LIST OF REF ANY ← input, list.rest UNTIL list = NIL DO
WITH list.first SELECT FROM
x: ATOM => SELECT x FROM
$Move => BEGIN
IF ~inProgress THEN Start[];
Feedback[self, mouseX, mouseY];
END;
$Start => IF ~inProgress THEN Start[];
$End => IF inProgress THEN BEGIN
InputFocus.ReleaseButtons[];
Feedback[self, LAST[INTEGER], LAST[INTEGER], TRUE];
ViewerOps.ReleaseContext[context];
ViewerOps.MoveViewer[self, mouseX-(width/2), mouseY-self.wh, self.ww, self.wh];
ViewerOps.MoveBoundary[mouseX, mouseY];
WindowManager.RestoreCursor[];
inProgress ← FALSE;
END;
ENDCASE => ERROR;
z: TIPUser.TIPScreenCoords => [mouseX, mouseY] ← Clip[z];
ENDCASE => ERROR;
ENDLOOP;
END;
Feedback: PROC [self: Viewer, x,y: INTEGER, remove: BOOLEAN ← FALSE] = BEGIN
Show: PROC [x, y: INTEGER] = INLINE BEGIN
Graphics.DrawBox[context, [x, y, x+2, openLeftTopY]];
Graphics.DrawBox[context, [0, y-2, screenW, y]];
END;
IF lastX=x AND lastY=y THEN RETURN; -- no change
IF lastX#LAST[INTEGER] THEN Show[lastX, lastY];
IF remove THEN lastX ← lastY ← LAST[INTEGER]
ELSE {Show[x, y]; lastX ← x; lastY ← y};
END;
Clip: PROC [position: TIPUser.TIPScreenCoords] RETURNS [x, y: INTEGER] = BEGIN
OPEN ViewerSpecs;
x ← SELECT position.mouseX FROM
< width => width,
> screenW-width => screenW-width,
ENDCASE => position.mouseX;
y ← SELECT position.mouseY FROM
< height => height,
< iconHeight+iconSpacing+(iconHeight/2) => iconHeight+iconSpacing,
ENDCASE => 2*(iconHeight+iconSpacing);
END;
boundaryAdjustClass: ViewerClass ← NEW[ViewerClassRec ← [
paint: BoundaryAdjustPaint,
notify: BoundaryAdjustNotify,
tipTable: TIPUser.InstantiateNewTIPTable["/Indigo/CedarViewers/Viewers/BoundaryAdjust.tip"],
cursor: bullseye
]];
ba: ViewerClasses.Viewer;
ViewerOps.RegisterViewerClass[$BoundaryAdjust, boundaryAdjustClass]; -- plug in to Viewers
ba ← ViewerOps.CreateViewer[flavor: $BoundaryAdjust, info: [name: "BA",
wx: ViewerSpecs.openLeftWidth-(width/2), wy: ViewerSpecs.openBottomY-height,
ww: width, wh: height, column: static], paint: FALSE];
ba.border ← FALSE;
ViewerOps.MoveViewer[ba, ba.wx, ba.wy, ba.ww, ba.wh]; -- recalculate client size
END.