DIRECTORY Cursors USING [AddCursorCorner, SetCursor], Imager USING [Context, MaskBits, SetColor], InputFocus USING [CaptureButtons, ReleaseButtons], MessageWindow USING [Append, Clear], Process USING [Detach], Rope USING [ROPE], TIPUser USING [InstantiateNewTIPTable, TIPScreenCoords, TIPTable], ViewerAdjust, ViewerClasses USING [NotifyProc, Viewer], ViewerLocks, ViewerMenus, ViewerOps, ViewerSpecs, WindowManager USING [RestoreCursor]; ViewerAdjustImpl: CEDAR MONITOR IMPORTS Cursors, Imager, InputFocus, MessageWindow, Process, TIPUser, ViewerLocks, ViewerOps, ViewerSpecs, WindowManager EXPORTS ViewerAdjust SHARES ViewerClasses, ViewerLocks, ViewerOps = BEGIN OPEN ViewerClasses; viewerMinHeight: INTEGER ~ ViewerSpecs.captionHeight; AdjustMode: TYPE = {top, bottom, column, none} ; mode: AdjustMode _ none; context: Imager.Context; stickyHeight, adjustBottom: BOOL; xPos, width, minY, maxY: INTEGER; lastX, lastY: INTEGER _ LAST[INTEGER]; Adjust: PUBLIC ENTRY PROC [viewer: Viewer, sticky: BOOL _ TRUE] = BEGIN ViewerLocks.LockViewerTree[]; InputFocus.CaptureButtons[BoundaryAdjustNotify, vaTIP, viewer]; context _ ViewerOps.AcquireContext[NIL]; Imager.SetColor[context, $XOR]; minY _ ViewerSpecs.openBottomY; maxY _ ViewerSpecs.openLeftTopY; xPos _ viewer.wx; width _ viewer.ww; stickyHeight _ sticky; adjustBottom _ FALSE; END; EndAdjust: PROC = BEGIN ChangeMode[none, 0, 0]; InputFocus.ReleaseButtons[]; ViewerOps.ReleaseContext[context]; ViewerLocks.ReleaseViewerTree[]; END; BoundaryAdjustNotify: NotifyProc = BEGIN ENABLE UNWIND => EndAdjust[]; 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 EndAdjust[]; IF self.openHeight = 0 THEN ViewerOps.PaintViewer[self, caption] ELSE {self.openHeight _ 0; ViewerOps.ComputeColumn[self.column]}; END; $Move => BEGIN SELECT mode FROM -- RFP CHANED [self.wx to (self.wx here 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; EndAdjust[]; SELECT change FROM top => BEGIN self.openHeight _ MAX[viewerMinHeight, mouseY-self.wy]; ViewerOps.ComputeColumn[self.column]; END; bottom => BEGIN self.openHeight _ MAX[viewerMinHeight, self.wy+self.wh-mouseY]; 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.ROPE _ NIL] = TRUSTED INLINE BEGIN IF msg=NIL THEN Process.Detach[FORK MessageWindow.Clear[]] ELSE Process.Detach[FORK MessageWindow.Append[msg, TRUE]]; END; grey: CARDINAL _ 122645B; Feedback: PROC [x, y: INTEGER, remove: BOOL _ FALSE] = BEGIN GreyRectangle: PROC [x, y, w, h: INTEGER] = TRUSTED INLINE BEGIN Imager.MaskBits[context, @grey, 1, [0,0,16,1], [x,y,w,h]]; END; Show: PROC [x, y: INTEGER] = BEGIN IF mode=column THEN BEGIN GreyRectangle[x-1, y, 2, ViewerSpecs.openLeftTopY-y+1]; GreyRectangle[0, y-1, ViewerSpecs.screenW, 2]; END ELSE GreyRectangle[xPos, y+1, width, 2]; 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; fudge : INTEGER = 15; -- RFP addition, used to "snap" to default column boundary IF ABS[position.mouseX-(screenW/2)] < fudge THEN x _ (screenW/2) ELSE IF ABS[position.mouseX-initialOpenLeftWidth] < fudge THEN x _ initialOpenLeftWidth ELSE 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. 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; ViewerAdjustImpl.mesa; written by S. McGregor Edited by McGregor on August 4, 1983 1:27 pm Last Edited by: Maxwell, May 20, 1983 9:58 am Last Edited by: Pausch, June 21, 1983 3:20 pm [minY, maxY] _ ComputeYBounds[viewer]; 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; self.position _ MAX[viewerMinHeight, mouseY-self.wy]; IF stickyHeight THEN self.openHeight _ self.position; self.position _ MAX[viewerMinHeight, self.wy+self.wh-mouseY]; IF stickyHeight THEN self.openHeight _ self.position; these are forked in case a client has done DisablePainting during an Adjust -- RFP addition: "snap" to the default setting for the two columns, and center Κρ– "cedar" style˜JšΟc-™-Jš,™,Jšœ-™-Jš-™-J˜šΟk ˜ Jšœžœ˜+Jšœžœ˜+Jšœ žœ"˜2Jšœžœ˜$Jšœžœ ˜Jšœžœžœ˜Jšœžœ5˜BJ˜ Jšœžœ˜)J˜ J˜ J˜ J˜ Jšœžœ˜$J˜—Jšœž ˜J˜Jšžœq˜xJšžœ ˜Jšžœ)žœžœ˜HJ˜Jšœžœ˜5J˜Jšœ žœ ˜0J˜J˜J˜Jšœžœ˜!Jšœžœ˜!Jšœžœžœžœ˜&J˜š Οnœžœž œžœžœž˜GJšœ˜J˜?Jšœ#žœ˜(Jšœ˜Jšœ&™&Jšœ˜Jšœ ˜ J˜J˜Jšœ˜Jšœžœ˜Jšžœ˜J˜—šŸ œžœž˜J˜J˜J˜"J˜ Jšžœ˜—J˜šΟbœž˜(Jšžœžœ˜Jšœžœ˜šžœžœžœžœžœžœžœž˜@šžœ žœž˜šœžœžœž˜šœ ž˜Jšžœžœ%™<šžœž™ Jšœ™Jšžœžœ!™5Jšœ%™%Jšžœ™—J˜ šžœ˜Jšžœ%˜)Jšžœ=˜A—Jšžœ˜—šœ ž˜šžœžœ)˜;šœžœžœžœž˜8J˜"šžœžœžœ˜Jšœ"˜"—Jšžœ˜—šœ žœžœžœž˜:J˜"šžœžœžœ˜'Jšœ˜—Jšžœ˜—J˜#šžœž˜J˜%J˜ Jšžœ˜——Jšžœ˜—šœ ž˜J˜J˜ šžœž˜šœž˜ Jšœžœ"™5Jšžœžœ!™5Jšœžœ"˜7J˜%Jšžœ˜—šœ ž˜Jšœžœ*™=Jšžœžœ!™5Jšœžœ*˜?Jšœ%˜%Jšžœ˜—J˜1Jšžœ˜—Jšžœ˜—Jšžœžœ˜—J˜9Jšžœžœ˜—Jšžœ˜—Jšžœ˜J˜—šŸ œžœ'žœž˜GJš œ žœžœžœžœžœ˜-šžœ ž˜J˜IJ˜MJ˜2Jšžœ.˜5—J˜Jšžœ žœ˜+Jšžœ˜J˜—š Ÿœžœ žœžœžœž˜:JšK™Kšžœžœžœžœ˜:Jšžœžœžœ˜:—Jšžœ˜J˜—Jšœžœ ˜J˜š Ÿœžœžœ žœžœž˜<š Ÿ œžœžœžœžœž˜@Jšœ:˜:Jšžœ˜—šŸœžœžœž˜"šžœ žœž˜Jšœ7˜7Jšœ.˜.Jšž˜—Jšžœ$˜(Jšžœ˜—Jš žœ žœ žœžœ ˜0Jšžœžœžœžœ˜/Jšžœžœžœžœ˜,Jšžœ$˜(Jšžœ˜J˜—š Ÿœžœ%žœžœž˜NJšžœ ˜Jšœžœ:˜PJšœO™OJšžœžœ&žœ=˜mJšžœžœ/žœ˜XJšœ9žœ˜RJ˜šžœ žœž˜Jšžœ žœžœ˜;šžœžœžœž˜4J˜ J˜BJšžœ˜&—Jšžœ˜Jšž˜—šžœžœž˜$J˜J˜Jšžœ˜—Jšžœ˜J˜—˜J˜PJ˜—Jšžœ˜J˜šŸœžœžœ žœ˜CJšžœžœ ˜šœ ž˜%šžœžœžœ žœ$˜SJšžœžœžœ žœ˜J—Jšžœ˜—Jšœžœ˜Jšœžœ˜Jšœ žœ˜0J˜&Jšœ3 ˜>˜Jšžœžœ#žœ ˜OJ˜M—šœ žœ#˜3Jšœ žœžœžœ˜P—Jšœžœžœ0˜=JšœžœžœE˜RJšžœ˜J˜—J˜—…—#)