Owen Rudge : comctl32: Move marquee logic into separate function.
Alexandre Julliard
julliard at winehq.org
Wed Nov 4 10:26:23 CST 2009
Module: wine
Branch: master
Commit: 038e36aded6d06c42dee6c08777c519cb97c2014
URL: http://source.winehq.org/git/wine.git/?a=commit;h=038e36aded6d06c42dee6c08777c519cb97c2014
Author: Owen Rudge <orudge at 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;
}
More information about the wine-cvs
mailing list