For wxMSW capture and release the mouse as the cursor moves out or

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
This commit is contained in:
Robin Dunn
2005-04-15 03:04:30 +00:00
parent 4249e33407
commit 414f2513fc
3 changed files with 102 additions and 20 deletions

View File

@@ -127,6 +127,11 @@ protected:
// get alerted when child gets deleted from under us // get alerted when child gets deleted from under us
void OnDestroy(wxWindowDestroyEvent& event); 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 // the child of this popup if any
wxWindow *m_child; wxWindow *m_child;
@@ -141,6 +146,7 @@ protected:
wxPopupWindowHandler *m_handlerPopup; wxPopupWindowHandler *m_handlerPopup;
wxPopupFocusHandler *m_handlerFocus; wxPopupFocusHandler *m_handlerFocus;
DECLARE_EVENT_TABLE()
DECLARE_DYNAMIC_CLASS(wxPopupTransientWindow) DECLARE_DYNAMIC_CLASS(wxPopupTransientWindow)
DECLARE_NO_COPY_CLASS(wxPopupTransientWindow) DECLARE_NO_COPY_CLASS(wxPopupTransientWindow)
}; };

View File

@@ -81,6 +81,7 @@ private:
wxScrolledWindow *m_panel; wxScrolledWindow *m_panel;
wxButton *m_button; wxButton *m_button;
wxSpinCtrl *m_spinCtrl; wxSpinCtrl *m_spinCtrl;
wxStaticText *m_mouseText;
private: private:
void OnMouse( wxMouseEvent &event ); 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 // 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 // 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 // under the cursor, the m_panel is set focus in the Popup() function
//m_panel->Connect(wxEVT_MOTION, m_panel->Connect(wxEVT_MOTION,
// wxMouseEventHandler(SimpleTransientPopup::OnMouse), wxMouseEventHandler(SimpleTransientPopup::OnMouse),
// NULL, this); NULL, this);
wxStaticText *text = new wxStaticText( m_panel, wxID_ANY, wxStaticText *text = new wxStaticText( m_panel, wxID_ANY,
wxT("wx.PopupTransientWindow is a\n") wxT("wx.PopupTransientWindow is a\n")
@@ -128,16 +129,23 @@ SimpleTransientPopup::SimpleTransientPopup( wxWindow *parent )
wxT("automatically when the user\n") wxT("automatically when the user\n")
wxT("clicks the mouse outside it or if it\n") wxT("clicks the mouse outside it or if it\n")
wxT("(or its first child) loses focus in \n") wxT("(or its first child) loses focus in \n")
wxT("any other way."), wxPoint( 10,10) ); wxT("any other way.") );
wxSize size = text->GetBestSize();
m_button = new wxButton(m_panel, Minimal_PopupButton, wxT("Press Me"), wxPoint(0, size.y + 10)); m_button = new wxButton(m_panel, Minimal_PopupButton, wxT("Press Me"));
size.y = m_button->GetRect().GetBottom(); m_spinCtrl = new wxSpinCtrl(m_panel, Minimal_PopupSpinctrl, wxT("Hello"));
m_spinCtrl = new wxSpinCtrl(m_panel, Minimal_PopupSpinctrl, wxT("Hello"), wxPoint(0, size.y + 5)); m_mouseText = new wxStaticText(m_panel, wxID_ANY,
size.y = m_spinCtrl->GetRect().GetBottom(); wxT("<- Test Mouse ->"));
m_panel->SetSize( size.x+20, size.y+20 ); wxBoxSizer *topSizer = new wxBoxSizer( wxVERTICAL );
SetClientSize( size.x+20, size.y+20 ); 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() SimpleTransientPopup::~SimpleTransientPopup()
@@ -187,7 +195,22 @@ void SimpleTransientPopup::OnKillFocus(wxFocusEvent &event)
void SimpleTransientPopup::OnMouse(wxMouseEvent &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()); 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(); event.Skip();
} }
@@ -317,6 +340,12 @@ MyFrame::MyFrame(const wxString& title)
SetMenuBar(menuBar); SetMenuBar(menuBar);
#endif // wxUSE_MENUS #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); wxPanel *panel = new wxPanel(this, -1);
wxButton *button1 = new wxButton( panel, Minimal_StartSimplePopup, wxT("Show simple popup"), wxPoint(20,20) ); 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) ); 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->SetAutoLayout( true );
panel->SetSizer( topSizer ); 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() MyFrame::~MyFrame()

View File

@@ -110,6 +110,12 @@ BEGIN_EVENT_TABLE(wxPopupFocusHandler, wxEvtHandler)
EVT_KEY_DOWN(wxPopupFocusHandler::OnKeyDown) EVT_KEY_DOWN(wxPopupFocusHandler::OnKeyDown)
END_EVENT_TABLE() END_EVENT_TABLE()
BEGIN_EVENT_TABLE(wxPopupTransientWindow, wxPopupWindow)
#ifdef __WXMSW__
EVT_IDLE(wxPopupTransientWindow::OnIdle)
#endif
END_EVENT_TABLE()
// ============================================================================ // ============================================================================
// implementation // implementation
// ============================================================================ // ============================================================================
@@ -199,7 +205,10 @@ void wxPopupTransientWindow::PopHandlers()
// handler - so don't risk deleting it second time // handler - so don't risk deleting it second time
m_handlerPopup = NULL; m_handlerPopup = NULL;
} }
if (m_child->HasCapture())
{
m_child->ReleaseMouse();
}
m_child = NULL; m_child = NULL;
} }
@@ -303,6 +312,13 @@ bool wxPopupTransientWindow::Show( bool show )
} }
#endif #endif
#ifdef __WXMSW__
if (!show && m_child && m_child->HasCapture())
{
m_child->ReleaseMouse();
}
#endif
bool ret = wxPopupWindow::Show( show ); bool ret = wxPopupWindow::Show( show );
#ifdef __WXGTK__ #ifdef __WXGTK__
@@ -337,20 +353,27 @@ bool wxPopupTransientWindow::Show( bool show )
CurrentTime ); CurrentTime );
} }
#endif #endif
#ifdef __WXMSW__
if (show && m_child)
{
// Assume that the mouse is outside the popup to begin with
m_child->CaptureMouse();
}
#endif
return ret; return ret;
} }
void wxPopupTransientWindow::Dismiss() void wxPopupTransientWindow::Dismiss()
{ {
PopHandlers();
Hide(); Hide();
PopHandlers();
} }
void wxPopupTransientWindow::DismissAndNotify() void wxPopupTransientWindow::DismissAndNotify()
{ {
Dismiss(); Dismiss();
OnDismiss(); OnDismiss();
} }
@@ -373,6 +396,35 @@ void wxPopupTransientWindow::OnDestroy(wxWindowDestroyEvent& event)
m_focus = NULL; 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__) #if wxUSE_COMBOBOX && defined(__WXUNIVERSAL__)
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------