1 // * This makes emacs happy -*-Mode: C++;-*-
2 /****************************************************************************
3 * Copyright (c) 1998-2003,2005 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.25 2005/08/13 18:10:36 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
51 friend class NCursesMenu
;
56 inline void OnError (int err
) const THROWS(NCursesMenuException
) {
58 THROW(new NCursesMenuException (err
));
62 NCursesMenuItem (const char* p_name
= NULL
,
63 const char* p_descript
= NULL
)
66 item
= p_name
? ::new_item (p_name
, p_descript
) : STATIC_CAST(ITEM
*)(0);
68 OnError (E_SYSTEM_ERROR
);
70 // Create an item. If you pass both parameters as NULL, a delimiting
71 // item is constructed which can be used to terminate a list of
72 // NCursesMenu objects.
74 NCursesMenuItem
& operator=(const NCursesMenuItem
& rhs
)
82 NCursesMenuItem(const NCursesMenuItem
& rhs
)
87 virtual ~NCursesMenuItem ();
88 // Release the items memory
90 inline const char* name () const {
91 return ::item_name (item
);
95 inline const char* description () const {
96 return ::item_description (item
);
98 // Description of the item
100 inline int (index
) (void) const {
101 return ::item_index (item
);
103 // Index of the item in an item array (or -1)
105 inline void options_on (Item_Options opts
) {
106 OnError (::item_opts_on (item
, opts
));
108 // Switch on the items options
110 inline void options_off (Item_Options opts
) {
111 OnError (::item_opts_off (item
, opts
));
113 // Switch off the item's option
115 inline Item_Options
options () const {
116 return ::item_opts (item
);
118 // Retrieve the items options
120 inline void set_options (Item_Options opts
) {
121 OnError (::set_item_opts (item
, opts
));
123 // Set the items options
125 inline void set_value (bool f
) {
126 OnError (::set_item_value (item
,f
));
128 // Set/Reset the items selection state
130 inline bool value () const {
131 return ::item_value (item
);
133 // Retrieve the items selection state
135 inline bool visible () const {
136 return ::item_visible (item
);
138 // Retrieve visibility of the item
140 virtual bool action();
141 // Perform an action associated with this item; you may use this in an
142 // user supplied driver for a menu; you may derive from this class and
143 // overload action() to supply items with different actions.
144 // If an action returns true, the menu will be exited. The default action
148 // Prototype for an items callback function.
149 typedef bool ITEMCALLBACK(NCursesMenuItem
&);
151 // If you don't like to create a child class for individual items to
152 // overload action(), you may use this class and provide a callback
153 // function pointer for items.
154 class NCURSES_IMPEXP NCursesMenuCallbackItem
: public NCursesMenuItem
160 NCursesMenuCallbackItem(ITEMCALLBACK
* fct
= NULL
,
161 const char* p_name
= NULL
,
162 const char* p_descript
= NULL
)
163 : NCursesMenuItem (p_name
, p_descript
),
167 NCursesMenuCallbackItem
& operator=(const NCursesMenuCallbackItem
& rhs
)
175 NCursesMenuCallbackItem(const NCursesMenuCallbackItem
& rhs
)
176 : NCursesMenuItem(rhs
),
181 virtual ~NCursesMenuCallbackItem();
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.
190 void _nc_xx_mnu_init(MENU
*);
191 void _nc_xx_mnu_term(MENU
*);
192 void _nc_xx_itm_init(MENU
*);
193 void _nc_xx_itm_term(MENU
*);
197 // -------------------------------------------------------------------------
198 // This wraps the MENU type of <menu.h>
199 // -------------------------------------------------------------------------
201 class NCURSES_IMPEXP NCursesMenu
: public NCursesPanel
207 NCursesWindow
* sub
; // the subwindow object
208 bool b_sub_owner
; // is this our own subwindow?
209 bool b_framed
; // has the menu a border?
210 bool b_autoDelete
; // Delete items when deleting menu?
212 NCursesMenuItem
** my_items
; // The array of items for this menu
214 // This structure is used for the menu's user data field to link the
215 // MENU* to the C++ object and to provide extra space for a user pointer.
217 void* m_user
; // the pointer for the user's data
218 const NCursesMenu
* m_back
; // backward pointer to C++ object
222 // Get the backward pointer to the C++ object from a MENU
223 static inline NCursesMenu
* getHook(const MENU
*m
) {
224 UserHook
* hook
= STATIC_CAST(UserHook
*)(::menu_userptr(m
));
225 assert(hook
!= 0 && hook
->m_owner
==m
);
226 return const_cast<NCursesMenu
*>(hook
->m_back
);
229 friend void _nc_xx_mnu_init(MENU
*);
230 friend void _nc_xx_mnu_term(MENU
*);
231 friend void _nc_xx_itm_init(MENU
*);
232 friend void _nc_xx_itm_term(MENU
*);
234 // Calculate ITEM* array for the menu
235 ITEM
** mapItems(NCursesMenuItem
* nitems
[]);
239 inline void set_user(void *user
) {
240 UserHook
* uptr
= STATIC_CAST(UserHook
*)(::menu_userptr (menu
));
241 assert (uptr
!= 0 && uptr
->m_back
==this && uptr
->m_owner
==menu
);
245 inline void *get_user() {
246 UserHook
* uptr
= STATIC_CAST(UserHook
*)(::menu_userptr (menu
));
247 assert (uptr
!= 0 && uptr
->m_back
==this && uptr
->m_owner
==menu
);
251 void InitMenu (NCursesMenuItem
* menu
[],
253 bool autoDeleteItems
);
255 inline void OnError (int err
) const THROWS(NCursesMenuException
) {
257 THROW(new NCursesMenuException (this, err
));
260 // this wraps the menu_driver call.
261 virtual int driver (int c
) ;
263 // 'Internal' constructor to create a menu without association to
264 // an array of items.
265 NCursesMenu( int nlines
,
269 : NCursesPanel(nlines
,ncols
,begin_y
,begin_x
),
270 menu (STATIC_CAST(MENU
*)(0)),
280 // Make a full window size menu
281 NCursesMenu (NCursesMenuItem
* Items
[],
282 bool with_frame
=FALSE
, // Reserve space for a frame?
283 bool autoDelete_Items
=FALSE
) // Autocleanup of Items?
292 InitMenu(Items
, with_frame
, autoDelete_Items
);
295 // Make a menu with a window of this size.
296 NCursesMenu (NCursesMenuItem
* Items
[],
301 bool with_frame
=FALSE
, // Reserve space for a frame?
302 bool autoDelete_Items
=FALSE
) // Autocleanup of Items?
303 : NCursesPanel(nlines
, ncols
, begin_y
, begin_x
),
311 InitMenu(Items
, with_frame
, autoDelete_Items
);
314 NCursesMenu
& operator=(const NCursesMenu
& rhs
)
318 NCursesPanel::operator=(rhs
);
323 NCursesMenu(const NCursesMenu
& rhs
)
327 b_sub_owner(rhs
.b_sub_owner
),
328 b_framed(rhs
.b_framed
),
329 b_autoDelete(rhs
.b_autoDelete
),
330 my_items(rhs
.my_items
)
334 virtual ~NCursesMenu ();
336 // Retrieve the menus subwindow
337 inline NCursesWindow
& subWindow() const {
342 // Set the menus subwindow
343 void setSubWindow(NCursesWindow
& sub
);
345 // Set these items for the menu
346 inline void setItems(NCursesMenuItem
* Items
[]) {
347 OnError(::set_menu_items(menu
,mapItems(Items
)));
350 // Remove the menu from the screen
351 inline void unpost (void) {
352 OnError (::unpost_menu (menu
));
355 // Post the menu to the screen if flag is true, unpost it otherwise
356 inline void post(bool flag
= TRUE
) {
357 flag
? OnError (::post_menu(menu
)) : OnError (::unpost_menu (menu
));
360 // Get the numer of rows and columns for this menu
361 inline void scale (int& mrows
, int& mcols
) const {
362 OnError (::scale_menu (menu
, &mrows
, &mcols
));
365 // Set the format of this menu
366 inline void set_format(int mrows
, int mcols
) {
367 OnError (::set_menu_format(menu
, mrows
, mcols
));
370 // Get the format of this menu
371 inline void menu_format(int& rows
,int& ncols
) {
372 ::menu_format(menu
,&rows
,&ncols
);
376 inline NCursesMenuItem
* items() const {
380 // Get the number of items in this menu
381 inline int count() const {
382 return ::item_count(menu
);
385 // Get the current item (i.e. the one the cursor is located)
386 inline NCursesMenuItem
* current_item() const {
387 return my_items
[::item_index(::current_item(menu
))];
390 // Get the marker string
391 inline const char* mark() const {
392 return ::menu_mark(menu
);
395 // Set the marker string
396 inline void set_mark(const char *marker
) {
397 OnError (::set_menu_mark (menu
, marker
));
400 // Get the name of the request code c
401 inline static const char* request_name(int c
) {
402 return ::menu_request_name(c
);
405 // Get the current pattern
406 inline char* pattern() const {
407 return ::menu_pattern(menu
);
410 // true if there is a pattern match, false otherwise.
411 bool set_pattern (const char *pat
);
413 // set the default attributes for the menu
414 // i.e. set fore, back and grey attribute
415 virtual void setDefaultAttributes();
417 // Get the menus background attributes
418 inline chtype
back() const {
419 return ::menu_back(menu
);
422 // Get the menus foreground attributes
423 inline chtype
fore() const {
424 return ::menu_fore(menu
);
427 // Get the menus grey attributes (used for unselectable items)
428 inline chtype
grey() const {
429 return ::menu_grey(menu
);
432 // Set the menus background attributes
433 inline chtype
set_background(chtype a
) {
434 return ::set_menu_back(menu
,a
);
437 // Set the menus foreground attributes
438 inline chtype
set_foreground(chtype a
) {
439 return ::set_menu_fore(menu
,a
);
442 // Set the menus grey attributes (used for unselectable items)
443 inline chtype
set_grey(chtype a
) {
444 return ::set_menu_grey(menu
,a
);
447 inline void options_on (Menu_Options opts
) {
448 OnError (::menu_opts_on (menu
,opts
));
451 inline void options_off(Menu_Options opts
) {
452 OnError (::menu_opts_off(menu
,opts
));
455 inline Menu_Options
options() const {
456 return ::menu_opts(menu
);
459 inline void set_options (Menu_Options opts
) {
460 OnError (::set_menu_opts (menu
,opts
));
463 inline int pad() const {
464 return ::menu_pad(menu
);
467 inline void set_pad (int padch
) {
468 OnError (::set_menu_pad (menu
, padch
));
471 // Position the cursor to the current item
472 inline void position_cursor () const {
473 OnError (::pos_menu_cursor (menu
));
476 // Set the current item
477 inline void set_current(NCursesMenuItem
& I
) {
478 OnError (::set_current_item(menu
, I
.item
));
481 // Get the current top row of the menu
482 inline int top_row (void) const {
483 return ::top_row (menu
);
486 // Set the current top row of the menu
487 inline void set_top_row (int row
) {
488 OnError (::set_top_row (menu
, row
));
492 // Set the spacing for the menu
493 inline void setSpacing(int spc_description
,
496 OnError(::set_menu_spacing(menu
,
502 // Get the spacing info for the menu
503 inline void Spacing(int& spc_description
,
505 int& spc_columns
) const {
506 OnError(::menu_spacing(menu
,
513 inline void frame(const char *title
=NULL
, const char* btitle
=NULL
) {
515 NCursesPanel::frame(title
,btitle
);
517 OnError(E_SYSTEM_ERROR
);
520 inline void boldframe(const char *title
=NULL
, const char* btitle
=NULL
) {
522 NCursesPanel::boldframe(title
,btitle
);
524 OnError(E_SYSTEM_ERROR
);
527 inline void label(const char *topLabel
, const char *bottomLabel
) {
529 NCursesPanel::label(topLabel
,bottomLabel
);
531 OnError(E_SYSTEM_ERROR
);
538 // Called after the menu gets repositioned in its window.
539 // This is especially true if the menu is posted.
540 virtual void On_Menu_Init();
542 // Called before the menu gets repositioned in its window.
543 // This is especially true if the menu is unposted.
544 virtual void On_Menu_Termination();
546 // Called after the item became the current item
547 virtual void On_Item_Init(NCursesMenuItem
& item
);
549 // Called before this item is left as current item.
550 virtual void On_Item_Termination(NCursesMenuItem
& item
);
552 // Provide a default key virtualization. Translate the keyboard
553 // code c into a menu request code.
554 // The default implementation provides a hopefully straightforward
555 // mapping for the most common keystrokes and menu requests.
556 virtual int virtualize(int c
);
560 inline NCursesMenuItem
* operator[](int i
) const {
561 if ( (i
< 0) || (i
>= ::item_count (menu
)) )
562 OnError (E_BAD_ARGUMENT
);
563 return (my_items
[i
]);
566 // Perform the menu's operation
567 // Return the item where you left the selection mark for a single
568 // selection menu, or NULL for a multivalued menu.
569 virtual NCursesMenuItem
* operator()(void);
571 // --------------------
572 // Exception handlers
573 // Called by operator()
574 // --------------------
576 // Called if the request is denied
577 virtual void On_Request_Denied(int c
) const;
579 // Called if the item is not selectable
580 virtual void On_Not_Selectable(int c
) const;
582 // Called if pattern doesn't match
583 virtual void On_No_Match(int c
) const;
585 // Called if the command is unknown
586 virtual void On_Unknown_Command(int c
) const;
590 // -------------------------------------------------------------------------
591 // This is the typical C++ typesafe way to allow to attach
592 // user data to an item of a menu. Its assumed that the user
593 // data belongs to some class T. Use T as template argument
594 // to create a UserItem.
595 // -------------------------------------------------------------------------
597 template<class T
> class NCURSES_IMPEXP NCursesUserItem
: public NCursesMenuItem
600 NCursesUserItem (const char* p_name
,
601 const char* p_descript
= NULL
,
602 const T
* p_UserData
= STATIC_CAST(T
*)(0))
603 : NCursesMenuItem (p_name
, p_descript
) {
605 OnError (::set_item_userptr (item
, const_cast<void *>(reinterpret_cast<const void*>(p_UserData
))));
608 virtual ~NCursesUserItem() {}
610 inline const T
* UserData (void) const {
611 return reinterpret_cast<const T
*>(::item_userptr (item
));
614 inline virtual void setUserData(const T
* p_UserData
) {
616 OnError (::set_item_userptr (item
, const_cast<void *>(reinterpret_cast<const void *>(p_UserData
))));
620 // -------------------------------------------------------------------------
621 // The same mechanism is used to attach user data to a menu
622 // -------------------------------------------------------------------------
624 template<class T
> class NCURSES_IMPEXP NCursesUserMenu
: public NCursesMenu
627 NCursesUserMenu( int nlines
,
631 const T
* p_UserData
= STATIC_CAST(T
*)(0))
632 : NCursesMenu(nlines
,ncols
,begin_y
,begin_x
) {
634 set_user (const_cast<void *>(p_UserData
));
638 NCursesUserMenu (NCursesMenuItem Items
[],
639 const T
* p_UserData
= STATIC_CAST(T
*)(0),
640 bool with_frame
=FALSE
,
641 bool autoDelete_Items
=FALSE
)
642 : NCursesMenu (Items
, with_frame
, autoDelete_Items
) {
644 set_user (const_cast<void *>(p_UserData
));
647 NCursesUserMenu (NCursesMenuItem Items
[],
652 const T
* p_UserData
= STATIC_CAST(T
*)(0),
653 bool with_frame
=FALSE
)
654 : NCursesMenu (Items
, nlines
, ncols
, begin_y
, begin_x
, with_frame
) {
656 set_user (const_cast<void *>(p_UserData
));
659 virtual ~NCursesUserMenu() {
662 inline T
* UserData (void) const {
663 return reinterpret_cast<T
*>(get_user ());
666 inline virtual void setUserData (const T
* p_UserData
) {
668 set_user (const_cast<void *>(p_UserData
));
672 #endif /* NCURSES_CURSESM_H_incl */