From 971562cb51391676afccb9822e491d677f052c0d Mon Sep 17 00:00:00 2001 From: =?utf8?q?V=C3=A1clav=20Slav=C3=ADk?= Date: Thu, 3 Jun 2004 14:05:30 +0000 Subject: [PATCH] use current mouse position as default position in wxWindow::PopupMenu (works better in wxGTK and is what you need in majority of cases) git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@27599 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/latex/wx/window.tex | 15 +++++++++++---- include/wx/window.h | 8 +++++--- src/gtk/window.cpp | 32 +++++++++++++++++++++++--------- src/gtk1/window.cpp | 32 +++++++++++++++++++++++--------- src/mac/carbon/window.cpp | 11 ++++++++++- src/mac/classic/window.cpp | 11 ++++++++++- src/motif/window.cpp | 6 ++++++ src/msw/window.cpp | 6 ++++++ src/os2/window.cpp | 16 ++++++++++++---- src/unix/taskbarx11.cpp | 2 +- 10 files changed, 107 insertions(+), 32 deletions(-) diff --git a/docs/latex/wx/window.tex b/docs/latex/wx/window.tex index 7174076d68..ecd5b6798c 100644 --- a/docs/latex/wx/window.tex +++ b/docs/latex/wx/window.tex @@ -1987,6 +1987,8 @@ default value is {\tt false}.} \membersection{wxWindow::PopupMenu}\label{wxwindowpopupmenu} +\func{bool}{PopupMenu}{\param{wxMenu* }{menu}} + \func{bool}{PopupMenu}{\param{wxMenu* }{menu}, \param{const wxPoint\& }{pos}} \func{bool}{PopupMenu}{\param{wxMenu* }{menu}, \param{int }{x}, \param{int }{y}} @@ -1994,7 +1996,8 @@ default value is {\tt false}.} Pops up the given menu at the specified coordinates, relative to this window, and returns control when the user has dismissed the menu. If a menu item is selected, the corresponding menu event is generated and will be -processed as usually. +processed as usually. If the coordinates are not specified, current mouse +cursor position is used. \wxheading{Parameters} @@ -2012,9 +2015,13 @@ processed as usually. \wxheading{Remarks} -Just before the menu is popped up, \helpref{wxMenu::UpdateUI}{wxmenuupdateui} is called -to ensure that the menu items are in the correct state. The menu does not get deleted -by the window. +Just before the menu is popped up, \helpref{wxMenu::UpdateUI}{wxmenuupdateui} +is called to ensure that the menu items are in the correct state. The menu does +not get deleted by the window. + +It is recommended to not explicitly specify coordinates when calling PopupMenu +in response to mouse click, because some of the ports (namely, wxGTK) can do +a better job of positioning the menu in that case. \pythonnote{In place of a single overloaded method name, wxPython implements the following methods:\par diff --git a/include/wx/window.h b/include/wx/window.h index bf670b3b32..67e839fd66 100644 --- a/include/wx/window.h +++ b/include/wx/window.h @@ -804,9 +804,11 @@ public: virtual void DoUpdateWindowUI(wxUpdateUIEvent& event) ; #if wxUSE_MENUS - bool PopupMenu( wxMenu *menu, const wxPoint& pos ) + bool PopupMenu(wxMenu *menu) + { return DoPopupMenu(menu, -1, -1); } + bool PopupMenu(wxMenu *menu, const wxPoint& pos) { return DoPopupMenu(menu, pos.x, pos.y); } - bool PopupMenu( wxMenu *menu, int x, int y ) + bool PopupMenu(wxMenu *menu, int x, int y) { return DoPopupMenu(menu, x, y); } #endif // wxUSE_MENUS @@ -1203,7 +1205,7 @@ protected: #endif // wxUSE_TOOLTIPS #if wxUSE_MENUS - virtual bool DoPopupMenu( wxMenu *menu, int x, int y ) = 0; + virtual bool DoPopupMenu(wxMenu *menu, int x, int y) = 0; #endif // wxUSE_MENUS // Makes an adjustment to the window position to make it relative to the diff --git a/src/gtk/window.cpp b/src/gtk/window.cpp index d468e1b8e8..e5fd465440 100644 --- a/src/gtk/window.cpp +++ b/src/gtk/window.cpp @@ -4285,30 +4285,44 @@ extern "C" void wxPopupMenuPositionCallback( GtkMenu *menu, bool wxWindowGTK::DoPopupMenu( wxMenu *menu, int x, int y ) { - wxCHECK_MSG( m_widget != NULL, FALSE, wxT("invalid window") ); + wxCHECK_MSG( m_widget != NULL, false, wxT("invalid window") ); - wxCHECK_MSG( menu != NULL, FALSE, wxT("invalid popup-menu") ); + wxCHECK_MSG( menu != NULL, false, wxT("invalid popup-menu") ); SetInvokingWindow( menu, this ); menu->UpdateUI(); - wxPoint pos(ClientToScreen(wxPoint(x, y))); - - bool is_waiting = TRUE; + bool is_waiting = true; gtk_signal_connect( GTK_OBJECT(menu->m_menu), "hide", GTK_SIGNAL_FUNC(gtk_pop_hide_callback), (gpointer)&is_waiting ); + wxPoint pos; + gpointer userdata; + GtkMenuPositionFunc posfunc; + if ( x == -1 && y == -1 ) + { + // use GTK's default positioning algorithm + userdata = NULL; + posfunc = NULL; + } + else + { + pos = ClientToScreen(wxPoint(x, y)); + userdata = &pos; + posfunc = wxPopupMenuPositionCallback; + } + gtk_menu_popup( GTK_MENU(menu->m_menu), (GtkWidget *) NULL, // parent menu shell (GtkWidget *) NULL, // parent menu item - wxPopupMenuPositionCallback, // function to position it - &pos, // client data - 0 /* FIXME! */, // button used to activate it + posfunc, // function to position it + userdata, // client data + 0, // button used to activate it #ifdef __WXGTK20__ gtk_get_current_event_time() #else @@ -4321,7 +4335,7 @@ bool wxWindowGTK::DoPopupMenu( wxMenu *menu, int x, int y ) gtk_main_iteration(); } - return TRUE; + return true; } #endif // wxUSE_MENUS_NATIVE diff --git a/src/gtk1/window.cpp b/src/gtk1/window.cpp index d468e1b8e8..e5fd465440 100644 --- a/src/gtk1/window.cpp +++ b/src/gtk1/window.cpp @@ -4285,30 +4285,44 @@ extern "C" void wxPopupMenuPositionCallback( GtkMenu *menu, bool wxWindowGTK::DoPopupMenu( wxMenu *menu, int x, int y ) { - wxCHECK_MSG( m_widget != NULL, FALSE, wxT("invalid window") ); + wxCHECK_MSG( m_widget != NULL, false, wxT("invalid window") ); - wxCHECK_MSG( menu != NULL, FALSE, wxT("invalid popup-menu") ); + wxCHECK_MSG( menu != NULL, false, wxT("invalid popup-menu") ); SetInvokingWindow( menu, this ); menu->UpdateUI(); - wxPoint pos(ClientToScreen(wxPoint(x, y))); - - bool is_waiting = TRUE; + bool is_waiting = true; gtk_signal_connect( GTK_OBJECT(menu->m_menu), "hide", GTK_SIGNAL_FUNC(gtk_pop_hide_callback), (gpointer)&is_waiting ); + wxPoint pos; + gpointer userdata; + GtkMenuPositionFunc posfunc; + if ( x == -1 && y == -1 ) + { + // use GTK's default positioning algorithm + userdata = NULL; + posfunc = NULL; + } + else + { + pos = ClientToScreen(wxPoint(x, y)); + userdata = &pos; + posfunc = wxPopupMenuPositionCallback; + } + gtk_menu_popup( GTK_MENU(menu->m_menu), (GtkWidget *) NULL, // parent menu shell (GtkWidget *) NULL, // parent menu item - wxPopupMenuPositionCallback, // function to position it - &pos, // client data - 0 /* FIXME! */, // button used to activate it + posfunc, // function to position it + userdata, // client data + 0, // button used to activate it #ifdef __WXGTK20__ gtk_get_current_event_time() #else @@ -4321,7 +4335,7 @@ bool wxWindowGTK::DoPopupMenu( wxMenu *menu, int x, int y ) gtk_main_iteration(); } - return TRUE; + return true; } #endif // wxUSE_MENUS_NATIVE diff --git a/src/mac/carbon/window.cpp b/src/mac/carbon/window.cpp index 90e55a094b..c2a4d8fe40 100644 --- a/src/mac/carbon/window.cpp +++ b/src/mac/carbon/window.cpp @@ -1439,7 +1439,16 @@ bool wxWindowMac::DoPopupMenu(wxMenu *menu, int x, int y) { menu->SetInvokingWindow(this); menu->UpdateUI(); - ClientToScreen( &x , &y ) ; + + if ( x == -1 && y == -1 ) + { + wxPoint mouse = wxGetMousePosition(); + x = mouse.x; y = mouse.y; + } + else + { + ClientToScreen( &x , &y ) ; + } menu->MacBeforeDisplay( true ) ; long menuResult = ::PopUpMenuSelect((MenuHandle) menu->GetHMenu() ,y,x, 0) ; diff --git a/src/mac/classic/window.cpp b/src/mac/classic/window.cpp index a5c56e4202..4af9bf6ce2 100644 --- a/src/mac/classic/window.cpp +++ b/src/mac/classic/window.cpp @@ -364,7 +364,16 @@ bool wxWindowMac::DoPopupMenu(wxMenu *menu, int x, int y) { menu->SetInvokingWindow(this); menu->UpdateUI(); - ClientToScreen( &x , &y ) ; + + if ( x == -1 && y == -1 ) + { + wxPoint mouse = wxGetMousePosition(); + x = mouse.x; y = mouse.y; + } + else + { + ClientToScreen( &x , &y ) ; + } menu->MacBeforeDisplay( true ) ; long menuResult = ::PopUpMenuSelect((MenuHandle) menu->GetHMenu() ,y,x, 0) ; diff --git a/src/motif/window.cpp b/src/motif/window.cpp index b1fc9b524e..207afc3ed0 100644 --- a/src/motif/window.cpp +++ b/src/motif/window.cpp @@ -1075,6 +1075,12 @@ void wxWindow::DoSetToolTip(wxToolTip * WXUNUSED(tooltip)) bool wxWindow::DoPopupMenu(wxMenu *menu, int x, int y) { + if ( x == -1 && y == -1 ) + { + wxPoint mouse = ScreenToClient(wxGetMousePosition()); + x = mouse.x; y = mouse.y; + } + Widget widget = (Widget) GetMainWidget(); /* The menuId field seems to be usused, so we'll use it to diff --git a/src/msw/window.cpp b/src/msw/window.cpp index 6a4ffb7334..5c826bf7bc 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -1737,6 +1737,12 @@ bool wxWindowMSW::DoPopupMenu(wxMenu *menu, int x, int y) menu->SetInvokingWindow(this); menu->UpdateUI(); + if ( x == -1 && y == -1 ) + { + wxPoint mouse = ScreenToClient(wxGetMousePosition()); + x = mouse.x; y = mouse.y; + } + HWND hWnd = GetHwnd(); HMENU hMenu = GetHmenuOf(menu); POINT point; diff --git a/src/os2/window.cpp b/src/os2/window.cpp index fb3aee34a1..0c448ce6f5 100644 --- a/src/os2/window.cpp +++ b/src/os2/window.cpp @@ -1955,10 +1955,18 @@ bool wxWindowOS2::DoPopupMenu( pMenu->SetInvokingWindow(this); pMenu->UpdateUI(); - - DoClientToScreen( &nX - ,&nY - ); + + if ( x == -1 && y == -1 ) + { + wxPoint mouse = wxGetMousePosition(); + nX = mouse.x; nY = mouse.y; + } + else + { + DoClientToScreen( &nX + ,&nY + ); + } wxCurrentPopupMenu = pMenu; ::WinPopupMenu( hWndParent diff --git a/src/unix/taskbarx11.cpp b/src/unix/taskbarx11.cpp index 5ec54ac876..759be00a01 100644 --- a/src/unix/taskbarx11.cpp +++ b/src/unix/taskbarx11.cpp @@ -314,6 +314,6 @@ bool wxTaskBarIcon::PopupMenu(wxMenu *menu) if (!m_iconWnd) return false; wxSize size(m_iconWnd->GetClientSize()); - m_iconWnd->PopupMenu(menu, size.x/2, size.y/2); + m_iconWnd->PopupMenu(menu); return true; } -- 2.47.2