X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/9cd28f4815acd26ff734e5a022ffbaae615602a7..5858fe6806cd4568c05a493087951fef65e0756e:/src/common/menucmn.cpp diff --git a/src/common/menucmn.cpp b/src/common/menucmn.cpp index 37c0c127f1..4c7abae78d 100644 --- a/src/common/menucmn.cpp +++ b/src/common/menucmn.cpp @@ -30,6 +30,7 @@ #include "wx/intl.h" #include "wx/log.h" #include "wx/menu.h" + #include "wx/frame.h" #endif #include "wx/stockitem.h" @@ -58,6 +59,39 @@ wxMenuItemBase::wxMenuItemBase(wxMenu *parentMenu, wxItemKind kind, wxMenu *subMenu) { + switch ( id ) + { + case wxID_ANY: + m_id = wxWindow::NewControlId(); + break; + + case wxID_SEPARATOR: + m_id = wxID_SEPARATOR; + + // there is a lot of existing code just doing Append(wxID_SEPARATOR) + // and it makes sense to omit the following optional parameters, + // including the kind one which doesn't default to wxITEM_SEPARATOR, + // of course, so override it here + kind = wxITEM_SEPARATOR; + break; + + case wxID_NONE: + // (popup) menu titles in wxMSW use this ID to indicate that + // it's not a real menu item, so we don't want the check below to + // apply to it + m_id = id; + break; + + default: + // ids are limited to 16 bits under MSW so portable code shouldn't + // use ids outside of this range (negative ids generated by wx are + // fine though) + wxASSERT_MSG( (id >= 0 && id < SHRT_MAX) || + (id >= wxID_AUTO_LOWEST && id <= wxID_AUTO_HIGHEST), + wxS("invalid id value") ); + m_id = id; + } + // notice that parentMenu can be NULL: the item can be attached to the menu // later with SetMenu() @@ -65,12 +99,7 @@ wxMenuItemBase::wxMenuItemBase(wxMenu *parentMenu, m_subMenu = subMenu; m_isEnabled = true; m_isChecked = false; - m_id = id; m_kind = kind; - if (m_id == wxID_ANY) - m_id = wxWindow::NewControlId(); - if (m_id == wxID_SEPARATOR) - m_kind = wxITEM_SEPARATOR; SetItemLabel(text); SetHelp(help); @@ -148,12 +177,12 @@ bool wxMenuBase::ms_locked = true; void wxMenuBase::Init(long style) { - m_menuBar = (wxMenuBar *)NULL; - m_menuParent = (wxMenu *)NULL; + m_menuBar = NULL; + m_menuParent = NULL; - m_invokingWindow = (wxWindow *)NULL; + m_invokingWindow = NULL; m_style = style; - m_clientData = (void *)NULL; + m_clientData = NULL; m_eventHandler = this; } @@ -168,7 +197,7 @@ wxMenuBase::~wxMenuBase() void wxMenuBase::AddSubMenu(wxMenu *submenu) { - wxCHECK_RET( submenu, _T("can't add a NULL submenu") ); + wxCHECK_RET( submenu, wxT("can't add a NULL submenu") ); submenu->SetParent((wxMenu *)this); } @@ -240,11 +269,11 @@ wxMenuItem *wxMenuBase::DoRemove(wxMenuItem *item) m_items.Erase(node); // item isn't attached to anything any more - item->SetMenu((wxMenu *)NULL); + item->SetMenu(NULL); wxMenu *submenu = item->GetSubMenu(); if ( submenu ) { - submenu->SetParent((wxMenu *)NULL); + submenu->SetParent(NULL); if ( submenu->IsAttached() ) submenu->Detach(); } @@ -265,7 +294,7 @@ bool wxMenuBase::DoDelete(wxMenuItem *item) wxCHECK_MSG( item2, false, wxT("failed to delete menu item") ); // don't delete the submenu - item2->SetSubMenu((wxMenu *)NULL); + item2->SetSubMenu(NULL); delete item2; @@ -356,7 +385,7 @@ wxMenuItem *wxMenuBase::FindItem(int itemId, wxMenu **itemMenu) const // non recursive search wxMenuItem *wxMenuBase::FindChildItem(int id, size_t *ppos) const { - wxMenuItem *item = (wxMenuItem *)NULL; + wxMenuItem *item = NULL; wxMenuItemList::compatibility_iterator node = GetMenuItems().GetFirst(); size_t pos; @@ -384,7 +413,7 @@ wxMenuItem *wxMenuBase::FindChildItem(int id, size_t *ppos) const wxMenuItem* wxMenuBase::FindItemByPosition(size_t position) const { wxCHECK_MSG( position < m_items.GetCount(), NULL, - _T("wxMenu::FindItemByPosition(): invalid menu index") ); + wxT("wxMenu::FindItemByPosition(): invalid menu index") ); return m_items.Item( position )->GetData(); } @@ -453,30 +482,17 @@ bool wxMenuBase::SendEvent(int id, int checked) bool processed = false; - // Try the menu's event handler - // if ( !processed ) - { - wxEvtHandler *handler = GetEventHandler(); - if ( handler ) - processed = handler->SafelyProcessEvent(event); - } + // Try the menu's event handler first + wxEvtHandler *handler = GetEventHandler(); + if ( handler ) + processed = handler->SafelyProcessEvent(event); - // Try the window the menu was popped up from (and up through the - // hierarchy) + // Try the window the menu was popped up from or its menu bar belongs to if ( !processed ) { - const wxMenuBase *menu = this; - while ( menu ) - { - wxWindow *win = menu->GetInvokingWindow(); - if ( win ) - { - processed = win->HandleWindowEvent(event); - break; - } - - menu = menu->GetParent(); - } + wxWindow * const win = GetWindow(); + if ( win ) + processed = win->HandleWindowEvent(event); } return processed; @@ -496,10 +512,10 @@ wxMenuBar* wxMenuBase::GetMenuBar() const void wxMenuBase::Attach(wxMenuBarBase *menubar) { // use Detach() instead! - wxASSERT_MSG( menubar, _T("menu can't be attached to NULL menubar") ); + wxASSERT_MSG( menubar, wxT("menu can't be attached to NULL menubar") ); // use IsAttached() to prevent this from happening - wxASSERT_MSG( !m_menuBar, _T("attaching menu twice?") ); + wxASSERT_MSG( !m_menuBar, wxT("attaching menu twice?") ); m_menuBar = (wxMenuBar *)menubar; } @@ -507,11 +523,39 @@ void wxMenuBase::Attach(wxMenuBarBase *menubar) void wxMenuBase::Detach() { // use IsAttached() to prevent this from happening - wxASSERT_MSG( m_menuBar, _T("detaching unattached menu?") ); + wxASSERT_MSG( m_menuBar, wxT("detaching unattached menu?") ); m_menuBar = NULL; } +// ---------------------------------------------------------------------------- +// wxMenu invoking window handling +// ---------------------------------------------------------------------------- + +void wxMenuBase::SetInvokingWindow(wxWindow *win) +{ + wxASSERT_MSG( !GetParent(), + "should only be called for top level popup menus" ); + wxASSERT_MSG( !IsAttached(), + "menus attached to menu bar can't have invoking window" ); + + m_invokingWindow = win; +} + +wxWindow *wxMenuBase::GetWindow() const +{ + // only the top level menus have non-NULL invoking window or a pointer to + // the menu bar so recurse upwards until we find it + const wxMenuBase *menu = this; + while ( menu->GetParent() ) + { + menu = menu->GetParent(); + } + + return menu->GetMenuBar() ? menu->GetMenuBar()->GetFrame() + : menu->GetInvokingWindow(); +} + // ---------------------------------------------------------------------------- // wxMenu functions forwarded to wxMenuItem // ---------------------------------------------------------------------------- @@ -616,9 +660,10 @@ wxMenu *wxMenuBarBase::GetMenu(size_t pos) const return node->GetData(); } -bool wxMenuBarBase::Append(wxMenu *menu, const wxString& WXUNUSED(title)) +bool wxMenuBarBase::Append(wxMenu *menu, const wxString& title) { wxCHECK_MSG( menu, false, wxT("can't append NULL menu") ); + wxCHECK_MSG( !title.empty(), false, wxT("can't append menu with empty title") ); m_menus.Append(menu); menu->Attach(this);