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
This commit is contained in:
Václav Slavík
2004-06-03 14:05:30 +00:00
parent e77d093dbe
commit 971562cb51
10 changed files with 107 additions and 32 deletions

View File

@@ -1987,6 +1987,8 @@ default value is {\tt false}.}
\membersection{wxWindow::PopupMenu}\label{wxwindowpopupmenu} \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{const wxPoint\& }{pos}}
\func{bool}{PopupMenu}{\param{wxMenu* }{menu}, \param{int }{x}, \param{int }{y}} \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 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 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 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} \wxheading{Parameters}
@@ -2012,9 +2015,13 @@ processed as usually.
\wxheading{Remarks} \wxheading{Remarks}
Just before the menu is popped up, \helpref{wxMenu::UpdateUI}{wxmenuupdateui} is called Just before the menu is popped up, \helpref{wxMenu::UpdateUI}{wxmenuupdateui}
to ensure that the menu items are in the correct state. The menu does not get deleted is called to ensure that the menu items are in the correct state. The menu does
by the window. 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 \pythonnote{In place of a single overloaded method name, wxPython
implements the following methods:\par implements the following methods:\par

View File

@@ -804,9 +804,11 @@ public:
virtual void DoUpdateWindowUI(wxUpdateUIEvent& event) ; virtual void DoUpdateWindowUI(wxUpdateUIEvent& event) ;
#if wxUSE_MENUS #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); } { 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); } { return DoPopupMenu(menu, x, y); }
#endif // wxUSE_MENUS #endif // wxUSE_MENUS
@@ -1203,7 +1205,7 @@ protected:
#endif // wxUSE_TOOLTIPS #endif // wxUSE_TOOLTIPS
#if wxUSE_MENUS #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 #endif // wxUSE_MENUS
// Makes an adjustment to the window position to make it relative to the // Makes an adjustment to the window position to make it relative to the

View File

@@ -4285,30 +4285,44 @@ extern "C" void wxPopupMenuPositionCallback( GtkMenu *menu,
bool wxWindowGTK::DoPopupMenu( wxMenu *menu, int x, int y ) 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 ); SetInvokingWindow( menu, this );
menu->UpdateUI(); menu->UpdateUI();
wxPoint pos(ClientToScreen(wxPoint(x, y))); bool is_waiting = true;
bool is_waiting = TRUE;
gtk_signal_connect( GTK_OBJECT(menu->m_menu), gtk_signal_connect( GTK_OBJECT(menu->m_menu),
"hide", "hide",
GTK_SIGNAL_FUNC(gtk_pop_hide_callback), GTK_SIGNAL_FUNC(gtk_pop_hide_callback),
(gpointer)&is_waiting ); (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_popup(
GTK_MENU(menu->m_menu), GTK_MENU(menu->m_menu),
(GtkWidget *) NULL, // parent menu shell (GtkWidget *) NULL, // parent menu shell
(GtkWidget *) NULL, // parent menu item (GtkWidget *) NULL, // parent menu item
wxPopupMenuPositionCallback, // function to position it posfunc, // function to position it
&pos, // client data userdata, // client data
0 /* FIXME! */, // button used to activate it 0, // button used to activate it
#ifdef __WXGTK20__ #ifdef __WXGTK20__
gtk_get_current_event_time() gtk_get_current_event_time()
#else #else
@@ -4321,7 +4335,7 @@ bool wxWindowGTK::DoPopupMenu( wxMenu *menu, int x, int y )
gtk_main_iteration(); gtk_main_iteration();
} }
return TRUE; return true;
} }
#endif // wxUSE_MENUS_NATIVE #endif // wxUSE_MENUS_NATIVE

View File

