1 /////////////////////////////////////////////////////////////////////////////// 2 // Name: wx/menu.h 3 // Purpose: wxMenu and wxMenuBar classes 4 // Author: Vadim Zeitlin 5 // Modified by: 6 // Created: 26.10.99 7 // RCS-ID: $Id: menu.h,v 1.1 2006/12/02 15:58:25 scara Exp $ 8 // Copyright: (c) wxWindows team 9 // Licence: wxWindows license 10 /////////////////////////////////////////////////////////////////////////////// 11 12 #ifndef _WX_MENU_H_BASE_ 13 #define _WX_MENU_H_BASE_ 14 15 #if defined(__GNUG__) && !defined(__APPLE__) 16 #pragma interface "menubase.h" 17 #endif 18 19 #if wxUSE_MENUS 20 21 // ---------------------------------------------------------------------------- 22 // headers 23 // ---------------------------------------------------------------------------- 24 25 #include "wx/list.h" // for "template" list classes 26 #include "wx/window.h" // base class for wxMenuBar 27 28 // also include this one to ensure compatibility with old code which only 29 // included wx/menu.h 30 #include "wx/menuitem.h" 31 32 class WXDLLEXPORT wxMenu; 33 class WXDLLEXPORT wxMenuBarBase; 34 class WXDLLEXPORT wxMenuBar; 35 class WXDLLEXPORT wxMenuItem; 36 37 // pseudo template list classes 38 WX_DECLARE_EXPORTED_LIST(wxMenu, wxMenuList); 39 WX_DECLARE_EXPORTED_LIST(wxMenuItem, wxMenuItemList); 40 41 // ---------------------------------------------------------------------------- 42 // conditional compilation 43 // ---------------------------------------------------------------------------- 44 45 // having callbacks in menus is a wxWin 1.6x feature which should be replaced 46 // with event tables in wxWin 2.xx code - however provide it because many 47 // people like it a lot by default 48 #ifndef wxUSE_MENU_CALLBACK 49 #if WXWIN_COMPATIBILITY_2 50 #define wxUSE_MENU_CALLBACK 1 51 #else 52 #define wxUSE_MENU_CALLBACK 0 53 #endif // WXWIN_COMPATIBILITY_2 54 #endif // !defined(wxUSE_MENU_CALLBACK) 55 56 // ---------------------------------------------------------------------------- 57 // wxMenu 58 // ---------------------------------------------------------------------------- 59 60 class WXDLLEXPORT wxMenuBase : public wxEvtHandler 61 { 62 public: 63 // create a menu 64 static wxMenu *New(const wxString& title = wxEmptyString, long style = 0); 65 66 // ctors m_title(title)67 wxMenuBase(const wxString& title, long style = 0) : m_title(title) 68 { Init(style); } 69 wxMenuBase(long style = 0) 70 { Init(style); } 71 72 // dtor deletes all the menu items we own 73 virtual ~wxMenuBase(); 74 75 // menu construction 76 // ----------------- 77 78 // append any kind of item (normal/check/radio/separator) 79 void Append(int id, 80 const wxString& text, 81 const wxString& help = wxEmptyString, 82 wxItemKind kind = wxITEM_NORMAL) 83 { 84 DoAppend(wxMenuItem::New((wxMenu *)this, id, text, help, kind)); 85 } 86 87 // append a separator to the menu AppendSeparator()88 void AppendSeparator() { Append(wxID_SEPARATOR, wxEmptyString); } 89 90 // append a check item 91 void AppendCheckItem(int id, 92 const wxString& text, 93 const wxString& help = wxEmptyString) 94 { 95 Append(id, text, help, wxITEM_CHECK); 96 } 97 98 // append a radio item 99 void AppendRadioItem(int id, 100 const wxString& text, 101 const wxString& help = wxEmptyString) 102 { 103 Append(id, text, help, wxITEM_RADIO); 104 } 105 106 // append a submenu 107 void Append(int id, 108 const wxString& text, 109 wxMenu *submenu, 110 const wxString& help = wxEmptyString) 111 { 112 DoAppend(wxMenuItem::New((wxMenu *)this, id, text, help, 113 wxITEM_NORMAL, submenu)); 114 } 115 116 // the most generic form of Append() - append anything Append(wxMenuItem * item)117 void Append(wxMenuItem *item) { DoAppend(item); } 118 119 // insert a break in the menu (only works when appending the items, not 120 // inserting them) Break()121 virtual void Break() { } 122 123 // insert an item before given position 124 bool Insert(size_t pos, wxMenuItem *item); 125 126 // insert an item before given position 127 void Insert(size_t pos, 128 int id, 129 const wxString& text, 130 const wxString& help = wxEmptyString, 131 wxItemKind kind = wxITEM_NORMAL) 132 { 133 Insert(pos, wxMenuItem::New((wxMenu *)this, id, text, help, kind)); 134 } 135 136 // insert a separator InsertSeparator(size_t pos)137 void InsertSeparator(size_t pos) 138 { 139 Insert(pos, wxMenuItem::New((wxMenu *)this)); 140 } 141 142 // insert a check item 143 void InsertCheckItem(size_t pos, 144 int id, 145 const wxString& text, 146 const wxString& help = wxEmptyString) 147 { 148 Insert(pos, id, text, help, wxITEM_CHECK); 149 } 150 151 // insert a radio item 152 void InsertRadioItem(size_t pos, 153 int id, 154 const wxString& text, 155 const wxString& help = wxEmptyString) 156 { 157 Insert(pos, id, text, help, wxITEM_RADIO); 158 } 159 160 // insert a submenu 161 void Insert(size_t pos, 162 int id, 163 const wxString& text, 164 wxMenu *submenu, 165 const wxString& help = wxEmptyString) 166 { 167 Insert(pos, wxMenuItem::New((wxMenu *)this, id, text, help, 168 wxITEM_NORMAL, submenu)); 169 } 170 171 // prepend an item to the menu Prepend(wxMenuItem * item)172 void Prepend(wxMenuItem *item) 173 { 174 Insert(0u, item); 175 } 176 177 // prepend any item to the menu 178 void Prepend(int id, 179 const wxString& text, 180 const wxString& help = wxEmptyString, 181 wxItemKind kind = wxITEM_NORMAL) 182 { 183 Insert(0u, id, text, help, kind); 184 } 185 186 // prepend a separator PrependSeparator()187 void PrependSeparator() 188 { 189 InsertSeparator(0u); 190 } 191 192 // prepend a check item 193 void PrependCheckItem(int id, 194 const wxString& text, 195 const wxString& help = wxEmptyString) 196 { 197 InsertCheckItem(0u, id, text, help); 198 } 199 200 // prepend a radio item 201 void PrependRadioItem(int id, 202 const wxString& text, 203 const wxString& help = wxEmptyString) 204 { 205 InsertRadioItem(0u, id, text, help); 206 } 207 208 // prepend a submenu 209 void Prepend(int id, 210 const wxString& text, 211 wxMenu *submenu, 212 const wxString& help = wxEmptyString) 213 { 214 Insert(0u, id, text, submenu, help); 215 } 216 217 // detach an item from the menu, but don't delete it so that it can be 218 // added back later (but if it's not, the caller is responsible for 219 // deleting it!) Remove(int id)220 wxMenuItem *Remove(int id) { return Remove(FindChildItem(id)); } 221 wxMenuItem *Remove(wxMenuItem *item); 222 223 // delete an item from the menu (submenus are not destroyed by this 224 // function, see Destroy) Delete(int id)225 bool Delete(int id) { return Delete(FindChildItem(id)); } 226 bool Delete(wxMenuItem *item); 227 228 // delete the item from menu and destroy it (if it's a submenu) Destroy(int id)229 bool Destroy(int id) { return Destroy(FindChildItem(id)); } 230 bool Destroy(wxMenuItem *item); 231 232 // menu items access 233 // ----------------- 234 235 // get the items GetMenuItemCount()236 size_t GetMenuItemCount() const { return m_items.GetCount(); } 237 GetMenuItems()238 const wxMenuItemList& GetMenuItems() const { return m_items; } GetMenuItems()239 wxMenuItemList& GetMenuItems() { return m_items; } 240 241 // search 242 virtual int FindItem(const wxString& item) const; 243 wxMenuItem* FindItem(int id, wxMenu **menu = NULL) const; 244 245 // get/set items attributes 246 void Enable(int id, bool enable); 247 bool IsEnabled(int id) const; 248 249 void Check(int id, bool check); 250 bool IsChecked(int id) const; 251 252 void SetLabel(int id, const wxString& label); 253 wxString GetLabel(int id) const; 254 255 virtual void SetHelpString(int id, const wxString& helpString); 256 virtual wxString GetHelpString(int id) const; 257 258 // misc accessors 259 // -------------- 260 261 // the title SetTitle(const wxString & title)262 virtual void SetTitle(const wxString& title) { m_title = title; } GetTitle()263 const wxString GetTitle() const { return m_title; } 264 265 // event handler SetEventHandler(wxEvtHandler * handler)266 void SetEventHandler(wxEvtHandler *handler) { m_eventHandler = handler; } GetEventHandler()267 wxEvtHandler *GetEventHandler() const { return m_eventHandler; } 268 269 // invoking window SetInvokingWindow(wxWindow * win)270 void SetInvokingWindow(wxWindow *win) { m_invokingWindow = win; } GetInvokingWindow()271 wxWindow *GetInvokingWindow() const { return m_invokingWindow; } 272 273 // style GetStyle()274 long GetStyle() const { return m_style; } 275 276 // implementation helpers 277 // ---------------------- 278 279 // Updates the UI for a menu and all submenus recursively. source is the 280 // object that has the update event handlers defined for it. If NULL, the 281 // menu or associated window will be used. 282 void UpdateUI(wxEvtHandler* source = (wxEvtHandler*)NULL); 283 284 // get the menu bar this menu is attached to (may be NULL, always NULL for 285 // popup menus) GetMenuBar()286 wxMenuBar *GetMenuBar() const { return m_menuBar; } 287 288 // called when the menu is attached/detached to/from a menu bar 289 virtual void Attach(wxMenuBarBase *menubar); 290 virtual void Detach(); 291 292 // is the menu attached to a menu bar (or is it a popup one)? IsAttached()293 bool IsAttached() const { return m_menuBar != NULL; } 294 295 // set/get the parent of this menu SetParent(wxMenu * parent)296 void SetParent(wxMenu *parent) { m_menuParent = parent; } GetParent()297 wxMenu *GetParent() const { return m_menuParent; } 298 299 // implementation only from now on 300 // ------------------------------- 301 302 // unlike FindItem(), this function doesn't recurse but only looks through 303 // our direct children and also may return the index of the found child if 304 // pos != NULL 305 wxMenuItem *FindChildItem(int id, size_t *pos = NULL) const; 306 307 // called to generate a wxCommandEvent, return TRUE if it was processed, 308 // FALSE otherwise 309 // 310 // the checked parameter may have boolean value or -1 for uncheckable items 311 bool SendEvent(int id, int checked = -1); 312 313 // compatibility: these functions are deprecated, use the new ones instead 314 // ----------------------------------------------------------------------- 315 316 // use the versions taking wxItem_XXX now instead, they're more readable 317 // and allow adding the radio items as well Append(int id,const wxString & text,const wxString & help,bool isCheckable)318 void Append(int id, 319 const wxString& text, 320 const wxString& help, 321 bool isCheckable) 322 { 323 Append(id, text, help, isCheckable ? wxITEM_CHECK : wxITEM_NORMAL); 324 } 325 Insert(size_t pos,int id,const wxString & text,const wxString & help,bool isCheckable)326 void Insert(size_t pos, 327 int id, 328 const wxString& text, 329 const wxString& help, 330 bool isCheckable) 331 { 332 Insert(pos, id, text, help, isCheckable ? wxITEM_CHECK : wxITEM_NORMAL); 333 } 334 Prepend(int id,const wxString & text,const wxString & help,bool isCheckable)335 void Prepend(int id, 336 const wxString& text, 337 const wxString& help, 338 bool isCheckable) 339 { 340 Insert(0u, id, text, help, isCheckable); 341 } 342 343 #if WXWIN_COMPATIBILITY Enabled(int id)344 bool Enabled(int id) const { return IsEnabled(id); } Checked(int id)345 bool Checked(int id) const { return IsChecked(id); } 346 FindItemForId(int itemId,wxMenu ** itemMenu)347 wxMenuItem* FindItemForId(int itemId, wxMenu **itemMenu) const 348 { return FindItem(itemId, itemMenu); } 349 GetItems()350 wxList& GetItems() const { return (wxList &)m_items; } 351 #endif // WXWIN_COMPATIBILITY 352 353 #if wxUSE_MENU_CALLBACK || defined(__WXMOTIF__) 354 // wxWin 1.6x compatible menu event handling GetCallback()355 wxFunction GetCallback() const { return m_callback; } Callback(const wxFunction func)356 void Callback(const wxFunction func) { m_callback = func; } 357 358 wxFunction m_callback; 359 #endif // wxUSE_MENU_CALLBACK 360 361 protected: 362 // virtuals to override in derived classes 363 // --------------------------------------- 364 365 virtual bool DoAppend(wxMenuItem *item); 366 virtual bool DoInsert(size_t pos, wxMenuItem *item); 367 368 virtual wxMenuItem *DoRemove(wxMenuItem *item); 369 virtual bool DoDelete(wxMenuItem *item); 370 virtual bool DoDestroy(wxMenuItem *item); 371 372 // helpers 373 // ------- 374 375 // common part of all ctors 376 void Init(long style); 377 378 // associate the submenu with this menu 379 void AddSubMenu(wxMenu *submenu); 380 381 wxMenuBar *m_menuBar; // menubar we belong to or NULL 382 wxMenu *m_menuParent; // parent menu or NULL 383 384 wxString m_title; // the menu title or label 385 wxMenuItemList m_items; // the list of menu items 386 387 wxWindow *m_invokingWindow; // for popup menus 388 389 long m_style; // combination of wxMENU_XXX flags 390 391 wxEvtHandler *m_eventHandler; // a pluggable in event handler 392 }; 393 394 // ---------------------------------------------------------------------------- 395 // wxMenuBar 396 // ---------------------------------------------------------------------------- 397 398 class WXDLLEXPORT wxMenuBarBase : public wxWindow 399 { 400 public: 401 // default ctor 402 wxMenuBarBase(); 403 404 // dtor will delete all menus we own 405 virtual ~wxMenuBarBase(); 406 407 // menu bar construction 408 // --------------------- 409 410 // append a menu to the end of menubar, return TRUE if ok 411 virtual bool Append(wxMenu *menu, const wxString& title); 412 413 // insert a menu before the given position into the menubar, return TRUE 414 // if inserted ok 415 virtual bool Insert(size_t pos, wxMenu *menu, const wxString& title); 416 417 // menu bar items access 418 // --------------------- 419 420 // get the number of menus in the menu bar GetMenuCount()421 size_t GetMenuCount() const { return m_menus.GetCount(); } 422 423 // get the menu at given position 424 wxMenu *GetMenu(size_t pos) const; 425 426 // replace the menu at given position with another one, returns the 427 // previous menu (which should be deleted by the caller) 428 virtual wxMenu *Replace(size_t pos, wxMenu *menu, const wxString& title); 429 430 // delete the menu at given position from the menu bar, return the pointer 431 // to the menu (which should be deleted by the caller) 432 virtual wxMenu *Remove(size_t pos); 433 434 // enable or disable a submenu 435 virtual void EnableTop(size_t pos, bool enable) = 0; 436 437 // is the menu enabled? IsEnabledTop(size_t WXUNUSED (pos))438 virtual bool IsEnabledTop(size_t WXUNUSED(pos)) const { return TRUE; } 439 440 // get or change the label of the menu at given position 441 virtual void SetLabelTop(size_t pos, const wxString& label) = 0; 442 virtual wxString GetLabelTop(size_t pos) const = 0; 443 444 // item search 445 // ----------- 446 447 // by menu and item names, returns wxNOT_FOUND if not found or id of the 448 // found item 449 virtual int FindMenuItem(const wxString& menu, const wxString& item) const; 450 451 // find item by id (in any menu), returns NULL if not found 452 // 453 // if menu is !NULL, it will be filled with wxMenu this item belongs to 454 virtual wxMenuItem* FindItem(int id, wxMenu **menu = NULL) const; 455 456 // find menu by its caption, return wxNOT_FOUND on failure 457 int FindMenu(const wxString& title) const; 458 459 // item access 460 // ----------- 461 462 // all these functions just use FindItem() and then call an appropriate 463 // method on it 464 // 465 // NB: under MSW, these methods can only be used after the menubar had 466 // been attached to the frame 467 468 void Enable(int id, bool enable); 469 void Check(int id, bool check); 470 bool IsChecked(int id) const; 471 bool IsEnabled(int id) const; 472 473 void SetLabel(int id, const wxString &label); 474 wxString GetLabel(int id) const; 475 476 void SetHelpString(int id, const wxString& helpString); 477 wxString GetHelpString(int id) const; 478 479 // implementation helpers 480 481 // get the frame we are attached to (may return NULL) GetFrame()482 wxFrame *GetFrame() const { return m_menuBarFrame; } 483 484 // returns TRUE if we're attached to a frame IsAttached()485 bool IsAttached() const { return GetFrame() != NULL; } 486 487 // associate the menubar with the frame 488 virtual void Attach(wxFrame *frame); 489 490 // called before deleting the menubar normally 491 virtual void Detach(); 492 493 // need to override these ones to avoid virtual function hiding 494 virtual bool Enable(bool enable = TRUE) { return wxWindow::Enable(enable); } SetLabel(const wxString & s)495 virtual void SetLabel(const wxString& s) { wxWindow::SetLabel(s); } GetLabel()496 virtual wxString GetLabel() const { return wxWindow::GetLabel(); } 497 498 // don't want menu bars to accept the focus by tabbing to them AcceptsFocusFromKeyboard()499 virtual bool AcceptsFocusFromKeyboard() const { return FALSE; } 500 501 // compatibility only: these functions are deprecated, use the new ones 502 // instead 503 #if WXWIN_COMPATIBILITY Enabled(int id)504 bool Enabled(int id) const { return IsEnabled(id); } Checked(int id)505 bool Checked(int id) const { return IsChecked(id); } 506 FindMenuItemById(int id)507 wxMenuItem* FindMenuItemById(int id) const 508 { return FindItem(id); } 509 wxMenuItem* FindItemForId(int id, wxMenu **menu = NULL) const 510 { return FindItem(id, menu); } 511 #endif // WXWIN_COMPATIBILITY 512 513 protected: 514 // the list of all our menus 515 wxMenuList m_menus; 516 517 // the frame we are attached to (may be NULL) 518 wxFrame *m_menuBarFrame; 519 }; 520 521 // ---------------------------------------------------------------------------- 522 // include the real class declaration 523 // ---------------------------------------------------------------------------- 524 525 #ifdef wxUSE_BASE_CLASSES_ONLY 526 #define wxMenuItem wxMenuItemBase 527 #else // !wxUSE_BASE_CLASSES_ONLY 528 #if defined(__WXUNIVERSAL__) 529 #include "wx/univ/menu.h" 530 #elif defined(__WXMSW__) 531 #include "wx/msw/menu.h" 532 #elif defined(__WXMOTIF__) 533 #include "wx/motif/menu.h" 534 #elif defined(__WXGTK__) 535 #include "wx/gtk/menu.h" 536 #elif defined(__WXMAC__) 537 #include "wx/mac/menu.h" 538 #elif defined(__WXPM__) 539 #include "wx/os2/menu.h" 540 #elif defined(__WXSTUBS__) 541 #include "wx/stubs/menu.h" 542 #endif 543 #endif // wxUSE_BASE_CLASSES_ONLY/!wxUSE_BASE_CLASSES_ONLY 544 545 #endif // wxUSE_MENUS 546 547 #endif 548 // _WX_MENU_H_BASE_ 549