comctl32: Improve LISTVIEW_MarqueeHighlight performance.

This commit is contained in:
Piotr Caban 2011-06-06 20:52:34 +02:00 committed by Alexandre Julliard
parent 609602cb38
commit a87e726d6b
1 changed files with 63 additions and 31 deletions

View File

@ -1497,6 +1497,37 @@ static BOOL iterator_visibleitems(ITERATOR *i, const LISTVIEW_INFO *infoPtr, HDC
return TRUE;
}
/* Remove common elements from two iterators */
/* Passed iterators have to point on the first elements */
static BOOL iterator_remove_common_items(ITERATOR *iter1, ITERATOR *iter2)
{
iterator_next(iter1);
iterator_next(iter2);
while(1) {
if(iter1->nItem==-1 || iter2->nItem==-1)
break;
if(iter1->nItem == iter2->nItem) {
int delete = iter1->nItem;
iterator_prev(iter1);
iterator_prev(iter2);
ranges_delitem(iter1->ranges, delete);
ranges_delitem(iter2->ranges, delete);
iterator_next(iter1);
iterator_next(iter2);
} else if(iter1->nItem > iter2->nItem)
iterator_next(iter2);
else
iterator_next(iter1);
}
iter1->nItem = iter1->range.lower = iter1->range.upper = -1;
iter2->nItem = iter2->range.lower = iter2->range.upper = -1;
return TRUE;
}
/******** Misc helper functions ************************************/
static inline LRESULT CallWindowProcT(WNDPROC proc, HWND hwnd, UINT uMsg,
@ -3733,7 +3764,7 @@ static void LISTVIEW_MarqueeHighlight(LISTVIEW_INFO *infoPtr, const POINT *coord
{
BOOL controlDown = FALSE;
LVITEMW item;
ITERATOR i;
ITERATOR old_elems, new_elems;
RECT rect;
if (coords_offs->x > infoPtr->marqueeOrigin.x)
@ -3776,54 +3807,55 @@ static void LISTVIEW_MarqueeHighlight(LISTVIEW_INFO *infoPtr, const POINT *coord
if ((scroll & SCROLL_DOWN) && (coords_orig->y >= infoPtr->rcList.bottom))
LISTVIEW_Scroll(infoPtr, 0, (coords_orig->y - infoPtr->rcList.bottom));
/* Invert the items in the old marquee rectangle */
iterator_frameditems_absolute(&i, infoPtr, &infoPtr->marqueeRect);
while (iterator_next(&i))
{
if (i.nItem > -1)
{
if (LISTVIEW_GetItemState(infoPtr, i.nItem, LVIS_SELECTED) == LVIS_SELECTED)
item.state = 0;
else
item.state = LVIS_SELECTED;
item.stateMask = LVIS_SELECTED;
LISTVIEW_SetItemState(infoPtr, i.nItem, &item);
}
}
iterator_destroy(&i);
iterator_frameditems_absolute(&old_elems, infoPtr, &infoPtr->marqueeRect);
CopyRect(&infoPtr->marqueeRect, &rect);
CopyRect(&infoPtr->marqueeDrawRect, &rect);
OffsetRect(&infoPtr->marqueeDrawRect, offset->x, offset->y);
/* Iterate over the items within our marquee rectangle */
iterator_frameditems_absolute(&i, infoPtr, &infoPtr->marqueeRect);
iterator_frameditems_absolute(&new_elems, infoPtr, &infoPtr->marqueeRect);
iterator_remove_common_items(&old_elems, &new_elems);
if (GetKeyState(VK_CONTROL) & 0x8000)
controlDown = TRUE;
while (iterator_next(&i))
/* Iterate over no longer selected items */
while (iterator_next(&old_elems))
{
if (i.nItem > -1)
if (old_elems.nItem > -1)
{
/* If CTRL is pressed, invert. If not, always select the item. */
if ((controlDown) && (LISTVIEW_GetItemState(infoPtr, i.nItem, LVIS_SELECTED)))
if (LISTVIEW_GetItemState(infoPtr, old_elems.nItem, LVIS_SELECTED) == LVIS_SELECTED)
item.state = 0;
else
item.state = LVIS_SELECTED;
item.stateMask = LVIS_SELECTED;
LISTVIEW_SetItemState(infoPtr, i.nItem, &item);
LISTVIEW_SetItemState(infoPtr, old_elems.nItem, &item);
}
}
iterator_destroy(&old_elems);
/* Iterate over newly selected items */
if (GetKeyState(VK_CONTROL) & 0x8000)
controlDown = TRUE;
while (iterator_next(&new_elems))
{
if (new_elems.nItem > -1)
{
/* If CTRL is pressed, invert. If not, always select the item. */
if ((controlDown) && (LISTVIEW_GetItemState(infoPtr, new_elems.nItem, LVIS_SELECTED)))
item.state = 0;
else
item.state = LVIS_SELECTED;
item.stateMask = LVIS_SELECTED;
LISTVIEW_SetItemState(infoPtr, new_elems.nItem, &item);
}
}
iterator_destroy(&new_elems);
iterator_destroy(&i);
LISTVIEW_InvalidateRect(infoPtr, &rect);
}