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:
@@ -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)
|
||||
};
|
||||
|
@@ -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()
|
||||
|
@@ -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__)
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
Reference in New Issue
Block a user