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: INTEGER ← LAST[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:
BOOL ←
FALSE] =
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.