void SetEventHandler(wxEvtHandler *handler) { m_eventHandler = handler; }
wxEvtHandler *GetEventHandler() const { return m_eventHandler; }
- // invoking window
- void SetInvokingWindow(wxWindow *win) { m_invokingWindow = win; }
- wxWindow *GetInvokingWindow() const { return m_invokingWindow; }
+ // Invoking window: this is set by wxWindow::PopupMenu() before showing a
+ // popup menu and reset after it's hidden. Notice that GetInvokingWindow()
+ // recurses upwards and will return the invoking window for any submenu of
+ // a popup menu as well as the menu itself.
+ void SetInvokingWindow(wxWindow *win);
+ wxWindow *GetInvokingWindow() const;
// style
long GetStyle() const { return m_style; }
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::GetInvokingWindow() const
+{
+ // only the popup menu itself has a non-NULL invoking window so recurse
+ // upwards until we find it
+ const wxMenuBase *menu = this;
+ while ( menu->GetParent() )
+ {
+ menu = menu->GetParent();
+ }
+
+ // menu is a top level menu here
+ return menu->m_invokingWindow;
+}
+
// ----------------------------------------------------------------------------
// wxMenu functions forwarded to wxMenuItem
// ----------------------------------------------------------------------------
wxWindow *wxMenu::GetWindow() const
{
- if ( m_invokingWindow != NULL )
- return m_invokingWindow;
- else if ( GetMenuBar() != NULL)
- return GetMenuBar()->GetFrame();
-
- return NULL;
+ return GetMenuBar() ? GetMenuBar()->GetFrame() : GetInvokingWindow();
}
// ---------------------------------------------------------------------------
#if wxUSE_ACCEL
AddAccelFor(item);
#endif // wxUSE_ACCEL
-
- // the submenus of a popup menu should have the same invoking window as it
- // has
- if ( m_invokingWindow && item->IsSubMenu() )
- {
- item->GetSubMenu()->SetInvokingWindow(m_invokingWindow);
- }
}
void wxMenu::EndRadioGroup()
wxWindow *wxMenu::GetRootWindow() const
{
- if ( GetMenuBar() )
- {
- // simple case - a normal menu attached to the menubar
- return GetMenuBar();
- }
-
- // we're a popup menu but the trouble is that only the top level popup menu
- // has a pointer to the invoking window, so we must walk up the menu chain
- // if needed
- wxWindow *win = GetInvokingWindow();
- if ( win )
- {
- // we already have it
- return win;
- }
-
- wxMenu *menu = GetParent();
- while ( menu )
- {
- // We are a submenu of a menu of a menubar
- if (menu->GetMenuBar())
- return menu->GetMenuBar();
-
- win = menu->GetInvokingWindow();
- if ( win )
- break;
-
- menu = menu->GetParent();
- }
-
- // we're probably going to crash in the caller anyhow, but try to detect
- // this error as soon as possible
- wxASSERT_MSG( win, wxT("menu without any associated window?") );
-
- // also remember it in this menu so that we don't have to search for it the
- // next time
- wxConstCast(this, wxMenu)->m_invokingWindow = win;
-
- return win;
+ return GetMenuBar() ? GetMenuBar() : GetInvokingWindow();
}
wxRenderer *wxMenu::GetRenderer() const
}
else // popup menu
{
- wxCHECK_RET( m_invokingWindow, wxT("what kind of menu is this?") );
+ wxWindow * const win = GetInvokingWindow();
+ wxCHECK_RET( win, wxT("what kind of menu is this?") );
- m_invokingWindow->DismissPopupMenu();
-
- // Why reset it here? We need it for sending the event to...
- // SetInvokingWindow(NULL);
+ win->DismissPopupMenu();
}
}
}
// item, not to the right of it
wxRect rectItem = GetItemRect(m_current);
- m_menuShown->SetInvokingWindow(m_frameLast);
-
m_menuShown->Popup(ClientToScreen(rectItem.GetPosition()),
wxSize(0, rectItem.GetHeight()),
selectFirst);