jpayne@69
|
1 // * This makes emacs happy -*-Mode: C++;-*-
|
jpayne@69
|
2 // vile:cppmode
|
jpayne@69
|
3 /****************************************************************************
|
jpayne@69
|
4 * Copyright 2019-2021,2022 Thomas E. Dickey *
|
jpayne@69
|
5 * Copyright 1998-2012,2014 Free Software Foundation, Inc. *
|
jpayne@69
|
6 * *
|
jpayne@69
|
7 * Permission is hereby granted, free of charge, to any person obtaining a *
|
jpayne@69
|
8 * copy of this software and associated documentation files (the *
|
jpayne@69
|
9 * "Software"), to deal in the Software without restriction, including *
|
jpayne@69
|
10 * without limitation the rights to use, copy, modify, merge, publish, *
|
jpayne@69
|
11 * distribute, distribute with modifications, sublicense, and/or sell *
|
jpayne@69
|
12 * copies of the Software, and to permit persons to whom the Software is *
|
jpayne@69
|
13 * furnished to do so, subject to the following conditions: *
|
jpayne@69
|
14 * *
|
jpayne@69
|
15 * The above copyright notice and this permission notice shall be included *
|
jpayne@69
|
16 * in all copies or substantial portions of the Software. *
|
jpayne@69
|
17 * *
|
jpayne@69
|
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS *
|
jpayne@69
|
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF *
|
jpayne@69
|
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. *
|
jpayne@69
|
21 * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
|
jpayne@69
|
22 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
|
jpayne@69
|
23 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR *
|
jpayne@69
|
24 * THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
jpayne@69
|
25 * *
|
jpayne@69
|
26 * Except as contained in this notice, the name(s) of the above copyright *
|
jpayne@69
|
27 * holders shall not be used in advertising or otherwise to promote the *
|
jpayne@69
|
28 * sale, use or other dealings in this Software without prior written *
|
jpayne@69
|
29 * authorization. *
|
jpayne@69
|
30 ****************************************************************************/
|
jpayne@69
|
31
|
jpayne@69
|
32 /****************************************************************************
|
jpayne@69
|
33 * Author: Juergen Pfeifer, 1997 *
|
jpayne@69
|
34 ****************************************************************************/
|
jpayne@69
|
35
|
jpayne@69
|
36 #ifndef NCURSES_CURSESP_H_incl
|
jpayne@69
|
37 #define NCURSES_CURSESP_H_incl 1
|
jpayne@69
|
38
|
jpayne@69
|
39 // $Id: cursesp.h,v 1.36 2022/08/20 20:52:15 tom Exp $
|
jpayne@69
|
40
|
jpayne@69
|
41 #include <ncursesw/cursesw.h>
|
jpayne@69
|
42
|
jpayne@69
|
43 extern "C" {
|
jpayne@69
|
44 # include <ncursesw/panel.h>
|
jpayne@69
|
45 }
|
jpayne@69
|
46
|
jpayne@69
|
47 class NCURSES_CXX_IMPEXP NCursesPanel
|
jpayne@69
|
48 : public NCursesWindow
|
jpayne@69
|
49 {
|
jpayne@69
|
50 protected:
|
jpayne@69
|
51 PANEL *p;
|
jpayne@69
|
52 static NCursesPanel *dummy;
|
jpayne@69
|
53
|
jpayne@69
|
54 private:
|
jpayne@69
|
55 // This structure is used for the panel's user data field to link the
|
jpayne@69
|
56 // PANEL* to the C++ object and to provide extra space for a user pointer.
|
jpayne@69
|
57 typedef struct {
|
jpayne@69
|
58 void* m_user; // the pointer for the user's data
|
jpayne@69
|
59 const NCursesPanel* m_back; // backward pointer to C++ object
|
jpayne@69
|
60 const PANEL* m_owner; // the panel itself
|
jpayne@69
|
61 } UserHook;
|
jpayne@69
|
62
|
jpayne@69
|
63 inline UserHook *UserPointer()
|
jpayne@69
|
64 {
|
jpayne@69
|
65 UserHook* uptr = reinterpret_cast<UserHook*>(
|
jpayne@69
|
66 const_cast<void *>(::panel_userptr (p)));
|
jpayne@69
|
67 return uptr;
|
jpayne@69
|
68 }
|
jpayne@69
|
69
|
jpayne@69
|
70 void init(); // Initialize the panel object
|
jpayne@69
|
71
|
jpayne@69
|
72 protected:
|
jpayne@69
|
73 void set_user(void *user)
|
jpayne@69
|
74 {
|
jpayne@69
|
75 UserHook* uptr = UserPointer();
|
jpayne@69
|
76 if (uptr != 0 && uptr->m_back==this && uptr->m_owner==p) {
|
jpayne@69
|
77 uptr->m_user = user;
|
jpayne@69
|
78 }
|
jpayne@69
|
79 }
|
jpayne@69
|
80 // Set the user pointer of the panel.
|
jpayne@69
|
81
|
jpayne@69
|
82 void *get_user()
|
jpayne@69
|
83 {
|
jpayne@69
|
84 UserHook* uptr = UserPointer();
|
jpayne@69
|
85 void *result = 0;
|
jpayne@69
|
86 if (uptr != 0 && uptr->m_back==this && uptr->m_owner==p)
|
jpayne@69
|
87 result = uptr->m_user;
|
jpayne@69
|
88 return result;
|
jpayne@69
|
89 }
|
jpayne@69
|
90
|
jpayne@69
|
91 void OnError (int err) const THROW2(NCursesException const, NCursesPanelException)
|
jpayne@69
|
92 {
|
jpayne@69
|
93 if (err==ERR)
|
jpayne@69
|
94 THROW(new NCursesPanelException (this, err));
|
jpayne@69
|
95 }
|
jpayne@69
|
96 // If err is equal to the curses error indicator ERR, an error handler
|
jpayne@69
|
97 // is called.
|
jpayne@69
|
98
|
jpayne@69
|
99 // Get a keystroke. Default implementation calls getch()
|
jpayne@69
|
100 virtual int getKey(void);
|
jpayne@69
|
101
|
jpayne@69
|
102 public:
|
jpayne@69
|
103 NCursesPanel(int nlines,
|
jpayne@69
|
104 int ncols,
|
jpayne@69
|
105 int begin_y = 0,
|
jpayne@69
|
106 int begin_x = 0)
|
jpayne@69
|
107 : NCursesWindow(nlines,ncols,begin_y,begin_x), p(0)
|
jpayne@69
|
108 {
|
jpayne@69
|
109 init();
|
jpayne@69
|
110 }
|
jpayne@69
|
111 // Create a panel with this size starting at the requested position.
|
jpayne@69
|
112
|
jpayne@69
|
113 NCursesPanel()
|
jpayne@69
|
114 : NCursesWindow(::stdscr), p(0)
|
jpayne@69
|
115 {
|
jpayne@69
|
116 init();
|
jpayne@69
|
117 }
|
jpayne@69
|
118 // This constructor creates the default Panel associated with the
|
jpayne@69
|
119 // ::stdscr window
|
jpayne@69
|
120
|
jpayne@69
|
121 NCursesPanel& operator=(const NCursesPanel& rhs)
|
jpayne@69
|
122 {
|
jpayne@69
|
123 if (this != &rhs) {
|
jpayne@69
|
124 *this = rhs;
|
jpayne@69
|
125 NCursesWindow::operator=(rhs);
|
jpayne@69
|
126 }
|
jpayne@69
|
127 return *this;
|
jpayne@69
|
128 }
|
jpayne@69
|
129
|
jpayne@69
|
130 NCursesPanel(const NCursesPanel& rhs)
|
jpayne@69
|
131 : NCursesWindow(rhs),
|
jpayne@69
|
132 p(rhs.p)
|
jpayne@69
|
133 {
|
jpayne@69
|
134 }
|
jpayne@69
|
135
|
jpayne@69
|
136 virtual ~NCursesPanel() THROWS(NCursesException);
|
jpayne@69
|
137
|
jpayne@69
|
138 // basic manipulation
|
jpayne@69
|
139 inline void hide()
|
jpayne@69
|
140 {
|
jpayne@69
|
141 OnError (::hide_panel(p));
|
jpayne@69
|
142 }
|
jpayne@69
|
143 // Hide the panel. It stays in the stack but becomes invisible.
|
jpayne@69
|
144
|
jpayne@69
|
145 inline void show()
|
jpayne@69
|
146 {
|
jpayne@69
|
147 OnError (::show_panel(p));
|
jpayne@69
|
148 }
|
jpayne@69
|
149 // Show the panel, i.e. make it visible.
|
jpayne@69
|
150
|
jpayne@69
|
151 inline void top()
|
jpayne@69
|
152 {
|
jpayne@69
|
153 OnError (::top_panel(p));
|
jpayne@69
|
154 }
|
jpayne@69
|
155 // Make this panel the top panel in the stack.
|
jpayne@69
|
156
|
jpayne@69
|
157 inline void bottom()
|
jpayne@69
|
158 {
|
jpayne@69
|
159 OnError (::bottom_panel(p));
|
jpayne@69
|
160 }
|
jpayne@69
|
161 // Make this panel the bottom panel in the stack.
|
jpayne@69
|
162 // N.B.: The panel associated with ::stdscr is always on the bottom. So
|
jpayne@69
|
163 // actually bottom() makes the panel the first above ::stdscr.
|
jpayne@69
|
164
|
jpayne@69
|
165 virtual int mvwin(int y, int x) NCURSES_OVERRIDE
|
jpayne@69
|
166 {
|
jpayne@69
|
167 OnError(::move_panel(p, y, x));
|
jpayne@69
|
168 return OK;
|
jpayne@69
|
169 }
|
jpayne@69
|
170
|
jpayne@69
|
171 inline bool hidden() const
|
jpayne@69
|
172 {
|
jpayne@69
|
173 return (::panel_hidden (p) ? TRUE : FALSE);
|
jpayne@69
|
174 }
|
jpayne@69
|
175 // Return TRUE if the panel is hidden, FALSE otherwise.
|
jpayne@69
|
176
|
jpayne@69
|
177 /* The functions panel_above() and panel_below() are not reflected in
|
jpayne@69
|
178 the NCursesPanel class. The reason for this is, that we cannot
|
jpayne@69
|
179 assume that a panel retrieved by those operations is one wrapped
|
jpayne@69
|
180 by a C++ class. Although this situation might be handled, we also
|
jpayne@69
|
181 need a reverse mapping from PANEL to NCursesPanel which needs some
|
jpayne@69
|
182 redesign of the low level stuff. At the moment, we define them in the
|
jpayne@69
|
183 interface but they will always produce an error. */
|
jpayne@69
|
184 inline NCursesPanel& above() const
|
jpayne@69
|
185 {
|
jpayne@69
|
186 OnError(ERR);
|
jpayne@69
|
187 return *dummy;
|
jpayne@69
|
188 }
|
jpayne@69
|
189
|
jpayne@69
|
190 inline NCursesPanel& below() const
|
jpayne@69
|
191 {
|
jpayne@69
|
192 OnError(ERR);
|
jpayne@69
|
193 return *dummy;
|
jpayne@69
|
194 }
|
jpayne@69
|
195
|
jpayne@69
|
196 // Those two are rewrites of the corresponding virtual members of
|
jpayne@69
|
197 // NCursesWindow
|
jpayne@69
|
198 virtual int refresh() NCURSES_OVERRIDE;
|
jpayne@69
|
199 // Propagate all panel changes to the virtual screen and update the
|
jpayne@69
|
200 // physical screen.
|
jpayne@69
|
201
|
jpayne@69
|
202 virtual int noutrefresh() NCURSES_OVERRIDE;
|
jpayne@69
|
203 // Propagate all panel changes to the virtual screen.
|
jpayne@69
|
204
|
jpayne@69
|
205 static void redraw();
|
jpayne@69
|
206 // Redraw all panels.
|
jpayne@69
|
207
|
jpayne@69
|
208 // decorations
|
jpayne@69
|
209 virtual void frame(const char* title=NULL,
|
jpayne@69
|
210 const char* btitle=NULL);
|
jpayne@69
|
211 // Put a frame around the panel and put the title centered in the top line
|
jpayne@69
|
212 // and btitle in the bottom line.
|
jpayne@69
|
213
|
jpayne@69
|
214 virtual void boldframe(const char* title=NULL,
|
jpayne@69
|
215 const char* btitle=NULL);
|
jpayne@69
|
216 // Same as frame(), but use highlighted attributes.
|
jpayne@69
|
217
|
jpayne@69
|
218 virtual void label(const char* topLabel,
|
jpayne@69
|
219 const char* bottomLabel);
|
jpayne@69
|
220 // Put the title centered in the top line and btitle in the bottom line.
|
jpayne@69
|
221
|
jpayne@69
|
222 virtual void centertext(int row,const char* label);
|
jpayne@69
|
223 // Put the label text centered in the specified row.
|
jpayne@69
|
224 };
|
jpayne@69
|
225
|
jpayne@69
|
226 /* We use templates to provide a typesafe mechanism to associate
|
jpayne@69
|
227 * user data with a panel. A NCursesUserPanel<T> is a panel
|
jpayne@69
|
228 * associated with some user data of type T.
|
jpayne@69
|
229 */
|
jpayne@69
|
230 template<class T> class NCursesUserPanel : public NCursesPanel
|
jpayne@69
|
231 {
|
jpayne@69
|
232 public:
|
jpayne@69
|
233 NCursesUserPanel (int nlines,
|
jpayne@69
|
234 int ncols,
|
jpayne@69
|
235 int begin_y = 0,
|
jpayne@69
|
236 int begin_x = 0,
|
jpayne@69
|
237 const T* p_UserData = STATIC_CAST(T*)(0))
|
jpayne@69
|
238 : NCursesPanel (nlines, ncols, begin_y, begin_x)
|
jpayne@69
|
239 {
|
jpayne@69
|
240 if (p)
|
jpayne@69
|
241 set_user (const_cast<void *>(reinterpret_cast<const void*>
|
jpayne@69
|
242 (p_UserData)));
|
jpayne@69
|
243 };
|
jpayne@69
|
244 // This creates an user panel of the requested size with associated
|
jpayne@69
|
245 // user data pointed to by p_UserData.
|
jpayne@69
|
246
|
jpayne@69
|
247 explicit NCursesUserPanel(const T* p_UserData = STATIC_CAST(T*)(0)) : NCursesPanel()
|
jpayne@69
|
248 {
|
jpayne@69
|
249 if (p)
|
jpayne@69
|
250 set_user(const_cast<void *>(reinterpret_cast<const void*>(p_UserData)));
|
jpayne@69
|
251 };
|
jpayne@69
|
252 // This creates an user panel associated with the ::stdscr and user data
|
jpayne@69
|
253 // pointed to by p_UserData.
|
jpayne@69
|
254
|
jpayne@69
|
255 virtual ~NCursesUserPanel() THROWS(NCursesException) {};
|
jpayne@69
|
256
|
jpayne@69
|
257 T* UserData (void)
|
jpayne@69
|
258 {
|
jpayne@69
|
259 return reinterpret_cast<T*>(get_user ());
|
jpayne@69
|
260 };
|
jpayne@69
|
261 // Retrieve the user data associated with the panel.
|
jpayne@69
|
262
|
jpayne@69
|
263 virtual void setUserData (const T* p_UserData)
|
jpayne@69
|
264 {
|
jpayne@69
|
265 if (p)
|
jpayne@69
|
266 set_user (const_cast<void *>(reinterpret_cast<const void*>(p_UserData)));
|
jpayne@69
|
267 }
|
jpayne@69
|
268 // Associate the user panel with the user data pointed to by p_UserData.
|
jpayne@69
|
269 };
|
jpayne@69
|
270
|
jpayne@69
|
271 #endif /* NCURSES_CURSESP_H_incl */
|