(*
 * Title: h.dbox
 * Purpose: Creation/deletion/manipulation of dialogue boxes.
 *
 *)

(* 
 * It is important to note that the structure of your dialogue templates is
 * an integral part of your program. Always use symbolic names for templates
 * and for fields and action buttons within them.  Templates for the
 * dialogue boxes can be loaded using the template module in this library
 *
 *)

(* 
 * See separate documentation for how to use the RISC OS Template Editor
 * in conjunction with this interface. 
 *)

#ifndef __dbox_h
#define __dbox_h


(* ------------------------------ dbox ------------------------------------
 * a dbox is an abstract dialogue box handle
 *
 *)
type dbox = ^dbox__str;
     dbox__str = record end;



(* ********************** Creation, Deletion functions ***************** *)


(* ------------------------------ dbox_new ------------------------------
 * Description:   Builds a dialogue box from a named template 
 *                Template editor (FormEd) may have been used to create
 *                this template in the "Templates" file for the application.
 *
 * Parameters:    char *name -- template name (from templates previously
 *                              read in by template_init), from which to
 *                              construct dialogue box. Name is as given
 *                              when using FormEd to create template
 * Returns:       On successful completion, pointer to a dialogue box
 *                structure otherwise null (eg. when not enough space).
 * Other Info:    This only creates a structure. It doesn't display anything!
 *                *However* it does register the dialogue box as an active 
 *                window with the window manager.
 *)
function dbox_new(name : string) : dbox; extern;


(* ------------------------------ dbox_dispose ----------------------------
 * Description:   Disposes of dialogue box structure.
 *
 * Parameters:    dbox* -- pointer to pointer to a dialogue box structure
 * Returns:       void.
 * Other Info:    This also has the side-efffect of hiding the dialogue box,
 *                so that it no longer appears on the screen. It also
 *                "un-registers" it as an active window with the
 *                window manager.
 *)
procedure dbox_dispose(var d : dbox); extern;



(* *************************** Display functions ************************ *)

(* ----------------------------- dbox_show --------------------------------
 * Description:   Displays given dialogue box on the screen.
 *
 * Parameters:    dbox -- dialogue box to be displayed
 *                        (typically created by dbox_new)
 * Returns:       void.
 * Other Info:    Typically used when dialogue box is from a submenu
 *                so that it disappears when the menu is closed. If called
 *                when dialogue box is showing then no effect. The show will
 *                occur near the last menu selection or last caret setting
 *                (whichever is most recent).
 *)  
procedure dbox_show(d : dbox); extern;


(* ----------------------------dbox_showstatic ----------------------------
 * Description:   Displays given dialogue box on the screen, and leaves it
 *                there, until explicitly closed.
 *
 * Parameters:    dbox -- dialogue box to be displayed
 *                        (typically created by dbox_new)
 * Returns:       void.
 * Other Info:    typically, not used from menu selection, because it will
 *                persist longer than the menu (otherwise same as dbox_show).
 *)
procedure dbox_showstatic(d : dbox); extern;


(* ----------------------------- dbox_hide --------------------------------
 * Description:   Hides a previously displayed dialogue box.
 * 
 * Parameters:    dbox -- dialogue box to be hidden
 * Returns:       void.
 * Other Info:    Note that this does not release any storage. It just
 *                hides the dialogue box. If called when dialogue box  is
 *                already hidden, then no effect.
 *)
procedure dbox_hide(d : dbox); extern;




(* ***************************** dbox Fields. *************************** *)

(* A dbox has a number of fields, labelled from 0. There are the following
 * distinct field types:
 *
 * "action" fields. Mouse clicks here are communicated to the client. The 
 * fields are usually labelled "go", "quit", etc. Set/GetField apply to the
 * label on the field, although this is usually set up in the template.
 *
 * "output" fields. These display a message to the user, using SetField.
 *  Mouse clicks etc. have no effect.
 *
 *"input" fields. The user can type into these, and simple local editing is
 * provided. Set/GetField can be used on the textual value, or 
 * Set/GetNumeric if the user should type in numeric values.
 *
 * "on/off" fields. The user can click on these to display their on/off 
 * status. They are always "off" when the dbox is first created. The 
 * template editor can set up mutually exclusive sets of these at will. 
 * Set/GetField apply to the label on this field, Set/GetNumeric 
 * set/get 1 (on) and 0 (off) values.
 *
 *)

(* ---------------------- dbox_field / dbox_fieldtype --------------------
 * type dbox_field values are field numbers within a dbox
 * type dbox_fieldtype values indicate what sort a field is
 *                          (ie. action, output, input, on/off)
 *
 *)

type dbox_field_ptr = ^dbox_field;
     dbox_field = integer;

const dbox_FACTION = 0;
      dbox_FOUTPUT = 1;
      dbox_FINPUT  = 2;
      dbox_FONOFF  = 3;

type dbox_fieldtype_ptr = ^dbox_fieldtype;
     dbox_fieldtype = integer;


