/*
    ####             #    #     # #
    #   #            #    #       #          The FreeWare C library for
    #   #  ##   ###  #  # #     # ###             RISC OS machines
    #   # #  # #     # #  #     # #  #   ___________________________________
    #   # ####  ###  ##   #     # #  #
    #   # #        # # #  #     # #  #    Please refer to the accompanying
    ####   ### ####  #  # ##### # ###    documentation for conditions of use
    ________________________________________________________________________

    File:    Dialog.h
    Author:  Copyright  1993 Tim Browse, with modifications by JW
    Version: 1.01 (02 Mar 1994)
    Purpose: Very high-level window (dialogue box) handling
*/

#ifndef __Desk_Dialog_h
#define __Desk_Dialog_h

#ifdef __cplusplus
	extern "C" {
#endif


#ifndef __Desk_Wimp_h
	#include "Wimp.h"
#endif

#ifndef __Desk_Window_h
	#include "Window.h"
#endif


/*K**************************************************************************

> Dialog Boxes


  A dialog box is a window that is popped open to get user choices and
  then goes away - They can act like menus (go away when you click outside
  them) if opened with Desk_Dialog_Show(), or can be permanent windows if
  you open them using Desk_Dialog_ShowStatic().
  This code simplifies popping up such dialogs, as it handles opening,
  closing and simple processing of the window for you.

  To use Dialog, you do something like the following:
  (Assuming a window where icon 0 is the 'OK' button, and icon 1 is the
   'Cancel' button)

  {
    dialog dlog;

    dlog = Desk_Dialog_Create("template", 0);           // Create the window
    Desk_Dialog_ShowStatic(dlog, Desk_open_UNDERPOINTER);    // Pop up under pointer

    while (Desk_Dialog_WaitForClick(dlog) > 1 || Desk_Dialog_Persist(dlog))
      |* Busy wait loop *| ;                       // Wait for OK/Cancel

    Desk_Window_Hide(dlog);      // Hide the window before we start processing

    if (Desk_Dialog_LastClicked(dlog) == 0)
      ProcessTheData();     // OK was clicked, so go ahead with processing

    Desk_Dialog_Destroy(dlog);
  }


  SeeAlso:  Desk_dialog_record; dialog

****************************************************************************/



typedef struct
  {
    Desk_window_handle window;         /* The window handle of this dialog      */

    Desk_icon_handle   lastclicked;    /* The icon handle of the last icon that
                                   * was clicked, or Desk_dialog_NOCHOICE if no
                                   * icons have been clicked yet.
                                   */

    Desk_button_state  button;         /* The button state for the last
                                   * click event.
                                   */
    struct
    {
      unsigned int stillopen : 1; /* The dialogue window is still open     */

      unsigned int persist   : 1; /* It should persist (adjust was clicked)*/

      unsigned int isstatic  : 1; /* It is a static (permanent) dialogue   */
    } state;
  } Desk_dialog_record;
/*
  Purpose:  Encapsulate the information pertaining to a particular dialog
            box.  It records the dialog box's current state, and details
            of the last event it received.
  SeeAlso:  dialog; Dialog Boxes
*/



typedef Desk_dialog_record *dialog;
/*
  Purpose:  The usual type passed to Dialog functions.  The Desk_dialog_record
            type specifies the information contained therein.
  SeeAlso:  Desk_dialog_record; Dialog Boxes
*/




#define Desk_dialog_CLOSE    ((Desk_icon_handle) -1)
/*
  MACRO:    Constant: Desk_dialog_CLOSE

  Purpose:  Used by Desk_Dialog_WaitForClick to signify when the user causes the
            dialog box to be closed by click outside the window or clicking
            on a close icon.
  SeeAlso:  Desk_Dialog_WaitForClick
*/



#define Desk_dialog_NOCHOICE ((Desk_icon_handle) -2)
/*
  MACRO:    Constant: Desk_dialog_NOCHOICE

  Purpose:  The setting returned by Desk_Dialog_LastClicked() when the user has
            not yet done anything (i.e. no icons have been clicked and the
            window is open)
  SeeAlso:  Desk_Dialog_LastClicked
*/



extern dialog Desk_Dialog_Create(char *Desk_template_name, int maxtitlesize);
/*
  Inputs:   Desk_template_name - the name of the window template to use in
                            constructing the dialog box.
            maxtitlesize  - the maximum space to reserve for the dialog box
                            title bar (See Desk_Window_Create for more details).
  Returns:  dialog - the newly created dialog box, or NULL if it was not
                     possible to create the dialog.
  Purpose:  Creates (but does not show) a dialog box from a named template.
  Errors:   Out of memory; Could not find window template
  SeeAlso:  Desk_Window_Create; Desk_Dialog_Show; Desk_Dialog_ShowStatic
*/



extern void Desk_Dialog_Destroy(dialog d);
/*
  Inputs:   d - the dialog box to destroy.
  Purpose:  Removes from display and deletes a dialog box structure.
            NOTE that the dialog structure is free'd by this, so you cannot
            call any dialog functions (except Create of course) with it
            after a Destroy.
  SeeAlso:  Desk_Dialog_Create; Desk_Dialog_Hide
*/




extern void Desk_Dialog_Show(dialog d);
/*
  Inputs:   d - the dialog box to show.
  Purpose:  Shows a dialog box in the centre of the screen, as a submenu
            window. (i.e. clicking outside the window or pressing escape
            will remove it)
  SeeAlso:  Desk_Dialog_ShowAt; Desk_Dialog_ShowStatic
*/



extern void Desk_Dialog_ShowAt(dialog d, int x, int y);
/*
  Inputs:   d    - the dialog to show.
            x, y - the position to show the window at (top-left of window
                   area).
  Purpose:  Shows a dialogue box at a specified position. (i.e. clicking
            outside the window or pressing escape will remove it)
  SeeAlso:  Desk_Dialog_Show; Desk_Dialog_ShowStatic
*/




extern void Desk_Dialog_ShowStatic(dialog d, Desk_window_openpos openpos);
/*
  Inputs:   d - the dialog to show.
            openpos - where to show the dialog.
  Purpose:  As Desk_Dialog_Show(), but more permanent - only a click on the close
            icon (if present) will close it.  Of course it may be closed by
            other means if the application assigns special meaning to an
            icon  - e.g. a cancel button - and closes it itself when this
            icon is clicked on.
            Opens the window at the position requested (see Window.h), of:
              Desk_open_ WHEREVER, CENTERED, OVERCARET, UNDERPOINTER, NEARLAST

            (It is very convenient if dialogs always appear under the mouse
            pointer especially as mouse-movement distances (screen sizes)
            increase.)
  SeeAlso:  Desk_Dialog_Show; Desk_Dialog_ShowAt
*/



extern void Desk_Dialog_Hide(dialog d);
/*
  Inputs:   d - the dialog to hide.
  Purpose:  Hides the dialog box by closing the window, but does not
            destroy it.
            Subsequent calls to Desk_Dialog_Show[Static] will work correctly.
  SeeAlso:  Desk_Dialog_Show; Desk_Dialog_Destroy
*/



extern int Desk_Dialog_WaitForClick(dialog d);
/*
  Inputs:   d - the dialog to process click events for.
  Returns:  The handle of the icon clicked, or Desk_dialog_CLOSE.
  Purpose:  Waits for an icon to be clicked in the dialogue box.  All other
            events are processed as usual.  If the user closes the window,
            Desk_dialog_CLOSE is returned.
            Note that Desk_Dialog_LastClicked can be called at any time up until
            you call Desk_Dialog_Destroy() to find out what the last valid icon
            click was (i.e. the last positive value that Desk_Dialog_WaitForClick
            returned)
  SeeAlso:  Desk_Dialog_LastClicked
*/



#define Desk_Dialog_WindowHandle(d) ((d)->window)
/*
  MACRO:    Desk_window_handle Desk_Dialog_WindowHandle(dialog d)

  Inputs:   d - the dialog in question.
  Returns:  Window handle of the dialog.
  Purpose:  Obtain the RISC OS Wimp window handle associated with this
            dialog box.  This allows filling in of fields using, e.g.
            DeskLib's 'Icon' module.
*/



#define Desk_Dialog_Persist(D) ((D)->state.persist && (D)->lastclicked >= 0)
/*
  MACRO:    Desk_bool Desk_Dialog_Persist(dialog d);

  Inputs:   d - the dialog to be checked for persistence.
  Returns:  Desk_bool_TRUE if the last choice made on this dialog was made using
            'adjust' - i.e. the user wants the dialog to stay open;
            Desk_bool_FALSE otherwise.
  Purpose:  Find out if the user wants the dialog to stay open after a
            click event.
            Unlike RISC OS Lib, this remembers the last click rather than
            just checking if Adjust is down when called, so will work even
            after an indentation delay.
  SeeAlso:  Desk_Dialog_LastClicked; Desk_Dialog_StillOpen
*/



#define Desk_Dialog_LastClicked(D) ((D)->lastclicked)
/*
  MACRO:    Desk_icon_handle Desk_Dialog_LastClicked(dialog d);

  Inputs:   d - the dialog to check for the click event.
  Returns:  The handle of the icon that was last clicked on this dialog,
            or Desk_dialog_NOCHOICE if the user has not yet clicked an icon.
  Purpose:  find out the last icon clicked on by the user in this dialog.
  SeeAlso:  Desk_Dialog_Persist; Desk_Dialog_StillOpen
*/



#define Desk_Dialog_StillOpen(D) ((D)->state.stillopen)
/*
  MACRO:    Desk_bool Desk_Dialog_StillOpen(dialog d)

  Inputs:   d - the dialog to check.
  Returns:  Desk_bool_TRUE if the dialog box is still open on screen;
            Desk_bool_FALSE otherwise.
  Purpose:  Find out if a dialog box is still open or not.
  SeeAlso:  Desk_Dialog_Persist; Desk_Dialog_LastClicked.
*/


#ifdef __cplusplus
}
#endif


#endif
