Merge branch 'search-events'

Harmonize the behaviour across platforms.

Also fix ChangeValue() for this control.

And finally rename the events to use simpler names.

See https://github.com/wxWidgets/wxWidgets/pull/699
This commit is contained in:
Vadim Zeitlin
2018-01-30 14:12:30 +01:00
10 changed files with 150 additions and 91 deletions

View File

@@ -178,6 +178,8 @@ All (GUI):
- Add Set/GetFooter/Text/Icon() to wxRichMessageDialog (Tobias Taschner)
- Add wxFloatingPointValidator::SetFactor().
- Add "hint" property to wxSearchCtrl XRC handler.
- Add wxEVT_SEARCH[_CANCEL] synonyms for wxSearchCtrl events.
- Generate wxEVT_SEARCH on Enter under all platforms.
wxGTK:

View File

@@ -193,7 +193,10 @@ private:
if ( child == this )
return; // not a child, we don't want to Connect() to ourselves
// Always capture wxEVT_KILL_FOCUS:
child->Connect(wxEVT_SET_FOCUS,
wxFocusEventHandler(wxCompositeWindow::OnSetFocus),
NULL, this);
child->Connect(wxEVT_KILL_FOCUS,
wxFocusEventHandler(wxCompositeWindow::OnKillFocus),
NULL, this);
@@ -221,6 +224,27 @@ private:
event.Skip();
}
void OnSetFocus(wxFocusEvent& event)
{
event.Skip();
// When a child of a composite window gains focus, the entire composite
// focus gains focus as well -- unless it had it already.
//
// We suppose that we hadn't had focus if the event doesn't carry the
// previously focused window as it normally means that it comes from
// outside of this program.
wxWindow* const oldFocus = event.GetWindow();
if ( !oldFocus || oldFocus->GetMainWindowOfCompositeControl() != this )
{
wxFocusEvent eventThis(wxEVT_SET_FOCUS, this->GetId());
eventThis.SetEventObject(this);
eventThis.SetWindow(event.GetWindow());
this->ProcessWindowEvent(eventThis);
}
}
void OnKillFocus(wxFocusEvent& event)
{
// Ignore focus changes within the composite control:

View File

@@ -88,6 +88,8 @@ public:
// operations
// ----------
virtual void ChangeValue(const wxString& value) wxOVERRIDE;
// editing
virtual void Clear() wxOVERRIDE;
virtual void Replace(long from, long to, const wxString& value) wxOVERRIDE;
@@ -223,7 +225,6 @@ protected:
void OnCancelButton( wxCommandEvent& event );
void OnSetFocus( wxFocusEvent& event );
void OnSize( wxSizeEvent& event );
bool HasMenu() const

View File

@@ -41,8 +41,8 @@
extern WXDLLIMPEXP_DATA_CORE(const char) wxSearchCtrlNameStr[];
wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_CORE, wxEVT_SEARCHCTRL_CANCEL_BTN, wxCommandEvent);
wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_CORE, wxEVT_SEARCHCTRL_SEARCH_BTN, wxCommandEvent);
wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_CORE, wxEVT_SEARCH_CANCEL, wxCommandEvent);
wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_CORE, wxEVT_SEARCH, wxCommandEvent);
// ----------------------------------------------------------------------------
// a search ctrl is a text control with a search button and a cancel button
@@ -90,13 +90,20 @@ private:
// macros for handling search events
// ----------------------------------------------------------------------------
#define EVT_SEARCHCTRL_CANCEL_BTN(id, fn) \
wx__DECLARE_EVT1(wxEVT_SEARCHCTRL_CANCEL_BTN, id, wxCommandEventHandler(fn))
#define EVT_SEARCH_CANCEL(id, fn) \
wx__DECLARE_EVT1(wxEVT_SEARCH_CANCEL, id, wxCommandEventHandler(fn))
#define EVT_SEARCHCTRL_SEARCH_BTN(id, fn) \
wx__DECLARE_EVT1(wxEVT_SEARCHCTRL_SEARCH_BTN, id, wxCommandEventHandler(fn))
#define EVT_SEARCH(id, fn) \
wx__DECLARE_EVT1(wxEVT_SEARCH, id, wxCommandEventHandler(fn))
// old wxEVT_COMMAND_* constants
// old synonyms
#define wxEVT_SEARCHCTRL_CANCEL_BTN wxEVT_SEARCH_CANCEL
#define wxEVT_SEARCHCTRL_SEARCH_BTN wxEVT_SEARCH
#define EVT_SEARCHCTRL_CANCEL_BTN(id, fn) EVT_SEARCH_CANCEL(id, fn)
#define EVT_SEARCHCTRL_SEARCH_BTN(id, fn) EVT_SEARCH(id, fn)
// even older wxEVT_COMMAND_* constants
#define wxEVT_COMMAND_SEARCHCTRL_CANCEL_BTN wxEVT_SEARCHCTRL_CANCEL_BTN
#define wxEVT_COMMAND_SEARCHCTRL_SEARCH_BTN wxEVT_SEARCHCTRL_SEARCH_BTN

