ViewerAdjustImpl.mesa;
Edited by McGregor on January 6, 1983 2:21 pm
Last Edited by: Maxwell, January 3, 1983 1:08 pm
DIRECTORY
Convert USING [ValueToRope],
Cursors USING [AddCursorCorner, SetCursor],
Graphics USING [Context, DrawBox, SetPaintMode, SetStipple],
InputFocus USING [CaptureButtons, ReleaseButtons],
MessageWindow USING [Append, Clear],
Process USING [Detach],
Rope USING [Cat, ROPE],
TIPUser USING [InstantiateNewTIPTable, TIPScreenCoords, TIPTable],
ViewerAdjust,
ViewerClasses USING [NotifyProc, Viewer],
ViewerMenus,
ViewerOps,
ViewerSpecs,
WindowManager USING [RestoreCursor];
ViewerAdjustImpl: CEDAR MONITOR
IMPORTS Convert, Cursors, Graphics, InputFocus, MessageWindow, Process, Rope, TIPUser, ViewerOps, ViewerSpecs, WindowManager
EXPORTS ViewerAdjust
SHARES ViewerClasses, ViewerOps = BEGIN OPEN ViewerClasses;
viewerMinHeight: INTEGER ~ ViewerSpecs.captionHeight;
Adjust: PUBLIC ENTRY PROC [viewer: Viewer, sticky: BOOLTRUE] = BEGIN
grey: CARDINAL ~ 122645B;
InputFocus.CaptureButtons[BoundaryAdjustNotify, vaTIP, viewer];
context ← ViewerOps.AcquireContext[NIL];
[] ← Graphics.SetPaintMode[context, invert];
Graphics.SetStipple[context, grey];
[minY, maxY] ← ComputeYBounds[viewer];
xPos ← viewer.wx;
width ← viewer.ww;
stickyHeight ← sticky;
adjustBottom ← FALSE;
END;
AdjustMode: TYPE = {top, bottom, column, none} ;
stickyHeight, adjustBottom: BOOL;
mode: AdjustMode ← none;
lastX, lastY: INTEGERLAST[INTEGER];
context: Graphics.Context;
maxY, minY, xPos, width: INTEGER;
ComputeYBounds: PROC [viewer: Viewer] RETURNS [min, max: INTEGER] =
BEGIN OPEN ViewerSpecs;
LimitProc: ViewerOps.EnumProc = BEGIN
IF v.column=viewer.column AND NOT v.iconic THEN columnRequested ← columnRequested +
MAX[viewerMinHeight, (IF v.position#0 THEN v.position ELSE v.openHeight)];
END;
columnRequested: INTEGER ← 0;
columnFree, percent: INTEGER;
columnSpace: INTEGER ~ openLeftTopY-openBottomY;
ViewerOps.EnumerateViewers[LimitProc];
percent ← 10*((11*columnRequested-1)/columnSpace); -- round up
SetMsg[Rope.Cat["The ",
SELECT viewer.column FROM left => "left", right => "right", ENDCASE => "color",
" column is constrained ", Convert.ValueToRope[[signed[percent, 10]]], "%"]];
columnFree ← MAX[0, columnSpace - columnRequested -
(viewer.wh-(IF viewer.position#0 THEN viewer.position ELSE viewer.openHeight))];
min ← MAX[MIN[viewer.wy, viewer.wy-columnFree], openBottomY];
max ← MIN[MAX[viewer.wy+viewer.wh, viewer.wy+viewer.wh+columnFree], openLeftTopY];
END;
BoundaryAdjustNotify: NotifyProc = BEGIN
ENABLE UNWIND => {InputFocus.ReleaseButtons[]; ViewerOps.ReleaseContext[context]};
mouseX, mouseY: INTEGER;
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
ChangeMode[none, 0, 0];
InputFocus.ReleaseButtons[];
ViewerOps.ReleaseContext[context];
IF self.position=0 THEN ViewerOps.PaintViewer[self, caption]
ELSE BEGIN
self.position ← 0;
IF stickyHeight THEN self.openHeight ← self.position;
ViewerOps.ComputeColumn[self.column];
END;
END;
$Move => BEGIN
SELECT mode FROM
top  => IF mouseX NOT IN [self.wx..self.wx+self.ww) THEN
ChangeMode[column, mouseX, mouseY]
ELSE IF mouseY <= self.wy THEN
ChangeMode[bottom, mouseX, mouseY]
ELSE Feedback[mouseX, mouseY];
bottom => IF mouseX NOT IN [self.wx..self.wx+self.ww) THEN
ChangeMode[column, mouseX, mouseY]
ELSE IF mouseY >= self.wy+self.wh THEN
ChangeMode[top, mouseX, mouseY]
ELSE Feedback[mouseX, mouseY];
column => Feedback[mouseX, mouseY];
ENDCASE => BEGIN
ViewerOps.PaintViewer[self, caption];
ChangeMode[top, mouseX, mouseY];
END;
END;
$End  => BEGIN
change: AdjustMode ← mode;
ChangeMode[none, 0, 0];
InputFocus.ReleaseButtons[];
ViewerOps.ReleaseContext[context];
SELECT change FROM
top  => BEGIN
self.position ← MAX[viewerMinHeight, mouseY-self.wy];
IF stickyHeight THEN self.openHeight ← self.position;
ViewerOps.ComputeColumn[self.column];
END;
bottom => BEGIN
self.position ← MAX[viewerMinHeight, self.wy+self.wh-mouseY];
IF stickyHeight THEN self.openHeight ← self.position;
ViewerOps.ComputeColumn[self.column];
END;
column => ViewerOps.MoveBoundary[mouseX, mouseY];
ENDCASE;
END;
ENDCASE => NULL;
z: TIPUser.TIPScreenCoords => [mouseX, mouseY] ← Clip[z];
ENDCASE => ERROR;
ENDLOOP;
END;
ChangeMode: PROC [newMode: AdjustMode, mouseX, mouseY: INTEGER] = BEGIN
Feedback[LAST[INTEGER], LAST[INTEGER], TRUE];
SELECT newMode FROM
top  => {Cursors.SetCursor[pointUp]; Cursors.AddCursorCorner[upperSide]};
bottom => {Cursors.SetCursor[pointDown]; Cursors.AddCursorCorner[lowerSide]};
column => {Cursors.SetCursor[activate]; SetMsg[]};
ENDCASE => {WindowManager.RestoreCursor[]; SetMsg[]};
mode ← newMode;
IF mode#none THEN Feedback[mouseX, mouseY];
END;
SetMsg: PROC [msg: Rope.ROPENIL] = TRUSTED INLINE BEGIN
these are forked in case a client has done DisablePainting during an Adjust
IF msg=NIL THEN Process.Detach[FORK MessageWindow.Clear[]]
ELSE Process.Detach[FORK MessageWindow.Append[msg, TRUE]];
END;
Feedback: PROC [x, y: INTEGER, remove: BOOLFALSE] = BEGIN
Show: PROC [x, y: INTEGER] = BEGIN
IF mode=column THEN BEGIN
Graphics.DrawBox[context, [x-1, y, x+1, ViewerSpecs.openLeftTopY]];
Graphics.DrawBox[context, [0, y-1, ViewerSpecs.screenW, y+1]];
END
ELSE Graphics.DrawBox[context, [xPos, y+1, xPos+width, y-1]];
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 ← position.mouseX;
IF mode=column THEN BEGIN
IF position.mouseY <= openBottomY THEN adjustBottom ← TRUE;
IF adjustBottom THEN y ← SELECT position.mouseY FROM
< iconHeight => position.mouseY,
< iconHeight+iconSpacing+(iconHeight/2) => iconHeight+iconSpacing,
ENDCASE  => 2*(iconHeight+iconSpacing)
ELSE y ← openBottomY;
END
ELSE y ← SELECT position.mouseY FROM
< minY => minY,
> maxY => maxY,
ENDCASE => position.mouseY
END;
vaTIP: TIPUser.TIPTable ←
TIPUser.InstantiateNewTIPTable["/Indigo/CedarViewers/Viewers/ViewerAdjust.tip"];
END.