1 // * This makes emacs happy -*-Mode: C++;-*-
2 /****************************************************************************
3 * Copyright (c) 1998-2002,2003 Free Software Foundation, Inc. *
5 * Permission is hereby granted, free of charge, to any person obtaining a *
6 * copy of this software and associated documentation files (the *
7 * "Software"), to deal in the Software without restriction, including *
8 * without limitation the rights to use, copy, modify, merge, publish, *
9 * distribute, distribute with modifications, sublicense, and/or sell *
10 * copies of the Software, and to permit persons to whom the Software is *
11 * furnished to do so, subject to the following conditions: *
13 * The above copyright notice and this permission notice shall be included *
14 * in all copies or substantial portions of the Software. *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS *
17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF *
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. *
19 * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
20 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
21 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR *
22 * THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
24 * Except as contained in this notice, the name(s) of the above copyright *
25 * holders shall not be used in advertising or otherwise to promote the *
26 * sale, use or other dealings in this Software without prior written *
28 ****************************************************************************/
30 /****************************************************************************
31 * Author: Juergen Pfeifer, 1997 *
32 ****************************************************************************/
34 // $Id: cursesm.h,v 1.17 2003/10/25 15:04:46 tom Exp $
36 #ifndef NCURSES_CURSESM_H_incl
37 #define NCURSES_CURSESM_H_incl 1
45 // -------------------------------------------------------------------------
46 // This wraps the ITEM type of <menu.h>
47 // -------------------------------------------------------------------------
49 class NCURSES_IMPEXP NCursesMenuItem
{
50 friend class NCursesMenu
;
55 inline void OnError (int err
) const THROWS(NCursesMenuException
) {
57 THROW(new NCursesMenuException (err
));
61 NCursesMenuItem (const char* p_name
= NULL
,
62 const char* p_descript
= NULL
) {
63 item
= p_name
? ::new_item (p_name
, p_descript
) : (ITEM
*)0;
65 OnError (E_SYSTEM_ERROR
);
67 // Create an item. If you pass both parameters as NULL, a delimiting
68 // item is constructed which can be used to terminate a list of
69 // NCursesMenu objects.
71 virtual ~NCursesMenuItem ();
72 // Release the items memory
74 inline const char* name () const {
75 return ::item_name (item
);
79 inline const char* description () const {
80 return ::item_description (item
);
82 // Description of the item
84 inline int (index
) (void) const {
85 return ::item_index (item
);
87 // Index of the item in an item array (or -1)
89 inline void options_on (Item_Options options
) {
90 OnError (::item_opts_on (item
, options
));
92 // Switch on the items options
94 inline void options_off (Item_Options options
) {
95 OnError (::item_opts_off (item
, options
));
97 // Switch off the item's option
99 inline Item_Options
options () const {
100 return ::item_opts (item
);
102 // Retrieve the items options
104 inline void set_options (Item_Options options
) {
105 OnError (::set_item_opts (item
, options
));
107 // Set the items options
109 inline void set_value (bool f
) {
110 OnError (::set_item_value (item
,f
));
112 // Set/Reset the items selection state
114 inline bool value () const {
115 return ::item_value (item
);
117 // Retrieve the items selection state
119 inline bool visible () const {
120 return ::item_visible (item
);
122 // Retrieve visibility of the item
124 virtual bool action();
125 // Perform an action associated with this item; you may use this in an
126 // user supplied driver for a menu; you may derive from this class and
127 // overload action() to supply items with different actions.
128 // If an action returns true, the menu will be exited. The default action
132 // Prototype for an items callback function.
133 typedef bool ITEMCALLBACK(NCursesMenuItem
&);
135 // If you don't like to create a child class for individual items to
136 // overload action(), you may use this class and provide a callback
137 // function pointer for items.
138 class NCURSES_IMPEXP NCursesMenuCallbackItem
: public NCursesMenuItem
{
143 NCursesMenuCallbackItem(ITEMCALLBACK
* fct
= NULL
,
144 const char* p_name
= NULL
,
145 const char* p_descript
= NULL
)
146 : NCursesMenuItem (p_name
, p_descript
),
150 virtual ~NCursesMenuCallbackItem();
155 // -------------------------------------------------------------------------
156 // This wraps the MENU type of <menu.h>
157 // -------------------------------------------------------------------------
159 class NCURSES_IMPEXP NCursesMenu
: public NCursesPanel
{
164 NCursesWindow
* sub
; // the subwindow object
165 bool b_sub_owner
; // is this our own subwindow?
166 bool b_framed
; // has the menu a border?
167 bool b_autoDelete
; // Delete items when deleting menu?
169 NCursesMenuItem
** my_items
; // The array of items for this menu
171 // This structure is used for the menu's user data field to link the
172 // MENU* to the C++ object and to provide extra space for a user pointer.
174 void* m_user
; // the pointer for the user's data
175 const NCursesMenu
* m_back
; // backward pointer to C++ object
179 // Get the backward pointer to the C++ object from a MENU
180 static inline NCursesMenu
* getHook(const MENU
*m
) {
181 UserHook
* hook
= (UserHook
*)::menu_userptr(m
);
182 assert(hook
!= 0 && hook
->m_owner
==m
);
183 return (NCursesMenu
*)(hook
->m_back
);
186 // This are the built-in hook functions in this C++ binding. In C++ we use
187 // virtual member functions (see below On_..._Init and On_..._Termination)
188 // to provide this functionality in an object oriented manner.
189 static void mnu_init(MENU
*);
190 static void mnu_term(MENU
*);
191 static void itm_init(MENU
*);
192 static void itm_term(MENU
*);
194 // Calculate ITEM* array for the menu
195 ITEM
** mapItems(NCursesMenuItem
* nitems
[]);
199 inline void set_user(void *user
) {
200 UserHook
* uptr
= (UserHook
*)::menu_userptr (menu
);
201 assert (uptr
!= 0 && uptr
->m_back
==this && uptr
->m_owner
==menu
);
205 inline void *get_user() {
206 UserHook
* uptr
= (UserHook
*)::menu_userptr (menu
);
207 assert (uptr
!= 0 && uptr
->m_back
==this && uptr
->m_owner
==menu
);
211 void InitMenu (NCursesMenuItem
* menu
[],
213 bool autoDeleteItems
);
215 inline void OnError (int err
) const THROWS(NCursesMenuException
) {
217 THROW(new NCursesMenuException (this, err
));
220 // this wraps the menu_driver call.
221 virtual int driver (int c
) ;
223 // 'Internal' constructor to create a menu without association to
224 // an array of items.
225 NCursesMenu( int lines
,
229 : NCursesPanel(lines
,cols
,begin_y
,begin_x
),
234 // Make a full window size menu
235 NCursesMenu (NCursesMenuItem
* Items
[],
236 bool with_frame
=FALSE
, // Reserve space for a frame?
237 bool autoDelete_Items
=FALSE
) // Autocleanup of Items?
239 InitMenu(Items
, with_frame
, autoDelete_Items
);
242 // Make a menu with a window of this size.
243 NCursesMenu (NCursesMenuItem
* Items
[],
248 bool with_frame
=FALSE
, // Reserve space for a frame?
249 bool autoDelete_Items
=FALSE
) // Autocleanup of Items?
250 : NCursesPanel(lines
, cols
, begin_y
, begin_x
) {
251 InitMenu(Items
, with_frame
, autoDelete_Items
);
254 virtual ~NCursesMenu ();
256 // Retrieve the menus subwindow
257 inline NCursesWindow
& subWindow() const {
262 // Set the menus subwindow
263 void setSubWindow(NCursesWindow
& sub
);
265 // Set these items for the menu
266 inline void setItems(NCursesMenuItem
* Items
[]) {
267 OnError(::set_menu_items(menu
,mapItems(Items
)));
270 // Remove the menu from the screen
271 inline void unpost (void) {
272 OnError (::unpost_menu (menu
));
275 // Post the menu to the screen if flag is true, unpost it otherwise
276 inline void post(bool flag
= TRUE
) {
277 flag
? OnError (::post_menu(menu
)) : OnError (::unpost_menu (menu
));
280 // Get the numer of rows and columns for this menu
281 inline void scale (int& mrows
, int& mcols
) const {
282 OnError (::scale_menu (menu
, &mrows
, &mcols
));
285 // Set the format of this menu
286 inline void set_format(int mrows
, int mcols
) {
287 OnError (::set_menu_format(menu
, mrows
, mcols
));
290 // Get the format of this menu
291 inline void menu_format(int& rows
,int& cols
) {
292 ::menu_format(menu
,&rows
,&cols
);
296 inline NCursesMenuItem
* items() const {
300 // Get the number of items in this menu
301 inline int count() const {
302 return ::item_count(menu
);
305 // Get the current item (i.e. the one the cursor is located)
306 inline NCursesMenuItem
* current_item() const {
307 return my_items
[::item_index(::current_item(menu
))];
310 // Get the marker string
311 inline const char* mark() const {
312 return ::menu_mark(menu
);
315 // Set the marker string
316 inline void set_mark(const char *mark
) {
317 OnError (::set_menu_mark (menu
, mark
));
320 // Get the name of the request code c
321 inline static const char* request_name(int c
) {
322 return ::menu_request_name(c
);
325 // Get the current pattern
326 inline char* pattern() const {
327 return ::menu_pattern(menu
);
330 // true if there is a pattern match, false otherwise.
331 bool set_pattern (const char *pat
);
333 // set the default attributes for the menu
334 // i.e. set fore, back and grey attribute
335 virtual void setDefaultAttributes();
337 // Get the menus background attributes
338 inline chtype
back() const {
339 return ::menu_back(menu
);
342 // Get the menus foreground attributes
343 inline chtype
fore() const {
344 return ::menu_fore(menu
);
347 // Get the menus grey attributes (used for unselectable items)
348 inline chtype
grey() const {
349 return ::menu_grey(menu
);
352 // Set the menus background attributes
353 inline chtype
set_background(chtype a
) {
354 return ::set_menu_back(menu
,a
);
357 // Set the menus foreground attributes
358 inline chtype
set_foreground(chtype a
) {
359 return ::set_menu_fore(menu
,a
);
362 // Set the menus grey attributes (used for unselectable items)
363 inline chtype
set_grey(chtype a
) {
364 return ::set_menu_grey(menu
,a
);
367 inline void options_on (Menu_Options opts
) {
368 OnError (::menu_opts_on (menu
,opts
));
371 inline void options_off(Menu_Options opts
) {
372 OnError (::menu_opts_off(menu
,opts
));
375 inline Menu_Options
options() const {
376 return ::menu_opts(menu
);
379 inline void set_options (Menu_Options opts
) {
380 OnError (::set_menu_opts (menu
,opts
));
383 inline int pad() const {
384 return ::menu_pad(menu
);
387 inline void set_pad (int padch
) {
388 OnError (::set_menu_pad (menu
, padch
));
391 // Position the cursor to the current item
392 inline void position_cursor () const {
393 OnError (::pos_menu_cursor (menu
));
396 // Set the current item
397 inline void set_current(NCursesMenuItem
& I
) {
398 OnError (::set_current_item(menu
, I
.item
));
401 // Get the current top row of the menu
402 inline int top_row (void) const {
403 return ::top_row (menu
);
406 // Set the current top row of the menu
407 inline void set_top_row (int row
) {
408 OnError (::set_top_row (menu
, row
));
412 // Set the spacing for the menu
413 inline void setSpacing(int spc_description
,
416 OnError(::set_menu_spacing(menu
,
422 // Get the spacing info for the menu
423 inline void Spacing(int& spc_description
,
425 int& spc_columns
) const {
426 OnError(::menu_spacing(menu
,
433 inline void frame(const char *title
=NULL
, const char* btitle
=NULL
) {
435 NCursesPanel::frame(title
,btitle
);
437 OnError(E_SYSTEM_ERROR
);
440 inline void boldframe(const char *title
=NULL
, const char* btitle
=NULL
) {
442 NCursesPanel::boldframe(title
,btitle
);
444 OnError(E_SYSTEM_ERROR
);
447 inline void label(const char *topLabel
, const char *bottomLabel
) {
449 NCursesPanel::label(topLabel
,bottomLabel
);
451 OnError(E_SYSTEM_ERROR
);
458 // Called after the menu gets repositioned in its window.
459 // This is especially true if the menu is posted.
460 virtual void On_Menu_Init();
462 // Called before the menu gets repositioned in its window.
463 // This is especially true if the menu is unposted.
464 virtual void On_Menu_Termination();
466 // Called after the item became the current item
467 virtual void On_Item_Init(NCursesMenuItem
& item
);
469 // Called before this item is left as current item.
470 virtual void On_Item_Termination(NCursesMenuItem
& item
);
472 // Provide a default key virtualization. Translate the keyboard
473 // code c into a menu request code.
474 // The default implementation provides a hopefully straightforward
475 // mapping for the most common keystrokes and menu requests.
476 virtual int virtualize(int c
);
480 inline NCursesMenuItem
* operator[](int i
) const {
481 if ( (i
< 0) || (i
>= ::item_count (menu
)) )
482 OnError (E_BAD_ARGUMENT
);
483 return (my_items
[i
]);
486 // Perform the menu's operation
487 // Return the item where you left the selection mark for a single
488 // selection menu, or NULL for a multivalued menu.
489 virtual NCursesMenuItem
* operator()(void);
491 // --------------------
492 // Exception handlers
493 // Called by operator()
494 // --------------------
496 // Called if the request is denied
497 virtual void On_Request_Denied(int c
) const;
499 // Called if the item is not selectable
500 virtual void On_Not_Selectable(int c
) const;
502 // Called if pattern doesn't match
503 virtual void On_No_Match(int c
) const;
505 // Called if the command is unknown
506 virtual void On_Unknown_Command(int c
) const;
510 // -------------------------------------------------------------------------
511 // This is the typical C++ typesafe way to allow to attach
512 // user data to an item of a menu. Its assumed that the user
513 // data belongs to some class T. Use T as template argument
514 // to create a UserItem.
515 // -------------------------------------------------------------------------
517 template<class T
> class NCURSES_IMPEXP NCursesUserItem
: public NCursesMenuItem
520 NCursesUserItem (const char* p_name
,
521 const char* p_descript
= NULL
,
522 const T
* p_UserData
= (T
*)0)
523 : NCursesMenuItem (p_name
, p_descript
) {
525 OnError (::set_item_userptr (item
, (void *)p_UserData
));
528 virtual ~NCursesUserItem() {};
530 inline const T
* UserData (void) const {
531 return (const T
*)::item_userptr (item
);
534 inline virtual void setUserData(const T
* p_UserData
) {
536 OnError (::set_item_userptr (item
, (void *)p_UserData
));
540 // -------------------------------------------------------------------------
541 // The same mechanism is used to attach user data to a menu
542 // -------------------------------------------------------------------------
544 template<class T
> class NCURSES_IMPEXP NCursesUserMenu
: public NCursesMenu
547 NCursesUserMenu( int lines
,
551 const T
* p_UserData
= (T
*)0)
552 : NCursesMenu(lines
,cols
,begin_y
,begin_x
) {
554 set_user ((void *)p_UserData
);
558 NCursesUserMenu (NCursesMenuItem Items
[],
559 const T
* p_UserData
= (T
*)0,
560 bool with_frame
=FALSE
,
561 bool autoDelete_Items
=FALSE
)
562 : NCursesMenu (Items
, with_frame
, autoDelete_Items
) {
564 set_user ((void *)p_UserData
);
567 NCursesUserMenu (NCursesMenuItem Items
[],
572 const T
* p_UserData
= (T
*)0,
573 bool with_frame
=FALSE
)
574 : NCursesMenu (Items
, lines
, cols
, begin_y
, begin_x
, with_frame
) {
576 set_user ((void *)p_UserData
);
579 virtual ~NCursesUserMenu() {
582 inline T
* UserData (void) const {
583 return (T
*)get_user ();
586 inline virtual void setUserData (const T
* p_UserData
) {
588 set_user ((void *)p_UserData
);
592 #endif // NCURSES_CURSESM_H_incl