comparison CSP2/CSP2_env/env-d9b9114564458d9d-741b3de822f2aaca6c6caa4325c4afce/include/ncurses/cursesm.h @ 69:33d812a61356

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