cwidget  0.5.17
menu.h
1 // menu.h -*-c++-*-
2 //
3 // Copyright (C) 2000-2005 Daniel Burrows
4 //
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License as
7 // published by the Free Software Foundation; either version 2 of
8 // the License, or (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program; see the file COPYING. If not, write to
17 // the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 // Boston, MA 02111-1307, USA.
19 //
20 // A nice menu with selectable entries. (fairly basic atm)
21 
22 #ifndef MENU_H
23 #define MENU_H
24 
25 #include "widget.h"
26 
28 
29 #include <cwidget/generic/util/bool_accumulate.h>
31 
32 #include <vector>
33 
34 namespace cwidget
35 {
36  namespace widgets
37  {
38  // Currently, menu-items aren't full widgets--it's simply too much
39  // baggage (lots of signals and a Curses window) for something that's
40  // quite simple and special-purpose.
41  class menu_item
42  {
43  // The text displayed in the menu entry
44  std::wstring title;
45 
46  // A string describing the item's function
47  std::wstring description;
48 
49  // The keybinding whose definition (in the GLOBAL bindings list) is
50  // displayed to the right of the menu entry.
51  std::string binding;
52 
53  // The key that directly activates this item *while the menu is open*
54  chtype hotkey;
55  public:
56  // Infers the hotkey from the title
57  menu_item(const std::wstring &_title, const std::string &_binding,
58  const std::wstring &_description);
59 
60  std::wstring get_title() const {return title;}
61  std::string get_binding() const {return binding;}
62  std::wstring get_description() const {return description;}
63  chtype get_hotkey() const {return hotkey;}
64 
66  bool is_enabled() const;
67 
69  sigc::signal0<void> selected;
70 
77  sigc::signal0<bool, util::accumulate_or> enabled;
78  };
79 
80 #define MENU_NOP NULL
81 
82  // Info for easy static generation of menus
83 
84  struct menu_info
85  {
86  public:
87  // MENU_ITEM: a "real" menu-item
88  // MENU_END: the last item in this information block
89  enum item_types {MENU_ITEM, MENU_SEPARATOR, MENU_END} item_type;
90 
92  const char *item_name, *item_binding, *item_description;
93 
94  // How to communicate with the outside world..
95  util::slot0arg item_slot;
96 
97  // For activation
98  util::slotarg<sigc::slot0<bool> > item_enabled;
99 
100  menu_info(item_types type, const char *name, const char *binding,
101  const char *description, sigc::slot0<void> slot);
102 
103  menu_info(item_types type, const char *name, const char *binding,
104  const char *description, sigc::slot0<void> *slot);
105 
106  menu_info(item_types type, const char *name, const char *binding,
107  const char *description, sigc::slot0<void> slot,
108  sigc::slot0<bool> enabled);
109 
110  menu_info(item_types type, const char *name, const char *binding,
111  const char *description, sigc::slot0<void> *slot,
112  sigc::slot0<bool> enabled);
113 
114  menu_info(item_types type);
115  };
116 
117  const menu_info MENU_SEPARATOR(menu_info::MENU_SEPARATOR);
118  const menu_info MENU_END(menu_info::MENU_END);
119 
120  class menu : public widget
121  {
122  typedef std::vector<menu_item *> itemlist;
123 
124  // A set of menu items. NULL indicates a separator.
125  // These items are deleted with the menu.
126  itemlist items;
127 
129  itemlist::size_type cursorloc;
130 
132  itemlist::size_type startloc;
133 
135  int min_width;
136 
137  // connected to "shown"
138  void appear();
139 
140  // connected to "hidden"
141  void disappear();
142 
146  void update_startloc();
147 
149  bool selectable(itemlist::size_type pos);
150 
152  void set_cursor(itemlist::size_type pos);
153 
157  void highlight_current();
158 
165  itemlist::size_type next_selectable(itemlist::size_type pos);
166 
174  itemlist::size_type prev_selectable(itemlist::size_type pos);
175 
182  void sanitize_cursor(bool forward);
183 
184  protected:
185  virtual bool handle_key(const config::key &k);
186 
188  menu();
189 
190  // Initialize a menu from a block of information. If there is no
191  // MENU_END in the block, RANDOM ERRORS WILL OCCUR!!
192  menu(int x, int y, int w, menu_info *inf);
193  public:
194  static util::ref_ptr<menu> create()
195  {
196  util::ref_ptr<menu> rval(new menu);
197  rval->decref();
198  return rval;
199  }
200 
201  static util::ref_ptr<menu> create(int x, int y, int w, menu_info *inf)
202  {
203  util::ref_ptr<menu> rval(new menu(x, y, w, inf));
204  rval->decref();
205  return rval;
206  }
207 
208  // Deletes the items it holds!
209  ~menu();
210 
211  bool get_cursorvisible();
212  point get_cursorloc();
213 
214  int width_request();
215  int height_request(int width);
216 
217  void append_item(menu_item *newitem);
218  void remove_item(menu_item *item);
219 
221  void move_selection_up();
222 
224  void move_selection_down();
225 
227  void move_selection_top();
228 
230  void move_selection_bottom();
231 
232  virtual bool focus_me();
233  virtual void paint(const style &st);
234  virtual void dispatch_mouse(short id, int x, int y, int z, mmask_t bstate);
235 
236  // Emitted when an item is highlighted or when the selection "goes away".
237  // In the latter case, the argument is NULL. (happens only when
238  // the menu is hidden -- FIXME?)
239  sigc::signal1<void, menu_item *> item_highlighted;
240 
241  // FIXME: there should be a less hacky way..
242  sigc::signal0<void> menus_goaway;
243 
244  static config::keybindings *bindings;
245  static void init_bindings();
246  };
247 
249  }
250 }
251 
252 #endif
A "style" is a setting to be applied to a display element (widget, text, etc).
Definition: style.h:51
Definition: menu.h:84
Stores the keys bound to various functions.
Definition: keybindings.h:87
bool is_enabled() const
The canonical way to test whether an item is really enabled.
Definition: menu.cc:90
sigc::signal0< void > selected
Emitted when the menu item is selected.
Definition: menu.h:69
Provides a simple mechanism for passing in optional slots to a function.
Definition: widget.h:89
Definition: ref_ptr.h:19
Definition: menu.h:120
The namespace containing everything defined by cwidget.
Definition: columnify.cc:26
const char * item_name
item_name and item_description are multibyte representations.
Definition: menu.h:92
The basic widget interface.
Definition: widget.h:107
Represents a keystroke as seen by curses.
Definition: keybindings.h:42
sigc::signal0< bool, util::accumulate_or > enabled
Emitted to test whether the menu item should be displayed as "active".
Definition: menu.h:77
Support for defining and remapping keybindings.
Definition: menu.h:41