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:
ali kettab
2020-09-06 00:53:45 +01:00
committed by Vadim Zeitlin
parent 80a3cd2db9
commit fedc80eee3
6 changed files with 432 additions and 99 deletions

View File

@@ -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