Listview updates (J3)
Dimitrie O. Paun
dpaun at rogers.com
Wed Oct 2 12:46:11 CDT 2002
Relative to J2.
This one eliminates the flicker we had in REPORT mode on
every mouse click.
ChangeLog
Fancy/optimized EnsureVisible method that eliminates flicker.
Minor cleanups.
--- dlls/comctl32/listview.c.J2 Wed Oct 2 02:05:13 2002
+++ dlls/comctl32/listview.c Wed Oct 2 13:43:06 2002
@@ -750,7 +750,7 @@
} while (0)
#define LISTVIEW_InvalidateList(infoPtr)\
- LISTVIEW_InvalidateRect(infoPtr, NULL)
+ LISTVIEW_InvalidateRect(infoPtr, &infoPtr->rcList)
static inline BOOL LISTVIEW_GetItemW(LISTVIEW_INFO *infoPtr, LPLVITEMW lpLVItem, BOOL internal)
{
@@ -1009,6 +1009,8 @@
RECT winRect;
POINT point[2];
+ TRACE("nNewScrollPos=%d", nNewScrollPos);
+
GetWindowRect(infoPtr->hwndHeader, &winRect);
point[0].x = winRect.left;
point[0].y = winRect.top;
@@ -2937,12 +2939,10 @@
static inline BOOL LISTVIEW_FillBkgnd(LISTVIEW_INFO *infoPtr, HDC hdc, const RECT* lprcBox)
{
if (!infoPtr->hBkBrush) return FALSE;
- FillRect(hdc, lprcBox, infoPtr->hBkBrush);
- TRACE("filling (%d,%d)-(%d,%d) using brush %x\n",
- lprcBox->left, lprcBox->top, lprcBox->right, lprcBox->bottom,
- infoPtr->hBkBrush);
- return TRUE;
+ TRACE("(hdc=%x, lprcBox=%s, hBkBrush=%x)\n", hdc, debugrect(lprcBox), infoPtr->hBkBrush);
+
+ return FillRect(hdc, lprcBox, infoPtr->hBkBrush);
}
/***
@@ -4379,143 +4379,76 @@
*/
static BOOL LISTVIEW_EnsureVisible(LISTVIEW_INFO *infoPtr, INT nItem, BOOL bPartial)
{
- UINT uView = LISTVIEW_GetType(infoPtr);
- INT nScrollPosHeight = 0;
- INT nScrollPosWidth = 0;
- SCROLLINFO scrollInfo;
- RECT rcItem;
- BOOL bRedraw = FALSE;
-
- scrollInfo.cbSize = sizeof(SCROLLINFO);
- scrollInfo.fMask = SIF_POS;
+ UINT uView = LISTVIEW_GetType(infoPtr);
+ INT nScrollPosHeight = 0;
+ INT nScrollPosWidth = 0;
+ INT nPartialAdjust = 0;
+ INT nHorzDiff = 0;
+ INT nVertDiff = 0;
+ RECT rcItem;
- /* ALWAYS bPartial == FALSE, FOR NOW! */
+ /* FIXME: ALWAYS bPartial == FALSE, FOR NOW! */
- rcItem.left = LVIR_BOUNDS;
- if (LISTVIEW_GetItemRect(infoPtr, nItem, &rcItem))
- {
- if (rcItem.left < infoPtr->rcList.left)
+ rcItem.left = LVIR_BOUNDS;
+ if (!LISTVIEW_GetItemRect(infoPtr, nItem, &rcItem)) return FALSE;
+
+ if (rcItem.left < infoPtr->rcList.left || rcItem.right > infoPtr->rcList.right)
{
- if (GetScrollInfo(infoPtr->hwndSelf, SB_HORZ, &scrollInfo))
- {
- /* scroll left */
- bRedraw = TRUE;
+ /* scroll left/right, but in LVS_REPORT mode */
if (uView == LVS_LIST)
- {
- nScrollPosWidth = infoPtr->nItemWidth;
- rcItem.left += infoPtr->rcList.left;
- }
+ nScrollPosWidth = infoPtr->nItemWidth;
else if ((uView == LVS_SMALLICON) || (uView == LVS_ICON))
- {
- nScrollPosWidth = 1;
- rcItem.left += infoPtr->rcList.left;
- }
+ nScrollPosWidth = 1;
- /* When in LVS_REPORT view, the scroll position should
- not be updated. */
- if (nScrollPosWidth != 0)
+ if (rcItem.left < infoPtr->rcList.left)
{
- if (rcItem.left % nScrollPosWidth == 0)
- scrollInfo.nPos += rcItem.left / nScrollPosWidth;
- else
- scrollInfo.nPos += rcItem.left / nScrollPosWidth - 1;
-
- SetScrollInfo(infoPtr->hwndSelf, SB_HORZ, &scrollInfo, TRUE);
+ nPartialAdjust = -1;
+ if (uView != LVS_REPORT) nHorzDiff = rcItem.left + infoPtr->rcList.left;
}
- }
- }
- else if (rcItem.right > infoPtr->rcList.right)
- {
- if (GetScrollInfo(infoPtr->hwndSelf, SB_HORZ, &scrollInfo))
- {
- /* scroll right */
- bRedraw = TRUE;
- if (uView == LVS_LIST)
- {
- rcItem.right -= infoPtr->rcList.right;
- nScrollPosWidth = infoPtr->nItemWidth;
- }
- else if ((uView == LVS_SMALLICON) || (uView == LVS_ICON))
- {
- rcItem.right -= infoPtr->rcList.right;
- nScrollPosWidth = 1;
- }
-
- /* When in LVS_REPORT view, the scroll position should
- not be updated. */
- if (nScrollPosWidth != 0)
+ else
{
- if (rcItem.right % nScrollPosWidth == 0)
- scrollInfo.nPos += rcItem.right / nScrollPosWidth;
- else
- scrollInfo.nPos += rcItem.right / nScrollPosWidth + 1;
-
- SetScrollInfo(infoPtr->hwndSelf, SB_HORZ, &scrollInfo, TRUE);
+ nPartialAdjust = 1;
+ if (uView != LVS_REPORT) nHorzDiff = rcItem.right - infoPtr->rcList.right;
}
- }
}
- if (rcItem.top < infoPtr->rcList.top)
+ if (rcItem.top < infoPtr->rcList.top || rcItem.bottom > infoPtr->rcList.bottom)
{
- /* scroll up */
- bRedraw = TRUE;
- if (GetScrollInfo(infoPtr->hwndSelf, SB_VERT, &scrollInfo))
- {
+ /* scroll up/down, but not in LVS_LIST mode */
if (uView == LVS_REPORT)
- {
- rcItem.top -= infoPtr->rcList.top;
- nScrollPosHeight = infoPtr->nItemHeight;
- }
+ nScrollPosHeight = infoPtr->nItemHeight;
else if ((uView == LVS_ICON) || (uView == LVS_SMALLICON))
- {
- nScrollPosHeight = 1;
- rcItem.top += infoPtr->rcList.top;
- }
+ nScrollPosHeight = 1;
- if (nScrollPosHeight)
+ if (rcItem.top < infoPtr->rcList.top)
{
- if (rcItem.top % nScrollPosHeight == 0)
- scrollInfo.nPos += rcItem.top / nScrollPosHeight;
- else
- scrollInfo.nPos += rcItem.top / nScrollPosHeight - 1;
-
- SetScrollInfo(infoPtr->hwndSelf, SB_VERT, &scrollInfo, TRUE);
+ nPartialAdjust = -1;
+ if (uView != LVS_LIST) nVertDiff = rcItem.top + infoPtr->rcList.top;
+ }
+ else
+ {
+ nPartialAdjust = 1;
+ if (uView != LVS_LIST) nVertDiff = rcItem.bottom - infoPtr->rcList.bottom;
}
- }
}
- else if (rcItem.bottom > infoPtr->rcList.bottom)
- {
- /* scroll down */
- bRedraw = TRUE;
- if (GetScrollInfo(infoPtr->hwndSelf, SB_VERT, &scrollInfo))
- {
- if (uView == LVS_REPORT)
- {
- rcItem.bottom -= infoPtr->rcList.bottom;
- nScrollPosHeight = infoPtr->nItemHeight;
- }
- else if ((uView == LVS_ICON) || (uView == LVS_SMALLICON))
- {
- nScrollPosHeight = 1;
- rcItem.bottom -= infoPtr->rcList.bottom;
- }
- if (nScrollPosHeight)
- {
- if (rcItem.bottom % nScrollPosHeight == 0)
- scrollInfo.nPos += rcItem.bottom / nScrollPosHeight;
- else
- scrollInfo.nPos += rcItem.bottom / nScrollPosHeight + 1;
+ if (!nScrollPosWidth && !nScrollPosHeight) return TRUE;
- SetScrollInfo(infoPtr->hwndSelf, SB_VERT, &scrollInfo, TRUE);
- }
- }
+ if (nScrollPosWidth)
+ {
+ INT diff = nHorzDiff / nScrollPosWidth;
+ if (rcItem.left % nScrollPosWidth) diff += nPartialAdjust;
+ LISTVIEW_HScroll(infoPtr, SB_INTERNAL, diff, 0);
}
- }
- if(bRedraw) LISTVIEW_InvalidateList(infoPtr);
-
- return TRUE;
+ if (nScrollPosHeight)
+ {
+ INT diff = nVertDiff / nScrollPosHeight;
+ if (rcItem.top % nScrollPosHeight) diff += nPartialAdjust;
+ LISTVIEW_VScroll(infoPtr, SB_INTERNAL, diff, 0);
+ }
+
+ return TRUE;
}
/***
More information about the wine-patches
mailing list