LFUtilImpl.mesa
Michael Plass, July 15, 1983 9:31 am
Last Edited by: Beach, August 22, 1983 10:32 am
DIRECTORY
Cursors,
InputFocus,
Graphics,
LFUtil,
TIPUser,
ViewerClasses,
ViewerOps,
UserTerminal
;
LFUtilImpl: CEDAR MONITOR
IMPORTS Cursors, InputFocus, Graphics, TIPUser, ViewerOps
EXPORTS LFUtil
SHARES ViewerOps
~ BEGIN
lastX, lastY: INTEGERLAST[INTEGER];
topY, leftX, sourceBottom, sourceHeight, sourceLeft, sourceWidth: INTEGER;
mode: {waitingForUpperLeft, waitingForLowerRight, done, abort} ← done;
context: Graphics.Context;
ready: CONDITION;
AbortAdjust: PUBLIC SIGNAL ~ CODE;
GetArea: PUBLIC ENTRY PROC RETURNS [sMin, fMin: INTEGER, sSize, fSize: NAT] = {
ENABLE UNWIND => NULL;
grey: CARDINAL ~ 122645B;
mode ← waitingForUpperLeft;
InputFocus.CaptureButtons[BoxAdjustNotify, vaTIP];
Cursors.SetCursor[crossHairsCircle];
context ← ViewerOps.AcquireContext[NIL];
[] ← Graphics.SetPaintMode[context, invert];
Graphics.SetStipple[context, grey];
lastX ← lastY ← LAST[INTEGER];
UNTIL mode = done OR mode = abort DO WAIT ready ENDLOOP;
IF mode = abort THEN SIGNAL AbortAdjust;
sMin ← sourceBottom;
sSize ← sourceHeight;
fMin ← sourceLeft;
fSize ← sourceWidth;
};
Clip: PROC [position: TIPUser.TIPScreenCoords] RETURNS [x, y: INTEGER] = BEGIN
x ← position.mouseX;
y ← position.mouseY;
END;
BoxAdjustNotify: ENTRY ViewerClasses.NotifyProc ~ {
ENABLE UNWIND => EndAdjust[];
mouseX, mouseY: INTEGER ← 0;
FOR list: LIST OF REF ANY ← input, list.rest UNTIL list = NIL DO
WITH list.first SELECT FROM
x: ATOM => SELECT x FROM
$Abort => BEGIN
EndAdjust[];
mode ← done;
NOTIFY ready;
END;
$Move => BEGIN
IF mode = waitingForUpperLeft THEN {
mode ← waitingForLowerRight;
topY ← mouseY;
leftX ← mouseX;
};
Feedback[mouseX, mouseY];
END;
$End  => BEGIN
Feedback[mouseX, mouseY];
IF mode = waitingForLowerRight THEN {
mode ← done;
EndAdjust[];
IF topY < mouseY THEN {t: NAT ← topY; topY ← mouseY; mouseY ← t};
IF leftX > mouseX THEN {t: NAT ← leftX; leftX ← mouseX; mouseX ← t};
sourceBottom ← mouseY;
sourceHeight ← topY - mouseY + 1;
sourceLeft ← leftX;
sourceWidth ← mouseX - leftX + 1;
NOTIFY ready;
};
END;
ENDCASE => NULL;
z: TIPUser.TIPScreenCoords => [mouseX, mouseY] ← Clip[z];
ENDCASE => ERROR;
ENDLOOP;
};
EndAdjust: PROC = BEGIN
Feedback[LAST[INTEGER], LAST[INTEGER], TRUE];
InputFocus.ReleaseButtons[];
ViewerOps.ReleaseContext[context];
END;
Feedback: PROC [x, y: INTEGER, remove: BOOLFALSE] = BEGIN
Show: PROC [x1, y1: INTEGER] = BEGIN
x2: INTEGER ← leftX;
y2: INTEGER ← topY;
IF x1 > x2 THEN {t: INTEGER ← x2; x2 ← x1; x1 ← t};
IF y1 > y2 THEN {t: INTEGER ← y2; y2 ← y1; y1 ← t};
Graphics.DrawBox[context, [x1-5, y1-5, x1, y2+5]]; -- left side
Graphics.DrawBox[context, [x2, y1-5, x2+5, y2+5]]; -- right side
Graphics.DrawBox[context, [x1, y1-5, x2, y1]]; -- top side
Graphics.DrawBox[context, [x1, y2, x2, y2+5]]; -- bottom side
END;
IF lastX=x AND lastY=y THEN RETURN; -- no change
IF lastX#LAST[INTEGER] THEN Show[lastX, lastY]; -- to remove the old box
IF remove THEN
lastX ← lastY ← LAST[INTEGER]
ELSE {
Show[x, y]; -- to show the new box
lastX ← x; lastY ← y;
};
END;
vaTIP: TIPUser.TIPTable ←
TIPUser.InstantiateNewTIPTable["BoundingBox.tip"];
END.