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

    File:    Menu2.h
    Author:  Copyright  1995 Julian Smith
    Version: 1.00 (22 Jun 1995)
    Purpose: Easy menu handling
    History:
             1.10 (29 Aug 1996)	Added closefn.
             07 Jan 1997	Added helpfn.
*/


#ifndef __Desk_Menu2_h
#define __Desk_Menu2_h

#ifdef __cplusplus
	extern "C" {
#endif


#ifndef __Desk_Menu_h
#include "Desk.Menu.h"
#endif


/*
Menu2

Menu2 provides a slightly higher-level interface to menus than the
Menu library. It uses Menu functions. The application should
supply up to four functions for each menu it uses. These functions are
automatically called when required, to handle menu-choices, set
menuflags, find submenus, and generate custom menus.

The Menu2 library automatically handles the re-opening of menus after an
ADJUST choice, and also frees the menu data after a menu has closed.

If your app uses Menu2 then, when it starts up, it should call
Desk_Menu2_Create for every menu it will use, and store the returned
pointers.

These pointers are used to open menu in the future using Desk_Menu2_Open(),
or to specify what submenu should be opened when required.

Note that Menu2 only creates menus when they are actually open, in order
to save RMA memory.

There is also a function Desk_Menu2_AttachMenu which automatically opens
menus in response to a click on an icon/window.

*/


typedef int	Desk_menu2_handle;
/*
This type is used to identify menus.
*/

typedef Desk_menu_ptr	(*Desk_menu2_makefn)( void *reference);
/*
This function-type should make a menu and return a pointer to it.

'reference' is the reference originally passed to Desk_Menu2_Create for
this menu.
 */

typedef void	(*Desk_menu2_closefn)( Desk_menu_ptr menu, void *reference);
/*
This function-type is called when a menu is finished with (ie either a
choice is made with 'Select' or 'Menu', or a Desk_message_MENUSDELETED
message is received).

If a Desk_Menu2 menu has a makefn, you should provide a closefn which
frees all data associated with the menu.
 */

typedef void	(*Desk_menu2_flagsfn)( Desk_menu_ptr menu, void *reference);
/*
This function-type should set any flags in the menu. It will be called
whenever the menu is created or reopened following an ADJUST
menu-choice.

'reference' is the reference originally passed to Desk_Menu2_Create for
this menu.
 */


typedef void	(*Desk_menu2_selectfn)( int itemnum, void *reference);
/*
This function-type is called whenever a menu-choice is made. 'itemnum'
determines the menu item-number which was chosen.

'reference' is the reference originally passed to Desk_Menu2_Create for
this menu.

Functions of this type shoule use globals such as Desk_Event_lastevent
and Desk_menu_currentopen if they need to know more about the menu.
 */

typedef Desk_menu2_handle	(*Desk_menu2_subfn)( int itemnum, Desk_event_pollblock *event, void *reference);
/*
This function-type is called whenever a submenu is required. 'itemnum'
is the number of the menu item which needs a submenu, while 'event' is
the original Desk_message_MENUWARN.

'event' is included so that you can open a dialog box (or your own
submenu menu) using the information in the Desk_message_menuwarn
'event->data.message.data.menuwarn'. If this is done, the function
should return NULL, so that Menu2 knows that a submenu has been opened.

'reference' is the reference originally passed to Desk_Menu2_Create for
this menu.
 */

typedef void	(*Desk_menu2_helpfn)( char* buffer, int buffsize, int itemnum, void *reference);
/*
This function should put 0-terminated help text into 'buffer' relevent
for menu item 'itemnum'.
 */





Desk_menu2_handle Desk_Menu2_Create( 
	const char		*title,
	const char		*spec,
	Desk_menu2_makefn	makefn, 	/* If !=NULL, called to make the menu	*/
	Desk_menu2_flagsfn	flagsfn, 	/* Called every time menu is opened	*/
	Desk_menu2_subfn	subfn, 		/* Called when submenu is needed	*/
	Desk_menu2_selectfn	selectfn, 	/* Called when selection is made	*/
	Desk_menu2_closefn	closefn,	/* Called when menu is closed		*/
	void			*reference	/* Passed to the 5 fns above		*/
	);
/*
As Desk_Menu2_Create2, but doesn't expect a helpfn pointer.
 */


Desk_menu2_handle Desk_Menu2_Create2( 
	const char		*title,
	const char		*spec,
	Desk_menu2_makefn	makefn, 	/* If !=NULL, called to make the menu	*/
	Desk_menu2_flagsfn	flagsfn, 	/* Called every time menu is opened	*/
	Desk_menu2_subfn	subfn, 		/* Called when submenu is needed	*/
	Desk_menu2_selectfn	selectfn, 	/* Called when selection is made	*/
	Desk_menu2_closefn	closefn,	/* Called when menu is closed		*/
	Desk_menu2_helpfn	helpfn,		/* Called when help is required		*/
	void			*reference	/* Passed to the 5 fns above		*/
	);
/*
This returns a unique handle for a menu.

Returns 0 if unable to make the menu - eg not enough memory.

If 'makefn' is NULL, the menu will be made, when required, from 'title'
and 'spec' using Desk_Menu_New. Otherwise, 'title' and 'spec' are ignored,
and the 'makefn' is relied apon to make the menu and return a pointer to
it.

If not NULL, 'closefn' will be called when the menu is finished (ie a
choice made with SELECT or MENU, or a Desk_message_MENUSDELETED is
received).

If 'makefn' is NULL, Desk_Menu2 will free the menu itself, with
Desk_Icon_DisposeIndData and Desk_DeskMem_Free. Otherwise, you should
provide a 'closefn' which frees the data created by 'makefn'.

NB 'title' and 'spec' are *not* copied, so they must point to permanent
strings, or be NULL, in which case makefn must not be NULL.
*/



Desk_menu2_handle	Desk_Menu2_CreateFromMsgs(
			const char		*titletag,
			const char		*spectag,
			Desk_menu2_makefn	makefn,
			Desk_menu2_flagsfn	flagsfn,
			Desk_menu2_subfn	subfn,
			Desk_menu2_selectfn	selectfn,
			Desk_menu2_closefn	closefn,
			Desk_menu2_helpfn	helpfn,
			void			*reference
			);
/*
Same as Desk_Menu2_Create, except the title and menu specification are read
from a message file using Desk_Msgs_Lookup( titletag, ...) and Desk_Msgs_Lookup(
spectag, ...) .
*/


void	Desk_Menu2_Open( Desk_menu2_handle handle, int x, int y);
/*
This opens the specified menu. It uses Desk_Menu_Show, so use y=-1 if the
menu is an iconbar menu.
*/






void	Desk_Menu2_AttachMenu( 
	Desk_window_handle	window, 
	Desk_icon_handle	icon,
	Desk_menu2_handle	menu,
	int			button
	);
/*
This uses Desk_Event_Claim to open a menu when the specified icon-window is
clicked with the specified button(s). If the click is on the iconbar,
the menu will be automatically opened in the correct position for
iconbar menus.

Eg

Desk_Menu2_AttachMenu( w, i, specialmenu, Desk_button_MENU | Desk_button_SELECT);
Desk_Menu2_AttachMenu( w, Desk_event_ANY, generalmenu, Desk_button_MENU);

See also: Desk_Menu2_DetachMenu.
*/


void	Desk_Menu2_DetachMenu( 
	Desk_window_handle	window, 
	Desk_icon_handle	icon,
	Desk_menu2_handle	menu,
	int			button
	);
/*
Stops the specified menu being opened when the icon-window is clicked
with the specified button(s).

See also: Desk_Menu2_AttachMenu.
*/






#ifdef Desk_DeskLib_DEBUG
	#ifdef Desk__making_Menu2
		#include "Debug.h"
		#define Desk_debug_level Desk_menu2_debuglevel
	#endif
	
	extern int	Desk_menu2_debuglevel;
/*
In the debug version of DeskLib, this is the Menu2 library's own
version of Desk_debug_level. It is initially 0; a program can set it to
different values to turn on different debug ouputs in the Menu2
library.
 */
#endif


#ifdef __cplusplus
}
#endif


#endif
