1 // * This makes emacs happy -*-Mode: C++;-*-
2 /****************************************************************************
3 * Copyright (c) 1998,1999,2000 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 * Contact: http://www.familiepfeifer.de/Contact.aspx?Lang=en *
33 ****************************************************************************/
35 // $Id: cursesm.h,v 1.16 2002/07/06 15:47:52 juergen Exp $
37 #ifndef NCURSES_CURSESM_H_incl
38 #define NCURSES_CURSESM_H_incl 1
46 // -------------------------------------------------------------------------
47 // This wraps the ITEM type of <menu.h>
48 // -------------------------------------------------------------------------
50 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 ) {
64 item = p_name ? ::new_item (p_name, p_descript) : (ITEM*)0;
66 OnError (E_SYSTEM_ERROR);
68 // Create an item. If you pass both parameters as NULL, a delimiting
69 // item is constructed which can be used to terminate a list of
70 // NCursesMenu objects.
72 virtual ~NCursesMenuItem ();
73 // Release the items memory
75 inline const char* name () const {
76 return ::item_name (item);
80 inline const char* description () const {
81 return ::item_description (item);
83 // Description of the item
85 inline int (index) (void) const {
86 return ::item_index (item);
88 // Index of the item in an item array (or -1)
90 inline void options_on (Item_Options options) {
91 OnError (::item_opts_on (item, options));
93 // Switch on the items options
95 inline void options_off (Item_Options options) {
96 OnError (::item_opts_off (item, options));
98 // Switch off the item's option
100 inline Item_Options options () const {
101 return ::item_opts (item);
103 // Retrieve the items options
105 inline void set_options (Item_Options options) {
106 OnError (::set_item_opts (item, options));
108 // Set the items options
110 inline void set_value (bool f) {
111 OnError (::set_item_value (item,f));
113 // Set/Reset the items selection state
115 inline bool value () const {
116 return ::item_value (item);
118 // Retrieve the items selection state
120 inline bool visible () const {
121 return ::item_visible (item);
123 // Retrieve visibility of the item
125 virtual bool action();
126 // Perform an action associated with this item; you may use this in an
127 // user supplied driver for a menu; you may derive from this class and
128 // overload action() to supply items with different actions.
129 // If an action returns true, the menu will be exited. The default action
133 // Prototype for an items callback function.
134 typedef bool ITEMCALLBACK(NCursesMenuItem&);
136 // If you don't like to create a child class for individual items to
137 // overload action(), you may use this class and provide a callback
138 // function pointer for items.
139 class NCURSES_IMPEXP NCursesMenuCallbackItem : public NCursesMenuItem {
144 NCursesMenuCallbackItem(ITEMCALLBACK* fct = NULL,
145 const char* p_name = NULL,
146 const char* p_descript = NULL )
147 : NCursesMenuItem (p_name, p_descript),
151 virtual ~NCursesMenuCallbackItem();
156 // -------------------------------------------------------------------------
157 // This wraps the MENU type of <menu.h>
158 // -------------------------------------------------------------------------
160 class NCURSES_IMPEXP NCursesMenu : public NCursesPanel {
165 NCursesWindow* sub; // the subwindow object
166 bool b_sub_owner; // is this our own subwindow?
167 bool b_framed; // has the menu a border?
168 bool b_autoDelete; // Delete items when deleting menu?
170 NCursesMenuItem** my_items; // The array of items for this menu
172 // This structure is used for the menu's user data field to link the
173 // MENU* to the C++ object and to provide extra space for a user pointer.
175 void* m_user; // the pointer for the user's data
176 const NCursesMenu* m_back; // backward pointer to C++ object
180 // Get the backward pointer to the C++ object from a MENU
181 static inline NCursesMenu* getHook(const MENU *m) {
182 UserHook* hook = (UserHook*)::menu_userptr(m);
183 assert(hook != 0 && hook->m_owner==m);
184 return (NCursesMenu*)(hook->m_back);
187 // This are the built-in hook functions in this C++ binding. In C++ we use
188 // virtual member functions (see below On_..._Init and On_..._Termination)
189 // to provide this functionality in an object oriented manner.
190 static void mnu_init(MENU *);
191 static void mnu_term(MENU *);
192 static void itm_init(MENU *);
193 static void itm_term(MENU *);
195 // Calculate ITEM* array for the menu
196 ITEM** mapItems(NCursesMenuItem* nitems[]);
200 inline void set_user(void *user) {
201 UserHook* uptr = (UserHook*)::menu_userptr (menu);
202 assert (uptr != 0 && uptr->m_back==this && uptr->m_owner==menu);
206 inline void *get_user() {
207 UserHook* uptr = (UserHook*)::menu_userptr (menu);
208 assert (uptr != 0 && uptr->m_back==this && uptr->m_owner==menu);
212 void InitMenu (NCursesMenuItem* menu[],
214 bool autoDeleteItems);
216 inline void OnError (int err) const THROWS(NCursesMenuException) {
218 THROW(new NCursesMenuException (this, err));
221 // this wraps the menu_driver call.
222 virtual int driver (int c) ;
224 // 'Internal' constructor to create a menu without association to
225 // an array of items.
226 NCursesMenu( int lines,
230 : NCursesPanel(lines,cols,begin_y,begin_x),
235 // Make a full window size menu
236 NCursesMenu (NCursesMenuItem* Items[],
237 bool with_frame=FALSE, // Reserve space for a frame?
238 bool autoDelete_Items=FALSE) // Autocleanup of Items?
240 InitMenu(Items, with_frame, autoDelete_Items);
243 // Make a menu with a window of this size.
244 NCursesMenu (NCursesMenuItem* Items[],
249 bool with_frame=FALSE, // Reserve space for a frame?
250 bool autoDelete_Items=FALSE) // Autocleanup of Items?
251 : NCursesPanel(lines, cols, begin_y, begin_x) {
252 InitMenu(Items, with_frame, autoDelete_Items);
255 virtual ~NCursesMenu ();
257 // Retrieve the menus subwindow
258 inline NCursesWindow& subWindow() const {
263 // Set the menus subwindow
264 void setSubWindow(NCursesWindow& sub);
266 // Set these items for the menu
267 inline void setItems(NCursesMenuItem* Items[]) {
268 OnError(::set_menu_items(menu,mapItems(Items)));
271 // Remove the menu from the screen
272 inline void unpost (void) {
273 OnError (::unpost_menu (menu));
276 // Post the menu to the screen if flag is true, unpost it otherwise
277 inline void post(bool flag = TRUE) {
278 flag ? OnError (::post_menu(menu)) : OnError (::unpost_menu (menu));
281 // Get the numer of rows and columns for this menu
282 inline void scale (int& mrows, int& mcols) const {
283 OnError (::scale_menu (menu, &mrows, &mcols));
286 // Set the format of this menu
287 inline void set_format(int mrows, int mcols) {
288 OnError (::set_menu_format(menu, mrows, mcols));
291 // Get the format of this menu
292 inline void menu_format(int& rows,int& cols) {
293 ::menu_format(menu,&rows,&cols);
297 inline NCursesMenuItem* items() const {
301 // Get the number of items in this menu
302 inline int count() const {
303 return ::item_count(menu);
306 // Get the current item (i.e. the one the cursor is located)
307 inline NCursesMenuItem* current_item() const {
308 return my_items[::item_index(::current_item(menu))];
311 // Get the marker string
312 inline const char* mark() const {
313 return ::menu_mark(menu);
316 // Set the marker string
317 inline void set_mark(const char *mark) {
318 OnError (::set_menu_mark (menu, mark));
321 // Get the name of the request code c
322 inline static const char* request_name(int c) {
323 return ::menu_request_name(c);
326 // Get the current pattern
327 inline char* pattern() const {
328 return ::menu_pattern(menu);
331 // true if there is a pattern match, false otherwise.
332 bool set_pattern (const char *pat);
334 // set the default attributes for the menu
335 // i.e. set fore, back and grey attribute
336 virtual void setDefaultAttributes();
338 // Get the menus background attributes
339 inline chtype back() const {
340 return ::menu_back(menu);
343 // Get the menus foreground attributes
344 inline chtype fore() const {
345 return ::menu_fore(menu);
348 // Get the menus grey attributes (used for unselectable items)
349 inline chtype grey() const {
350 return ::menu_grey(menu);
353 // Set the menus background attributes
354 inline chtype set_background(chtype a) {
355 return ::set_menu_back(menu,a);
358 // Set the menus foreground attributes
359 inline chtype set_foreground(chtype a) {
360 return ::set_menu_fore(menu,a);
363 // Set the menus grey attributes (used for unselectable items)
364 inline chtype set_grey(chtype a) {
365 return ::set_menu_grey(menu,a);
368 inline void options_on (Menu_Options opts) {
369 OnError (::menu_opts_on (menu,opts));
372 inline void options_off(Menu_Options opts) {
373 OnError (::menu_opts_off(menu,opts));
376 inline Menu_Options options() const {
377 return ::menu_opts(menu);
380 inline void set_options (Menu_Options opts) {
381 OnError (::set_menu_opts (menu,opts));
384 inline int pad() const {
385 return ::menu_pad(menu);
388 inline void set_pad (int padch) {
389 OnError (::set_menu_pad (menu, padch));
392 // Position the cursor to the current item
393 inline void position_cursor () const {
394 OnError (::pos_menu_cursor (menu));
397 // Set the current item
398 inline void set_current(NCursesMenuItem& I) {
399 OnError (::set_current_item(menu, I.item));
402 // Get the current top row of the menu
403 inline int top_row (void) const {
404 return ::top_row (menu);
407 // Set the current top row of the menu
408 inline void set_top_row (int row) {
409 OnError (::set_top_row (menu, row));
413 // Set the spacing for the menu
414 inline void setSpacing(int spc_description,
417 OnError(::set_menu_spacing(menu,
423 // Get the spacing info for the menu
424 inline void Spacing(int& spc_description,
426 int& spc_columns) const {
427 OnError(::menu_spacing(menu,
434 inline void frame(const char *title=NULL, const char* btitle=NULL) {
436 NCursesPanel::frame(title,btitle);
438 OnError(E_SYSTEM_ERROR);
441 inline void boldframe(const char *title=NULL, const char* btitle=NULL) {
443 NCursesPanel::boldframe(title,btitle);
445 OnError(E_SYSTEM_ERROR);
448 inline void label(const char *topLabel, const char *bottomLabel) {
450 NCursesPanel::label(topLabel,bottomLabel);
452 OnError(E_SYSTEM_ERROR);
459 // Called after the menu gets repositioned in its window.
460 // This is especially true if the menu is posted.
461 virtual void On_Menu_Init();
463 // Called before the menu gets repositioned in its window.
464 // This is especially true if the menu is unposted.
465 virtual void On_Menu_Termination();
467 // Called after the item became the current item
468 virtual void On_Item_Init(NCursesMenuItem& item);
470 // Called before this item is left as current item.
471 virtual void On_Item_Termination(NCursesMenuItem& item);
473 // Provide a default key virtualization. Translate the keyboard
474 // code c into a menu request code.
475 // The default implementation provides a hopefully straightforward
476 // mapping for the most common keystrokes and menu requests.
477 virtual int virtualize(int c);
481 inline NCursesMenuItem* operator[](int i) const {
482 if ( (i < 0) || (i >= ::item_count (menu)) )
483 OnError (E_BAD_ARGUMENT);
484 return (my_items[i]);
487 // Perform the menu's operation
488 // Return the item where you left the selection mark for a single
489 // selection menu, or NULL for a multivalued menu.
490 virtual NCursesMenuItem* operator()(void);
492 // --------------------
493 // Exception handlers
494 // Called by operator()
495 // --------------------
497 // Called if the request is denied
498 virtual void On_Request_Denied(int c) const;
500 // Called if the item is not selectable
501 virtual void On_Not_Selectable(int c) const;
503 // Called if pattern doesn't match
504 virtual void On_No_Match(int c) const;
506 // Called if the command is unknown
507 virtual void On_Unknown_Command(int c) const;
511 // -------------------------------------------------------------------------
512 // This is the typical C++ typesafe way to allow to attach
513 // user data to an item of a menu. Its assumed that the user
514 // data belongs to some class T. Use T as template argument
515 // to create a UserItem.
516 // -------------------------------------------------------------------------
518 template<class T> class NCURSES_IMPEXP NCursesUserItem : public NCursesMenuItem
521 NCursesUserItem (const char* p_name,
522 const char* p_descript = NULL,
523 const T* p_UserData = (T*)0)
524 : NCursesMenuItem (p_name, p_descript) {
526 OnError (::set_item_userptr (item, (void *)p_UserData));
529 virtual ~NCursesUserItem() {};
531 inline const T* UserData (void) const {
532 return (const T*)::item_userptr (item);
535 inline virtual void setUserData(const T* p_UserData) {
537 OnError (::set_item_userptr (item, (void *)p_UserData));
541 // -------------------------------------------------------------------------
542 // The same mechanism is used to attach user data to a menu
543 // -------------------------------------------------------------------------
545 template<class T> class NCURSES_IMPEXP NCursesUserMenu : public NCursesMenu
548 NCursesUserMenu( int lines,
552 const T* p_UserData = (T*)0)
553 : NCursesMenu(lines,cols,begin_y,begin_x) {
555 set_user ((void *)p_UserData);
559 NCursesUserMenu (NCursesMenuItem Items[],
560 const T* p_UserData = (T*)0,
561 bool with_frame=FALSE,
562 bool autoDelete_Items=FALSE)
563 : NCursesMenu (Items, with_frame, autoDelete_Items) {
565 set_user ((void *)p_UserData);
568 NCursesUserMenu (NCursesMenuItem Items[],
573 const T* p_UserData = (T*)0,
574 bool with_frame=FALSE)
575 : NCursesMenu (Items, lines, cols, begin_y, begin_x, with_frame) {
577 set_user ((void *)p_UserData);
580 virtual ~NCursesUserMenu() {
583 inline T* UserData (void) const {
584 return (T*)get_user ();
587 inline virtual void setUserData (const T* p_UserData) {
589 set_user ((void *)p_UserData);
593 #endif // NCURSES_CURSESM_H_incl