eliminated flicker when selecting items

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@11214 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2001-07-30 13:47:22 +00:00
parent 78bcfcfcb6
commit 68a9ef0ef0

View File

@@ -8,16 +8,6 @@
// Licence: wxWindows licence // Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
/*
FIXME for virtual list controls
+1. clicking on the item with a mouse is awfully slow, what is going on?
note that selecting with keyboard seems to be much faster
=> fixed HighlightAll() - iterating over 1000000 items *is* slow
2. background colour is wrong?
*/
/* /*
TODO for better virtual list control support: TODO for better virtual list control support:
@@ -175,7 +165,14 @@ public:
bool SelectItem(size_t item, bool select = TRUE); bool SelectItem(size_t item, bool select = TRUE);
// select the range of items // select the range of items
void SelectRange(size_t itemFrom, size_t itemTo, bool select = TRUE); //
// return true and fill the itemsChanged array with the indices of items
// which have changed state if "few" of them did, otherwise return false
// (meaning that too many items changed state to bother counting them
// individually)
bool SelectRange(size_t itemFrom, size_t itemTo,
bool select = TRUE,
wxArrayInt *itemsChanged = NULL);
// return true if the given item is selected // return true if the given item is selected
bool IsSelected(size_t item) const; bool IsSelected(size_t item) const;
@@ -895,8 +892,15 @@ bool wxSelectionStore::SelectItem(size_t item, bool select)
return FALSE; return FALSE;
} }
void wxSelectionStore::SelectRange(size_t itemFrom, size_t itemTo, bool select) bool wxSelectionStore::SelectRange(size_t itemFrom, size_t itemTo,
bool select,
wxArrayInt *itemsChanged)
{ {
// 100 is hardcoded but it shouldn't matter much: the important thing is
// that we don't refresh everything when really few (e.g. 1 or 2) items
// change state
static const size_t MANY_ITEMS = 100;
wxASSERT_MSG( itemFrom <= itemTo, _T("should be in order") ); wxASSERT_MSG( itemFrom <= itemTo, _T("should be in order") );
// are we going to have more [un]selected items than the other ones? // are we going to have more [un]selected items than the other ones?
@@ -927,6 +931,9 @@ void wxSelectionStore::SelectRange(size_t itemFrom, size_t itemTo, bool select)
if ( selOld.Index(item) == wxNOT_FOUND ) if ( selOld.Index(item) == wxNOT_FOUND )
m_itemsSel.Add(item); m_itemsSel.Add(item);
} }
// many items (> half) changed state
itemsChanged = NULL;
} }
else // select == m_defaultState else // select == m_defaultState
{ {
@@ -950,6 +957,17 @@ void wxSelectionStore::SelectRange(size_t itemFrom, size_t itemTo, bool select)
// delete all of them (from end to avoid changing indices) // delete all of them (from end to avoid changing indices)
for ( int i = end; i >= (int)start; i-- ) for ( int i = end; i >= (int)start; i-- )
{ {
if ( itemsChanged )
{
if ( itemsChanged->GetCount() > MANY_ITEMS )
{
// stop counting (see comment below)
itemsChanged = NULL;
}
itemsChanged->Add(m_itemsSel[i]);
}
m_itemsSel.RemoveAt(i); m_itemsSel.RemoveAt(i);
} }
} }
@@ -957,13 +975,32 @@ void wxSelectionStore::SelectRange(size_t itemFrom, size_t itemTo, bool select)
} }
else // "few" items change state else // "few" items change state
{ {
if ( itemsChanged )
{
itemsChanged->Empty();
}
// just add the items to the selection // just add the items to the selection
for ( size_t item = itemFrom; item <= itemTo; item++ ) for ( size_t item = itemFrom; item <= itemTo; item++ )
{ {
SelectItem(item, select); if ( SelectItem(item, select) && itemsChanged )
{
itemsChanged->Add(item);
if ( itemsChanged->GetCount() > MANY_ITEMS )
{
// stop counting them, we'll just eat gobs of memory
// for nothing at all - faster to refresh everything in
// this case
itemsChanged = NULL;
} }
} }
} }
}
// we set it to NULL if there are many items changing state
return itemsChanged != NULL;
}
void wxSelectionStore::OnItemDelete(size_t item) void wxSelectionStore::OnItemDelete(size_t item)
{ {
@@ -2346,25 +2383,37 @@ bool wxListMainWindow::IsHighlighted(size_t line) const
} }
} }
void wxListMainWindow::HighlightLines( size_t lineFrom, size_t lineTo, bool highlight ) void wxListMainWindow::HighlightLines( size_t lineFrom,
size_t lineTo,
bool highlight )
{ {
if ( IsVirtual() ) if ( IsVirtual() )
{ {
m_selStore.SelectRange(lineFrom, lineTo, highlight); wxArrayInt linesChanged;
if ( !m_selStore.SelectRange(lineFrom, lineTo, highlight,
&linesChanged) )
{
// meny items changed state, refresh everything
RefreshLines(lineFrom, lineTo); RefreshLines(lineFrom, lineTo);
} }
else else // only a few items changed state, refresh only them
{
size_t count = linesChanged.GetCount();
for ( size_t n = 0; n < count; n++ )
{
RefreshLine(linesChanged[n]);
}
}
}
else // iterate over all items in non report view
{ {
// do it the dumb way
bool needsRefresh = FALSE;
for ( size_t line = lineFrom; line <= lineTo; line++ ) for ( size_t line = lineFrom; line <= lineTo; line++ )
{ {
if ( HighlightLine(line, highlight) ) if ( HighlightLine(line, highlight) )
needsRefresh = TRUE; {
RefreshLine(line);
}
} }
if ( needsRefresh )
RefreshLines(lineFrom, lineTo);
} }
} }