Module: wine Branch: master Commit: 038e36aded6d06c42dee6c08777c519cb97c2014 URL: http://source.winehq.org/git/wine.git/?a=commit;h=038e36aded6d06c42dee6c0877...
Author: Owen Rudge orudge@codeweavers.com Date: Mon Nov 2 10:57:52 2009 -0600
comctl32: Move marquee logic into separate function.
---
dlls/comctl32/listview.c | 210 ++++++++++++++++++++++++++++------------------ 1 files changed, 127 insertions(+), 83 deletions(-)
diff --git a/dlls/comctl32/listview.c b/dlls/comctl32/listview.c index 4bedd89..415a863 100644 --- a/dlls/comctl32/listview.c +++ b/dlls/comctl32/listview.c @@ -249,7 +249,9 @@ typedef struct tagLISTVIEW_INFO BOOL bRButtonDown; BOOL bDragging; BOOL bMarqueeSelect; /* marquee selection/highlight underway */ - RECT marqueeRect; + RECT marqueeRect; /* absolute coordinates of marquee selection */ + RECT marqueeDrawRect; /* relative coordinates for drawing marquee */ + POINT marqueeOrigin; /* absolute coordinates of marquee click origin */ POINT ptClickPos; /* point where the user clicked */ BOOL bNoItemMetrics; /* flags if item metrics are not yet computed */ INT nItemHeight; @@ -3595,6 +3597,103 @@ static LRESULT LISTVIEW_MouseHover(LISTVIEW_INFO *infoPtr, WORD fwKeys, INT x, I
/*** * DESCRIPTION: + * Utility routine to draw and highlight items within a marquee selection rectangle. + * + * PARAMETER(S): + * [I] infoPtr : valid pointer to the listview structure + * [I] coords_orig : original co-ordinates of the cursor + * [I] coords_offs : offsetted coordinates of the cursor + * [I] offset : offset amount + * [I] scroll : Bitmask of which directions we should scroll, if at all + * + * RETURN: + * None. + */ +static void LISTVIEW_MarqueeHighlight(LISTVIEW_INFO *infoPtr, LPPOINT coords_orig, LPPOINT coords_offs, LPPOINT offset, INT scroll) +{ + BOOL controlDown = FALSE; + LVITEMW item; + ITERATOR i; + RECT rect; + + if (coords_offs->x > infoPtr->marqueeOrigin.x) + { + rect.left = infoPtr->marqueeOrigin.x; + rect.right = coords_offs->x; + } + else + { + rect.left = coords_offs->x; + rect.right = infoPtr->marqueeOrigin.x; + } + + if (coords_offs->y > infoPtr->marqueeOrigin.y) + { + rect.top = infoPtr->marqueeOrigin.y; + rect.bottom = coords_offs->y; + } + else + { + rect.top = coords_offs->y; + rect.bottom = infoPtr->marqueeOrigin.y; + } + + /* Cancel out the old marquee rectangle and draw the new one */ + LISTVIEW_InvalidateRect(infoPtr, &infoPtr->marqueeDrawRect); + + /* 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); + + 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); + + if (GetKeyState(VK_CONTROL) & 0x8000) + controlDown = TRUE; + + while (iterator_next(&i)) + { + if (i.nItem > -1) + { + /* If CTRL is pressed, invert. If not, always select the item. */ + if ((controlDown) && (LISTVIEW_GetItemState(infoPtr, i.nItem, LVIS_SELECTED))) + item.state = 0; + else + item.state = LVIS_SELECTED; + + item.stateMask = LVIS_SELECTED; + + LISTVIEW_SetItemState(infoPtr, i.nItem, &item); + } + } + + iterator_destroy(&i); + LISTVIEW_InvalidateRect(infoPtr, &rect); +} + +/*** + * DESCRIPTION: * Called whenever WM_MOUSEMOVE is received. * * PARAMETER(S): @@ -3620,93 +3719,27 @@ static LRESULT LISTVIEW_MouseMove(LISTVIEW_INFO *infoPtr, WORD fwKeys, INT x, IN WORD wDragWidth = GetSystemMetrics(SM_CXDRAG); WORD wDragHeight= GetSystemMetrics(SM_CYDRAG);
- /* Ensure coordinates are within client bounds */ - if (x < 0) - x = 0; - - if (y < 0) - y = 0; - - if (x > infoPtr->rcList.right) - x = infoPtr->rcList.right; - - if (y > infoPtr->rcList.bottom) - y = infoPtr->rcList.bottom; - if (infoPtr->bMarqueeSelect) { - LVITEMW item; - ITERATOR i; - - if (x > infoPtr->ptClickPos.x) - { - rect.left = infoPtr->ptClickPos.x; - rect.right = x; - } - else - { - rect.left = x; - rect.right = infoPtr->ptClickPos.x; - } - - if (y > infoPtr->ptClickPos.y) - { - rect.top = infoPtr->ptClickPos.y; - rect.bottom = y; - } - else - { - rect.top = y; - rect.bottom = infoPtr->ptClickPos.y; - } - - /* Cancel out the old marquee rectangle and draw the new one */ - LISTVIEW_InvalidateRect(infoPtr, &infoPtr->marqueeRect); - - /* Invert the items in the old marquee rectangle */ - iterator_frameditems(&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); + POINT coords_orig; + POINT coords_offs; + POINT offset;
- CopyRect(&infoPtr->marqueeRect, &rect); + coords_orig.x = x; + coords_orig.y = y;
- /* Iterate over the items within our marquee rectangle */ - iterator_frameditems(&i, infoPtr, &rect); + /* Get offset */ + LISTVIEW_GetOrigin(infoPtr, &offset);
- while (iterator_next(&i)) - { - if (i.nItem > -1) - { - /* If CTRL is pressed, invert. If not, always select the item. */ - if ((fwKeys & MK_CONTROL) && (LISTVIEW_GetItemState(infoPtr, i.nItem, LVIS_SELECTED))) - item.state = 0; - else - item.state = LVIS_SELECTED; + /* Ensure coordinates are within client bounds */ + coords_offs.x = max(min(x, infoPtr->rcList.right), 0); + coords_offs.y = max(min(y, infoPtr->rcList.bottom), 0);
- item.stateMask = LVIS_SELECTED; + /* Offset coordinates by the appropriate amount */ + coords_offs.x -= offset.x; + coords_offs.y -= offset.y;
- LISTVIEW_SetItemState(infoPtr, i.nItem, &item); - } - } - - iterator_destroy(&i); - - LISTVIEW_InvalidateRect(infoPtr, &rect); + LISTVIEW_MarqueeHighlight(infoPtr, &coords_orig, &coords_offs, &offset, 0); return 0; }
@@ -3758,6 +3791,14 @@ static LRESULT LISTVIEW_MouseMove(LISTVIEW_INFO *infoPtr, WORD fwKeys, INT x, IN If return value is non-zero, cancel. */ if (!(infoPtr->dwStyle & LVS_SINGLESEL) && (notify_hdr(infoPtr, LVN_MARQUEEBEGIN, &hdr) == 0)) { + /* Store the absolute coordinates of the click */ + POINT offset; + LISTVIEW_GetOrigin(infoPtr, &offset); + + infoPtr->marqueeOrigin.x = infoPtr->ptClickPos.x - offset.x; + infoPtr->marqueeOrigin.y = infoPtr->ptClickPos.y - offset.y; + + /* Begin selection and capture mouse */ infoPtr->bMarqueeSelect = TRUE; SetCapture(infoPtr->hwndSelf); } @@ -4767,7 +4808,7 @@ enddraw:
/* Draw marquee rectangle if appropriate */ if (infoPtr->bMarqueeSelect) - DrawFocusRect(hdc, &infoPtr->marqueeRect); + DrawFocusRect(hdc, &infoPtr->marqueeDrawRect);
if (cdmode & CDRF_NOTIFYPOSTPAINT) notify_postpaint(infoPtr, &nmlvcd); @@ -9621,14 +9662,17 @@ static LRESULT LISTVIEW_LButtonUp(LISTVIEW_INFO *infoPtr, WORD wKey, INT x, INT /* Remove the marquee rectangle and release our mouse capture */ if (infoPtr->bMarqueeSelect) { - LISTVIEW_InvalidateRect(infoPtr, &infoPtr->marqueeRect); + LISTVIEW_InvalidateRect(infoPtr, &infoPtr->marqueeDrawRect); ReleaseCapture(); }
SetRect(&infoPtr->marqueeRect, 0, 0, 0, 0); + SetRect(&infoPtr->marqueeDrawRect, 0, 0, 0, 0);
infoPtr->bDragging = FALSE; infoPtr->bMarqueeSelect = FALSE; + + KillTimer(infoPtr->hwndSelf, (UINT_PTR) infoPtr); return 0; }