mirror of
https://github.com/reactos/wine.git
synced 2024-12-03 01:12:25 +00:00
comctl32: Implement highlighting (marquee) selection support in listview.
This commit is contained in:
parent
cc4a6693f1
commit
69b76a18fb
@ -7,6 +7,7 @@
|
|||||||
* Copyright 2001 CodeWeavers Inc.
|
* Copyright 2001 CodeWeavers Inc.
|
||||||
* Copyright 2002 Dimitrie O. Paun
|
* Copyright 2002 Dimitrie O. Paun
|
||||||
* Copyright 2009 Nikolay Sivov
|
* Copyright 2009 Nikolay Sivov
|
||||||
|
* Copyright 2009 Owen Rudge for CodeWeavers
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
@ -98,7 +99,6 @@
|
|||||||
* -- LVN_BEGINSCROLL, LVN_ENDSCROLL
|
* -- LVN_BEGINSCROLL, LVN_ENDSCROLL
|
||||||
* -- LVN_GETINFOTIP
|
* -- LVN_GETINFOTIP
|
||||||
* -- LVN_HOTTRACK
|
* -- LVN_HOTTRACK
|
||||||
* -- LVN_MARQUEEBEGIN
|
|
||||||
* -- LVN_SETDISPINFO
|
* -- LVN_SETDISPINFO
|
||||||
* -- NM_HOVER
|
* -- NM_HOVER
|
||||||
* -- LVN_BEGINRDRAG
|
* -- LVN_BEGINRDRAG
|
||||||
@ -248,6 +248,8 @@ typedef struct tagLISTVIEW_INFO
|
|||||||
BOOL bLButtonDown;
|
BOOL bLButtonDown;
|
||||||
BOOL bRButtonDown;
|
BOOL bRButtonDown;
|
||||||
BOOL bDragging;
|
BOOL bDragging;
|
||||||
|
BOOL bMarqueeSelect; /* marquee selection/highlight underway */
|
||||||
|
RECT marqueeRect;
|
||||||
POINT ptClickPos; /* point where the user clicked */
|
POINT ptClickPos; /* point where the user clicked */
|
||||||
BOOL bNoItemMetrics; /* flags if item metrics are not yet computed */
|
BOOL bNoItemMetrics; /* flags if item metrics are not yet computed */
|
||||||
INT nItemHeight;
|
INT nItemHeight;
|
||||||
@ -3605,17 +3607,94 @@ static LRESULT LISTVIEW_MouseMove(LISTVIEW_INFO *infoPtr, WORD fwKeys, INT x, IN
|
|||||||
WORD wDragWidth = GetSystemMetrics(SM_CXDRAG);
|
WORD wDragWidth = GetSystemMetrics(SM_CXDRAG);
|
||||||
WORD wDragHeight= GetSystemMetrics(SM_CYDRAG);
|
WORD wDragHeight= GetSystemMetrics(SM_CYDRAG);
|
||||||
|
|
||||||
rect.left = infoPtr->ptClickPos.x - wDragWidth;
|
|
||||||
rect.right = infoPtr->ptClickPos.x + wDragWidth;
|
|
||||||
rect.top = infoPtr->ptClickPos.y - wDragHeight;
|
|
||||||
rect.bottom = infoPtr->ptClickPos.y + wDragHeight;
|
|
||||||
|
|
||||||
tmp.x = x;
|
tmp.x = x;
|
||||||
tmp.y = y;
|
tmp.y = y;
|
||||||
|
|
||||||
lvHitTestInfo.pt = tmp;
|
lvHitTestInfo.pt = tmp;
|
||||||
LISTVIEW_HitTest(infoPtr, &lvHitTestInfo, TRUE, TRUE);
|
LISTVIEW_HitTest(infoPtr, &lvHitTestInfo, TRUE, TRUE);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
CopyRect(&infoPtr->marqueeRect, &rect);
|
||||||
|
|
||||||
|
/* Iterate over the items within our marquee rectangle */
|
||||||
|
iterator_frameditems(&i, infoPtr, &rect);
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
item.stateMask = LVIS_SELECTED;
|
||||||
|
|
||||||
|
LISTVIEW_SetItemState(infoPtr, i.nItem, &item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
iterator_destroy(&i);
|
||||||
|
|
||||||
|
LISTVIEW_InvalidateRect(infoPtr, &rect);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
rect.left = infoPtr->ptClickPos.x - wDragWidth;
|
||||||
|
rect.right = infoPtr->ptClickPos.x + wDragWidth;
|
||||||
|
rect.top = infoPtr->ptClickPos.y - wDragHeight;
|
||||||
|
rect.bottom = infoPtr->ptClickPos.y + wDragHeight;
|
||||||
|
|
||||||
/* reset item marker */
|
/* reset item marker */
|
||||||
if (infoPtr->nLButtonDownItem != lvHitTestInfo.iItem)
|
if (infoPtr->nLButtonDownItem != lvHitTestInfo.iItem)
|
||||||
infoPtr->nLButtonDownItem = -1;
|
infoPtr->nLButtonDownItem = -1;
|
||||||
@ -3640,17 +3719,31 @@ static LRESULT LISTVIEW_MouseMove(LISTVIEW_INFO *infoPtr, WORD fwKeys, INT x, IN
|
|||||||
|
|
||||||
if (!infoPtr->bDragging)
|
if (!infoPtr->bDragging)
|
||||||
{
|
{
|
||||||
NMLISTVIEW nmlv;
|
|
||||||
|
|
||||||
lvHitTestInfo.pt = infoPtr->ptClickPos;
|
lvHitTestInfo.pt = infoPtr->ptClickPos;
|
||||||
LISTVIEW_HitTest(infoPtr, &lvHitTestInfo, TRUE, TRUE);
|
LISTVIEW_HitTest(infoPtr, &lvHitTestInfo, TRUE, TRUE);
|
||||||
|
|
||||||
ZeroMemory(&nmlv, sizeof(nmlv));
|
/* If the click is outside the range of an item, begin a
|
||||||
nmlv.iItem = lvHitTestInfo.iItem;
|
highlight. If not, begin an item drag. */
|
||||||
nmlv.ptAction = infoPtr->ptClickPos;
|
if (lvHitTestInfo.iItem == -1)
|
||||||
|
{
|
||||||
|
NMHDR hdr;
|
||||||
|
|
||||||
notify_listview(infoPtr, LVN_BEGINDRAG, &nmlv);
|
/* If we're allowing multiple selections, send notification.
|
||||||
infoPtr->bDragging = TRUE;
|
If return value is non-zero, cancel. */
|
||||||
|
if (!(infoPtr->dwStyle & LVS_SINGLESEL) && (notify_hdr(infoPtr, LVN_MARQUEEBEGIN, &hdr) == 0))
|
||||||
|
infoPtr->bMarqueeSelect = TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NMLISTVIEW nmlv;
|
||||||
|
|
||||||
|
ZeroMemory(&nmlv, sizeof(nmlv));
|
||||||
|
nmlv.iItem = lvHitTestInfo.iItem;
|
||||||
|
nmlv.ptAction = infoPtr->ptClickPos;
|
||||||
|
|
||||||
|
notify_listview(infoPtr, LVN_BEGINDRAG, &nmlv);
|
||||||
|
infoPtr->bDragging = TRUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -4643,6 +4736,10 @@ enddraw:
|
|||||||
if ((infoPtr->uView == LV_VIEW_DETAILS) && infoPtr->dwLvExStyle & LVS_EX_GRIDLINES)
|
if ((infoPtr->uView == LV_VIEW_DETAILS) && infoPtr->dwLvExStyle & LVS_EX_GRIDLINES)
|
||||||
LISTVIEW_RefreshReportGrid(infoPtr, hdc);
|
LISTVIEW_RefreshReportGrid(infoPtr, hdc);
|
||||||
|
|
||||||
|
/* Draw marquee rectangle if appropriate */
|
||||||
|
if (infoPtr->bMarqueeSelect)
|
||||||
|
DrawFocusRect(hdc, &infoPtr->marqueeRect);
|
||||||
|
|
||||||
if (cdmode & CDRF_NOTIFYPOSTPAINT)
|
if (cdmode & CDRF_NOTIFYPOSTPAINT)
|
||||||
notify_postpaint(infoPtr, &nmlvcd);
|
notify_postpaint(infoPtr, &nmlvcd);
|
||||||
|
|
||||||
@ -9312,6 +9409,7 @@ static LRESULT LISTVIEW_LButtonDown(LISTVIEW_INFO *infoPtr, WORD wKey, INT x, IN
|
|||||||
infoPtr->bLButtonDown = TRUE;
|
infoPtr->bLButtonDown = TRUE;
|
||||||
infoPtr->ptClickPos = pt;
|
infoPtr->ptClickPos = pt;
|
||||||
infoPtr->bDragging = FALSE;
|
infoPtr->bDragging = FALSE;
|
||||||
|
infoPtr->bMarqueeSelect = FALSE;
|
||||||
|
|
||||||
lvHitTestInfo.pt.x = x;
|
lvHitTestInfo.pt.x = x;
|
||||||
lvHitTestInfo.pt.y = y;
|
lvHitTestInfo.pt.y = y;
|
||||||
@ -9433,9 +9531,16 @@ static LRESULT LISTVIEW_LButtonUp(LISTVIEW_INFO *infoPtr, WORD wKey, INT x, INT
|
|||||||
LISTVIEW_SetSelection(infoPtr, infoPtr->nLButtonDownItem);
|
LISTVIEW_SetSelection(infoPtr, infoPtr->nLButtonDownItem);
|
||||||
infoPtr->nLButtonDownItem = -1;
|
infoPtr->nLButtonDownItem = -1;
|
||||||
|
|
||||||
if (infoPtr->bDragging)
|
if (infoPtr->bDragging || infoPtr->bMarqueeSelect)
|
||||||
{
|
{
|
||||||
|
/* Remove the marquee rectangle */
|
||||||
|
if (infoPtr->bMarqueeSelect)
|
||||||
|
LISTVIEW_InvalidateRect(infoPtr, &infoPtr->marqueeRect);
|
||||||
|
|
||||||
|
SetRect(&infoPtr->marqueeRect, 0, 0, 0, 0);
|
||||||
|
|
||||||
infoPtr->bDragging = FALSE;
|
infoPtr->bDragging = FALSE;
|
||||||
|
infoPtr->bMarqueeSelect = FALSE;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user