View File

@@ -12,10 +12,6 @@
control, and a cancel button.
@beginStyleTable
@style{wxTE_PROCESS_ENTER}
The control will generate the event @c wxEVT_TEXT_ENTER
(otherwise pressing Enter key is either processed internally by the
control or used for navigation between dialog controls).
@style{wxTE_PROCESS_TAB}
The control will receive @c wxEVT_CHAR events for TAB pressed -
normally, TAB is used for passing to the next control in a dialog
@@ -39,16 +35,19 @@
@endStyleTable
@beginEventEmissionTable{wxCommandEvent}
To retrieve actual search queries, use EVT_TEXT and EVT_TEXT_ENTER events,
just as you would with wxTextCtrl.
@event{EVT_SEARCHCTRL_SEARCH_BTN(id, func)}
Respond to a @c wxEVT_SEARCHCTRL_SEARCH_BTN event, generated when the
To react to the changes in the control contents, use wxEVT_TEXT event, just
as you would do with wxTextCtrl. However it is recommended to use
wxEVT_SEARCH to actually start searching to avoid doing it too soon, while
the user is still typing (note that wxEVT_SEARCH is also triggered by
pressing Enter in the control).
@event{EVT_SEARCH(id, func)}
Respond to a @c wxEVT_SEARCH event, generated when the
search button is clicked. Note that this does not initiate a search on
its own, you need to perform the appropriate action in your event
handler. You may use @code event.GetString() @endcode to retrieve the
string to search for in the event handler code.
@event{EVT_SEARCHCTRL_CANCEL_BTN(id, func)}
Respond to a @c wxEVT_SEARCHCTRL_CANCEL_BTN event, generated when the
@event{EVT_SEARCH_CANCEL(id, func)}
Respond to a @c wxEVT_SEARCH_CANCEL event, generated when the
cancel button is clicked.
@endEventTable
@@ -56,7 +55,7 @@
@category{ctrl}
@appearance{searchctrl}
@see wxTextCtrl::Create, wxValidator
@see wxTextCtrl
*/
class wxSearchCtrl : public wxTextCtrl
{
@@ -162,5 +161,5 @@ public:
};
wxEventType wxEVT_SEARCHCTRL_CANCEL_BTN;
wxEventType wxEVT_SEARCHCTRL_SEARCH_BTN;
wxEventType wxEVT_SEARCH_CANCEL;
wxEventType wxEVT_SEARCH;

View File

