jpayne@69
|
1 // * This makes emacs happy -*-Mode: C++;-*-
|
jpayne@69
|
2 /****************************************************************************
|
jpayne@69
|
3 * Copyright 2019-2020,2022 Thomas E. Dickey *
|
jpayne@69
|
4 * Copyright 1998-2012,2014 Free Software Foundation, Inc. *
|
jpayne@69
|
5 * *
|
jpayne@69
|
6 * Permission is hereby granted, free of charge, to any person obtaining a *
|
jpayne@69
|
7 * copy of this software and associated documentation files (the *
|
jpayne@69
|
8 * "Software"), to deal in the Software without restriction, including *
|
jpayne@69
|
9 * without limitation the rights to use, copy, modify, merge, publish, *
|
jpayne@69
|
10 * distribute, distribute with modifications, sublicense, and/or sell *
|
jpayne@69
|
11 * copies of the Software, and to permit persons to whom the Software is *
|
jpayne@69
|
12 * furnished to do so, subject to the following conditions: *
|
jpayne@69
|
13 * *
|
jpayne@69
|
14 * The above copyright notice and this permission notice shall be included *
|
jpayne@69
|
15 * in all copies or substantial portions of the Software. *
|
jpayne@69
|
16 * *
|
jpayne@69
|
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS *
|
jpayne@69
|
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF *
|
jpayne@69
|
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. *
|
jpayne@69
|
20 * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
|
jpayne@69
|
21 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
|
jpayne@69
|
22 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR *
|
jpayne@69
|
23 * THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
jpayne@69
|
24 * *
|
jpayne@69
|
25 * Except as contained in this notice, the name(s) of the above copyright *
|
jpayne@69
|
26 * holders shall not be used in advertising or otherwise to promote the *
|
jpayne@69
|
27 * sale, use or other dealings in this Software without prior written *
|
jpayne@69
|
28 * authorization. *
|
jpayne@69
|
29 ****************************************************************************/
|
jpayne@69
|
30
|
jpayne@69
|
31 /****************************************************************************
|
jpayne@69
|
32 * Author: Juergen Pfeifer, 1997 *
|
jpayne@69
|
33 ****************************************************************************/
|
jpayne@69
|
34
|
jpayne@69
|
35 // $Id: cursesm.h,v 1.35 2022/08/20 20:52:15 tom Exp $
|
jpayne@69
|
36
|
jpayne@69
|
37 #ifndef NCURSES_CURSESM_H_incl
|
jpayne@69
|
38 #define NCURSES_CURSESM_H_incl 1
|
jpayne@69
|
39
|
jpayne@69
|
40 #include <ncursesw/cursesp.h>
|
jpayne@69
|
41
|
jpayne@69
|
42 extern "C" {
|
jpayne@69
|
43 # include <ncursesw/menu.h>
|
jpayne@69
|
44 }
|
jpayne@69
|
45 //
|
jpayne@69
|
46 // -------------------------------------------------------------------------
|
jpayne@69
|
47 // This wraps the ITEM type of <ncursesw/menu.h>
|
jpayne@69
|
48 // -------------------------------------------------------------------------
|
jpayne@69
|
49 //
|
jpayne@69
|
50 class NCURSES_CXX_IMPEXP NCursesMenuItem
|
jpayne@69
|
51 {
|
jpayne@69
|
52 friend class NCursesMenu;
|
jpayne@69
|
53
|
jpayne@69
|
54 protected:
|
jpayne@69
|
55 ITEM *item;
|
jpayne@69
|
56
|
jpayne@69
|
57 inline void OnError (int err) const THROW2(NCursesException const, NCursesMenuException) {
|
jpayne@69
|
58 if (err != E_OK)
|
jpayne@69
|
59 THROW(new NCursesMenuException (err));
|
jpayne@69
|
60 }
|
jpayne@69
|
61
|
jpayne@69
|
62 public:
|
jpayne@69
|
63 NCursesMenuItem (const char* p_name = NULL,
|
jpayne@69
|
64 const char* p_descript = NULL)
|
jpayne@69
|
65 : item(0)
|
jpayne@69
|
66 {
|
jpayne@69
|
67 item = p_name ? ::new_item (p_name, p_descript) : STATIC_CAST(ITEM*)(0);
|
jpayne@69
|
68 if (p_name && !item)
|
jpayne@69
|
69 OnError (E_SYSTEM_ERROR);
|
jpayne@69
|
70 }
|
jpayne@69
|
71 // Create an item. If you pass both parameters as NULL, a delimiting
|
jpayne@69
|
72 // item is constructed which can be used to terminate a list of
|
jpayne@69
|
73 // NCursesMenu objects.
|
jpayne@69
|
74
|
jpayne@69
|
75 NCursesMenuItem& operator=(const NCursesMenuItem& rhs)
|
jpayne@69
|
76 {
|
jpayne@69
|
77 if (this != &rhs) {
|
jpayne@69
|
78 *this = rhs;
|
jpayne@69
|
79 }
|
jpayne@69
|
80 return *this;
|
jpayne@69
|
81 }
|
jpayne@69
|
82
|
jpayne@69
|
83 NCursesMenuItem(const NCursesMenuItem& rhs)
|
jpayne@69
|
84 : item(0)
|
jpayne@69
|
85 {
|
jpayne@69
|
86 (void) rhs;
|
jpayne@69
|
87 }
|
jpayne@69
|
88
|
jpayne@69
|
89 virtual ~NCursesMenuItem () THROWS(NCursesException);
|
jpayne@69
|
90 // Release the items memory
|
jpayne@69
|
91
|
jpayne@69
|
92 inline const char* name () const {
|
jpayne@69
|
93 return ::item_name (item);
|
jpayne@69
|
94 }
|
jpayne@69
|
95 // Name of the item
|
jpayne@69
|
96
|
jpayne@69
|
97 inline const char* description () const {
|
jpayne@69
|
98 return ::item_description (item);
|
jpayne@69
|
99 }
|
jpayne@69
|
100 // Description of the item
|
jpayne@69
|
101
|
jpayne@69
|
102 inline int (index) (void) const {
|
jpayne@69
|
103 return ::item_index (item);
|
jpayne@69
|
104 }
|
jpayne@69
|
105 // Index of the item in an item array (or -1)
|
jpayne@69
|
106
|
jpayne@69
|
107 inline void options_on (Item_Options opts) {
|
jpayne@69
|
108 OnError (::item_opts_on (item, opts));
|
jpayne@69
|
109 }
|
jpayne@69
|
110 // Switch on the items options
|
jpayne@69
|
111
|
jpayne@69
|
112 inline void options_off (Item_Options opts) {
|
jpayne@69
|
113 OnError (::item_opts_off (item, opts));
|
jpayne@69
|
114 }
|
jpayne@69
|
115 // Switch off the item's option
|
jpayne@69
|
116
|
jpayne@69
|
117 inline Item_Options options () const {
|
jpayne@69
|
118 return ::item_opts (item);
|
jpayne@69
|
119 }
|
jpayne@69
|
120 // Retrieve the items options
|
jpayne@69
|
121
|
jpayne@69
|
122 inline void set_options (Item_Options opts) {
|
jpayne@69
|
123 OnError (::set_item_opts (item, opts));
|
jpayne@69
|
124 }
|
jpayne@69
|
125 // Set the items options
|
jpayne@69
|
126
|
jpayne@69
|
127 inline void set_value (bool f) {
|
jpayne@69
|
128 OnError (::set_item_value (item,f));
|
jpayne@69
|
129 }
|
jpayne@69
|
130 // Set/Reset the items selection state
|
jpayne@69
|
131
|
jpayne@69
|
132 inline bool value () const {
|
jpayne@69
|
133 return ::item_value (item);
|
jpayne@69
|
134 }
|
jpayne@69
|
135 // Retrieve the items selection state
|
jpayne@69
|
136
|
jpayne@69
|
137 inline bool visible () const {
|
jpayne@69
|
138 return ::item_visible (item);
|
jpayne@69
|
139 }
|
jpayne@69
|
140 // Retrieve visibility of the item
|
jpayne@69
|
141
|
jpayne@69
|
142 virtual bool action();
|
jpayne@69
|
143 // Perform an action associated with this item; you may use this in an
|
jpayne@69
|
144 // user supplied driver for a menu; you may derive from this class and
|
jpayne@69
|
145 // overload action() to supply items with different actions.
|
jpayne@69
|
146 // If an action returns true, the menu will be exited. The default action
|
jpayne@69
|
147 // is to do nothing.
|
jpayne@69
|
148 };
|
jpayne@69
|
149
|
jpayne@69
|
150 // Prototype for an items callback function.
|
jpayne@69
|
151 typedef bool ITEMCALLBACK(NCursesMenuItem&);
|
jpayne@69
|
152
|
jpayne@69
|
153 // If you don't like to create a child class for individual items to
|
jpayne@69
|
154 // overload action(), you may use this class and provide a callback
|
jpayne@69
|
155 // function pointer for items.
|
jpayne@69
|
156 class NCURSES_CXX_IMPEXP NCursesMenuCallbackItem : public NCursesMenuItem
|
jpayne@69
|
157 {
|
jpayne@69
|
158 private:
|
jpayne@69
|
159 ITEMCALLBACK* p_fct;
|
jpayne@69
|
160
|
jpayne@69
|
161 public:
|
jpayne@69
|
162 NCursesMenuCallbackItem(ITEMCALLBACK* fct = NULL,
|
jpayne@69
|
163 const char* p_name = NULL,
|
jpayne@69
|
164 const char* p_descript = NULL )
|
jpayne@69
|
165 : NCursesMenuItem (p_name, p_descript),
|
jpayne@69
|
166 p_fct (fct) {
|
jpayne@69
|
167 }
|
jpayne@69
|
168
|
jpayne@69
|
169 NCursesMenuCallbackItem& operator=(const NCursesMenuCallbackItem& rhs)
|
jpayne@69
|
170 {
|
jpayne@69
|
171 if (this != &rhs) {
|
jpayne@69
|
172 *this = rhs;
|
jpayne@69
|
173 }
|
jpayne@69
|
174 return *this;
|
jpayne@69
|
175 }
|
jpayne@69
|
176
|
jpayne@69
|
177 NCursesMenuCallbackItem(const NCursesMenuCallbackItem& rhs)
|
jpayne@69
|
178 : NCursesMenuItem(rhs),
|
jpayne@69
|
179 p_fct(0)
|
jpayne@69
|
180 {
|
jpayne@69
|
181 }
|
jpayne@69
|
182
|
jpayne@69
|
183 virtual ~NCursesMenuCallbackItem() THROWS(NCursesException);
|
jpayne@69
|
184
|
jpayne@69
|
185 bool action() NCURSES_OVERRIDE;
|
jpayne@69
|
186 };
|
jpayne@69
|
187
|
jpayne@69
|
188 // This are the built-in hook functions in this C++ binding. In C++ we use
|
jpayne@69
|
189 // virtual member functions (see below On_..._Init and On_..._Termination)
|
jpayne@69
|
190 // to provide this functionality in an object oriented manner.
|
jpayne@69
|
191 extern "C" {
|
jpayne@69
|
192 void _nc_xx_mnu_init(MENU *);
|
jpayne@69
|
193 void _nc_xx_mnu_term(MENU *);
|
jpayne@69
|
194 void _nc_xx_itm_init(MENU *);
|
jpayne@69
|
195 void _nc_xx_itm_term(MENU *);
|
jpayne@69
|
196 }
|
jpayne@69
|
197
|
jpayne@69
|
198 //
|
jpayne@69
|
199 // -------------------------------------------------------------------------
|
jpayne@69
|
200 // This wraps the MENU type of <ncursesw/menu.h>
|
jpayne@69
|
201 // -------------------------------------------------------------------------
|
jpayne@69
|
202 //
|
jpayne@69
|
203 class NCURSES_CXX_IMPEXP NCursesMenu : public NCursesPanel
|
jpayne@69
|
204 {
|
jpayne@69
|
205 protected:
|
jpayne@69
|
206 MENU *menu;
|
jpayne@69
|
207
|
jpayne@69
|
208 private:
|
jpayne@69
|
209 NCursesWindow* sub; // the subwindow object
|
jpayne@69
|
210 bool b_sub_owner; // is this our own subwindow?
|
jpayne@69
|
211 bool b_framed; // has the menu a border?
|
jpayne@69
|
212 bool b_autoDelete; // Delete items when deleting menu?
|
jpayne@69
|
213
|
jpayne@69
|
214 NCursesMenuItem** my_items; // The array of items for this menu
|
jpayne@69
|
215
|
jpayne@69
|
216 // This structure is used for the menu's user data field to link the
|
jpayne@69
|
217 // MENU* to the C++ object and to provide extra space for a user pointer.
|
jpayne@69
|
218 typedef struct {
|
jpayne@69
|
219 void* m_user; // the pointer for the user's data
|
jpayne@69
|
220 const NCursesMenu* m_back; // backward pointer to C++ object
|
jpayne@69
|
221 const MENU* m_owner;
|
jpayne@69
|
222 } UserHook;
|
jpayne@69
|
223
|
jpayne@69
|
224 // Get the backward pointer to the C++ object from a MENU
|
jpayne@69
|
225 static inline NCursesMenu* getHook(const MENU *m) {
|
jpayne@69
|
226 UserHook* hook = STATIC_CAST(UserHook*)(::menu_userptr(m));
|
jpayne@69
|
227 assert(hook != 0 && hook->m_owner==m);
|
jpayne@69
|
228 return const_cast<NCursesMenu*>(hook->m_back);
|
jpayne@69
|
229 }
|
jpayne@69
|
230
|
jpayne@69
|
231 friend void _nc_xx_mnu_init(MENU *);
|
jpayne@69
|
232 friend void _nc_xx_mnu_term(MENU *);
|
jpayne@69
|
233 friend void _nc_xx_itm_init(MENU *);
|
jpayne@69
|
234 friend void _nc_xx_itm_term(MENU *);
|
jpayne@69
|
235
|
jpayne@69
|
236 // Calculate ITEM* array for the menu
|
jpayne@69
|
237 ITEM** mapItems(NCursesMenuItem* nitems[]);
|
jpayne@69
|
238
|
jpayne@69
|
239 protected:
|
jpayne@69
|
240 // internal routines
|
jpayne@69
|
241 inline void set_user(void *user) {
|
jpayne@69
|
242 UserHook* uptr = STATIC_CAST(UserHook*)(::menu_userptr (menu));
|
jpayne@69
|
243 assert (uptr != 0 && uptr->m_back==this && uptr->m_owner==menu);
|
jpayne@69
|
244 uptr->m_user = user;
|
jpayne@69
|
245 }
|
jpayne@69
|
246
|
jpayne@69
|
247 inline void *get_user() {
|
jpayne@69
|
248 UserHook* uptr = STATIC_CAST(UserHook*)(::menu_userptr (menu));
|
jpayne@69
|
249 assert (uptr != 0 && uptr->m_back==this && uptr->m_owner==menu);
|
jpayne@69
|
250 return uptr->m_user;
|
jpayne@69
|
251 }
|
jpayne@69
|
252
|
jpayne@69
|
253 void InitMenu (NCursesMenuItem* menu[],
|
jpayne@69
|
254 bool with_frame,
|
jpayne@69
|
255 bool autoDeleteItems);
|
jpayne@69
|
256
|
jpayne@69
|
257 inline void OnError (int err) const THROW2(NCursesException const, NCursesMenuException) {
|
jpayne@69
|
258 if (err != E_OK)
|
jpayne@69
|
259 THROW(new NCursesMenuException (this, err));
|
jpayne@69
|
260 }
|
jpayne@69
|
261
|
jpayne@69
|
262 // this wraps the menu_driver call.
|
jpayne@69
|
263 virtual int driver (int c) ;
|
jpayne@69
|
264
|
jpayne@69
|
265 // 'Internal' constructor to create a menu without association to
|
jpayne@69
|
266 // an array of items.
|
jpayne@69
|
267 NCursesMenu( int nlines,
|
jpayne@69
|
268 int ncols,
|
jpayne@69
|
269 int begin_y = 0,
|
jpayne@69
|
270 int begin_x = 0)
|
jpayne@69
|
271 : NCursesPanel(nlines,ncols,begin_y,begin_x),
|
jpayne@69
|
272 menu (STATIC_CAST(MENU*)(0)),
|
jpayne@69
|
273 sub(0),
|
jpayne@69
|
274 b_sub_owner(0),
|
jpayne@69
|
275 b_framed(0),
|
jpayne@69
|
276 b_autoDelete(0),
|
jpayne@69
|
277 my_items(0)
|
jpayne@69
|
278 {
|
jpayne@69
|
279 }
|
jpayne@69
|
280
|
jpayne@69
|
281 public:
|
jpayne@69
|
282 // Make a full window size menu
|
jpayne@69
|
283 NCursesMenu (NCursesMenuItem* Items[],
|
jpayne@69
|
284 bool with_frame=FALSE, // Reserve space for a frame?
|
jpayne@69
|
285 bool autoDelete_Items=FALSE) // Autocleanup of Items?
|
jpayne@69
|
286 : NCursesPanel(),
|
jpayne@69
|
287 menu(0),
|
jpayne@69
|
288 sub(0),
|
jpayne@69
|
289 b_sub_owner(0),
|
jpayne@69
|
290 b_framed(0),
|
jpayne@69
|
291 b_autoDelete(0),
|
jpayne@69
|
292 my_items(0)
|
jpayne@69
|
293 {
|
jpayne@69
|
294 InitMenu(Items, with_frame, autoDelete_Items);
|
jpayne@69
|
295 }
|
jpayne@69
|
296
|
jpayne@69
|
297 // Make a menu with a window of this size.
|
jpayne@69
|
298 NCursesMenu (NCursesMenuItem* Items[],
|
jpayne@69
|
299 int nlines,
|
jpayne@69
|
300 int ncols,
|
jpayne@69
|
301 int begin_y = 0,
|
jpayne@69
|
302 int begin_x = 0,
|
jpayne@69
|
303 bool with_frame=FALSE, // Reserve space for a frame?
|
jpayne@69
|
304 bool autoDelete_Items=FALSE) // Autocleanup of Items?
|
jpayne@69
|
305 : NCursesPanel(nlines, ncols, begin_y, begin_x),
|
jpayne@69
|
306 menu(0),
|
jpayne@69
|
307 sub(0),
|
jpayne@69
|
308 b_sub_owner(0),
|
jpayne@69
|
309 b_framed(0),
|
jpayne@69
|
310 b_autoDelete(0),
|
jpayne@69
|
311 my_items(0)
|
jpayne@69
|
312 {
|
jpayne@69
|
313 InitMenu(Items, with_frame, autoDelete_Items);
|
jpayne@69
|
314 }
|
jpayne@69
|
315
|
jpayne@69
|
316 NCursesMenu& operator=(const NCursesMenu& rhs)
|
jpayne@69
|
317 {
|
jpayne@69
|
318 if (this != &rhs) {
|
jpayne@69
|
319 *this = rhs;
|
jpayne@69
|
320 NCursesPanel::operator=(rhs);
|
jpayne@69
|
321 }
|
jpayne@69
|
322 return *this;
|
jpayne@69
|
323 }
|
jpayne@69
|
324
|
jpayne@69
|
325 NCursesMenu(const NCursesMenu& rhs)
|
jpayne@69
|
326 : NCursesPanel(rhs),
|
jpayne@69
|
327 menu(rhs.menu),
|
jpayne@69
|
328 sub(rhs.sub),
|
jpayne@69
|
329 b_sub_owner(rhs.b_sub_owner),
|
jpayne@69
|
330 b_framed(rhs.b_framed),
|
jpayne@69
|
331 b_autoDelete(rhs.b_autoDelete),
|
jpayne@69
|
332 my_items(rhs.my_items)
|
jpayne@69
|
333 {
|
jpayne@69
|
334 }
|
jpayne@69
|
335
|
jpayne@69
|
336 virtual ~NCursesMenu () THROWS(NCursesException);
|
jpayne@69
|
337
|
jpayne@69
|
338 // Retrieve the menus subwindow
|
jpayne@69
|
339 inline NCursesWindow& subWindow() const {
|
jpayne@69
|
340 assert(sub!=NULL);
|
jpayne@69
|
341 return *sub;
|
jpayne@69
|
342 }
|
jpayne@69
|
343
|
jpayne@69
|
344 // Set the menus subwindow
|
jpayne@69
|
345 void setSubWindow(NCursesWindow& sub);
|
jpayne@69
|
346
|
jpayne@69
|
347 // Set these items for the menu
|
jpayne@69
|
348 inline void setItems(NCursesMenuItem* Items[]) {
|
jpayne@69
|
349 OnError(::set_menu_items(menu,mapItems(Items)));
|
jpayne@69
|
350 }
|
jpayne@69
|
351
|
jpayne@69
|
352 // Remove the menu from the screen
|
jpayne@69
|
353 inline void unpost (void) {
|
jpayne@69
|
354 OnError (::unpost_menu (menu));
|
jpayne@69
|
355 }
|
jpayne@69
|
356
|
jpayne@69
|
357 // Post the menu to the screen if flag is true, unpost it otherwise
|
jpayne@69
|
358 inline void post(bool flag = TRUE) {
|
jpayne@69
|
359 flag ? OnError (::post_menu(menu)) : OnError (::unpost_menu (menu));
|
jpayne@69
|
360 }
|
jpayne@69
|
361
|
jpayne@69
|
362 // Get the number of rows and columns for this menu
|
jpayne@69
|
363 inline void scale (int& mrows, int& mcols) const {
|
jpayne@69
|
364 OnError (::scale_menu (menu, &mrows, &mcols));
|
jpayne@69
|
365 }
|
jpayne@69
|
366
|
jpayne@69
|
367 // Set the format of this menu
|
jpayne@69
|
368 inline void set_format(int mrows, int mcols) {
|
jpayne@69
|
369 OnError (::set_menu_format(menu, mrows, mcols));
|
jpayne@69
|
370 }
|
jpayne@69
|
371
|
jpayne@69
|
372 // Get the format of this menu
|
jpayne@69
|
373 inline void menu_format(int& rows,int& ncols) {
|
jpayne@69
|
374 ::menu_format(menu,&rows,&ncols);
|
jpayne@69
|
375 }
|
jpayne@69
|
376
|
jpayne@69
|
377 // Items of the menu
|
jpayne@69
|
378 inline NCursesMenuItem* items() const {
|
jpayne@69
|
379 return *my_items;
|
jpayne@69
|
380 }
|
jpayne@69
|
381
|
jpayne@69
|
382 // Get the number of items in this menu
|
jpayne@69
|
383 inline int count() const {
|
jpayne@69
|
384 return ::item_count(menu);
|
jpayne@69
|
385 }
|
jpayne@69
|
386
|
jpayne@69
|
387 // Get the current item (i.e. the one the cursor is located)
|
jpayne@69
|
388 inline NCursesMenuItem* current_item() const {
|
jpayne@69
|
389 return my_items[::item_index(::current_item(menu))];
|
jpayne@69
|
390 }
|
jpayne@69
|
391
|
jpayne@69
|
392 // Get the marker string
|
jpayne@69
|
393 inline const char* mark() const {
|
jpayne@69
|
394 return ::menu_mark(menu);
|
jpayne@69
|
395 }
|
jpayne@69
|
396
|
jpayne@69
|
397 // Set the marker string
|
jpayne@69
|
398 inline void set_mark(const char *marker) {
|
jpayne@69
|
399 OnError (::set_menu_mark (menu, marker));
|
jpayne@69
|
400 }
|
jpayne@69
|
401
|
jpayne@69
|
402 // Get the name of the request code c
|
jpayne@69
|
403 inline static const char* request_name(int c) {
|
jpayne@69
|
404 return ::menu_request_name(c);
|
jpayne@69
|
405 }
|
jpayne@69
|
406
|
jpayne@69
|
407 // Get the current pattern
|
jpayne@69
|
408 inline char* pattern() const {
|
jpayne@69
|
409 return ::menu_pattern(menu);
|
jpayne@69
|
410 }
|
jpayne@69
|
411
|
jpayne@69
|
412 // true if there is a pattern match, false otherwise.
|
jpayne@69
|
413 bool set_pattern (const char *pat);
|
jpayne@69
|
414
|
jpayne@69
|
415 // set the default attributes for the menu
|
jpayne@69
|
416 // i.e. set fore, back and grey attribute
|
jpayne@69
|
417 virtual void setDefaultAttributes();
|
jpayne@69
|
418
|
jpayne@69
|
419 // Get the menus background attributes
|
jpayne@69
|
420 inline chtype back() const {
|
jpayne@69
|
421 return ::menu_back(menu);
|
jpayne@69
|
422 }
|
jpayne@69
|
423
|
jpayne@69
|
424 // Get the menus foreground attributes
|
jpayne@69
|
425 inline chtype fore() const {
|
jpayne@69
|
426 return ::menu_fore(menu);
|
jpayne@69
|
427 }
|
jpayne@69
|
428
|
jpayne@69
|
429 // Get the menus grey attributes (used for unselectable items)
|
jpayne@69
|
430 inline chtype grey() const {
|
jpayne@69
|
431 return ::menu_grey(menu);
|
jpayne@69
|
432 }
|
jpayne@69
|
433
|
jpayne@69
|
434 // Set the menus background attributes
|
jpayne@69
|
435 inline chtype set_background(chtype a) {
|
jpayne@69
|
436 return ::set_menu_back(menu,a);
|
jpayne@69
|
437 }
|
jpayne@69
|
438
|
jpayne@69
|
439 // Set the menus foreground attributes
|
jpayne@69
|
440 inline chtype set_foreground(chtype a) {
|
jpayne@69
|
441 return ::set_menu_fore(menu,a);
|
jpayne@69
|
442 }
|
jpayne@69
|
443
|
jpayne@69
|
444 // Set the menus grey attributes (used for unselectable items)
|
jpayne@69
|
445 inline chtype set_grey(chtype a) {
|
jpayne@69
|
446 return ::set_menu_grey(menu,a);
|
jpayne@69
|
447 }
|
jpayne@69
|
448
|
jpayne@69
|
449 inline void options_on (Menu_Options opts) {
|
jpayne@69
|
450 OnError (::menu_opts_on (menu,opts));
|
jpayne@69
|
451 }
|
jpayne@69
|
452
|
jpayne@69
|
453 inline void options_off(Menu_Options opts) {
|
jpayne@69
|
454 OnError (::menu_opts_off(menu,opts));
|
jpayne@69
|
455 }
|
jpayne@69
|
456
|
jpayne@69
|
457 inline Menu_Options options() const {
|
jpayne@69
|
458 return ::menu_opts(menu);
|
jpayne@69
|
459 }
|
jpayne@69
|
460
|
jpayne@69
|
461 inline void set_options (Menu_Options opts) {
|
jpayne@69
|
462 OnError (::set_menu_opts (menu,opts));
|
jpayne@69
|
463 }
|
jpayne@69
|
464
|
jpayne@69
|
465 inline int pad() const {
|
jpayne@69
|
466 return ::menu_pad(menu);
|
jpayne@69
|
467 }
|
jpayne@69
|
468
|
jpayne@69
|
469 inline void set_pad (int padch) {
|
jpayne@69
|
470 OnError (::set_menu_pad (menu, padch));
|
jpayne@69
|
471 }
|
jpayne@69
|
472
|
jpayne@69
|
473 // Position the cursor to the current item
|
jpayne@69
|
474 inline void position_cursor () const {
|
jpayne@69
|
475 OnError (::pos_menu_cursor (menu));
|
jpayne@69
|
476 }
|
jpayne@69
|
477
|
jpayne@69
|
478 // Set the current item
|
jpayne@69
|
479 inline void set_current(NCursesMenuItem& I) {
|
jpayne@69
|
480 OnError (::set_current_item(menu, I.item));
|
jpayne@69
|
481 }
|
jpayne@69
|
482
|
jpayne@69
|
483 // Get the current top row of the menu
|
jpayne@69
|
484 inline int top_row (void) const {
|
jpayne@69
|
485 return ::top_row (menu);
|
jpayne@69
|
486 }
|
jpayne@69
|
487
|
jpayne@69
|
488 // Set the current top row of the menu
|
jpayne@69
|
489 inline void set_top_row (int row) {
|
jpayne@69
|
490 OnError (::set_top_row (menu, row));
|
jpayne@69
|
491 }
|
jpayne@69
|
492
|
jpayne@69
|
493 // spacing control
|
jpayne@69
|
494 // Set the spacing for the menu
|
jpayne@69
|
495 inline void setSpacing(int spc_description,
|
jpayne@69
|
496 int spc_rows,
|
jpayne@69
|
497 int spc_columns) {
|
jpayne@69
|
498 OnError(::set_menu_spacing(menu,
|
jpayne@69
|
499 spc_description,
|
jpayne@69
|
500 spc_rows,
|
jpayne@69
|
501 spc_columns));
|
jpayne@69
|
502 }
|
jpayne@69
|
503
|
jpayne@69
|
504 // Get the spacing info for the menu
|
jpayne@69
|
505 inline void Spacing(int& spc_description,
|
jpayne@69
|
506 int& spc_rows,
|
jpayne@69
|
507 int& spc_columns) const {
|
jpayne@69
|
508 OnError(::menu_spacing(menu,
|
jpayne@69
|
509 &spc_description,
|
jpayne@69
|
510 &spc_rows,
|
jpayne@69
|
511 &spc_columns));
|
jpayne@69
|
512 }
|
jpayne@69
|
513
|
jpayne@69
|
514 // Decorations
|
jpayne@69
|
515 inline void frame(const char *title=NULL, const char* btitle=NULL) NCURSES_OVERRIDE {
|
jpayne@69
|
516 if (b_framed)
|
jpayne@69
|
517 NCursesPanel::frame(title,btitle);
|
jpayne@69
|
518 else
|
jpayne@69
|
519 OnError(E_SYSTEM_ERROR);
|
jpayne@69
|
520 }
|
jpayne@69
|
521
|
jpayne@69
|
522 inline void boldframe(const char *title=NULL, const char* btitle=NULL) NCURSES_OVERRIDE {
|
jpayne@69
|
523 if (b_framed)
|
jpayne@69
|
524 NCursesPanel::boldframe(title,btitle);
|
jpayne@69
|
525 else
|
jpayne@69
|
526 OnError(E_SYSTEM_ERROR);
|
jpayne@69
|
527 }
|
jpayne@69
|
528
|
jpayne@69
|
529 inline void label(const char *topLabel, const char *bottomLabel) NCURSES_OVERRIDE {
|
jpayne@69
|
530 if (b_framed)
|
jpayne@69
|
531 NCursesPanel::label(topLabel,bottomLabel);
|
jpayne@69
|
532 else
|
jpayne@69
|
533 OnError(E_SYSTEM_ERROR);
|
jpayne@69
|
534 }
|
jpayne@69
|
535
|
jpayne@69
|
536 // -----
|
jpayne@69
|
537 // Hooks
|
jpayne@69
|
538 // -----
|
jpayne@69
|
539
|
jpayne@69
|
540 // Called after the menu gets repositioned in its window.
|
jpayne@69
|
541 // This is especially true if the menu is posted.
|
jpayne@69
|
542 virtual void On_Menu_Init();
|
jpayne@69
|
543
|
jpayne@69
|
544 // Called before the menu gets repositioned in its window.
|
jpayne@69
|
545 // This is especially true if the menu is unposted.
|
jpayne@69
|
546 virtual void On_Menu_Termination();
|
jpayne@69
|
547
|
jpayne@69
|
548 // Called after the item became the current item
|
jpayne@69
|
549 virtual void On_Item_Init(NCursesMenuItem& item);
|
jpayne@69
|
550
|
jpayne@69
|
551 // Called before this item is left as current item.
|
jpayne@69
|
552 virtual void On_Item_Termination(NCursesMenuItem& item);
|
jpayne@69
|
553
|
jpayne@69
|
554 // Provide a default key virtualization. Translate the keyboard
|
jpayne@69
|
555 // code c into a menu request code.
|
jpayne@69
|
556 // The default implementation provides a hopefully straightforward
|
jpayne@69
|
557 // mapping for the most common keystrokes and menu requests.
|
jpayne@69
|
558 virtual int virtualize(int c);
|
jpayne@69
|
559
|
jpayne@69
|
560
|
jpayne@69
|
561 // Operators
|
jpayne@69
|
562 inline NCursesMenuItem* operator[](int i) const {
|
jpayne@69
|
563 if ( (i < 0) || (i >= ::item_count (menu)) )
|
jpayne@69
|
564 OnError (E_BAD_ARGUMENT);
|
jpayne@69
|
565 return (my_items[i]);
|
jpayne@69
|
566 }
|
jpayne@69
|
567
|
jpayne@69
|
568 // Perform the menu's operation
|
jpayne@69
|
569 // Return the item where you left the selection mark for a single
|
jpayne@69
|
570 // selection menu, or NULL for a multivalued menu.
|
jpayne@69
|
571 virtual NCursesMenuItem* operator()(void);
|
jpayne@69
|
572
|
jpayne@69
|
573 // --------------------
|
jpayne@69
|
574 // Exception handlers
|
jpayne@69
|
575 // Called by operator()
|
jpayne@69
|
576 // --------------------
|
jpayne@69
|
577
|
jpayne@69
|
578 // Called if the request is denied
|
jpayne@69
|
579 virtual void On_Request_Denied(int c) const;
|
jpayne@69
|
580
|
jpayne@69
|
581 // Called if the item is not selectable
|
jpayne@69
|
582 virtual void On_Not_Selectable(int c) const;
|
jpayne@69
|
583
|
jpayne@69
|
584 // Called if pattern doesn't match
|
jpayne@69
|
585 virtual void On_No_Match(int c) const;
|
jpayne@69
|
586
|
jpayne@69
|
587 // Called if the command is unknown
|
jpayne@69
|
588 virtual void On_Unknown_Command(int c) const;
|
jpayne@69
|
589
|
jpayne@69
|
590 };
|
jpayne@69
|
591 //
|
jpayne@69
|
592 // -------------------------------------------------------------------------
|
jpayne@69
|
593 // This is the typical C++ typesafe way to allow to attach
|
jpayne@69
|
594 // user data to an item of a menu. Its assumed that the user
|
jpayne@69
|
595 // data belongs to some class T. Use T as template argument
|
jpayne@69
|
596 // to create a UserItem.
|
jpayne@69
|
597 // -------------------------------------------------------------------------
|
jpayne@69
|
598 //
|
jpayne@69
|
599 template<class T> class NCURSES_CXX_IMPEXP NCursesUserItem : public NCursesMenuItem
|
jpayne@69
|
600 {
|
jpayne@69
|
601 public:
|
jpayne@69
|
602 NCursesUserItem (const char* p_name,
|
jpayne@69
|
603 const char* p_descript = NULL,
|
jpayne@69
|
604 const T* p_UserData = STATIC_CAST(T*)(0))
|
jpayne@69
|
605 : NCursesMenuItem (p_name, p_descript) {
|
jpayne@69
|
606 if (item)
|
jpayne@69
|
607 OnError (::set_item_userptr (item, const_cast<void *>(reinterpret_cast<const void*>(p_UserData))));
|
jpayne@69
|
608 }
|
jpayne@69
|
609
|
jpayne@69
|
610 virtual ~NCursesUserItem() THROWS(NCursesException) {}
|
jpayne@69
|
611
|
jpayne@69
|
612 inline const T* UserData (void) const {
|
jpayne@69
|
613 return reinterpret_cast<const T*>(::item_userptr (item));
|
jpayne@69
|
614 };
|
jpayne@69
|
615
|
jpayne@69
|
616 inline virtual void setUserData(const T* p_UserData) {
|
jpayne@69
|
617 if (item)
|
jpayne@69
|
618 OnError (::set_item_userptr (item, const_cast<void *>(reinterpret_cast<const void *>(p_UserData))));
|
jpayne@69
|
619 }
|
jpayne@69
|
620 };
|
jpayne@69
|
621 //
|
jpayne@69
|
622 // -------------------------------------------------------------------------
|
jpayne@69
|
623 // The same mechanism is used to attach user data to a menu
|
jpayne@69
|
624 // -------------------------------------------------------------------------
|
jpayne@69
|
625 //
|
jpayne@69
|
626 template<class T> class NCURSES_CXX_IMPEXP NCursesUserMenu : public NCursesMenu
|
jpayne@69
|
627 {
|
jpayne@69
|
628 protected:
|
jpayne@69
|
629 NCursesUserMenu( int nlines,
|
jpayne@69
|
630 int ncols,
|
jpayne@69
|
631 int begin_y = 0,
|
jpayne@69
|
632 int begin_x = 0,
|
jpayne@69
|
633 const T* p_UserData = STATIC_CAST(T*)(0))
|
jpayne@69
|
634 : NCursesMenu(nlines,ncols,begin_y,begin_x) {
|
jpayne@69
|
635 if (menu)
|
jpayne@69
|
636 set_user (const_cast<void *>(reinterpret_cast<const void*>(p_UserData)));
|
jpayne@69
|
637 }
|
jpayne@69
|
638
|
jpayne@69
|
639 public:
|
jpayne@69
|
640 NCursesUserMenu (NCursesMenuItem* Items[],
|
jpayne@69
|
641 const T* p_UserData = STATIC_CAST(T*)(0),
|
jpayne@69
|
642 bool with_frame=FALSE,
|
jpayne@69
|
643 bool autoDelete_Items=FALSE)
|
jpayne@69
|
644 : NCursesMenu (Items, with_frame, autoDelete_Items) {
|
jpayne@69
|
645 if (menu)
|
jpayne@69
|
646 set_user (const_cast<void *>(reinterpret_cast<const void*>(p_UserData)));
|
jpayne@69
|
647 };
|
jpayne@69
|
648
|
jpayne@69
|
649 NCursesUserMenu (NCursesMenuItem* Items[],
|
jpayne@69
|
650 int nlines,
|
jpayne@69
|
651 int ncols,
|
jpayne@69
|
652 int begin_y = 0,
|
jpayne@69
|
653 int begin_x = 0,
|
jpayne@69
|
654 const T* p_UserData = STATIC_CAST(T*)(0),
|
jpayne@69
|
655 bool with_frame=FALSE)
|
jpayne@69
|
656 : NCursesMenu (Items, nlines, ncols, begin_y, begin_x, with_frame) {
|
jpayne@69
|
657 if (menu)
|
jpayne@69
|
658 set_user (const_cast<void *>(reinterpret_cast<const void*>(p_UserData)));
|
jpayne@69
|
659 };
|
jpayne@69
|
660
|
jpayne@69
|
661 virtual ~NCursesUserMenu() THROWS(NCursesException) {
|
jpayne@69
|
662 };
|
jpayne@69
|
663
|
jpayne@69
|
664 inline T* UserData (void) {
|
jpayne@69
|
665 return reinterpret_cast<T*>(get_user ());
|
jpayne@69
|
666 };
|
jpayne@69
|
667
|
jpayne@69
|
668 inline virtual void setUserData (const T* p_UserData) {
|
jpayne@69
|
669 if (menu)
|
jpayne@69
|
670 set_user (const_cast<void *>(reinterpret_cast<const void*>(p_UserData)));
|
jpayne@69
|
671 }
|
jpayne@69
|
672 };
|
jpayne@69
|
673
|
jpayne@69
|
674 #endif /* NCURSES_CURSESM_H_incl */
|