]> git.saurik.com Git - wxWidgets.git/commitdiff
disable UI updating during GetPopupMenuSelectionFromUser() execution to avoid unexpec...
authorVadim Zeitlin <vadim@wxwidgets.org>
Mon, 15 Dec 2008 11:02:49 +0000 (11:02 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Mon, 15 Dec 2008 11:02:49 +0000 (11:02 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@57355 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/window.h
interface/wx/window.h
src/common/wincmn.cpp

index fb66bf004eea193d9d4246be7c643d347674c38a..84da1edd65a39344f7501659d5b04f6289e03567 100644 (file)
@@ -1651,8 +1651,9 @@ private:
     void NotifyWindowOnEnableChange(bool enabled);
 
 #if wxUSE_MENUS
-    // temporary event handler used by GetPopupMenuSelectionFromUser()
+    // temporary event handlers used by GetPopupMenuSelectionFromUser()
     void InternalOnPopupMenu(wxCommandEvent& event);
+    void InternalOnPopupMenuUpdate(wxUpdateUIEvent& event);
 
     // implementation of the public GetPopupMenuSelectionFromUser() method
     int DoGetPopupMenuSelectionFromUser(wxMenu& menu, int x, int y);
index 4b7f8a7c0a001a5b9ef98a5daab78a3df4b4eb93..8f8a9d8364b5c7632fd39e93ca1a263bcac2f9cb 100644 (file)
@@ -1060,28 +1060,35 @@ public:
     */
     wxWindow* GetParent() const;
 
+    //@{
     /**
         This function shows a popup menu at the given position in this window and
-        returns the selected id. It can be more convenient than the general purpose
-        PopupMenu() function for simple menus proposing a choice in a list of
-        strings to the user.
+        returns the selected id.
+
+        It can be more convenient than the general purpose PopupMenu() function
+        for simple menus proposing a choice in a list of strings to the user.
+
+        Notice that to avoid unexpected conflicts between the (usually
+        consecutive range of) ids used by the menu passed to this function and
+        the existing EVT_UPDATE_UI() handlers, this function temporarily
+        disables UI updates for the window, so you need to manually disable
+        (or toggle or ...) any items which should be disabled in the menu
+        before showing it.
 
         @param menu
-            The menu to show
+            The menu to show.
         @param pos
-            The position at which to show the menu in client coordinates
+            The position at which to show the menu in client coordinates.
 
-        @return The selected menu item id or wxID_NONE if none selected or an
-                 error occurred.
-    */
-    int GetPopupMenuSelectionFromUser(wxMenu& menu, const wxPoint& pos);
+        @return
+             The selected menu item id or @c wxID_NONE if none selected or an
+             error occurred.
 
-    /**
-        See the GetPopupMenuSelectionFromUser(wxMenu&, const wxPoint&) overload.
-        This overload differs only because it takes two integers for the
-        menu position instead of a wxPoint.
+        @since 2.9.0
     */
+    int GetPopupMenuSelectionFromUser(wxMenu& menu, const wxPoint& pos);
     int GetPopupMenuSelectionFromUser(wxMenu& menu, int x, int y);
+    //@}
 
     /**
         This gets the position of the window in pixels, relative to the parent window
index 6eac63e1a929196e12349ec74dd2c74baf0694c0..a519ffd7f07070bf408fed5141f5a6552ee89b8f 100644 (file)
@@ -2407,6 +2407,11 @@ void wxWindowBase::InternalOnPopupMenu(wxCommandEvent& event)
     gs_popupMenuSelection = event.GetId();
 }
 
+void wxWindowBase::InternalOnPopupMenuUpdate(wxUpdateUIEvent& WXUNUSED(event))
+{
+    // nothing to do but do not skip it
+}
+
 int
 wxWindowBase::DoGetPopupMenuSelectionFromUser(wxMenu& menu, int x, int y)
 {
@@ -2417,8 +2422,24 @@ wxWindowBase::DoGetPopupMenuSelectionFromUser(wxMenu& menu, int x, int y)
             NULL,
             this);
 
+    // it is common to construct the menu passed to this function dynamically
+    // using some fixed range of ids which could clash with the ids used
+    // elsewhere in the program, which could result in some menu items being
+    // unintentionally disabled or otherwise modified by update UI handlers
+    // elsewhere in the program code and this is difficult to avoid in the
+    // program itself, so instead we just temporarily suspend UI updating while
+    // this menu is shown
+    Connect(wxEVT_UPDATE_UI,
+            wxUpdateUIEventHandler(wxWindowBase::InternalOnPopupMenuUpdate),
+            NULL,
+            this);
+
     PopupMenu(&menu, x, y);
 
+    Disconnect(wxEVT_UPDATE_UI,
+               wxUpdateUIEventHandler(wxWindowBase::InternalOnPopupMenuUpdate),
+               NULL,
+               this);
     Disconnect(wxEVT_COMMAND_MENU_SELECTED,
                wxCommandEventHandler(wxWindowBase::InternalOnPopupMenu),
                NULL,