]> git.saurik.com Git - wxWidgets.git/commitdiff
For wxMSW capture and release the mouse as the cursor moves out or
authorRobin Dunn <robin@alldunn.com>
Fri, 15 Apr 2005 03:04:30 +0000 (03:04 +0000)
committerRobin Dunn <robin@alldunn.com>
Fri, 15 Apr 2005 03:04:30 +0000 (03:04 +0000)
back in to the transient popup window to enable the transient to be
automatically dismissed when a click happens outside of it.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@33618 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/popupwin.h
samples/popup/popup.cpp
src/common/popupcmn.cpp

index b02debc98f72be12f270c681a9ccbdad7650f052..a347db9dc63169402c965e06939f70e6750b5def 100644 (file)
@@ -127,6 +127,11 @@ protected:
     // get alerted when child gets deleted from under us
     void OnDestroy(wxWindowDestroyEvent& event);
 
+#ifdef __WXMSW__
+    // check if the mouse needs captured or released
+    void OnIdle(wxIdleEvent& event);
+#endif
+    
     // the child of this popup if any
     wxWindow *m_child;
 
@@ -141,6 +146,7 @@ protected:
     wxPopupWindowHandler *m_handlerPopup;
     wxPopupFocusHandler  *m_handlerFocus;
 
+    DECLARE_EVENT_TABLE()
     DECLARE_DYNAMIC_CLASS(wxPopupTransientWindow)
     DECLARE_NO_COPY_CLASS(wxPopupTransientWindow)
 };
index 4741bfe738bf01af1bc86c772b8af9ffea76bbde..0306e91ccf2748c3c72aaf561a0e5cdece5092f3 100644 (file)
@@ -81,6 +81,7 @@ private:
     wxScrolledWindow *m_panel;
     wxButton *m_button;
     wxSpinCtrl *m_spinCtrl;
+    wxStaticText *m_mouseText;
 
 private:
     void OnMouse( wxMouseEvent &event );
@@ -118,9 +119,9 @@ SimpleTransientPopup::SimpleTransientPopup( wxWindow *parent )
     // Keep this code to verify if mouse events work, they're required if 
     // you're making a control like a combobox where the items are highlighted
     // under the cursor, the m_panel is set focus in the Popup() function
-    //m_panel->Connect(wxEVT_MOTION,
-    //                 wxMouseEventHandler(SimpleTransientPopup::OnMouse),
-    //                 NULL, this);
+    m_panel->Connect(wxEVT_MOTION,
+                     wxMouseEventHandler(SimpleTransientPopup::OnMouse),
+                     NULL, this);
 
     wxStaticText *text = new wxStaticText( m_panel, wxID_ANY,
                           wxT("wx.PopupTransientWindow is a\n")
@@ -128,16 +129,23 @@ SimpleTransientPopup::SimpleTransientPopup( wxWindow *parent )
                           wxT("automatically when the user\n")
                           wxT("clicks the mouse outside it or if it\n")
                           wxT("(or its first child) loses focus in \n")
-                          wxT("any other way."), wxPoint( 10,10) );
-    wxSize size = text->GetBestSize();
+                          wxT("any other way.") );
 
-    m_button = new wxButton(m_panel, Minimal_PopupButton, wxT("Press Me"), wxPoint(0, size.y + 10));
-    size.y = m_button->GetRect().GetBottom();
-    m_spinCtrl = new wxSpinCtrl(m_panel, Minimal_PopupSpinctrl, wxT("Hello"), wxPoint(0, size.y + 5));
-    size.y = m_spinCtrl->GetRect().GetBottom();
+    m_button = new wxButton(m_panel, Minimal_PopupButton, wxT("Press Me"));
+    m_spinCtrl = new wxSpinCtrl(m_panel, Minimal_PopupSpinctrl, wxT("Hello"));
+    m_mouseText = new wxStaticText(m_panel, wxID_ANY, 
+                                   wxT("<- Test Mouse ->"));
 
-    m_panel->SetSize( size.x+20, size.y+20 );
-    SetClientSize( size.x+20, size.y+20 );
+    wxBoxSizer *topSizer = new wxBoxSizer( wxVERTICAL );
+    topSizer->Add( text, 0, wxALL, 5 );
+    topSizer->Add( m_button, 0, wxALL, 5 );
+    topSizer->Add( m_spinCtrl, 0, wxALL, 5 );
+    topSizer->Add( m_mouseText, 0, wxCENTRE|wxALL, 5 );
+
+    m_panel->SetAutoLayout( true );
+    m_panel->SetSizer( topSizer );
+    topSizer->Fit(m_panel);
+    topSizer->Fit(this);
 }
 
 SimpleTransientPopup::~SimpleTransientPopup()
