DIRECTORY IO, ViewerClasses; MouseTrap: CEDAR DEFINITIONS ~ BEGIN TrapTillMouseUp: PROC [v: Viewer, circle, wrapAround: BOOL]; Viewer: TYPE ~ ViewerClasses.Viewer; Position: TYPE ~ RECORD [x, y: INTEGER]; MouseTrapSpecs: TYPE ~ RECORD [ enabled: BOOL ¬ FALSE, -- TRUE if trapping desired proc: MouseTrapProc ¬ NIL, -- proc to call with mouse coords data: REF ANY ¬ NIL -- data to pass to proc ]; MouseTrapProc: TYPE ~ PROC [mouse: Position, data: REF ANY] RETURNS [changed: BOOL ¬ FALSE, mouseTo: Position]; BoxTrapData: TYPE ~ REF BoxTrapDataRep; BoxTrapDataRep: TYPE ~ RECORD [ wrap: {no, x, yes, y} ¬ no, -- wrap mouse at edges, else stick minCorner: Position ¬ [370, 270], -- smallest coordinates in box trap maxCorner: Position ¬ [430, 330] -- largest coordinates in box trap ]; RoundTrapData: TYPE ~ REF RoundTrapDataRep; RoundTrapDataRep: TYPE ~ RECORD [ wrap: {no, yes} ¬ no, -- wrap mouse at edge, else stick center: Position ¬ [400, 300], -- center of circular trap radiusSquared: REAL ¬ 900 -- square of radius of circular trap ]; UserToMouseCoords: PROC [self: Viewer, vx, vy: INTEGER ¬ 0] RETURNS [Position]; UserFromMouseCoords: PROC [self: Viewer, mx, my: INTEGER ¬ 0] RETURNS [Position]; SetTrap: PROC [newSpecs: MouseTrapSpecs] RETURNS [MouseTrapSpecs]; GetTrap: PROC RETURNS [MouseTrapSpecs]; UnsetTrap: PROC RETURNS [MouseTrapSpecs]; StartWatchingMouseTrap: PROC; StopWatchingMouseTrap: PROC; Debug: PROC [out: IO.STREAM]; MouseUpEscape: PROC RETURNS [BOOL]; BoxTrap: MouseTrapProc; RoundTrap: MouseTrapProc; END. B MouseTrap.mesa Copyright Σ 1989, 1992 by Xerox Corporation. All rights reserved. Ken Shoemake, May 16, 1989 3:10:38 am PDT Jules Bloomenthal July 20, 1992 4:33 pm PDT This interface defines procedures for trapping the mouse, that is, adjusting its position (and that of the cursor) depending on its location. Simple Client Access Trap mouse in the given viewer; if circle, trap area is largest circle fitting in viewer. Type Declarations Sets changed to TRUE and returns new coords if mouse needs to be moved to stay in trap. Coords are hardware coords, so upper left of screen is [0, 0]. Wizard Control Procs The following is a typical application to keep the mouse inside a viewer while dragging: orgx, orgy, oppx, oppy: INTEGER; data: MouseTrap.BoxTrapData; [orgx, orgy] _ MouseTrap.UserToMouseCoords[self, 0, 0]; [oppx, oppy] _ MouseTrap.UserToMouseCoords[self, self.cw-1, self.ch-1]; IF oppx < orgx THEN {swap: INTEGER _ oppx; oppx _ orgx; orgx _ swap}; IF oppy < orgy THEN {swap: INTEGER _ oppy; oppy _ orgy; orgy _ swap}; data _ NEW[MouseTrap.BoxTrapDataRep _ [no, [orgx, orgy], [oppx, oppy]]]; [] _ MouseTrap.SetTrap[[enabled: TRUE, proc: MouseTrap.BoxTrap, data: data]]; To stop trapping, typically upon a mouse up, simply: [] _ MouseTrap.UnsetTrap[]; An appropriate place for these calls is in the TIP NotifyProc. You may consider claiming a viewer lock so the column can't be rearranged out from under your trap by some independent process opening or closing a viewer. So that a mouse up is certain to be noticed, you may wish to call InputFocus.CaptureButtons, though that probably isn't necessary. Traps (such as BoxTrap and RoundTrap) that use MouseUpEscape will probably catch all mouse ups. By supplying a custom trapping procedure the mouse may be confined to a fancier region than a rectangle or circle. Keep in mind that whatever you do should be done quickly! Convert coordinates in viewer to hardware mouse coordinates (upper left is [0, 0]). Convert hardware mouse coordinates (upper left is [0, 0]) to coordinates for viewer. Note that mouse may be outside this viewer. Not recommended for use within MouseTrapProc, where it's better to use only mouse coords to avoid overhead. Establish new mouse trap, not necessarily enabled. Returns old trap specifications. Get the specifications of the current mouse trap. Disable current mouse trap, without changing it otherwise. Returns old trap specifications. This is ordinarily called just once, when the Impl is run, to start background process. Kill the background process, after which no mice will be trapped. Turn off debugging with out = NIL. Internal Procs Unsets trap and returns TRUE if all mouse buttons are up. Together with BoxTrapData will keep mouse in rectangular box. Uses MouseUpEscape. Together with RoundTrapData will keep mouse in circle. Uses MouseUpEscape. Κ–"cedarcode" style•NewlineDelimiter ™šœ™Jšœ Οeœ7™BJ™)J™+J˜—šΟk œžœ˜J˜—šΡbln œžœž ˜J˜—šœž˜Jšœ™—headšΟl™šΟnœžœ!žœ˜™>J˜——Jšœžœžœ˜)šœžœžœ˜ Jšœ"’"˜DJšœ&’#˜IJšœ%’"˜Gšœ˜J˜——Jšœžœžœ˜,šœžœžœ˜!Jšœ’!˜?Jšœ$’˜>Jšœžœ ’%˜DJšœ˜——š ™Jšœržœ£žœ žœΟsœ%žœ žœ€œ,žœažœ(™ΑJ™QJšœΐ™ΐ™­J™—š‘œžœžœžœ ˜O™SJ™——š‘œžœžœžœ ˜QJ™TJ™K™LJ™——š‘œžœžœ˜B™TJ™——š‘œžœžœ˜'™1J™——š‘ œžœžœ˜)™\J™——š‘œžœ˜™WJ™——š‘œžœ˜J™AJ™—š‘œžœžœžœ˜Jšœ€œ™"——š ™š‘ œžœžœžœ˜#šœžœ™9J™——š‘œ˜šœR™RJ™——š‘ œ˜JšœK™K—J˜—Jšžœ˜—…—F