123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674 |
- // * This makes emacs happy -*-Mode: C++;-*-
- /****************************************************************************
- * Copyright 2019,2020 Thomas E. Dickey *
- * Copyright 1998-2012,2014 Free Software Foundation, Inc. *
- * *
- * Permission is hereby granted, free of charge, to any person obtaining a *
- * copy of this software and associated documentation files (the *
- * "Software"), to deal in the Software without restriction, including *
- * without limitation the rights to use, copy, modify, merge, publish, *
- * distribute, distribute with modifications, sublicense, and/or sell *
- * copies of the Software, and to permit persons to whom the Software is *
- * furnished to do so, subject to the following conditions: *
- * *
- * The above copyright notice and this permission notice shall be included *
- * in all copies or substantial portions of the Software. *
- * *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS *
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF *
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. *
- * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR *
- * THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
- * *
- * Except as contained in this notice, the name(s) of the above copyright *
- * holders shall not be used in advertising or otherwise to promote the *
- * sale, use or other dealings in this Software without prior written *
- * authorization. *
- ****************************************************************************/
- /****************************************************************************
- * Author: Juergen Pfeifer, 1997 *
- ****************************************************************************/
- // $Id: cursesm.h,v 1.33 2020/02/02 23:34:34 tom Exp $
- #ifndef NCURSES_CURSESM_H_incl
- #define NCURSES_CURSESM_H_incl 1
- #include <cursesp.h>
- extern "C" {
- # include <menu.h>
- }
- //
- // -------------------------------------------------------------------------
- // This wraps the ITEM type of <menu.h>
- // -------------------------------------------------------------------------
- //
- class NCURSES_IMPEXP NCursesMenuItem
- {
- friend class NCursesMenu;
- protected:
- ITEM *item;
- inline void OnError (int err) const THROW2(NCursesException const, NCursesMenuException) {
- if (err != E_OK)
- THROW(new NCursesMenuException (err));
- }
- public:
- NCursesMenuItem (const char* p_name = NULL,
- const char* p_descript = NULL)
- : item(0)
- {
- item = p_name ? ::new_item (p_name, p_descript) : STATIC_CAST(ITEM*)(0);
- if (p_name && !item)
- OnError (E_SYSTEM_ERROR);
- }
- // Create an item. If you pass both parameters as NULL, a delimiting
- // item is constructed which can be used to terminate a list of
- // NCursesMenu objects.
- NCursesMenuItem& operator=(const NCursesMenuItem& rhs)
- {
- if (this != &rhs) {
- *this = rhs;
- }
- return *this;
- }
- NCursesMenuItem(const NCursesMenuItem& rhs)
- : item(0)
- {
- (void) rhs;
- }
- virtual ~NCursesMenuItem () THROWS(NCursesException);
- // Release the items memory
- inline const char* name () const {
- return ::item_name (item);
- }
- // Name of the item
- inline const char* description () const {
- return ::item_description (item);
- }
- // Description of the item
- inline int (index) (void) const {
- return ::item_index (item);
- }
- // Index of the item in an item array (or -1)
- inline void options_on (Item_Options opts) {
- OnError (::item_opts_on (item, opts));
- }
- // Switch on the items options
- inline void options_off (Item_Options opts) {
- OnError (::item_opts_off (item, opts));
- }
- // Switch off the item's option
- inline Item_Options options () const {
- return ::item_opts (item);
- }
- // Retrieve the items options
- inline void set_options (Item_Options opts) {
- OnError (::set_item_opts (item, opts));
- }
- // Set the items options
- inline void set_value (bool f) {
- OnError (::set_item_value (item,f));
- }
- // Set/Reset the items selection state
- inline bool value () const {
- return ::item_value (item);
- }
- // Retrieve the items selection state
- inline bool visible () const {
- return ::item_visible (item);
- }
- // Retrieve visibility of the item
- virtual bool action();
- // Perform an action associated with this item; you may use this in an
- // user supplied driver for a menu; you may derive from this class and
- // overload action() to supply items with different actions.
- // If an action returns true, the menu will be exited. The default action
- // is to do nothing.
- };
- // Prototype for an items callback function.
- typedef bool ITEMCALLBACK(NCursesMenuItem&);
- // If you don't like to create a child class for individual items to
- // overload action(), you may use this class and provide a callback
- // function pointer for items.
- class NCURSES_IMPEXP NCursesMenuCallbackItem : public NCursesMenuItem
- {
- private:
- ITEMCALLBACK* p_fct;
- public:
- NCursesMenuCallbackItem(ITEMCALLBACK* fct = NULL,
- const char* p_name = NULL,
- const char* p_descript = NULL )
- : NCursesMenuItem (p_name, p_descript),
- p_fct (fct) {
- }
- NCursesMenuCallbackItem& operator=(const NCursesMenuCallbackItem& rhs)
- {
- if (this != &rhs) {
- *this = rhs;
- }
- return *this;
- }
- NCursesMenuCallbackItem(const NCursesMenuCallbackItem& rhs)
- : NCursesMenuItem(rhs),
- p_fct(0)
- {
- }
- virtual ~NCursesMenuCallbackItem() THROWS(NCursesException);
- bool action();
- };
- // This are the built-in hook functions in this C++ binding. In C++ we use
- // virtual member functions (see below On_..._Init and On_..._Termination)
- // to provide this functionality in an object oriented manner.
- extern "C" {
- void _nc_xx_mnu_init(MENU *);
- void _nc_xx_mnu_term(MENU *);
- void _nc_xx_itm_init(MENU *);
- void _nc_xx_itm_term(MENU *);
- }
- //
- // -------------------------------------------------------------------------
- // This wraps the MENU type of <menu.h>
- // -------------------------------------------------------------------------
- //
- class NCURSES_IMPEXP NCursesMenu : public NCursesPanel
- {
- protected:
- MENU *menu;
- private:
- NCursesWindow* sub; // the subwindow object
- bool b_sub_owner; // is this our own subwindow?
- bool b_framed; // has the menu a border?
- bool b_autoDelete; // Delete items when deleting menu?
- NCursesMenuItem** my_items; // The array of items for this menu
- // This structure is used for the menu's user data field to link the
- // MENU* to the C++ object and to provide extra space for a user pointer.
- typedef struct {
- void* m_user; // the pointer for the user's data
- const NCursesMenu* m_back; // backward pointer to C++ object
- const MENU* m_owner;
- } UserHook;
- // Get the backward pointer to the C++ object from a MENU
- static inline NCursesMenu* getHook(const MENU *m) {
- UserHook* hook = STATIC_CAST(UserHook*)(::menu_userptr(m));
- assert(hook != 0 && hook->m_owner==m);
- return const_cast<NCursesMenu*>(hook->m_back);
- }
- friend void _nc_xx_mnu_init(MENU *);
- friend void _nc_xx_mnu_term(MENU *);
- friend void _nc_xx_itm_init(MENU *);
- friend void _nc_xx_itm_term(MENU *);
- // Calculate ITEM* array for the menu
- ITEM** mapItems(NCursesMenuItem* nitems[]);
- protected:
- // internal routines
- inline void set_user(void *user) {
- UserHook* uptr = STATIC_CAST(UserHook*)(::menu_userptr (menu));
- assert (uptr != 0 && uptr->m_back==this && uptr->m_owner==menu);
- uptr->m_user = user;
- }
- inline void *get_user() {
- UserHook* uptr = STATIC_CAST(UserHook*)(::menu_userptr (menu));
- assert (uptr != 0 && uptr->m_back==this && uptr->m_owner==menu);
- return uptr->m_user;
- }
- void InitMenu (NCursesMenuItem* menu[],
- bool with_frame,
- bool autoDeleteItems);
- inline void OnError (int err) const THROW2(NCursesException const, NCursesMenuException) {
- if (err != E_OK)
- THROW(new NCursesMenuException (this, err));
- }
- // this wraps the menu_driver call.
- virtual int driver (int c) ;
- // 'Internal' constructor to create a menu without association to
- // an array of items.
- NCursesMenu( int nlines,
- int ncols,
- int begin_y = 0,
- int begin_x = 0)
- : NCursesPanel(nlines,ncols,begin_y,begin_x),
- menu (STATIC_CAST(MENU*)(0)),
- sub(0),
- b_sub_owner(0),
- b_framed(0),
- b_autoDelete(0),
- my_items(0)
- {
- }
- public:
- // Make a full window size menu
- NCursesMenu (NCursesMenuItem* Items[],
- bool with_frame=FALSE, // Reserve space for a frame?
- bool autoDelete_Items=FALSE) // Autocleanup of Items?
- : NCursesPanel(),
- menu(0),
- sub(0),
- b_sub_owner(0),
- b_framed(0),
- b_autoDelete(0),
- my_items(0)
- {
- InitMenu(Items, with_frame, autoDelete_Items);
- }
- // Make a menu with a window of this size.
- NCursesMenu (NCursesMenuItem* Items[],
- int nlines,
- int ncols,
- int begin_y = 0,
- int begin_x = 0,
- bool with_frame=FALSE, // Reserve space for a frame?
- bool autoDelete_Items=FALSE) // Autocleanup of Items?
- : NCursesPanel(nlines, ncols, begin_y, begin_x),
- menu(0),
- sub(0),
- b_sub_owner(0),
- b_framed(0),
- b_autoDelete(0),
- my_items(0)
- {
- InitMenu(Items, with_frame, autoDelete_Items);
- }
- NCursesMenu& operator=(const NCursesMenu& rhs)
- {
- if (this != &rhs) {
- *this = rhs;
- NCursesPanel::operator=(rhs);
- }
- return *this;
- }
- NCursesMenu(const NCursesMenu& rhs)
- : NCursesPanel(rhs),
- menu(rhs.menu),
- sub(rhs.sub),
- b_sub_owner(rhs.b_sub_owner),
- b_framed(rhs.b_framed),
- b_autoDelete(rhs.b_autoDelete),
- my_items(rhs.my_items)
- {
- }
- virtual ~NCursesMenu () THROWS(NCursesException);
- // Retrieve the menus subwindow
- inline NCursesWindow& subWindow() const {
- assert(sub!=NULL);
- return *sub;
- }
- // Set the menus subwindow
- void setSubWindow(NCursesWindow& sub);
- // Set these items for the menu
- inline void setItems(NCursesMenuItem* Items[]) {
- OnError(::set_menu_items(menu,mapItems(Items)));
- }
- // Remove the menu from the screen
- inline void unpost (void) {
- OnError (::unpost_menu (menu));
- }
- // Post the menu to the screen if flag is true, unpost it otherwise
- inline void post(bool flag = TRUE) {
- flag ? OnError (::post_menu(menu)) : OnError (::unpost_menu (menu));
- }
- // Get the number of rows and columns for this menu
- inline void scale (int& mrows, int& mcols) const {
- OnError (::scale_menu (menu, &mrows, &mcols));
- }
- // Set the format of this menu
- inline void set_format(int mrows, int mcols) {
- OnError (::set_menu_format(menu, mrows, mcols));
- }
- // Get the format of this menu
- inline void menu_format(int& rows,int& ncols) {
- ::menu_format(menu,&rows,&ncols);
- }
- // Items of the menu
- inline NCursesMenuItem* items() const {
- return *my_items;
- }
- // Get the number of items in this menu
- inline int count() const {
- return ::item_count(menu);
- }
- // Get the current item (i.e. the one the cursor is located)
- inline NCursesMenuItem* current_item() const {
- return my_items[::item_index(::current_item(menu))];
- }
- // Get the marker string
- inline const char* mark() const {
- return ::menu_mark(menu);
- }
- // Set the marker string
- inline void set_mark(const char *marker) {
- OnError (::set_menu_mark (menu, marker));
- }
- // Get the name of the request code c
- inline static const char* request_name(int c) {
- return ::menu_request_name(c);
- }
- // Get the current pattern
- inline char* pattern() const {
- return ::menu_pattern(menu);
- }
- // true if there is a pattern match, false otherwise.
- bool set_pattern (const char *pat);
- // set the default attributes for the menu
- // i.e. set fore, back and grey attribute
- virtual void setDefaultAttributes();
- // Get the menus background attributes
- inline chtype back() const {
- return ::menu_back(menu);
- }
- // Get the menus foreground attributes
- inline chtype fore() const {
- return ::menu_fore(menu);
- }
- // Get the menus grey attributes (used for unselectable items)
- inline chtype grey() const {
- return ::menu_grey(menu);
- }
- // Set the menus background attributes
- inline chtype set_background(chtype a) {
- return ::set_menu_back(menu,a);
- }
- // Set the menus foreground attributes
- inline chtype set_foreground(chtype a) {
- return ::set_menu_fore(menu,a);
- }
- // Set the menus grey attributes (used for unselectable items)
- inline chtype set_grey(chtype a) {
- return ::set_menu_grey(menu,a);
- }
- inline void options_on (Menu_Options opts) {
- OnError (::menu_opts_on (menu,opts));
- }
- inline void options_off(Menu_Options opts) {
- OnError (::menu_opts_off(menu,opts));
- }
- inline Menu_Options options() const {
- return ::menu_opts(menu);
- }
- inline void set_options (Menu_Options opts) {
- OnError (::set_menu_opts (menu,opts));
- }
- inline int pad() const {
- return ::menu_pad(menu);
- }
- inline void set_pad (int padch) {
- OnError (::set_menu_pad (menu, padch));
- }
- // Position the cursor to the current item
- inline void position_cursor () const {
- OnError (::pos_menu_cursor (menu));
- }
- // Set the current item
- inline void set_current(NCursesMenuItem& I) {
- OnError (::set_current_item(menu, I.item));
- }
- // Get the current top row of the menu
- inline int top_row (void) const {
- return ::top_row (menu);
- }
- // Set the current top row of the menu
- inline void set_top_row (int row) {
- OnError (::set_top_row (menu, row));
- }
- // spacing control
- // Set the spacing for the menu
- inline void setSpacing(int spc_description,
- int spc_rows,
- int spc_columns) {
- OnError(::set_menu_spacing(menu,
- spc_description,
- spc_rows,
- spc_columns));
- }
- // Get the spacing info for the menu
- inline void Spacing(int& spc_description,
- int& spc_rows,
- int& spc_columns) const {
- OnError(::menu_spacing(menu,
- &spc_description,
- &spc_rows,
- &spc_columns));
- }
- // Decorations
- inline void frame(const char *title=NULL, const char* btitle=NULL) {
- if (b_framed)
- NCursesPanel::frame(title,btitle);
- else
- OnError(E_SYSTEM_ERROR);
- }
- inline void boldframe(const char *title=NULL, const char* btitle=NULL) {
- if (b_framed)
- NCursesPanel::boldframe(title,btitle);
- else
- OnError(E_SYSTEM_ERROR);
- }
- inline void label(const char *topLabel, const char *bottomLabel) {
- if (b_framed)
- NCursesPanel::label(topLabel,bottomLabel);
- else
- OnError(E_SYSTEM_ERROR);
- }
- // -----
- // Hooks
- // -----
- // Called after the menu gets repositioned in its window.
- // This is especially true if the menu is posted.
- virtual void On_Menu_Init();
- // Called before the menu gets repositioned in its window.
- // This is especially true if the menu is unposted.
- virtual void On_Menu_Termination();
- // Called after the item became the current item
- virtual void On_Item_Init(NCursesMenuItem& item);
- // Called before this item is left as current item.
- virtual void On_Item_Termination(NCursesMenuItem& item);
- // Provide a default key virtualization. Translate the keyboard
- // code c into a menu request code.
- // The default implementation provides a hopefully straightforward
- // mapping for the most common keystrokes and menu requests.
- virtual int virtualize(int c);
- // Operators
- inline NCursesMenuItem* operator[](int i) const {
- if ( (i < 0) || (i >= ::item_count (menu)) )
- OnError (E_BAD_ARGUMENT);
- return (my_items[i]);
- }
- // Perform the menu's operation
- // Return the item where you left the selection mark for a single
- // selection menu, or NULL for a multivalued menu.
- virtual NCursesMenuItem* operator()(void);
- // --------------------
- // Exception handlers
- // Called by operator()
- // --------------------
- // Called if the request is denied
- virtual void On_Request_Denied(int c) const;
- // Called if the item is not selectable
- virtual void On_Not_Selectable(int c) const;
- // Called if pattern doesn't match
- virtual void On_No_Match(int c) const;
- // Called if the command is unknown
- virtual void On_Unknown_Command(int c) const;
- };
- //
- // -------------------------------------------------------------------------
- // This is the typical C++ typesafe way to allow to attach
- // user data to an item of a menu. Its assumed that the user
- // data belongs to some class T. Use T as template argument
- // to create a UserItem.
- // -------------------------------------------------------------------------
- //
- template<class T> class NCURSES_IMPEXP NCursesUserItem : public NCursesMenuItem
- {
- public:
- NCursesUserItem (const char* p_name,
- const char* p_descript = NULL,
- const T* p_UserData = STATIC_CAST(T*)(0))
- : NCursesMenuItem (p_name, p_descript) {
- if (item)
- OnError (::set_item_userptr (item, const_cast<void *>(reinterpret_cast<const void*>(p_UserData))));
- }
- virtual ~NCursesUserItem() THROWS(NCursesException) {}
- inline const T* UserData (void) const {
- return reinterpret_cast<const T*>(::item_userptr (item));
- };
- inline virtual void setUserData(const T* p_UserData) {
- if (item)
- OnError (::set_item_userptr (item, const_cast<void *>(reinterpret_cast<const void *>(p_UserData))));
- }
- };
- //
- // -------------------------------------------------------------------------
- // The same mechanism is used to attach user data to a menu
- // -------------------------------------------------------------------------
- //
- template<class T> class NCURSES_IMPEXP NCursesUserMenu : public NCursesMenu
- {
- protected:
- NCursesUserMenu( int nlines,
- int ncols,
- int begin_y = 0,
- int begin_x = 0,
- const T* p_UserData = STATIC_CAST(T*)(0))
- : NCursesMenu(nlines,ncols,begin_y,begin_x) {
- if (menu)
- set_user (const_cast<void *>(reinterpret_cast<const void*>(p_UserData)));
- }
- public:
- NCursesUserMenu (NCursesMenuItem* Items[],
- const T* p_UserData = STATIC_CAST(T*)(0),
- bool with_frame=FALSE,
- bool autoDelete_Items=FALSE)
- : NCursesMenu (Items, with_frame, autoDelete_Items) {
- if (menu)
- set_user (const_cast<void *>(reinterpret_cast<const void*>(p_UserData)));
- };
- NCursesUserMenu (NCursesMenuItem* Items[],
- int nlines,
- int ncols,
- int begin_y = 0,
- int begin_x = 0,
- const T* p_UserData = STATIC_CAST(T*)(0),
- bool with_frame=FALSE)
- : NCursesMenu (Items, nlines, ncols, begin_y, begin_x, with_frame) {
- if (menu)
- set_user (const_cast<void *>(reinterpret_cast<const void*>(p_UserData)));
- };
- virtual ~NCursesUserMenu() THROWS(NCursesException) {
- };
- inline T* UserData (void) {
- return reinterpret_cast<T*>(get_user ());
- };
- inline virtual void setUserData (const T* p_UserData) {
- if (menu)
- set_user (const_cast<void *>(reinterpret_cast<const void*>(p_UserData)));
- }
- };
- #endif /* NCURSES_CURSESM_H_incl */
|