]> git.saurik.com Git - wxWidgets.git/commitdiff
Refactored wxComboPopupExtraEventHandler::OnMouseEvent(). Now block mouse events...
authorJaakko Salli <jaakko.salli@dnainternet.net>
Tue, 1 Jun 2010 13:46:14 +0000 (13:46 +0000)
committerJaakko Salli <jaakko.salli@dnainternet.net>
Tue, 1 Jun 2010 13:46:14 +0000 (13:46 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@64455 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

src/common/combocmn.cpp

index ac52ecc81ded2c111bcf38b071657ff520d2a983..92112752a7fb775f6129a1c37f996bc4afd869ce 100644 (file)
@@ -670,6 +670,10 @@ public:
     {
         m_combo = combo;
         m_beenInside = false;
+
+        // Let's make it so that the popup control will not receive mouse
+        // events until mouse left button has been up.
+        m_blockEventsToPopup = true;
     }
     virtual ~wxComboPopupExtraEventHandler() { }
 
@@ -679,12 +683,14 @@ public:
     void OnPopupDismiss()
     {
         m_beenInside = false;
+        m_blockEventsToPopup = true;
     }
 
 protected:
     wxComboCtrlBase*     m_combo;
 
-    bool                    m_beenInside;
+    bool                m_beenInside;
+    bool                m_blockEventsToPopup;
 
 private:
     DECLARE_EVENT_TABLE()
@@ -706,43 +712,83 @@ void wxComboPopupExtraEventHandler::OnMouseEvent( wxMouseEvent& event )
 
     event.Skip();
 
-    // Block motion and click events outside the popup
-    if ( (!isInside || !m_combo->IsPopupShown())
-            &&
-         (evtType == wxEVT_MOTION ||
-          evtType == wxEVT_LEFT_DOWN ||
-          evtType == wxEVT_LEFT_UP ||
-          evtType == wxEVT_RIGHT_DOWN) )
-    {
-        event.Skip(false);
-    }
-    else if ( evtType == wxEVT_LEFT_UP )
+    if ( !isInside || !m_combo->IsPopupShown() )
     {
-        if ( !m_combo->IsPopupShown() )
+        // Mouse is outside the popup or popup is not actually shown (yet)
+
+        if ( evtType == wxEVT_MOTION ||
+             evtType == wxEVT_LEFT_DOWN ||
+             evtType == wxEVT_LEFT_UP ||
+             evtType == wxEVT_RIGHT_DOWN )
         {
+            // Block motion and click events outside the popup
             event.Skip(false);
-            relayToButton = true;
         }
-        else if ( !m_beenInside )
+    }
+    else
+    {
+        // Mouse is inside the popup, which is fully shown
+
+        m_beenInside = true;
+
+        // Do not let the popup control respond to mouse events until
+        // mouse press used to display the popup has been lifted. This
+        // is important for users with slower mouse fingers or mouse
+        // drivers. Note that we have some redundancy here, just in
+        // case the popup is some native control that does not emit all
+        // mouse event types.
+        if ( evtType == wxEVT_MOTION )
         {
-            if ( isInside )
+            if ( m_blockEventsToPopup )
             {
-                m_beenInside = true;
+                if ( event.LeftIsDown() )
+                    event.Skip(false);
+                else
+                    m_blockEventsToPopup = false;
             }
-            else
+        }
+        else if ( evtType == wxEVT_LEFT_DOWN )
+        {
+            if ( m_blockEventsToPopup )
+                m_blockEventsToPopup = false;
+        }
+        else if ( evtType == wxEVT_LEFT_UP )
+        {
+            if ( m_blockEventsToPopup )
             {
-                relayToButton = true;
+                // On first left up, stop blocking mouse events (but still
+                // block this one)
+                m_blockEventsToPopup = false;
+                event.Skip(false);
             }
         }
+        else if ( m_blockEventsToPopup )
+        {
+            event.Skip(false);
+        }
+    }
+
+    //
+    // Some mouse events to popup that happen outside it, before cursor
+    // has been inside the popup, need to be ignored by it but relayed to
+    // the dropbutton.
+    //
+    if ( evtType == wxEVT_LEFT_UP )
+    {
+        if ( !m_combo->IsPopupShown() )
+        {
+            event.Skip(false);
+            relayToButton = true;
+        }
+        else if ( !isInside && !m_beenInside )
+        {
+            // Popup is shown but the cursor is not inside, nor it has been
+            relayToButton = true;
+        }
     }
 
     if ( relayToButton )
     {
-        //
-        // Some mouse events to popup that happen outside it, before cursor
-        // has been inside the popup, need to be ignored by it but relayed to
-        // the dropbutton.
-        //
         wxWindow* eventSink = m_combo;
         wxWindow* btn = m_combo->GetButton();
         if ( btn )