DIRECTORY Cursors, Geom2D, Icons, Imager, ImagerTransformation, Menus, Rope, TIPUser, Vector2, ViewerClasses; BiScrollers: CEDAR DEFINITIONS = BEGIN LORA: TYPE = LIST OF REF ANY; ROPE: TYPE = Rope.ROPE; Viewer: TYPE = ViewerClasses.Viewer; Vec: TYPE = Vector2.VEC; VecList: TYPE = Geom2D.VecList; Transform: TYPE = ImagerTransformation.Transformation; Rect: TYPE = Geom2D.Rect; BiScroller: TYPE = REF BiScrollerRep; BiScrollerRep: TYPE = RECORD [ style: BiScrollerStyle, class: BiScrollerClass, rep: REF ANY ]; BiScrollerClass: TYPE = REF BiScrollerClassRep; BiScrollerClassRep: TYPE = RECORD [ style: BiScrollerStyle, common: ClassCommon, rep: REF ANY ]; ClassCommon: TYPE = RECORD [ flavor: ATOM, extrema: ExtremaProc, notify: ViewerClasses.NotifyProc ¬ NIL, bsUserAction: BSUserActionProc ¬ NIL, paint: ViewerClasses.PaintProc ¬ NIL, modify: ViewerClasses.ModifyProc ¬ NIL, destroy: ViewerClasses.DestroyProc ¬ NIL, copy: ViewerClasses.CopyProc ¬ NIL, set: ViewerClasses.SetProc ¬ NIL, get: ViewerClasses.GetProc ¬ NIL, init: ViewerClasses.InitProc ¬ NIL, finish: LORA ¬ NIL, save: ViewerClasses.SaveProc ¬ NIL, caption: ViewerClasses.CaptionProc ¬ NIL, adjust: ViewerClasses.AdjustProc ¬ NIL, menu: Menus.Menu ¬ NIL, tipTable: TIPUser.TIPTable ¬ NIL, icon: Icons.IconFlavor ¬ document, cursor: Cursors.CursorType ¬ textPointer, mayStretch: BOOLEAN ¬ TRUE, offsetsMustBeIntegers, preferIntegerCoefficients: BOOL ¬ FALSE, vanilla: TransformGenerator ¬ NIL --means GenID--, preserve: PreservationPair ¬ [0.5, 0.5] ]; ExtremaProc: TYPE = PROC [clientData: REF ANY, direction: Vec] RETURNS [min, max: Vec]; ClientCoords: TYPE = REF Vec; BSUserActionProc: TYPE = PROC [bs: BiScroller, input: LORA, device, user, display: REF ANY ¬ NIL]; DoBSUserAction: BSUserActionProc; TransformGenerator: TYPE = PROC [BiScroller] RETURNS [Transform]; GenID: TransformGenerator --={RETURN [Geom2D.id]}--; PreservationPair: TYPE = ARRAY Axis OF Preservation; Axis: TYPE = Geom2D.Axis; Preservation: TYPE = REAL--[0.0 .. 1.0]--; TransformsAge: TYPE = {current, previous}; AgeOp: TYPE = {remember, ignore}; BiScrollerStyle: TYPE = REF BiScrollerStyleRep; BiScrollerStyleRep: TYPE = RECORD [ NewBiScrollerClass: PROC [ClassCommon] RETURNS [BiScrollerClass], CreateBiScroller: PROC [class: BiScrollerClass, info: ViewerClasses.ViewerRec ¬ [], paint: BOOLEAN ¬ TRUE] RETURNS [new: BiScroller], Destroy: PROC [BiScroller] RETURNS [BiScroller --NIL, in fact--], GetTransforms: PROC [bs: BiScroller, age: TransformsAge ¬ current] RETURNS [clientToViewer, viewerToClient: Transform], ChangeTransform: PROC [bs: BiScroller, new: Transform, ageOp: AgeOp, paint: BOOL ¬ TRUE], AddChild: PROC [to: BiScroller, what: Viewer, x, y: REAL ¬ 0, useTheseCoords: BOOLEAN ¬ FALSE, paint: BOOLEAN ¬ TRUE], DeleteChild: PROC [of: BiScroller, who: Viewer], SetButtonsCapturedness: PROC [bs: BiScroller, captured: BOOL], ViewportOf: PROC [bs: BiScroller] RETURNS [VecList], QuaViewer: PROC [bs: BiScroller, inner: BOOL ¬ FALSE] RETURNS [Viewer], ClientDataOf: PROC [BiScroller] RETURNS [REF ANY] ]; GetStyle: PROC [name: ROPE ¬ NIL] RETURNS [style: BiScrollerStyle]; RegisterStyle: PROC [name: ROPE, style: BiScrollerStyle]; SetDefaultStyle: PROC [name: ROPE] RETURNS [old: ROPE]; IsBiScroller: PROC [REF ANY] RETURNS [BOOLEAN]; NarrowToBiScroller: PROC [REF ANY] RETURNS [BiScroller]; QuaViewer: PROC [bs: BiScroller, inner: BOOL ¬ FALSE] RETURNS [Viewer]; QuaBiScroller: PROC [Viewer] RETURNS [BiScroller]; ViewerIsABiScroller: PROC [Viewer] RETURNS [BOOLEAN]; ClientDataOf: PROC [BiScroller] RETURNS [REF ANY]; ClientDataOfViewer: PROC [Viewer] RETURNS [REF ANY]; ViewportExtrema: PROC [bs: BiScroller, direction: Vec] RETURNS [min, max: Vec]; ViewportBox: PROC [bs: BiScroller] RETURNS [Rect]; ViewLimitsOfImage: PROC [bs: BiScroller, axis: Axis] RETURNS [vmin, vmax: REAL]; Scale: PROC [bs: BiScroller, op: ScaleOp, paint: BOOL ¬ TRUE]; ScaleOp: TYPE = RECORD [variant: SELECT op: * FROM reset => [], byArg => [arg: REAL], diff => [x, y: REAL], ENDCASE]; Rotate: PROC [bs: BiScroller, op: RotateOp, paint: BOOL ¬ TRUE]; RotateOp: TYPE = RECORD [variant: SELECT op: * FROM reset => [], byArg => [arg: REAL--degrees--], ENDCASE]; Shift: PROC [bs: BiScroller, dx, dy: REAL, paint: BOOL ¬ TRUE]; Align: PROC [bs: BiScroller, client, viewer: Location, doX, doY, paint: BOOL ¬ TRUE, ageOp: AgeOp ¬ remember]; Location: TYPE = RECORD [variant: SELECT flavor: * FROM coord => [x, y: REAL --in the appropriate coord sys--], fraction => [fx, fy: REAL --fraction of X and Y extent, in viewer coords, of either client image or viewport--], ENDCASE]; BoxScale: PROC [bs: BiScroller, from, to: Rect --both in viewer coords--, paint, uniformly: BOOL ¬ TRUE]; bsMenu: Menus.Menu; CatenateMenus: PROC [pre, post: Menus.Menu] RETURNS [menu: Menus.Menu]; CreateScale, CreateRotate, CreateFit, CreateReset, CreateEdge, CreatePrev: PROC [viewerInfo: ViewerClasses.ViewerRec, bs: BiScroller, font: Imager.Font ¬ NIL] RETURNS [button: Viewer]; SetViewerPosition: PROC [v: Viewer, x, y, w, h: INTEGER]; SetBS: PROC [v: Viewer, bs: BiScroller]; END.  BiScrollers.Mesa Copyright Σ 1992 by Xerox Corporation. All rights reserved. Mike Spreitzer January 23, 1987 2:48:37 pm PST Last tweaked by Mike Spreitzer on March 20, 1992 7:32 am PST A subClass of Viewers for two-dimensional scrolling Passed to Notify when mouse leaves an Activated BiScroller OK to scale X and Y differently? What stays put when viewer grows/shrinks. What appears in NotifyProc's input for mouse coordinates instead of TIPUser.TIPScreenCoords. All the user input to a BiScroller goes thru one of two procs in the class: notify or bsUserAction. Input to the client goes through notify; input concerning the BiScroller goes through bsUserAction. horizontally (axis X), 0.0 is left and 1.0 is right; vertically (axis Y), 0.0 is bottom and 1.0 is top. Change scale and offsets so that client data previously in `from' covers as much as possible of `to'. A tool built using a BiScroller may provide either a menu of operations, or a set of buttons. Remember: Viewers requires you to always copy this menu, never use it directly. CatenateMenus includes copying. Here are procedures to create the standard buttons: For implementors of styles: Κ–(cedarcode) style•NewlineDelimiter ™code™Kšœ Οeœ1™K˜Kš‘ œžœžœ ˜4K˜Kš ‘ œžœžœžœžœ ˜GKš ‘ œžœžœžœžœ˜1K˜—K˜Kš ‘œžœžœžœžœ˜CKš‘ œžœžœ˜9Kš ‘œžœžœžœžœ˜7K˜Kš ‘ œžœžœžœžœžœ˜/Kš ‘œžœžœžœžœ˜8Kš ‘ œžœžœžœžœ ˜GKš‘ œžœ žœ˜2Kš‘œžœ žœžœ˜5Kš ‘ œžœžœžœžœ˜2Kš ‘œžœ žœžœžœ˜4K˜Kš‘œžœ"žœ˜OKš‘ œžœžœ˜2Kš‘œžœžœžœ˜PK˜š‘œžœ&žœžœ˜>šœ žœžœ žœž˜2Kšœ ˜ Kšœžœ˜Kšœžœ˜Kšžœ˜ ——K˜š‘œžœ'žœžœ˜@šœ žœžœ žœž˜3Kšœ ˜ Kšœž  œ˜ Kšžœ˜ ——K˜Kš ‘œžœžœ žœžœ˜?K˜š‘œžœ=žœžœ˜nšœ žœžœ žœ ž˜7Kšœžœ  œ˜7Kšœžœ Tœ˜pKšžœ˜ ——K˜š ‘œžœ! œžœžœ˜iK™e—K˜K™]K˜˜Kšœp™p—K˜Kš‘ œžœžœ˜GK˜™3Kš‘ œ‘ œ‘ œ‘ œ‘ œ‘ œžœKžœžœ˜Έ—K˜™K˜Kš‘œžœžœ˜9K˜Kš‘œžœ˜(—K˜Kšžœ˜K˜—…— !