menu.h
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef MENU_H
00023 #define MENU_H
00024
00025 #include "widget.h"
00026
00027 #include <cwidget/config/keybindings.h>
00028
00029 #include <cwidget/generic/util/bool_accumulate.h>
00030 #include <cwidget/generic/util/slotarg.h>
00031
00032 #include <vector>
00033
00034 namespace cwidget
00035 {
00036 namespace widgets
00037 {
00038
00039
00040
00041 class menu_item
00042 {
00043
00044 std::wstring title;
00045
00046
00047 std::wstring description;
00048
00049
00050
00051 std::string binding;
00052
00053
00054 chtype hotkey;
00055 public:
00056
00057 menu_item(const std::wstring &_title, const std::string &_binding,
00058 const std::wstring &_description);
00059
00060 std::wstring get_title() const {return title;}
00061 std::string get_binding() const {return binding;}
00062 std::wstring get_description() const {return description;}
00063 chtype get_hotkey() const {return hotkey;}
00064
00066 bool is_enabled() const;
00067
00069 sigc::signal0<void> selected;
00070
00077 sigc::signal0<bool, util::accumulate_or> enabled;
00078 };
00079
00080 #define MENU_NOP NULL
00081
00082
00083
00084 struct menu_info
00085 {
00086 public:
00087
00088
00089 enum item_types {MENU_ITEM, MENU_SEPARATOR, MENU_END} item_type;
00090
00092 const char *item_name, *item_binding, *item_description;
00093
00094
00095 util::slot0arg item_slot;
00096
00097
00098 util::slotarg<sigc::slot0<bool> > item_enabled;
00099
00100 menu_info(item_types type, const char *name, const char *binding,
00101 const char *description, sigc::slot0<void> slot);
00102
00103 menu_info(item_types type, const char *name, const char *binding,
00104 const char *description, sigc::slot0<void> *slot);
00105
00106 menu_info(item_types type, const char *name, const char *binding,
00107 const char *description, sigc::slot0<void> slot,
00108 sigc::slot0<bool> enabled);
00109
00110 menu_info(item_types type, const char *name, const char *binding,
00111 const char *description, sigc::slot0<void> *slot,
00112 sigc::slot0<bool> enabled);
00113
00114 menu_info(item_types type);
00115 };
00116
00117 const menu_info MENU_SEPARATOR(menu_info::MENU_SEPARATOR);
00118 const menu_info MENU_END(menu_info::MENU_END);
00119
00120 class menu : public widget
00121 {
00122 typedef std::vector<menu_item *> itemlist;
00123
00124
00125
00126 itemlist items;
00127
00129 itemlist::size_type cursorloc;
00130
00132 itemlist::size_type startloc;
00133
00135 int min_width;
00136
00137
00138 void appear();
00139
00140
00141 void disappear();
00142
00146 void update_startloc();
00147
00149 bool selectable(itemlist::size_type pos);
00150
00152 void set_cursor(itemlist::size_type pos);
00153
00157 void highlight_current();
00158
00165 itemlist::size_type next_selectable(itemlist::size_type pos);
00166
00174 itemlist::size_type prev_selectable(itemlist::size_type pos);
00175
00182 void sanitize_cursor(bool forward);
00183
00184 protected:
00185 virtual bool handle_key(const config::key &k);
00186
00188 menu();
00189
00190
00191
00192 menu(int x, int y, int w, menu_info *inf);
00193 public:
00194 static util::ref_ptr<menu> create()
00195 {
00196 util::ref_ptr<menu> rval(new menu);
00197 rval->decref();
00198 return rval;
00199 }
00200
00201 static util::ref_ptr<menu> create(int x, int y, int w, menu_info *inf)
00202 {
00203 util::ref_ptr<menu> rval(new menu(x, y, w, inf));
00204 rval->decref();
00205 return rval;
00206 }
00207
00208
00209 ~menu();
00210
00211 bool get_cursorvisible();
00212 point get_cursorloc();
00213
00214 int width_request();
00215 int height_request(int width);
00216
00217 void append_item(menu_item *newitem);
00218 void remove_item(menu_item *item);
00219
00221 void move_selection_up();
00222
00224 void move_selection_down();
00225
00227 void move_selection_top();
00228
00230 void move_selection_bottom();
00231
00232 virtual bool focus_me();
00233 virtual void paint(const style &st);
00234 virtual void dispatch_mouse(short id, int x, int y, int z, mmask_t bstate);
00235
00236
00237
00238
00239 sigc::signal1<void, menu_item *> item_highlighted;
00240
00241
00242 sigc::signal0<void> menus_goaway;
00243
00244 static config::keybindings *bindings;
00245 static void init_bindings();
00246 };
00247
00248 typedef util::ref_ptr<menu> menu_ref;
00249 }
00250 }
00251
00252 #endif