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
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,
Passed to Notify when mouse leaves an Activated BiScroller
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,
OK to scale X and Y differently?
offsetsMustBeIntegers, preferIntegerCoefficients: BOOL ¬ FALSE,
vanilla: TransformGenerator ¬ NIL --means GenID--,
preserve: PreservationPair ¬ [0.5, 0.5]
What stays put when viewer grows/shrinks.
];
ExtremaProc: TYPE = PROC [clientData: REF ANY, direction: Vec] RETURNS [min, max: Vec];
ClientCoords: TYPE = REF Vec;
What appears in NotifyProc's input for mouse coordinates instead of TIPUser.TIPScreenCoords.
BSUserActionProc: TYPE = PROC [bs: BiScroller, input: LORA, device, user, display: REF ANY ¬ NIL];
DoBSUserAction: BSUserActionProc;
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.
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]--;
horizontally (axis X), 0.0 is left and 1.0 is right;
vertically (axis Y), 0.0 is bottom and 1.0 is top.
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];
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.
bsMenu: Menus.Menu;
Remember: Viewers requires you to always copy this menu, never use it directly. CatenateMenus includes copying.
CatenateMenus: PROC [pre, post: Menus.Menu] RETURNS [menu: Menus.Menu];
Here are procedures to create the standard buttons:
CreateScale, CreateRotate, CreateFit, CreateReset, CreateEdge, CreatePrev: PROC [viewerInfo: ViewerClasses.ViewerRec, bs: BiScroller, font: Imager.Font ¬ NIL] RETURNS [button: Viewer];
For implementors of styles:
SetViewerPosition: PROC [v: Viewer, x, y, w, h: INTEGER];
SetBS: PROC [v: Viewer, bs: BiScroller];
END.