1 // -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*- 2 // Menu.hh for Blackbox - an X11 Window manager 3 // Copyright (c) 2001 - 2005 Sean 'Shaleh' Perry <shaleh@debian.org> 4 // Copyright (c) 1997 - 2000, 2002 - 2005 5 // Bradley T Hughes <bhughes at trolltech.com> 6 // 7 // Permission is hereby granted, free of charge, to any person obtaining a 8 // copy of this software and associated documentation files (the "Software"), 9 // to deal in the Software without restriction, including without limitation 10 // the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 // and/or sell copies of the Software, and to permit persons to whom the 12 // Software is furnished to do so, subject to the following conditions: 13 // 14 // The above copyright notice and this permission notice shall be included in 15 // all copies or substantial portions of the Software. 16 // 17 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 // DEALINGS IN THE SOFTWARE. 24 25 #ifndef __Menu_hh 26 #define __Menu_hh 27 28 #include "Color.hh" 29 #include "EventHandler.hh" 30 #include "Font.hh" 31 #include "Rect.hh" 32 #include "Texture.hh" 33 #include "Timer.hh" 34 #include "Util.hh" 35 36 #include <list> 37 #include <vector> 38 39 namespace bt { 40 41 class Application; 42 class Menu; 43 44 class MenuItem 45 { 46 public: 47 enum Type { Normal, Separator }; MenuItem(Type t,const ustring & l=ustring ())48 inline MenuItem(Type t, const ustring &l = ustring()) 49 : sub(0), lbl(l), ident(~0u), indx(~0u), height(0), 50 separator(t == Separator), 51 active(0), title(0), enabled(1), checked(0) 52 { } MenuItem(Menu * s,const ustring & l)53 inline MenuItem(Menu *s, const ustring &l) 54 : sub(s), lbl(l), ident(~0u), indx(~0u), height(0), separator(0), 55 active(0), title(0), enabled(1), checked(0) 56 { } 57 isSeparator(void) const58 inline bool isSeparator(void) const 59 { return bool(separator); } isActive(void) const60 inline bool isActive(void) const 61 { return bool(active); } isTitle(void) const62 inline bool isTitle(void) const 63 { return bool(title); } isEnabled(void) const64 inline bool isEnabled(void) const 65 { return bool(enabled); } isChecked(void) const66 inline bool isChecked(void) const 67 { return bool(checked); } 68 id(void) const69 inline unsigned int id(void) const 70 { return ident; } index(void) const71 inline unsigned int index(void) const 72 { return indx; } 73 submenu(void) const74 inline Menu *submenu(void) const 75 { return sub; } 76 label(void) const77 inline const ustring &label(void) const 78 { return lbl; } 79 80 private: 81 Menu *sub; 82 ustring lbl; 83 unsigned int ident; 84 unsigned int indx; 85 unsigned int height; 86 unsigned int separator : 1; 87 unsigned int active : 1; 88 unsigned int title : 1; 89 unsigned int enabled : 1; 90 unsigned int checked : 1; 91 92 friend class Menu; 93 }; 94 95 96 class Resource; 97 98 class MenuStyle : public NoCopy 99 { 100 public: 101 static MenuStyle *get(Application &app, unsigned int screen); 102 103 void load(const Resource &resource); 104 105 // fixed metrics 106 unsigned int separatorHeight(void) const; 107 unsigned int titleMargin(void) const; 108 unsigned int frameMargin(void) const; 109 unsigned int itemMargin(void) const; 110 111 // textures titleTexture(void) const112 inline const Texture &titleTexture(void) const 113 { return title.texture; } frameTexture(void) const114 inline const Texture &frameTexture(void) const 115 { return frame.texture; } activeTexture(void) const116 inline const Texture &activeTexture(void) const 117 { return active.texture; } 118 119 // colors titleForegroundColor(void) const120 inline const bt::Color &titleForegroundColor(void) const 121 { return title.foreground; } titleTextColor(void) const122 inline const bt::Color &titleTextColor(void) const 123 { return title.text; } frameForegroundColor(void) const124 inline const bt::Color &frameForegroundColor(void) const 125 { return frame.foreground; } frameTextColor(void) const126 inline const bt::Color &frameTextColor(void) const 127 { return frame.text; } 128 129 // fonts titleFont(void) const130 inline const Font &titleFont(void) const 131 { return title.font; } frameFont(void) const132 inline const Font &frameFont(void) const 133 { return frame.font; } 134 135 // size calculations 136 Rect titleRect(const ustring &text) const; 137 Rect itemRect(const MenuItem &item) const; 138 139 // drawing 140 void drawTitle(Window window, const Rect &rect, 141 const ustring &text) const; 142 void drawItem(Window window, const Rect &rect, 143 const MenuItem &item, Pixmap activePixmap) const; 144 145 private: 146 MenuStyle(Application &app, unsigned int screen); 147 148 Application &_app; 149 unsigned int _screen; 150 struct _title { 151 Texture texture; 152 Color foreground; 153 Color text; 154 Font font; 155 Alignment alignment; 156 } title; 157 struct _frame { 158 Texture texture; 159 Color foreground; 160 Color text; 161 Color disabled; 162 Font font; 163 Alignment alignment; 164 } frame; 165 struct _active { 166 Texture texture; 167 Color foreground; 168 Color text; 169 // font and alignment used from frame above 170 } active; 171 unsigned int title_margin, frame_margin, item_indent; 172 173 static MenuStyle **styles; 174 }; 175 176 177 class Menu : public EventHandler, public NoCopy 178 { 179 public: 180 Menu(Application &app, unsigned int screen); 181 virtual ~Menu(void); 182 windowID(void) const183 inline Window windowID(void) const 184 { return _window; } 185 186 unsigned int insertItem(const MenuItem &item, 187 unsigned int id = ~0u, 188 unsigned int index = ~0u); 189 insertItem(const ustring & label,unsigned int id=~0u,unsigned int index=~0u)190 inline unsigned int insertItem(const ustring &label, 191 unsigned int id = ~0u, 192 unsigned int index = ~0u) 193 { return insertItem(MenuItem(MenuItem::Normal, label), id, index); } 194 insertItem(const ustring & label,Menu * submenu,unsigned int id=~0u,unsigned int index=~0u)195 inline unsigned int insertItem(const ustring &label, 196 Menu *submenu, 197 unsigned int id = ~0u, 198 unsigned int index = ~0u) 199 { return insertItem(MenuItem(submenu, label), id, index); } 200 insertSeparator(unsigned int index=~0u)201 inline void insertSeparator(unsigned int index = ~0u) 202 { (void) insertItem(MenuItem(MenuItem::Separator), ~0u, index); } 203 204 205 void changeItem(unsigned int id, 206 const ustring &newlabel, 207 unsigned int newid = ~0u); 208 209 void setItemEnabled(unsigned int id, bool enabled); 210 bool isItemEnabled(unsigned int id) const; 211 212 void setItemChecked(unsigned int id, bool checked); 213 bool isItemChecked(unsigned int id) const; 214 215 void removeItem(unsigned int id); 216 void removeIndex(unsigned int index); 217 void clear(void); 218 count(void) const219 inline unsigned int count(void) const 220 { return _items.size(); } 221 title(void) const222 inline const ustring &title(void) const 223 { return _title; } setTitle(const ustring & newtitle)224 inline void setTitle(const ustring &newtitle) 225 { _title = newtitle; } 226 void showTitle(void); 227 void hideTitle(void); 228 isVisible(void) const229 inline bool isVisible(void) const 230 { return _visible; } 231 232 void popup(int x, int y, 233 bool centered = true); 234 virtual void popup(int x, int y, 235 const Rect &constraint, 236 bool centered = true); 237 void move(int x, int y); 238 virtual void show(void); 239 virtual void hide(void); 240 241 virtual void refresh(void); 242 virtual void reconfigure(void); 243 autoDelete(void) const244 inline bool autoDelete(void) const 245 { return _auto_delete; } setAutoDelete(bool ad)246 inline void setAutoDelete(bool ad) 247 { _auto_delete = ad; } 248 249 protected: 250 virtual void buttonPressEvent(const XButtonEvent * const event); 251 virtual void buttonReleaseEvent(const XButtonEvent * const event); 252 virtual void motionNotifyEvent(const XMotionEvent * const event); 253 virtual void leaveNotifyEvent(const XCrossingEvent * const /*unused*/); 254 virtual void exposeEvent(const XExposeEvent * const event); 255 virtual void keyPressEvent(const XKeyEvent * const event); 256 257 virtual void titleClicked(unsigned int button); 258 virtual void itemClicked(unsigned int id, unsigned int button); 259 260 virtual void hideAll(void); 261 262 virtual void tearOff(void); 263 264 Rect geometry(void) const; 265 266 private: 267 void updateSize(void); 268 void updatePixmaps(void); 269 270 typedef std::list<MenuItem> ItemList; 271 272 unsigned int verifyId(unsigned int id = ~0u); 273 void activateItem(const Rect &rect, MenuItem &item); 274 void deactivateItem(const Rect &rect, MenuItem &item, 275 bool hide_submenu = true); 276 void activateIndex(unsigned int index); 277 void showActiveSubmenu(void); 278 279 ItemList::iterator findItem(unsigned int id, Rect& r); 280 281 void activateSubmenu(void); 282 void positionRect(Rect& r, int &row, int &col); 283 void invalidateSize(void); 284 285 void removeItemByIterator(ItemList::iterator& it); 286 287 Application &_app; 288 unsigned int _screen; 289 290 Window _window; 291 Pixmap _tpixmap, _fpixmap, _apixmap; 292 293 Rect _rect; // entire menu 294 Rect _trect; // title 295 Rect _frect; // frame 296 Rect _irect; // items inside the frame 297 298 Timer _timer; 299 ustring _title; 300 301 ItemList _items; 302 std::vector<bool> _id_bits; 303 304 Menu *_parent_menu; 305 Menu *_current_submenu; 306 Menu *_active_submenu; 307 unsigned int _motion; 308 unsigned int _itemw; 309 unsigned int _active_index; 310 bool _auto_delete; 311 bool _pressed; 312 bool _title_pressed; 313 bool _size_dirty; 314 bool _show_title; 315 bool _visible; 316 bool _tornoff; 317 }; 318 319 } // namespace bt 320 321 #endif // __Menu_hh 322