CtViewer.mesa
Copyright Ó 1990, 1992 by Xerox Corporation. All rights reserved.
Bloomenthal, December 2, 1992 8:51 pm PST
DIRECTORY CtBasic, CtMap, KeyTypes, Imager, ImagerSample, Rope, SF, ViewerClasses;
CtViewer: CEDAR DEFINITIONS
~ BEGIN
Types
IntegerPair:  TYPE ~ CtBasic.IntegerPair;
SampleMap:  TYPE ~ CtBasic.SampleMap;
SampleMaps:  TYPE ~ CtBasic.SampleMaps;
Cmap:    TYPE ~ CtMap.Cmap;
Context:   TYPE ~ Imager.Context;
Vec:    TYPE ~ ImagerSample.Vec;
ROPE:    TYPE ~ Rope.ROPE;
Box:    TYPE ~ SF.Box;
Viewer:   TYPE ~ ViewerClasses.Viewer;
Origin:   TYPE ~ {upperLeft, lowerLeft};
       viewer and sample map origins are usually at upper left;
       context origin are usually at lower left.
CtViewer operations do not use the viewer.data field.
Viewer Image Operations
currentViewer: Viewer;
Most recently accessed ColorTrix class viewer.
ViewerProc: TYPE ~ PROC [
viewer: Viewer,
maps: SampleMaps,
context: Context,
clientData: REF ANY ¬ NIL]
RETURNS [affectedRegion: Box ¬ ImagerSample.maxBox];
May be a nested procedure.
This proc called from within a PaintProc; do not call ViewerOps.PaintViewer.
Only one ViewerProc should be called for a viewer at a time (viewer locking not assured).
ViewerProc called immediately upon call to DoWithViewer or DoWithNamedViewer.
affectedRegion is in terms of maps' coordinates; the origin of maps is at the upper left.
DoWithViewer: PROC [viewer: Viewer, action: ViewerProc, clientData: REF ANY ¬ NIL];
Apply action to viewer; no op if viewer is iconic.
See cautions about ViewerProc, above.
DoWithNamedViewer: PROC [
name: ROPE ¬ "ColorTrix",
action: ViewerProc,
clientData: REF ANY ¬ NIL,
column: ViewerClasses.Column ¬ left,
openHeight: NAT ¬ 300,
paint, top, closeOthers: BOOL ¬ FALSE]
RETURNS [Viewer];
As DoWithViewer except viewer is found via the given name.
If the named viewer does not exist, it is created.
If not paint, the created viewer will be iconic.
If paint, the created viewer will be opened in the given column,
either at top or bottom, and possibly closing other viewers in the given column.
When opened, the viewer will attempt to be openHeight high.
See cautions about ViewerProc, above.
GetViewer: PROC [
name: ROPE,
column: ViewerClasses.Column ¬ left,
openHeight: NAT ¬ 300,
paint, top, closeOthers: BOOL ¬ FALSE]
RETURNS [Viewer];
Return the named viewer. If the named viewer does not exist, it is created.
If not paint, the created viewer will be iconic.
If paint, the created viewer will be opened in the given column,
either at top or bottom, and possibly closing other viewers in the given column.
When opened, the viewer will attempt to be openHeight high.
Debug: PROC [set: BOOL];
If set true, uncaught errors will not be caught during a CtProc.
Buffering
GetBuffer: PROC [viewer: Viewer] RETURNS [SampleMaps];
Return the backing sample map(s) for this viewer, possibly NIL.
PutBuffer: PROC [viewer: Viewer, maps: SampleMaps, affectedRegion: Box];
Buffer the union of the affectedRegion with previously affected region of maps.
This is automatically called within DoWithViewer.
GetSave: PROC [viewer: Viewer] RETURNS [SampleMaps];
Get the save buffer (that part of the backing sample map(s) most recently overwritten).
PutSave: PROC [viewer: Viewer, save: SampleMaps];
Set the save buffer.
Bounding Box
User interactions with a bounding box: upon initial mouse down, the origin of the bounding
box is fixed and the opposite corner follows the mouse. Subsequent mouse downs will change
the location of a corner, edge, or entire box, depending upon proximity to corner, edge, or
center of the box.
BoundingBoxProc: TYPE ~ PROC [box: Box, clientData: REF ANY ¬ NIL]
       RETURNS [continue: BOOL ¬ TRUE];
