BiScrollers.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
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: LORANIL,
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: BOOLEANTRUE,
OK to scale X and Y differently?
offsetsMustBeIntegers, preferIntegerCoefficients: BOOLFALSE,
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];
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: BOOLEANTRUE] 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: BOOLTRUE],
AddChild: PROC [to: BiScroller, what: Viewer, x, y: REAL ← 0, useTheseCoords: BOOLEANFALSE, paint: BOOLEANTRUE],
DeleteChild: PROC [of: BiScroller, who: Viewer],
SetButtonsCapturedness: PROC [bs: BiScroller, captured: BOOL],
ViewportOf: PROC [bs: BiScroller] RETURNS [VecList],
QuaViewer: PROC [bs: BiScroller, inner: BOOLFALSE] RETURNS [Viewer],
ClientDataOf: PROC [BiScroller] RETURNS [REF ANY]
];
GetStyle: PROC [name: ROPENIL] 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: BOOLFALSE] 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: BOOLTRUE];
ScaleOp: TYPE = RECORD [variant: SELECT op: * FROM
reset => [],
byArg => [arg: REAL],
diff => [x, y: REAL],
ENDCASE];
Rotate: PROC [bs: BiScroller, op: RotateOp, paint: BOOLTRUE];
RotateOp: TYPE = RECORD [variant: SELECT op: * FROM
reset => [],
byArg => [arg: REAL--degrees--],
ENDCASE];
Shift: PROC [bs: BiScroller, dx, dy: REAL, paint: BOOLTRUE];
Align: PROC [bs: BiScroller, client, viewer: Location, doX, doY, paint: BOOLTRUE, 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: BOOLTRUE];
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.