(* -------------------------- dbox_setfield -------------------------------
 * Description:   Sets the given field, within the given dialogue box, to 
 *                the given text value.
 *
 * Parameters:    dbox -- the chosen dialogue box
 *                dbox_field -- chosen field number
 *                char* -- text to be displayed in field
 * Returns:       void.
 * Other Info:    if applied to non-text field then no effect
 *                if field is an indirected text icon then the text length
 *                is limited by the size value used when setting up the
 *                template in the template editor. Any longer text will be
 *                truncated to this length.
 *                otherwise text is truncated to 12 chars (11 text + 1 null)
 *                if dbox is currently showing, change is immediately 
 *                visible.
 *                
 *)
procedure dbox_setfield(d : dbox; df : dbox_field; text : string); extern;


(* ---------------------------- dbox_getfield ------------------------------
 * Description:   Puts the current contents of the chosen text field into
 *                buffer, whose size is given as third parameter
 *
 * Parameters:    dbox -- the chosen dialogue box
 *                dbox_field -- the chosen field number
 *                char *buffer -- buffer to be used
 *                int size -- size of buffer
 * Returns:       void.
 * Other Info:    if applied to non-text field then null string put in buffer
 *                if the length of the chosen field (plus null-terminator)
 *                is larger than the buffer, then result will be truncated.
 *)
procedure dbox_getfield(d : dbox;
                df : dbox_field;
                buffer : string;
                size : integer); extern;


(* ---------------------------- dbox_setnumeric ----------------------------
 * Description:   Sets the given field, in the given dbox, to the given
 *                integer value.
 *
 * Parameters:    dbox -- the chosen dialogue box
 *                dbox_field -- the chosen field number
 *                int -- field's contents will be set to this value
 * Returns:       void.
 * Other Info:    if field is input/output, then the integer value is
 *                converted to a string and displayed in the field
 *                if field is of type "action" or "on/off" then a non-zero
 *                integer value "selects" this field; zero "de-selects".
 * 
 *)
procedure dbox_setnumeric(d : dbox; df : dbox_field; v : integer); extern;


(* ---------------------------- dbox_getnumeric ----------------------------
 * Description:   Gets the integer value held in the chosen field of the
 *                chosen dbox.
 * 
 * Parameters:    dbox -- the chosen dialogue box
 *                dbox_field -- the chosen field number
 * Returns:       integer value held in chosen field
 * Other Info:    if the field is of type "on/off" then return value of 0
 *                means "off", 1 means "on"
 *                otherwise return value is integer equivalent of field
 *                contents.
 *
 *)
function dbox_getnumeric(d : dbox; df : dbox_field) : integer; extern;


(* --------------------------- dbox_fadefield ------------------------------
 * Description:   Makes a field unselectable (ie. faded by WIMP).
 *
 * Parameters:    dbox d -- the dialogue box in which field resides
 *                dbox_field f -- the field to be faded.
 * Returns:       void.
 * Other Info:    Fading an already faded field has no effect.
 *
 *)
procedure dbox_fadefield(d : dbox; df : dbox_field); extern;


(* --------------------------- dbox_unfadefield ----------------------------
 * Description:   Makes a field selectable (ie "unfades" it).
 *
 * Parameters:    dbox d -- the dialogue box in which field resides
 *                dbox_field f -- the field to be unfaded.
 * Returns:       void.
 * Other Info:    Unfading an already selectable field has no effect
 *
 *)
procedure dbox_unfadefield(d : dbox; df : dbox_field); extern;


(* ************************ Events from dboxes. ************************ *)

(* A dbox acts as an input device: a stream of characters comes from it
 * somewhat like a keyboard, and an up-call can be arranged when input is
 * waiting. 
 *)

const dbox_CLOSE = dbox_field(-1);

(* dboxes may have a "close" button that is separate from their action
 * buttons, usually in the header of the window. If this is pressed then 
 * CLOSE is returned, this should lead to the dbox being invisible. If the
 * dbox represents a particular pending operation then the operation should 
 * be cancelled. 
 *)

(* ------------------------------ dbox_get ---------------------------------
 * Description:   Tells caller which action field has been activated in the
 *                chosen dialogue box
 *
 * Parameters:    dbox -- the chosen dialogue box
 * Returns:       field number of activated field
 * Other Info:    This should only be called from an event handler
 *                (since this is the only situation where it makes sense).
 *
 *) 
function dbox_get(d : dbox) : dbox_field; extern;


(* ------------------------------ dbox_read ---------------------------------
 * Description:   Tells caller which action field has been activated in the
 *                chosen dialogue box. Does not cancel the event.
 *
 * Parameters:    dbox -- the chosen dialogue box
 * Returns:       field number of activated field
 * Other Info:    This should only be called from an event handler
 *                (since this is the only situation where it makes sense).
 *
 *) 
function dbox_read(d : dbox) : dbox_field; extern;


