(****************************************************************************)
(*                                                                          *)
(*                    GSX Support Module : BUTTON                           *)
(*                    ===========================                           *)
(* A BUTTON is a bar area on the screen, which can be selected by pressing  *)
(* a mouse ( or keyboard ) button.                                          *)
(*                                                                          *)
(* 16.5.1988          Wolfgang Muees, Hagenring 22, 3300 Braunschweig       *)
(*                                                                          *)
(****************************************************************************)

TYPE
  BUTTON      = ^ButtonEntry;
  ButtonEntry = RECORD
                   _X ,_Y   : INTEGER;        (* Lower left edge of button *)
                   _dX, _dY : INTEGER;        (* Dimensions of button      *)
                   _P       : INTEGER;        (* Associated actions        *)
                   END;

FUNCTION  CreateButton ( x, y, dx, dy, p : INTEGER ) : BUTTON;
          (* Creates a new button. x, y denote lower left egde of button bar,
             dx = width, dy = height. p is a procedure address executed if a
             terminating character is returned from input device; with this
             character as parameter. *)
Var NewButton : BUTTON;
BEGIN
  NEW ( NewButton );
  WITH NewButton^ DO
    BEGIN
      _X  := x;
      _Y  := y;
      _dX := dx;
      _dY := dy;
      _P  := p;
    END;
  CreateButton := NewButton;
END;


PROCEDURE DeleteButton ( VAR B : BUTTON );
          (* Deletes a button, deallocates storage for other purposes. *)
BEGIN
  DISPOSE ( B );
  B := NIL;
END;


FUNCTION  CursorAtButton ( B : BUTTON ) : BOOLEAN;
          (* After a mouse button is pressed, cursor coordinates are tested if
             they are in range of specified button area. *)
BEGIN
  IF B = NIL THEN
    BEGIN
      CursorAtButton := FALSE;
      Exit;
    END
  ELSE
    WITH B^ DO
      CursorAtButton := ( _X <= CursorX )
                    AND ( _Y <= CursorY )
                    AND ( _X + _dX > CursorX )
                    AND ( _Y + _dY > CursorY );
END;


PROCEDURE FlipButtonArea ( B : BUTTON );
          (* Used to hightlight / lowlight a button area after pressing them. *)
BEGIN
  IF B <> NIL THEN
    BEGIN
      DrawMode ( exor );
      FillStyle ( solid );
      FillColor ( 7 );
      WITH B^ DO
        FillBar ( _X, _Y, _dX, _dY );
    END;
END;


PROCEDURE ExecuteButton ( B : BUTTON; C : CHAR );
             (* If you have found the propper button with CursorAtButton then a call
                to ExecuteButton will do it. *)
Const
  Call_HL : BYTE = $E9;
Var
  Procedure_Address   : INTEGER;
  Procedure_Parameter : CHAR;
BEGIN
  IF B <> NIL THEN
    BEGIN
      Procedure_Address   := B^._P;
      Procedure_Parameter := C;
      inline ( $3A / Procedure_Parameter / $6F / $26 / $00 / $E5 /
               $2A / Procedure_Address /
               $CD / Call_HL );
    END;
END;


PROCEDURE FrameButton ( B : BUTTON );
          (* Used to mark a button area with a frame. *)
BEGIN
  IF B <> NIL THEN
    BEGIN
      DrawMode ( transparent );
      FillStyle ( hollow );
      FillColor ( 7 );
      WITH B^ DO
        FillBar ( _X, _Y, _dX, _dY );
    END;
END;

