Improve selection and focus events generation in wxGenericLisCtrl
Avoid sending spurious wxEVT_LIST_ITEM_{FOCUSED, SELECTED, DESELECTED} events and make the generic version consistent with the behaviour of the native wxMSW one. Also add/extend the tests and slightly improve the sample. Closes https://github.com/wxWidgets/wxWidgets/pull/2044
This commit is contained in:
committed by
Vadim Zeitlin
parent
80a3cd2db9
commit
fedc80eee3
@@ -26,6 +26,7 @@
|
||||
#include "wx/uiaction.h"
|
||||
#include "wx/imaglist.h"
|
||||
#include "wx/artprov.h"
|
||||
#include "wx/stopwatch.h"
|
||||
|
||||
void ListBaseTestCase::ColumnsOrder()
|
||||
{
|
||||
@@ -177,6 +178,123 @@ void ListBaseTestCase::ChangeMode()
|
||||
CPPUNIT_ASSERT_EQUAL( "First", list->GetItemText(0) );
|
||||
}
|
||||
|
||||
#ifdef __WXGTK__
|
||||
#define wxGTK_TIMED_YIELD(t) \
|
||||
if ( !IsRunningUnderXVFB() ) \
|
||||
for ( wxStopWatch sw; sw.Time() < t; ) wxYield()
|
||||
#else // !__WXGTK__
|
||||
#define wxGTK_TIMED_YIELD(t)
|
||||
#endif // __WXGTK__
|
||||
|
||||
void ListBaseTestCase::MultiSelect()
|
||||
{
|
||||
#if wxUSE_UIACTIONSIMULATOR
|
||||
|
||||
#ifndef __WXMSW__
|
||||
// FIXME: This test fails on Travis CI although works fine on
|
||||
// development machine, no idea why though!
|
||||
if ( IsAutomaticTest() )
|
||||
return;
|
||||
#endif // !__WXMSW__
|
||||
|
||||
wxListCtrl* const list = GetList();
|
||||
|
||||
EventCounter focused(list, wxEVT_LIST_ITEM_FOCUSED);
|
||||
EventCounter selected(list, wxEVT_LIST_ITEM_SELECTED);
|
||||
EventCounter deselected(list, wxEVT_LIST_ITEM_DESELECTED);
|
||||
|
||||
list->InsertColumn(0, "Header");
|
||||
|
||||
for ( int i = 0; i < 10; ++i )
|
||||
list->InsertItem(i, wxString::Format("Item %d", i));
|
||||
|
||||
wxUIActionSimulator sim;
|
||||
|
||||
wxRect pos;
|
||||
list->GetItemRect(2, pos); // Choose the third item as anchor
|
||||
|
||||
// We move in slightly so we are not on the edge
|
||||
wxPoint point = list->ClientToScreen(pos.GetPosition()) + wxPoint(10, 10);
|
||||
|
||||
sim.MouseMove(point);
|
||||
wxYield();
|
||||
|
||||
sim.MouseClick(); // select the anchor
|
||||
wxYield();
|
||||
|
||||
wxGTK_TIMED_YIELD(50);
|
||||
|
||||
list->GetItemRect(5, pos);
|
||||
point = list->ClientToScreen(pos.GetPosition()) + wxPoint(10, 10);
|
||||
|
||||
sim.MouseMove(point);
|
||||
wxYield();
|
||||
|
||||
sim.KeyDown(WXK_SHIFT);
|
||||
sim.MouseClick();
|
||||
sim.KeyUp(WXK_SHIFT);
|
||||
wxYield();
|
||||
|
||||
wxGTK_TIMED_YIELD(10);
|
||||
|
||||
// when the first item was selected the focus changes to it, but not
|
||||
// on subsequent clicks
|
||||
CPPUNIT_ASSERT_EQUAL(4, list->GetSelectedItemCount()); // item 2 to 5 (inclusive) are selected
|
||||
CPPUNIT_ASSERT_EQUAL(2, focused.GetCount()); // count the focus which was on the anchor
|
||||
CPPUNIT_ASSERT_EQUAL(4, selected.GetCount());
|
||||
CPPUNIT_ASSERT_EQUAL(0, deselected.GetCount());
|
||||
|
||||
focused.Clear();
|
||||
selected.Clear();
|
||||
deselected.Clear();
|
||||
|
||||
sim.Char(WXK_END, wxMOD_SHIFT); // extend the selection to the last item
|
||||
wxYield();
|
||||
|
||||
wxGTK_TIMED_YIELD(10);
|
||||
|
||||
CPPUNIT_ASSERT_EQUAL(8, list->GetSelectedItemCount()); // item 2 to 9 (inclusive) are selected
|
||||
CPPUNIT_ASSERT_EQUAL(1, focused.GetCount()); // focus is on the last item
|
||||
CPPUNIT_ASSERT_EQUAL(4, selected.GetCount()); // only newly selected items got the event
|
||||
CPPUNIT_ASSERT_EQUAL(0, deselected.GetCount());
|
||||
|
||||
focused.Clear();
|
||||
selected.Clear();
|
||||
deselected.Clear();
|
||||
|
||||
sim.Char(WXK_HOME, wxMOD_SHIFT); // select from anchor to the first item
|
||||
wxYield();
|
||||
|
||||
wxGTK_TIMED_YIELD(10);
|
||||
|
||||
CPPUNIT_ASSERT_EQUAL(3, list->GetSelectedItemCount()); // item 0 to 2 (inclusive) are selected
|
||||
CPPUNIT_ASSERT_EQUAL(1, focused.GetCount()); // focus is on item 0
|
||||
CPPUNIT_ASSERT_EQUAL(2, selected.GetCount()); // events are only generated for item 0 and 1
|
||||
CPPUNIT_ASSERT_EQUAL(7, deselected.GetCount()); // item 2 (exclusive) to 9 are deselected
|
||||
|
||||
focused.Clear();
|
||||
selected.Clear();
|
||||
deselected.Clear();
|
||||
|
||||
list->EnsureVisible(0);
|
||||
wxYield();
|
||||
|
||||
list->GetItemRect(2, pos);
|
||||
point = list->ClientToScreen(pos.GetPosition()) + wxPoint(10, 10);
|
||||
|
||||
sim.MouseMove(point);
|
||||
wxYield();
|
||||
|
||||
sim.MouseClick();
|
||||
wxYield();
|
||||
|
||||
CPPUNIT_ASSERT_EQUAL(1, list->GetSelectedItemCount()); // anchor is the only selected item
|
||||
CPPUNIT_ASSERT_EQUAL(1, focused.GetCount()); // because the focus changed from item 0 to anchor
|
||||
CPPUNIT_ASSERT_EQUAL(0, selected.GetCount()); // anchor is already in selection state
|
||||
CPPUNIT_ASSERT_EQUAL(2, deselected.GetCount()); // items 0 and 1 are deselected
|
||||
#endif // wxUSE_UIACTIONSIMULATOR
|
||||
}
|
||||
|
||||
void ListBaseTestCase::ItemClick()
|
||||
{
|
||||
#if wxUSE_UIACTIONSIMULATOR
|
||||
@@ -236,16 +354,9 @@ void ListBaseTestCase::ItemClick()
|
||||
|
||||
// when the first item was selected the focus changes to it, but not
|
||||
// on subsequent clicks
|
||||
|
||||
// FIXME: This test fail under wxGTK & wxOSX because we get 3 FOCUSED events and
|
||||
// 2 SELECTED ones instead of the one of each we expect for some
|
||||
// reason, this needs to be debugged as it may indicate a bug in the
|
||||
// generic wxListCtrl implementation.
|
||||
#ifndef _WX_GENERIC_LISTCTRL_H_
|
||||
CPPUNIT_ASSERT_EQUAL(1, focused.GetCount());
|
||||
CPPUNIT_ASSERT_EQUAL(1, selected.GetCount());
|
||||
CPPUNIT_ASSERT_EQUAL(1, deselected.GetCount());
|
||||
#endif
|
||||
CPPUNIT_ASSERT_EQUAL(1, activated.GetCount());
|
||||
CPPUNIT_ASSERT_EQUAL(1, rclick.GetCount());
|
||||
#endif // wxUSE_UIACTIONSIMULATOR
|
||||
|
Reference in New Issue
Block a user