@@ -187,7 +195,22 @@ void SimpleTransientPopup::OnKillFocus(wxFocusEvent &event)
 
 void SimpleTransientPopup::OnMouse(wxMouseEvent &event)
 {
+    wxRect rect(m_mouseText->GetRect());
+    rect.SetX(-100000);
+    rect.SetWidth(1000000);
+    wxColour colour(*wxLIGHT_GREY);
+
+    if (rect.Inside(event.GetPosition()))
+    {       
+        colour = wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT);
     wxLogMessage( wxT("0x%lx SimpleTransientPopup::OnMouse pos(%d, %d)"), long(event.GetEventObject()), event.GetX(), event.GetY());
+    }
+
+    if (colour != m_mouseText->GetBackgroundColour())
+    {
+        m_mouseText->SetBackgroundColour(colour);
+        m_mouseText->Refresh();
+    }
     event.Skip();
 }
 
@@ -317,6 +340,12 @@ MyFrame::MyFrame(const wxString& title)
     SetMenuBar(menuBar);
 #endif // wxUSE_MENUS
 
+#if wxUSE_STATUSBAR
+    // create a status bar just for fun (by default with 1 pane only)
+    CreateStatusBar(2);
+    SetStatusText(_T("Welcome to wxWidgets!"));
+#endif // wxUSE_STATUSBAR
+
     wxPanel *panel = new wxPanel(this, -1);
     wxButton *button1 = new wxButton( panel, Minimal_StartSimplePopup, wxT("Show simple popup"), wxPoint(20,20) );
     wxButton *button2 = new wxButton( panel, Minimal_StartScrolledPopup, wxT("Show scrolled popup"), wxPoint(20,70) );
@@ -336,11 +365,6 @@ MyFrame::MyFrame(const wxString& title)
     panel->SetAutoLayout( true );
     panel->SetSizer( topSizer );
 
-#if wxUSE_STATUSBAR
-    // create a status bar just for fun (by default with 1 pane only)
-    CreateStatusBar(2);
-    SetStatusText(_T("Welcome to wxWidgets!"));
-#endif // wxUSE_STATUSBAR
 }
 
 MyFrame::~MyFrame()
index 50b97f508074bbcdeda1e5619bbce1e3fcce1470..b4803861243fb4681b7c5d5074022e7a49af5fbb 100644 (file)
@@ -110,6 +110,12 @@ BEGIN_EVENT_TABLE(wxPopupFocusHandler, wxEvtHandler)
     EVT_KEY_DOWN(wxPopupFocusHandler::OnKeyDown)
 END_EVENT_TABLE()
 
+BEGIN_EVENT_TABLE(wxPopupTransientWindow, wxPopupWindow)
+#ifdef __WXMSW__
+    EVT_IDLE(wxPopupTransientWindow::OnIdle)
+#endif
+END_EVENT_TABLE()
+
 // ============================================================================
 // implementation
 // ============================================================================
@@ -199,7 +205,10 @@ void wxPopupTransientWindow::PopHandlers()
             // handler - so don't risk deleting it second time
             m_handlerPopup = NULL;
         }
-
+        if (m_child->HasCapture())
+        {       
+            m_child->ReleaseMouse();
+        }
         m_child = NULL;
     }
 
@@ -303,6 +312,13 @@ bool wxPopupTransientWindow::Show( bool show )
     }
 #endif
 
+#ifdef __WXMSW__
+    if (!show && m_child && m_child->HasCapture())
+    {       
+        m_child->ReleaseMouse();
+    }
+#endif
+    
     bool ret = wxPopupWindow::Show( show );
 
 #ifdef __WXGTK__
@@ -337,20 +353,27 @@ bool wxPopupTransientWindow::Show( bool show )
             CurrentTime );
     }
 #endif
+
+#ifdef __WXMSW__
+    if (show && m_child)
+    {
+        // Assume that the mouse is outside the popup to begin with
+        m_child->CaptureMouse();
+    }
+#endif
+
     return ret;
 }
 
 void wxPopupTransientWindow::Dismiss()
 {
-    PopHandlers();
-
     Hide();
+    PopHandlers();
 }
 
 void wxPopupTransientWindow::DismissAndNotify()
 {
     Dismiss();
-
     OnDismiss();
 }
 
@@ -373,6 +396,35 @@ void wxPopupTransientWindow::OnDestroy(wxWindowDestroyEvent& event)
         m_focus = NULL;
 }
 
+#ifdef __WXMSW__
+void wxPopupTransientWindow::OnIdle(wxIdleEvent& event)
+{
+    event.Skip();
+
+    if (IsShown() && m_child)
+    {
+        wxPoint pos = ScreenToClient(wxGetMousePosition());
+        wxRect rect(wxPoint(0,0), GetSize());
+
+        if ( rect.Inside(pos) )
+        {
+            if ( m_child->HasCapture() )
+            {
+                m_child->ReleaseMouse();
+            }
+        }
+        else
+        {
+            if ( !m_child->HasCapture() )
+            {
+                m_child->CaptureMouse();
+            }
+        }                
+    }
+}
+#endif
+
+
 #if wxUSE_COMBOBOX && defined(__WXUNIVERSAL__)
 
 // ----------------------------------------------------------------------------