@@ -4285,30 +4285,44 @@ extern "C" void wxPopupMenuPositionCallback( GtkMenu *menu,
bool wxWindowGTK::DoPopupMenu( wxMenu *menu, int x, int y ) 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 ); SetInvokingWindow( menu, this );
menu->UpdateUI(); menu->UpdateUI();
wxPoint pos(ClientToScreen(wxPoint(x, y))); bool is_waiting = true;
bool is_waiting = TRUE;
gtk_signal_connect( GTK_OBJECT(menu->m_menu), gtk_signal_connect( GTK_OBJECT(menu->m_menu),
"hide", "hide",
GTK_SIGNAL_FUNC(gtk_pop_hide_callback), GTK_SIGNAL_FUNC(gtk_pop_hide_callback),
(gpointer)&is_waiting ); (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_popup(
GTK_MENU(menu->m_menu), GTK_MENU(menu->m_menu),
(GtkWidget *) NULL, // parent menu shell (GtkWidget *) NULL, // parent menu shell
(GtkWidget *) NULL, // parent menu item (GtkWidget *) NULL, // parent menu item
wxPopupMenuPositionCallback, // function to position it posfunc, // function to position it
&pos, // client data userdata, // client data
0 /* FIXME! */, // button used to activate it 0, // button used to activate it
#ifdef __WXGTK20__ #ifdef __WXGTK20__
gtk_get_current_event_time() gtk_get_current_event_time()
#else #else
@@ -4321,7 +4335,7 @@ bool wxWindowGTK::DoPopupMenu( wxMenu *menu, int x, int y )
gtk_main_iteration(); gtk_main_iteration();
} }
return TRUE; return true;
} }
#endif // wxUSE_MENUS_NATIVE #endif // wxUSE_MENUS_NATIVE

View File

@@ -1439,7 +1439,16 @@ bool wxWindowMac::DoPopupMenu(wxMenu *menu, int x, int y)
{ {
menu->SetInvokingWindow(this); menu->SetInvokingWindow(this);
menu->UpdateUI(); 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 ) ; menu->MacBeforeDisplay( true ) ;
long menuResult = ::PopUpMenuSelect((MenuHandle) menu->GetHMenu() ,y,x, 0) ; long menuResult = ::PopUpMenuSelect((MenuHandle) menu->GetHMenu() ,y,x, 0) ;

View File

@@ -364,7 +364,16 @@ bool wxWindowMac::DoPopupMenu(wxMenu *menu, int x, int y)
{ {
menu->SetInvokingWindow(this); menu->SetInvokingWindow(this);
menu->UpdateUI(); 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 ) ; menu->MacBeforeDisplay( true ) ;
long menuResult = ::PopUpMenuSelect((MenuHandle) menu->GetHMenu() ,y,x, 0) ; long menuResult = ::PopUpMenuSelect((MenuHandle) menu->GetHMenu() ,y,x, 0) ;

View File

@@ -1075,6 +1075,12 @@ void wxWindow::DoSetToolTip(wxToolTip * WXUNUSED(tooltip))
bool wxWindow::DoPopupMenu(wxMenu *menu, int x, int y) 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(); Widget widget = (Widget) GetMainWidget();
/* The menuId field seems to be usused, so we'll use it to /* The menuId field seems to be usused, so we'll use it to

View File

@@ -1737,6 +1737,12 @@ bool wxWindowMSW::DoPopupMenu(wxMenu *menu, int x, int y)
menu->SetInvokingWindow(this); menu->SetInvokingWindow(this);
menu->UpdateUI(); menu->UpdateUI();
if ( x == -1 && y == -1 )
{
wxPoint mouse = ScreenToClient(wxGetMousePosition());
x = mouse.x; y = mouse.y;
}
HWND hWnd = GetHwnd(); HWND hWnd = GetHwnd();
HMENU hMenu = GetHmenuOf(menu); HMENU hMenu = GetHmenuOf(menu);
POINT point; POINT point;

View File

@@ -1955,10 +1955,18 @@ bool wxWindowOS2::DoPopupMenu(
pMenu->SetInvokingWindow(this); pMenu->SetInvokingWindow(this);
pMenu->UpdateUI(); pMenu->UpdateUI();
DoClientToScreen( &nX if ( x == -1 && y == -1 )
,&nY {
); wxPoint mouse = wxGetMousePosition();
nX = mouse.x; nY = mouse.y;
}
else
{
DoClientToScreen( &nX
,&nY
);
}
wxCurrentPopupMenu = pMenu; wxCurrentPopupMenu = pMenu;
::WinPopupMenu( hWndParent ::WinPopupMenu( hWndParent

View File

@@ -314,6 +314,6 @@ bool wxTaskBarIcon::PopupMenu(wxMenu *menu)
if (!m_iconWnd) if (!m_iconWnd)
return false; return false;
wxSize size(m_iconWnd->GetClientSize()); wxSize size(m_iconWnd->GetClientSize());
m_iconWnd->PopupMenu(menu, size.x/2, size.y/2); m_iconWnd->PopupMenu(menu);
return true; return true;
} }