(* ------------------------ dbox_eventhandler ------------------------------
 * Description:   Register an event handler function for the given dialogue 
 *                box.
 *
 * Parameters:    dbox -- the chosen dialogue box
 *                dbox_handler_proc -- name of handler function
 *                void *handle -- user-defined handle
 * Returns:       void.
 * Other Info:    When a field of the given dialogue box has been activated
 *                the user-supplied handler function is called.
 *                The handler should be defined in the form:
 *                           void foo (dbox d, void *handle)
 *                When called the function "foo" will be passed the relevant
 *                dialogue box, and its user-defined handle. A typical action
 *                in "foo" would be to call dbox_get to determine which
 *                field was activated. If handler==0 then no function is
 *                installed as a handler (and any existing handler is
 *                "un-registered".
 *
 *)
type dbox_handler_proc = ^procedure handler(d : dbox; handle : pointer);

procedure dbox_eventhandler(d : dbox;
                handler : dbox_handler_proc;
                handle : pointer); extern;


(* -------------------------- dbox_raweventhandler -------------------------
 * Description:   Register a "raw" event handler for the given dialogue box.
 *
 * Parameters:    dbox -- the given dialogue box
 *                dbox_raw_handler_proc proc -- handler function for event
 *                void *handle -- user-defined handle.
 * Returns:       void.
 * Other Info:    This registers a function which will be passed "unvetted"
 *                window events. Under the window manager in RISC OS, the
 *                event will be a wimp_eventstr* (see Wimp module). The
 *                supplied handler function should return true if it 
 *                processed the event; if it returns false, then the event
 *                will be passed on to any event handler defined using
 *                dbox_eventhandler() as above. The form of the handler's
 *                function header is:
 *                          BOOL func (dbox d, void *event, void *handle).
 *
 *)
type dbox_raw_handler_proc = ^function handler(d : dbox;
                                       event : pointer;
                                       handle : pointer) : boolean;



(* dboxes are often used to fill in the details of a pending operation. In
this case a down-call driven interface to the entire interaction is often
convenient. The following facilties aid this form of use. *)


(* -------------------------- dbox_fillin -------------------------------
 * Description:   Process events until a field in the given dialogue box
 *                has been activated.
 *
 * Parameters:    dbox d -- the given dialogue box
 * Returns:       field number of activated field.
 * Other Info:    Handling of harmful events, same as dbox_popup (see below).
 *                On each call to dbox_fillin, the caret is set to the end
 *                of the lowest numbered writeable icon
 *)
procedure dbox_fillin(d : dbox) : dbox_field; extern;


(* -------------------------- dbox_fillin_fixedcaret --------------------
 * Description:   Process events until a field in the given dialogue box
 *                has been activated.
 *
 * Parameters:    dbox d -- the given dialogue box
 * Returns:       field number of activated field.
 * Other Info:    Same as dbox_fillin, except caret is not set to end of lowest
 *                numbered writeable icon
 *)
procedure dbox_fillin_fixedcaret(d : dbox) : dbox_field; extern;



(* ------------------------------ dbox_popup -------------------------------
 * Description:   Build a dialogue box, from a named template, assign message
 *                to field 1, do a dbox_fillin, destroy the dialogue box,
 *                and return the number of the activated field.
 *
 * Parameters:    char *name -- template name for dialogue box
 *                char *message -- message to be displayed in field 1
 * Returns:       field number of activated field
 * Other Info:    "harmful" events are those which could cause the dialogue 
 *                to fail (eg. keystrokes, mouse clicks). These events will 
 *                cause the dialogue box to receive a CLOSE event.
 *
 *)
procedure dbox_popup(name : string; message : string) : dbox_field; extern;


(* ------------------------------ dbox_persist -----------------------------
 * Description:   When dbox_fillin has returned an action event, this
 *                function returns true if the user wishes the action to
 *                be performed, but the dialogue box to remain.
 *
 * Parameters:    void.
 * Returns:       BOOL -- does user want dbox to remain on screen?
 * Other Info:    Current implementation returns true when user has clicked
 *                Adjust. Caller should continue round fill-in
 *                loop if return value is true (ie. don't destroy dbox).
 *
 *)
function dbox_persist : boolean; extern;


(* ***************************** System hook. **************************** *)

(* --------------------------- dbox_syshandle ------------------------------
 * Description:   Allows the caller to get a handle on the window associated
 *                with the given dialogue box.
 *
 * Parameters:    dbox -- the given dialogue box
 * Returns:       window handle of dialogue box (this is a wimp_w under the
 *                RISC OS window manager).
 * Other Info:    This could be used to hang a menu off a dialogue box, or
 *                to "customise" the dialogue box in some way. Note that
 *                dbox_dispose will also dispose of any such attached menus.
 *     
 *)
function dbox_syshandle(d : dbox) : integer; extern;


(* ************************** Initialisation **************************** *)

(* ---------------------------- dbox_init ----------------------------------
 * Description:   Prepare for use of dialogue boxes from templates
 *
 * Parameters:    void
 * Returns:       void
 * Other Info:    This function must be called ONCE before any dbox functions
 *                are used. You should call template_init() before this
 *                function.
 *
 *)
procedure dbox_init; extern;

#endif

(* end dbox.h *)
