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]; 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. VBiScrollers.Mesa Mike Spreitzer January 23, 1987 2:48:37 pm PST Last tweaked by Mike Spreitzer on November 4, 1987 3:10:25 pm 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: ΚN˜code™K™.K™A—K™K™3K˜šΟk œd˜mK˜—KšΠbx œœ œ˜ K˜Kš˜K˜Kš œœœœœœ˜Kšœœœ˜Kšœœ˜$Kšœœ œ˜Kšœ œ˜Kšœ œ'˜6Kšœœ˜K˜Kšœ œœ˜%šœœœ˜Kšœ˜Kšœ˜Kšœœ˜ K˜—K˜Kšœœœ˜/šœœœ˜#Kšœ˜K˜Kšœœ˜ Kšœ˜—K˜šœ œœ˜Kšœœ˜ K˜Kšœ#œ˜'Kšœ!œ˜%Kšœ!œ˜%Kšœ#œ˜'Kšœ%œ˜)Kšœœ˜#Kšœœ˜!Kšœœ˜!Kšœœ˜#šœœœ˜J™:—Kšœœ˜#Kšœ%œ˜)Kšœ#œ˜'Kšœœ˜Kšœœ˜!K˜"K˜)šœ œœ˜Jšœ ™ —Kšœ2œœ˜?KšœœΟcœ˜2˜'K™)—K˜—K˜Kš Οn œœœœœœ˜WK˜šœœœ˜Kšœ\™\—K˜Kšœœœœ˜<š œ˜!Kš œLΟeœ‘ œ$‘œ/‘ œ™Θ—K˜Kš œœœœ ˜AKšœŸœ˜4K˜Kšœœœœ˜4Kšœœ˜šœœŸœ˜*K™4K™2—K˜Kšœœ˜*Kšœœ˜!K˜Kšœœœ˜/šœœœ˜#Kš œœ œ˜AKš  œœEœœœ˜…Kš œœœ Ÿœ˜AK˜Kš  œœ0œ-˜wKš œœ7œœ˜YK˜Kš œœ&œœœ œœ˜vKš  œœ˜0Kš œœœ˜>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˜—…—ή‚