EnableBoundingBox: PROC [
viewer: Viewer,
action: BoundingBoxProc ¬ NIL,
clientData: REF ANY ¬ NIL];
Future mouse events in viewer control a bounding box; other client mouse procs suspended.
As a "saftety valve," this mode is disabled upon some fixed number of mouse ups.
If action is non-nil, it's called for each future mouse event; action must not be nested.
Do not expect this to work if called from within a MouseProc.
DisableBoundingBox: PROC [viewer: Viewer] RETURNS [Box];
Disable bounding box interaction for this viewer; return the bounding box.
This needn't be called to disable (EnableBoundingBox.action can return FALSE).
GetBoundingBox: PROC [
viewer: Viewer,
start: Vec,
context: Context ¬ NIL,
origin: Origin ¬ lowerLeft]
RETURNS [Box];
Given a starting point and current mouse state down, draw a bounding box until mouse up.
If context is NIL, one will be created via a call to PaintProc.
OrderBox: PROC [box: Box] RETURNS [Box];
Order box such that box.min.s < box.max.s and box.min.f < box.max.f.
XOR: PROC [context: Context, box: Box];
Produce a bounding, xor'd box (6 pixel width outline) on the context.
User Interaction
MouseButton: TYPE ~ {none, left, middle, right}; -- which mouse button
MouseState:  TYPE ~ {none, down, held, up};  -- state of pressed button
Mouse:   TYPE ~ RECORD [      -- mouse information
pos:      IntegerPair ¬ [],      -- screen coordinates
state:      MouseState ¬ none,    -- up, down or held
button:     MouseButton ¬ none,   -- left, middle or right
control:     BOOL ¬ FALSE,     -- if control key held
shift:      BOOL ¬ FALSE     -- if shift key held
];
MouseProc:  TYPE ~ PROC [
viewer:     Viewer,
mouse:     Mouse,
clientData:    REF ANY];
PollProc:   TYPE ~ PROC [pos: IntegerPair] RETURNS [continue: BOOL ¬ TRUE];
RegisterMouse: PROC [
viewer: Viewer,
mouse: MouseProc,
clientData: REF ANY ¬ NIL,
origin: Origin ¬ upperLeft];
Register the MouseProc with the user event notifier for viewer.
MouseProc must not be a nested procedure!
viewer is presumed to be a Ct class viewer.
clientData is passed to the mouseProc.
mouse.pos is relative to the given origin.
UnregisterMouse: PROC [viewer: Viewer, mouse: MouseProc];
Unregister the MouseProc.
GetMousePos: PROC [viewer: Viewer, origin: Origin ¬ upperLeft] RETURNS [IntegerPair];
Return the current mouse position with respect to the viewer coordinates.
x IN [0..viewer.ww]; y IN [0..viewer.wh].
return value is relative to the given origin.
KeyDown: PROC [key: KeyTypes.KeySym] RETURNS [BOOL];
Poll the given key (mouse or keyboard).
MouseAllUp: PROC RETURNS [BOOL];
Are the left, middle and right mouse buttons up?
MouseInViewer: PROC [viewer: Viewer] RETURNS [BOOL];
Return true if the mouse is presently in the given viewer.
ChangeOrigin: PROC [pos: IntegerPair, viewer: Viewer, old, new: Origin]
RETURNS [IntegerPair];
Convert the mouse position to be with respect to the new origin.
DoWhileMouseDown: PROC [viewer: Viewer, action: PollProc, origin: Origin ¬ upperLeft];
Repeatedly poll the mouse and perform action while the mouse is down in the viewer.
The standard notify mechanism for viewer is disabled during this call.
action is called with pos relative to the given origin.
Colormap
GetColormap: PUBLIC PROC [viewer: Viewer] RETURNS [Cmap];
Get the colormap associated with the viewer.
PutColormap: PUBLIC PROC [viewer: Viewer, cmap: Cmap];
Associate cmap with viewer; future mouse-downs in viewer will set the display to use cmap.
END.