jpayne@69: // * This makes emacs happy -*-Mode: C++;-*- jpayne@69: // vile:cppmode jpayne@69: /**************************************************************************** jpayne@69: * Copyright 2019-2021,2022 Thomas E. Dickey * jpayne@69: * Copyright 1998-2012,2014 Free Software Foundation, Inc. * jpayne@69: * * jpayne@69: * Permission is hereby granted, free of charge, to any person obtaining a * jpayne@69: * copy of this software and associated documentation files (the * jpayne@69: * "Software"), to deal in the Software without restriction, including * jpayne@69: * without limitation the rights to use, copy, modify, merge, publish, * jpayne@69: * distribute, distribute with modifications, sublicense, and/or sell * jpayne@69: * copies of the Software, and to permit persons to whom the Software is * jpayne@69: * furnished to do so, subject to the following conditions: * jpayne@69: * * jpayne@69: * The above copyright notice and this permission notice shall be included * jpayne@69: * in all copies or substantial portions of the Software. * jpayne@69: * * jpayne@69: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * jpayne@69: * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * jpayne@69: * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * jpayne@69: * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * jpayne@69: * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * jpayne@69: * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * jpayne@69: * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * jpayne@69: * * jpayne@69: * Except as contained in this notice, the name(s) of the above copyright * jpayne@69: * holders shall not be used in advertising or otherwise to promote the * jpayne@69: * sale, use or other dealings in this Software without prior written * jpayne@69: * authorization. * jpayne@69: ****************************************************************************/ jpayne@69: jpayne@69: /**************************************************************************** jpayne@69: * Author: Juergen Pfeifer, 1997 * jpayne@69: ****************************************************************************/ jpayne@69: jpayne@69: #ifndef NCURSES_CURSESP_H_incl jpayne@69: #define NCURSES_CURSESP_H_incl 1 jpayne@69: jpayne@69: // $Id: cursesp.h,v 1.36 2022/08/20 20:52:15 tom Exp $ jpayne@69: jpayne@69: #include jpayne@69: jpayne@69: extern "C" { jpayne@69: # include jpayne@69: } jpayne@69: jpayne@69: class NCURSES_CXX_IMPEXP NCursesPanel jpayne@69: : public NCursesWindow jpayne@69: { jpayne@69: protected: jpayne@69: PANEL *p; jpayne@69: static NCursesPanel *dummy; jpayne@69: jpayne@69: private: jpayne@69: // This structure is used for the panel's user data field to link the jpayne@69: // PANEL* to the C++ object and to provide extra space for a user pointer. jpayne@69: typedef struct { jpayne@69: void* m_user; // the pointer for the user's data jpayne@69: const NCursesPanel* m_back; // backward pointer to C++ object jpayne@69: const PANEL* m_owner; // the panel itself jpayne@69: } UserHook; jpayne@69: jpayne@69: inline UserHook *UserPointer() jpayne@69: { jpayne@69: UserHook* uptr = reinterpret_cast( jpayne@69: const_cast(::panel_userptr (p))); jpayne@69: return uptr; jpayne@69: } jpayne@69: jpayne@69: void init(); // Initialize the panel object jpayne@69: jpayne@69: protected: jpayne@69: void set_user(void *user) jpayne@69: { jpayne@69: UserHook* uptr = UserPointer(); jpayne@69: if (uptr != 0 && uptr->m_back==this && uptr->m_owner==p) { jpayne@69: uptr->m_user = user; jpayne@69: } jpayne@69: } jpayne@69: // Set the user pointer of the panel. jpayne@69: jpayne@69: void *get_user() jpayne@69: { jpayne@69: UserHook* uptr = UserPointer(); jpayne@69: void *result = 0; jpayne@69: if (uptr != 0 && uptr->m_back==this && uptr->m_owner==p) jpayne@69: result = uptr->m_user; jpayne@69: return result; jpayne@69: } jpayne@69: jpayne@69: void OnError (int err) const THROW2(NCursesException const, NCursesPanelException) jpayne@69: { jpayne@69: if (err==ERR) jpayne@69: THROW(new NCursesPanelException (this, err)); jpayne@69: } jpayne@69: // If err is equal to the curses error indicator ERR, an error handler jpayne@69: // is called. jpayne@69: jpayne@69: // Get a keystroke. Default implementation calls getch() jpayne@69: virtual int getKey(void); jpayne@69: jpayne@69: public: jpayne@69: NCursesPanel(int nlines, jpayne@69: int ncols, jpayne@69: int begin_y = 0, jpayne@69: int begin_x = 0) jpayne@69: : NCursesWindow(nlines,ncols,begin_y,begin_x), p(0) jpayne@69: { jpayne@69: init(); jpayne@69: } jpayne@69: // Create a panel with this size starting at the requested position. jpayne@69: jpayne@69: NCursesPanel() jpayne@69: : NCursesWindow(::stdscr), p(0) jpayne@69: { jpayne@69: init(); jpayne@69: } jpayne@69: // This constructor creates the default Panel associated with the jpayne@69: // ::stdscr window jpayne@69: jpayne@69: NCursesPanel& operator=(const NCursesPanel& rhs) jpayne@69: { jpayne@69: if (this != &rhs) { jpayne@69: *this = rhs; jpayne@69: NCursesWindow::operator=(rhs); jpayne@69: } jpayne@69: return *this; jpayne@69: } jpayne@69: jpayne@69: NCursesPanel(const NCursesPanel& rhs) jpayne@69: : NCursesWindow(rhs), jpayne@69: p(rhs.p) jpayne@69: { jpayne@69: } jpayne@69: jpayne@69: virtual ~NCursesPanel() THROWS(NCursesException); jpayne@69: jpayne@69: // basic manipulation jpayne@69: inline void hide() jpayne@69: { jpayne@69: OnError (::hide_panel(p)); jpayne@69: } jpayne@69: // Hide the panel. It stays in the stack but becomes invisible. jpayne@69: jpayne@69: inline void show() jpayne@69: { jpayne@69: OnError (::show_panel(p)); jpayne@69: } jpayne@69: // Show the panel, i.e. make it visible. jpayne@69: jpayne@69: inline void top() jpayne@69: { jpayne@69: OnError (::top_panel(p)); jpayne@69: } jpayne@69: // Make this panel the top panel in the stack. jpayne@69: jpayne@69: inline void bottom() jpayne@69: { jpayne@69: OnError (::bottom_panel(p)); jpayne@69: } jpayne@69: // Make this panel the bottom panel in the stack. jpayne@69: // N.B.: The panel associated with ::stdscr is always on the bottom. So jpayne@69: // actually bottom() makes the panel the first above ::stdscr. jpayne@69: jpayne@69: virtual int mvwin(int y, int x) NCURSES_OVERRIDE jpayne@69: { jpayne@69: OnError(::move_panel(p, y, x)); jpayne@69: return OK; jpayne@69: } jpayne@69: jpayne@69: inline bool hidden() const jpayne@69: { jpayne@69: return (::panel_hidden (p) ? TRUE : FALSE); jpayne@69: } jpayne@69: // Return TRUE if the panel is hidden, FALSE otherwise. jpayne@69: jpayne@69: /* The functions panel_above() and panel_below() are not reflected in jpayne@69: the NCursesPanel class. The reason for this is, that we cannot jpayne@69: assume that a panel retrieved by those operations is one wrapped jpayne@69: by a C++ class. Although this situation might be handled, we also jpayne@69: need a reverse mapping from PANEL to NCursesPanel which needs some jpayne@69: redesign of the low level stuff. At the moment, we define them in the jpayne@69: interface but they will always produce an error. */ jpayne@69: inline NCursesPanel& above() const jpayne@69: { jpayne@69: OnError(ERR); jpayne@69: return *dummy; jpayne@69: } jpayne@69: jpayne@69: inline NCursesPanel& below() const jpayne@69: { jpayne@69: OnError(ERR); jpayne@69: return *dummy; jpayne@69: } jpayne@69: jpayne@69: // Those two are rewrites of the corresponding virtual members of jpayne@69: // NCursesWindow jpayne@69: virtual int refresh() NCURSES_OVERRIDE; jpayne@69: // Propagate all panel changes to the virtual screen and update the jpayne@69: // physical screen. jpayne@69: jpayne@69: virtual int noutrefresh() NCURSES_OVERRIDE; jpayne@69: // Propagate all panel changes to the virtual screen. jpayne@69: jpayne@69: static void redraw(); jpayne@69: // Redraw all panels. jpayne@69: jpayne@69: // decorations jpayne@69: virtual void frame(const char* title=NULL, jpayne@69: const char* btitle=NULL); jpayne@69: // Put a frame around the panel and put the title centered in the top line jpayne@69: // and btitle in the bottom line. jpayne@69: jpayne@69: virtual void boldframe(const char* title=NULL, jpayne@69: const char* btitle=NULL); jpayne@69: // Same as frame(), but use highlighted attributes. jpayne@69: jpayne@69: virtual void label(const char* topLabel, jpayne@69: const char* bottomLabel); jpayne@69: // Put the title centered in the top line and btitle in the bottom line. jpayne@69: jpayne@69: virtual void centertext(int row,const char* label); jpayne@69: // Put the label text centered in the specified row. jpayne@69: }; jpayne@69: jpayne@69: /* We use templates to provide a typesafe mechanism to associate jpayne@69: * user data with a panel. A NCursesUserPanel is a panel jpayne@69: * associated with some user data of type T. jpayne@69: */ jpayne@69: template class NCursesUserPanel : public NCursesPanel jpayne@69: { jpayne@69: public: jpayne@69: NCursesUserPanel (int nlines, jpayne@69: int ncols, jpayne@69: int begin_y = 0, jpayne@69: int begin_x = 0, jpayne@69: const T* p_UserData = STATIC_CAST(T*)(0)) jpayne@69: : NCursesPanel (nlines, ncols, begin_y, begin_x) jpayne@69: { jpayne@69: if (p) jpayne@69: set_user (const_cast(reinterpret_cast jpayne@69: (p_UserData))); jpayne@69: }; jpayne@69: // This creates an user panel of the requested size with associated jpayne@69: // user data pointed to by p_UserData. jpayne@69: jpayne@69: explicit NCursesUserPanel(const T* p_UserData = STATIC_CAST(T*)(0)) : NCursesPanel() jpayne@69: { jpayne@69: if (p) jpayne@69: set_user(const_cast(reinterpret_cast(p_UserData))); jpayne@69: }; jpayne@69: // This creates an user panel associated with the ::stdscr and user data jpayne@69: // pointed to by p_UserData. jpayne@69: jpayne@69: virtual ~NCursesUserPanel() THROWS(NCursesException) {}; jpayne@69: jpayne@69: T* UserData (void) jpayne@69: { jpayne@69: return reinterpret_cast(get_user ()); jpayne@69: }; jpayne@69: // Retrieve the user data associated with the panel. jpayne@69: jpayne@69: virtual void setUserData (const T* p_UserData) jpayne@69: { jpayne@69: if (p) jpayne@69: set_user (const_cast(reinterpret_cast(p_UserData))); jpayne@69: } jpayne@69: // Associate the user panel with the user data pointed to by p_UserData. jpayne@69: }; jpayne@69: jpayne@69: #endif /* NCURSES_CURSESP_H_incl */