;
; dbox.sh
;
; Dialogue box handling
;
;  1994-1998 Straylight
;

;----- Licensing note -------------------------------------------------------
;
; This file is part of Straylight's Sapphire library.
;
; Sapphire is free software; you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation; either version 2, or (at your option)
; any later version.
;
; Sapphire is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with Sapphire.  If not, write to the Free Software Foundation,
; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

;----- Overview -------------------------------------------------------------
;
; Functions provided:
;
;  dbox_create
;  dbox_fromEmbedded
;  dbox_fromDefn
;  dbox_destroy
;  dbox_init
;  dbox_open
;  dbox_close
;  dbox_writePos
;  dbox_select
;  dbox_shade
;  dbox_selectMany
;  dbox_shadeMany
;  dbox_isSelected
;  dbox_radio
;  dbox_slab
;  dbox_unslab
;  dbox_setField
;  dbox_getField
;  dbox_eventHandler
;  dbox_renderTitle
;  dbox_setEmbeddedTitle
;  dbox_setClickDrag
;  dbox_hasTitle
;  dbox_window
;  dbox_help

		[	:LNOT::DEF:dbox__dfn
		GBLL	dbox__dfn

; --- dbox_create ---
;
; On entry:	R0 == pointer to dialogue template name
;
; On exit:	R0 == dialogue box handle for the dialogue
;		May return an error
;
; Use:		Creates a dialogue box from a template definition.

		IMPORT	dbox_create

; --- dbox_fromEmbedded ---
;
; On entry:	R0 == pointer to an embedded template
;
; On exit:	R0 == dialogue box handle
;		May return an error
;
; Use:		Creates a dialogue box from an embedded template definition.

		IMPORT	dbox_fromEmbedded

; --- dbox_fromDefn ---
;
; On entry:	R0 == pointer to a window definition
;
; On exit:	R0 == dialogue box handle for the dialogue
;		May return an error
;
; Use:		Creates a dialogue box from an immediate window definition,
;		rather than a template.  There are several things you need
;		to be aware of when you use this call to create a dialogue
;		box:
;
;		* The window definition is not copied, but used directly
;		  for the duration the dialogue box exists.  It must
;		  not move for this duration.  When the dialogue is
;		  destroyed, you can release the memory for the definition,
;		  although this is your responsibility.
;
;		* The indirected data is not copied either, so you'll have
;		  to copy it yourself if you want multiple dialogues from
;		  the same window definition.
;
;		* The window definition and the indirected data must both
;		  be writable.

		IMPORT	dbox_fromDefn

; --- dbox_destroy ---
;
; On entry:	R0 == dialogue box handle
;
; On exit:	--
;
; Use:		Destroys a dialogue box, freeing all the memory it took
;		up etc.

		IMPORT	dbox_destroy

; --- dbox_init ---
;
; On entry:	--
;
; On exit:	--
;
; Use:		Initialises the dbox system.

		IMPORT	dbox_init

; --- dbox_open ---
;
; On entry:	R0 == dialogue box handle
;		R1 == how to open the dialogue box
;		Other registers depend on R1, and are described at the end
;		of this header file
;
; On exit:	--
;
; Use:		Displays the dialogue box on the screen in the given manner.

		IMPORT	dbox_open

; --- dbox_close ---
;
; On entry:	R0 == dialogue box handle
;
; On exit:	--
;
; Use:		Closes a dialogue box, by clearing the current menu if
;		necessary.

		IMPORT	dbox_close

; --- dbox_writePos ---
;
; On entry:	R0 == dialogue box handle
;
; On exit:	--
;
; Use:		Saves the dialogue's current position so that it will be
;		opened here the next time it is created.  If the dialogue
;		box was created from a template, the template is updated.
;		Otherwise, the new state is written back to the definition
;		supplied to dbox_fromDefn.

		IMPORT	dbox_writePos

; --- dbox_select ---
;
; On entry:	R0 == dialogue box handle
;		R1 == icon number
;		R2 == 0 to deselect the icon, 1 to select it, 2 to toggle
;		      its current selected state
;
; On exit:	--
;
; Use:		Selects or deselects the specified icon in the Acorn sense
;		(i.e. by flipping its selected bit).  The state is only
;		changed if required, to reduce flicker.

		IMPORT	dbox_select

; --- dbox_shade ---
;
; On entry:	R0 == dialogue box handle
;		R1 == icon number
;		R2 == 0 to unshade the icon, 1 to shade it, 2 to toggle its
;		      current shaded state
;
; On exit:	--
;
; Use:		Makes the icon look dimmer, to indicate that it is not
;		available.  It uses its own shading algorithms, rather than
;		the WindowManager's, so there are some things you must watch
;		out for:
;
;		* Don't use any other method of shading icons
;
;		* Don't assume that a shaded icon isn't going to give you
;		  events.  At the user level, this should have been tidied
;		  up, but at the Sapphire level, it's still a problem.
;		  There is a routine in winUtils which will tell you if an
;		  icon is shaded.
;
;		This routine has been written so that it only flickers icons
;		when they actually need it.

		IMPORT	dbox_shade

; --- dbox_selectMany ---
;
; On entry:	R0 == dialogue box handle
;		R1 == pointer to icon handle list, -1 terminated
;		R2 == select action (0 == unselect, 1 == select, 2 == toggle)
;
; On exit:	--
;
; Use:		Changes the select state of a group of icons.

		IMPORT	dbox_selectMany

; --- dbox_shadeMany ---
;
; On entry:	R0 == dialogue box handle
;		R1 == pointer to icon handle list, -1 terminated
;		R2 == shade action (0 == unshade, 1 == shade, 2 == toggle)
;
; On exit:	--
;
; Use:		Changes the shade state of a group of icons.

		IMPORT	dbox_shadeMany

; --- dbox_isSelected ---
;
; On entry:	R0 == dialogue box handle
;		R1 == icon number
;
; On exit:	CS if the icon is selected, CC otherwise
;
; Use:		Returns whether an icon is currently selected.

		IMPORT	dbox_isSelected

; --- dbox_radio ---
;
; On entry:	R0 == dialogue box handle
;		R1 == icon handle
;
; On exit:	--
;
; Use:		Checks to see if the icon is a radio button as defined by
;		Sapphire, i.e. button type 3 (debounced) and non-zero ESG.
;		If it is, it selects it, and deselects all other icons with
;		this ESG.

		IMPORT	dbox_radio

; --- dbox_slab ---
;
; On entry:	R0 == dialogue box handle
;		R1 == icon handle
;
; On exit:	May return an error
;
; Use:		Slabs an icon in properly, to give visual feedback when you
;		click it.

		IMPORT	dbox_slab

; --- dbox_unslab ---
;
; On entry:	--
;
; On exit:	CS if there are no more slabbed icons after this one, CC
;		if there are more left.
;
; Use:		Unslabs an icon slabbed with dbox_slab.  Icons are unslabbed
;		in reverse order to that in which they were slabbed.  The
;		carry flag is returned as an indication of whether there
;		are any more icons left in the list -- you can unslab all
;		icons in one go by doing:
;
;				BL	dbox_unslab
;				SUBCC	PC,PC,#12	;Avoids a label!
;
;		It is recommended that, if you are going to close a window,
;		you unslab icons within it *after* you close, but before you
;		actually destroy it, e.g.
;
;				LDR	R0,my_dbox
;				BL	dbox_close
;				BL	dbox_unslab
;				BL	dbox_destroy

		IMPORT	dbox_unslab

; --- dbox_setField ---
;
; On entry:	R0 == dialogue box handle
;		R1 == icon number to write to (may be -1 for title)
;		      flags in top byte if not -1:
;			dbFlag_dots (bit 31) == add `...' if text overflows
;		R2 == pointer to string to use
;
; On exit:	--
;
; Use:		Writes the string specified into the indirection buffer
;		for the given icon.  If the icon is not indirected, an
;		error is generated.  If the indirected buffer is too small,
;		the string is shortened by chopping off the beginning or
;		the end, according to the setting of the icon's right
;		justify flag.
;
;		The icon is only flickered if the text has actually changed.
;		The caret is moved correctly if it is within the icon to
;		prevent it `falling off' the end and deleting the validation
;		string, or being positioned incorrectly in centred icons if
;		the length changes.
;
;		Note that this routine requires a string to already be in
;		the buffer, and doesn't perform any substitution or other
;		transformations.  This helps to prevent buffer full errors
;		and similar problems.

		IMPORT	dbox_setField

; --- dbox_getField ---
;
; On entry:	R0 == dialogue box handle
;		R1 == icon number to interrogate
;
; On exit:	R0, R1 preserved
;		R2 == pointer to the icon text
;
; Use:		Returns a pointer to the text associated with an icon.
;		Note that if the icon is *not* indirected, the text will
;		be copied into the scratchpad.  Otherwise you get a pointer
;		to the actual indirected data.  You shouldn't write to the
;		string returned at all -- dbox_setField is specially
;		designed to do that sort of thing very well (i.e. not
;		flickering the text unless it has to, truncating if it's too
;		long, and handling the caret correctly).  You *are* allowed
;		to zero	terminate the string if you want to, though.
;
;		Despite all the PRM's assurances to the contrary, chances
;		are the text will be terminated by some weird control char,
;		so you'll have to handle this, and not just assume it's
;		going to be null-terminated.
;
;		Note: The indirected case is immensely quick -- just load a
;		pointer.  The non-indirected case has been optimised as much
;		as possible.

		IMPORT	dbox_getField

; --- dbox_eventHandler ---
;
; On entry:	R0 == dialogue box handle
;		R1 == pointer to handler routine
;		R2 == value to pass to handler in R10
;		R3 == value to pass to handler in R12
;
; On exit:	R0 preserved
;		R1 == pointer to old handler
;		R2 == old R10 value
;		R3 == old R12 value
;
; Use:		Sets up an event handler for a dialogue box, and returns
;		the previous one.  If the pointer to handler is 0, there is
;		no dialogue box event handler.

		IMPORT	dbox_eventHandler

; --- dbox_renderTitle ---
;
; On entry:	R0 == dialogue box handle
;		R1 == pointer to redraw block
;
; On exit:	--
;
; Use:		Renders a dialogue box's embedded title if there is one.

		IMPORT	dbox_renderTitle

; --- dbox_setEmbeddedTitle ---
;
; On entry:	R0 == dialogue box handle
;		R1 == icon which should contain the embedded title
;
; On exit:	--
;
; Use:		Declares a given dialogue box as requiring an embedded title
;		(rather than the one the WindowManager put on).

		IMPORT	dbox_setEmbeddedTitle

; --- dbox_setClickDrag ---
;
; On entry:	R0 == dialogue box handle
;
; On exit:	--
;
; Use:		Sets a given dialogue box so that the user can move it by
;		dragging from any part of the window, not just the title
;		bar.

		IMPORT	dbox_setClickDrag

; --- dbox_hasTitle ---
;
; On entry:	R0 == dialogue box handle
;
; On exit:	CS if the dialogue box has a title bar, CC if not
;
; Use:		Informs the caller whether the dialogue box has a title bar.
;		This is mainly useful for other library sections which
;		conditionally add in embedded titles etc.

		IMPORT	dbox_hasTitle

; --- dbox_window ---
;
; On entry:	R0 == dialogue box handle
;
; On exit:	R0 == the dialogue box's window handle
;
; Use:		Returns the Wimp window handle associated with a dialogue
;		box.  This may be useful if you want to perform lowlevel
;		Wimp operation on it, or to subclass it using win.

		IMPORT	dbox_window

; --- dbox_help ---
;
; On entry:	--
;
; On exit:	--
;
; Use:		Adds a help line to the current help message, read by
;		scanning the icon to which the help was sent for an `H'
;		validation string.

		IMPORT	dbox_help

;----- Useful constants -----------------------------------------------------

; --- Ways of opening dialogue boxes ---

		^	0
dbOpen_current	#	1			;In its current position
dbOpen_centre	#	1			;Centred on the screen
dbOpen_pointer	#	1			;Centred over the pointer
dbOpen_givenY	#	1			;At a given height on screen
						;  R2 == y coordinate to open
dbOpen_givenXY	#	1			;At a given position
						;  R2 == x coordinate
						;  R3 == y coordinate

dbOpen_trans	EQU	&00			;Make the dbox transient
dbOpen_persist	EQU	&80			;Make the dbox persistent
dbOpen_nonSub	EQU	&40			;Don't open as a submenu

; --- Dialogue box event codes ---

dbEvent_close	EQU	-2			;The user closed the dialogue
						;C flag ignored on exit

dbEvent_help	EQU	-3			;The user wants some help
						;R1 == icon number
						;C flag ignored on exit

dbEvent_OK	EQU	-4			;The user clicked OK
						;R1 == mouse button status
						;C flag ignored on exit

dbEvent_cancel	EQU	-5			;The user clicked Cancel
						;R1 == mouse button status
						;C flag ignored on exit

dbEvent_redraw	EQU	-6			;Redraw a single rectangle
						;R1 == pointer to redraw blk
						;R2,R3 == coords of origin
						;CS => don't do default draw

dbEvent_menu	EQU	-7			;User clicked Menu button
						;R1 == icon handle clicked
						;C flag ignored on exit

dbEvent_drag	EQU	-8			;User dragged an icon
						;R1 == mouse button status
						;R2 == icon handle dragged
						;C flag ignored on exit

dbEvent_save	EQU	-9			;User wants to import data
						;R1 == icon handle dropped on
						;R2 == filetype of data
						;R3 == pointer to filename
						;R4 == estimated file size
						;C flag ignored on exit

dbEvent_load	EQU	-10			;User wants to load data
						;R1 == icon handle dropped on
						;R2 == filetype of data
						;R3 == pointer to filename
						;R4 == estimated file size
						;C flag ignored on exit

dbEvent_key	EQU	-11			;User pressed a key
						;R1 == key code received
						;R2 == icon handle with caret
						;CC => unknown keypress
						;Key code has been translated

dbEvent_hint	EQU	-12			;Received a hint message
						;R2 == pointer to hint string

dbEvent_enter	EQU	-13			;Pointer has entered window

dbEvent_leave	EQU	-14			;Pointer has left window

; --- Other values ---

dbFlag_dots	EQU	(1<<31)			;Add dots if text overflows
						;  in dbox_setField

		]

;----- That's all, folks ----------------------------------------------------

		END