@@ -83,9 +83,15 @@ protected:
void OnToggleCancelButton(wxCommandEvent&);
void OnToggleSearchMenu(wxCommandEvent&);
void OnText(wxCommandEvent& event);
void OnTextEnter(wxCommandEvent& event);
void OnSearch(wxCommandEvent& event);
void OnSearchCancel(wxCommandEvent& event);
void OnSetFocus(wxFocusEvent& event);
void OnKillFocus(wxFocusEvent& event);
wxMenu* CreateTestMenu();
// (re)create the control
@@ -111,8 +117,11 @@ wxBEGIN_EVENT_TABLE(SearchCtrlWidgetsPage, WidgetsPage)
EVT_CHECKBOX(ID_CANCEL_CB, SearchCtrlWidgetsPage::OnToggleCancelButton)
EVT_CHECKBOX(ID_MENU_CB, SearchCtrlWidgetsPage::OnToggleSearchMenu)
EVT_SEARCHCTRL_SEARCH_BTN(wxID_ANY, SearchCtrlWidgetsPage::OnSearch)
EVT_SEARCHCTRL_CANCEL_BTN(wxID_ANY, SearchCtrlWidgetsPage::OnSearchCancel)
EVT_TEXT(wxID_ANY, SearchCtrlWidgetsPage::OnText)
EVT_TEXT_ENTER(wxID_ANY, SearchCtrlWidgetsPage::OnTextEnter)
EVT_SEARCH(wxID_ANY, SearchCtrlWidgetsPage::OnSearch)
EVT_SEARCH_CANCEL(wxID_ANY, SearchCtrlWidgetsPage::OnSearchCancel)
wxEND_EVENT_TABLE()
// ============================================================================
@@ -171,6 +180,9 @@ void SearchCtrlWidgetsPage::CreateControl()
m_srchCtrl = new wxSearchCtrl(this, -1, wxEmptyString, wxDefaultPosition,
wxSize(150, -1), style);
m_srchCtrl->Bind(wxEVT_SET_FOCUS, &SearchCtrlWidgetsPage::OnSetFocus, this);
m_srchCtrl->Bind(wxEVT_KILL_FOCUS, &SearchCtrlWidgetsPage::OnKillFocus, this);
}
void SearchCtrlWidgetsPage::RecreateWidget()
@@ -227,6 +239,18 @@ void SearchCtrlWidgetsPage::OnToggleSearchMenu(wxCommandEvent&)
m_srchCtrl->SetMenu(NULL);
}
void SearchCtrlWidgetsPage::OnText(wxCommandEvent& event)
{
wxLogMessage("Search control: text changes, contents is \"%s\".",
event.GetString());
}
void SearchCtrlWidgetsPage::OnTextEnter(wxCommandEvent& event)
{
wxLogMessage("Search control: enter pressed, contents is \"%s\".",
event.GetString());
}
void SearchCtrlWidgetsPage::OnSearch(wxCommandEvent& event)
{
wxLogMessage("Search button: search for \"%s\".", event.GetString());
@@ -239,4 +263,18 @@ void SearchCtrlWidgetsPage::OnSearchCancel(wxCommandEvent& event)
event.Skip();
}
void SearchCtrlWidgetsPage::OnSetFocus(wxFocusEvent& event)
{
wxLogMessage("Search control got focus");
event.Skip();
}
void SearchCtrlWidgetsPage::OnKillFocus(wxFocusEvent& event)
{
wxLogMessage("Search control lost focus");
event.Skip();
}
#endif // wxUSE_SEARCHCTRL

View File

@@ -34,8 +34,8 @@
const char wxSearchCtrlNameStr[] = "searchCtrl";
wxDEFINE_EVENT(wxEVT_SEARCHCTRL_CANCEL_BTN, wxCommandEvent);
wxDEFINE_EVENT(wxEVT_SEARCHCTRL_SEARCH_BTN, wxCommandEvent);
wxDEFINE_EVENT(wxEVT_SEARCH_CANCEL, wxCommandEvent);
wxDEFINE_EVENT(wxEVT_SEARCH, wxCommandEvent);
#endif // wxUSE_SEARCHCTRL

View File

