DEFINITION Effects; (* portable *) (* jm 18.1.95 *)

(*Implements special effects and encapsulates a few platform dependent features.
*)
 IMPORT Display3, Oberon;

 TYPE
  Callback = PROCEDURE (MX, MY, X, Y, W, H: INTEGER; keysum: SET);

 VAR 
  FlatHand: Oberon.Marker;  (* Marker used to indicate a dragging/moving operation.
*)
  PointHand: Oberon.Marker;  (* Marker used to indicate a pointing/resizing
operation. *)
  Arrow: Oberon.Marker;  (* Substitute for the normal Oberon marker that does
not operate using XOR mode. *)
  MoveHand: Oberon.Marker;  (* Marker used to indicate a moving operation.
*)
  CopyHand: Oberon.Marker;  (* Marker used to indicate a copying operation.
*)
  Cross: Oberon.Marker;  (* Marker used by Rembrandt. *)
  gravity: INTEGER;  (* Size of gravity spot used for "snapping" the cursor.
*)

(* Set the snapping grid origin and width and height used for all future effects.
*)
 PROCEDURE SetSnap (sX, sY, sW, sH: INTEGER);

(* Snap X, Y to the snapping grid. *)
 PROCEDURE Snap (VAR X, Y: INTEGER);

(* Temporarily save a part of the display in an offscreen buffer. Note that
the height of the buffer might be limited from
platform to platform. *)
 PROCEDURE OpenMenu (X, Y, W, H: INTEGER);

(* Restore the screen area saved  by OpenMenu. *)
 PROCEDURE CloseMenu;

(* Tempory save a part of the display in an offscreen buffer. This area must
be small, and is thought for saving the
areas under non-inverting cursors. *)
 PROCEDURE OpenCursor (X, Y, W, H: INTEGER);

(* Restore the screen area saved by OpenCursor. *)
 PROCEDURE CloseCursor;

(* Returns TRUE if mx, my is within gravity pixels from X, Y. *)
 PROCEDURE Invicinity (mx, my, X, Y: LONGINT): BOOLEAN;

(* Returns TRUE if mx, my is inside the rectange X, Y, W, H. *)
 PROCEDURE Inside (mx, my, X, Y, W, H: INTEGER): BOOLEAN;

(* Returns TRUE if mx, my is near (within gravity) one of the four corners of
 X, Y, W, H. The gravity is tempory adjusted should W, H be too small. *)
 PROCEDURE InCorner (mx, my, X, Y, W, H: INTEGER): BOOLEAN;

(* Returns TRUE if mx, my is inside the border of X, Y, W, H (gravity is used).
The gravity is tempory adjusted should W, H be too small. *)
 PROCEDURE InBorder (mx, my, X, Y, W, H: INTEGER): BOOLEAN;

(* Returns TRUE if mx, my is within gravity pixels of the line from X, Y to
X1, Y1. *)
 PROCEDURE InLineVicinity (mx, my, X, Y, X1, Y1: INTEGER): BOOLEAN;

(* Returns TRUE if the two rectangles intersect each other. *)
 PROCEDURE Intersect (X, Y, W, H, X1, Y1, W1, H1: INTEGER): BOOLEAN;

(* Polls the mouse, continually drawing the specified marker, until the mouse
snaps to the nearest grid position. *)
 PROCEDURE TrackMouse (VAR keys: SET; VAR X, Y: INTEGER; marker: Oberon.Marker);

(* Given a bar position, calculate the relative bar position. *)
 PROCEDURE BarValue (X, Y, W, H, B, BW: INTEGER; min, max: LONGINT): LONGINT;

(* Given the min, max, and val values, calculate the absolute bar position.
*)
 PROCEDURE BarPos (X, Y, W, H, BW: INTEGER; min, max, val: LONGINT): INTEGER;

(* Displays a scroll bar. B is the absolute control knob position and BW the
bar width/height. Use BarPos to calculate B. *)
 PROCEDURE Bar (R: Display3.Mask; X, Y, W, H, B, BW: INTEGER);

(* Drag rectangle X, Y, W, H outline until the mouse button is released. MX,
MY is the position where the mouse was released, and keys contains all the mouse
buttons that were pressed. *)
 PROCEDURE MoveRect (R: Display3.Mask; VAR keysum: SET; VAR MX, MY, X, Y, W, H: INTEGER);

(* Resize the rectangle X, Y, W, H using rubber-banding. The nearest resize
corner is determined according to the mouse position MX, MY. During resizing
the callback procedure is continually called.Keysum returns the set of mouse
buttons pressed and MX, MY the position where the mouse buttons were released.
*)
 PROCEDURE SizeRect (R: Display3.Mask; VAR keysum: SET; VAR MX, MY, X, Y, W, H: INTEGER; callback: Callback);

(* Track a cross mark inside the rectangle X, Y, W, H. Keysum returns all the
mouse buttons pressed and MX, MY the position where the mouse buttons were released.
*)
 PROCEDURE TrackCross (R: Display3.Mask; VAR keysum: SET; VAR MX, MY, X, Y, W, H: INTEGER);

(* Track the position knob of a scrollbar. By bars are meant scroll bars with
a knob. The bar orients itself according to the width/height ratio of the bounding
rectangle. The interpolation functions allow you to convert between internal
measurements and screen coordinates. *)
 PROCEDURE TrackBar (R: Display3.Mask; VAR keysum: SET; VAR MX, MY, X, Y, W, H, B, BW: INTEGER);

(* Track mouse in area X, Y, W, H, highlighting the border or inside of the
rectangle, depending on the mouse location. Keysum returnes all the mouse buttons
pressed and MX, MY the position where the mouse buttons were released. *)
 PROCEDURE TrackHighlight (R: Display3.Mask; VAR keysum: SET; VAR MX, MY: INTEGER; X, Y, W, H: INTEGER);
END Effects.

(* Remarks:

1. Gravity
Gravity is a measurement of how far the user can "miss" a point he/she points
to with the mouse and still indicate that point or object.  For example it determines
the thickness of the border of a rectangle (InBorder). To prevent the border
filling the rectangle when very small, the gravity is adjusted dynamicly when
very small features are to be selected. The resulting gravity is a value between
1 and the gravity setting.

2. Saving and Restoring areas
Often you need to save and restore small areas of the display, for example,
when using pop-up menus. There are two such areas, one for what is underneath
a cursor, and one for general use. The corresponding Open procedure saves the
area indicated by the rectangle, and the close area restores it to its previous
value. This cannot be done recursively. The buffer area is restricted and may
be less that 200 pixels in height. There are however more portable ways of doing
the same thing (see the Views and Bitmaps module).

3. Tracking
All the tracking procedures assume that the a mouse button is depressed when
they are called. They will return when all the mouse buttons are released.

4. Bars
By bars are meant scroll bars with a knob. The bar orients itself according
to the width/height ratio of the bounding rectangle. The height/width of the
knob is specified by BW. The interpolation functions BarPos and BarValue allow
you to convert between a value between a minimum and a maximum and screen coordinates.

5. The Gadgets Palette
The Gadgets system assume that the system palette is organized in the following
manner:

 Index Color
 0  white/background
 1  red
 2  green
 3  blue
 4  free to application
 5  free to application
 6  free to application
 7  free to application
 8  free to application
 9  free to application
 10  free to application
 11  free to application
 12  dark grey
 13  medium grey
 14  light grey
 15  black/foreground
 16 +  free to application
 
On Oberon for Windows, colors 16 to 19 are also fixed.

*)