@@ -92,19 +92,16 @@ protected:
m_search->GetEventHandler()->ProcessEvent(event);
}
void OnTextUrl(wxTextUrlEvent& eventText)
void OnTextEnter(wxCommandEvent& WXUNUSED(event))
{
// copy constructor is disabled for some reason?
//wxTextUrlEvent event(eventText);
wxTextUrlEvent event(
m_search->GetId(),
eventText.GetMouseEvent(),
eventText.GetURLStart(),
eventText.GetURLEnd()
);
event.SetEventObject(m_search);
if ( !IsEmpty() )
{
wxCommandEvent event(wxEVT_SEARCH, m_search->GetId());
event.SetEventObject(m_search);
event.SetString(m_search->GetValue());
m_search->GetEventHandler()->ProcessEvent(event);
m_search->ProcessWindowEvent(event);
}
}
#ifdef __WXMSW__
@@ -149,8 +146,7 @@ private:
wxBEGIN_EVENT_TABLE(wxSearchTextCtrl, wxTextCtrl)
EVT_TEXT(wxID_ANY, wxSearchTextCtrl::OnText)
EVT_TEXT_ENTER(wxID_ANY, wxSearchTextCtrl::OnText)
EVT_TEXT_URL(wxID_ANY, wxSearchTextCtrl::OnTextUrl)
EVT_TEXT_ENTER(wxID_ANY, wxSearchTextCtrl::OnTextEnter)
EVT_TEXT_MAXLEN(wxID_ANY, wxSearchTextCtrl::OnText)
wxEND_EVENT_TABLE()
@@ -166,7 +162,9 @@ public:
m_search(search),
m_eventType(eventType),
m_bmp(bmp)
{ }
{
SetBackgroundStyle(wxBG_STYLE_PAINT);
}
void SetBitmapLabel(const wxBitmap& label)
{
@@ -198,7 +196,7 @@ protected:
wxCommandEvent event(m_eventType, m_search->GetId());
event.SetEventObject(m_search);
if ( m_eventType == wxEVT_SEARCHCTRL_SEARCH_BTN )
if ( m_eventType == wxEVT_SEARCH )
{
// it's convenient to have the string to search for directly in the
// event instead of having to retrieve it from the control in the
@@ -211,7 +209,7 @@ protected:
m_search->SetFocus();
#if wxUSE_MENUS
if ( m_eventType == wxEVT_SEARCHCTRL_SEARCH_BTN )
if ( m_eventType == wxEVT_SEARCH )
{
// this happens automatically, just like on Mac OS X
m_search->PopupSearchMenu();
@@ -240,8 +238,7 @@ wxBEGIN_EVENT_TABLE(wxSearchButton, wxControl)
wxEND_EVENT_TABLE()
wxBEGIN_EVENT_TABLE(wxSearchCtrl, wxSearchCtrlBase)
EVT_SEARCHCTRL_CANCEL_BTN(wxID_ANY, wxSearchCtrl::OnCancelButton)
EVT_SET_FOCUS(wxSearchCtrl::OnSetFocus)
EVT_SEARCH_CANCEL(wxID_ANY, wxSearchCtrl::OnCancelButton)
EVT_SIZE(wxSearchCtrl::OnSize)
wxEND_EVENT_TABLE()
@@ -325,10 +322,10 @@ bool wxSearchCtrl::Create(wxWindow *parent, wxWindowID id,
m_text = new wxSearchTextCtrl(this, value, style);
m_searchButton = new wxSearchButton(this,
wxEVT_SEARCHCTRL_SEARCH_BTN,
wxEVT_SEARCH,
m_searchBitmap);
m_cancelButton = new wxSearchButton(this,
wxEVT_SEARCHCTRL_CANCEL_BTN,
wxEVT_SEARCH_CANCEL,
m_cancelBitmap);
SetBackgroundColour( m_text->GetBackgroundColour() );
@@ -916,6 +913,14 @@ wxTextCtrl& operator<<(double d);
wxTextCtrl& operator<<(const wxChar c);
#endif
// Note that overriding DoSetValue() is currently insufficient because the base
// class ChangeValue() only updates m_hintData of this object (which is null
// anyhow), instead of updating m_text->m_hintData, see #16998.
void wxSearchCtrl::ChangeValue(const wxString& value)
{
m_text->ChangeValue(value);
}
void wxSearchCtrl::DoSetValue(const wxString& value, int flags)
{
m_text->DoSetValue(value, flags);
@@ -1235,14 +1240,6 @@ void wxSearchCtrl::OnCancelButton( wxCommandEvent& event )
event.Skip();
}
void wxSearchCtrl::OnSetFocus( wxFocusEvent& /*event*/ )
{
if ( m_text )
{
m_text->SetFocus();
}
}
void wxSearchCtrl::OnSize( wxSizeEvent& WXUNUSED(event) )
{
LayoutControls();

View File

@@ -209,7 +209,7 @@ bool wxSearchCtrl::Create(wxWindow *parent, wxWindowID id,
bool wxSearchCtrl::HandleSearchFieldSearchHit()
{
wxCommandEvent event(wxEVT_SEARCHCTRL_SEARCH_BTN, m_windowId );
wxCommandEvent event(wxEVT_SEARCH, m_windowId );
event.SetEventObject(this);
// provide the string to search for directly in the event, this is more
@@ -221,7 +221,7 @@ bool wxSearchCtrl::HandleSearchFieldSearchHit()
bool wxSearchCtrl::HandleSearchFieldCancelHit()
{
wxCommandEvent event(wxEVT_SEARCHCTRL_CANCEL_BTN, m_windowId );
wxCommandEvent event(wxEVT_SEARCH_CANCEL, m_windowId );
event.SetEventObject(this);
return ProcessCommand(event);
}

View File

@@ -20,50 +20,41 @@
#include "wx/srchctrl.h"
class SearchCtrlTestCase : public CppUnit::TestCase
class SearchCtrlTestCase
{
public:
SearchCtrlTestCase() { }
SearchCtrlTestCase()
: m_search(new wxSearchCtrl(wxTheApp->GetTopWindow(), wxID_ANY))
{
}
virtual void setUp();
virtual void tearDown();
~SearchCtrlTestCase()
{
delete m_search;
}
private:
CPPUNIT_TEST_SUITE( SearchCtrlTestCase );
CPPUNIT_TEST( Focus );
CPPUNIT_TEST_SUITE_END();
void Focus();
wxSearchCtrl* m_search;
wxDECLARE_NO_COPY_CLASS(SearchCtrlTestCase);
protected:
wxSearchCtrl* const m_search;
};
// register in the unnamed registry so that these tests are run by default
CPPUNIT_TEST_SUITE_REGISTRATION( SearchCtrlTestCase );
#define SEARCH_CTRL_TEST_CASE(name, tags) \
TEST_CASE_METHOD(SearchCtrlTestCase, name, tags)
// also include in its own registry so that these tests can be run alone
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( SearchCtrlTestCase, "SearchCtrlTestCase" );
void SearchCtrlTestCase::setUp()
{
m_search = new wxSearchCtrl(wxTheApp->GetTopWindow(), wxID_ANY);
}
void SearchCtrlTestCase::tearDown()
{
delete m_search;
m_search = NULL;
}
void SearchCtrlTestCase::Focus()
{
// TODO OS X test only passes when run solo ...
// TODO OS X test only passes when run solo ...
#ifndef __WXOSX__
SEARCH_CTRL_TEST_CASE("wxSearchCtrl::Focus", "[wxSearchCtrl][focus]")
{
m_search->SetFocus();
CPPUNIT_ASSERT( m_search->HasFocus() );
#endif
CHECK( m_search->HasFocus() );
}
#endif // !__WXOSX__
SEARCH_CTRL_TEST_CASE("wxSearchCtrl::ChangeValue", "[wxSearchCtrl][text]")
{
CHECK( m_search->GetValue() == wxString() );
m_search->ChangeValue("foo");
CHECK( m_search->GetValue() == "foo" );
}
#endif // wxUSE_SEARCHCTRL