Fancy/optimized EnsureVisible method that eliminates flicker.

Minor cleanups.
This commit is contained in:
Dimitrie O. Paun 2002-10-02 23:45:50 +00:00 committed by Alexandre Julliard
parent f9c011193e
commit 91d41c7fe3
1 changed files with 54 additions and 121 deletions

View File

@ -750,7 +750,7 @@ static inline LRESULT CallWindowProcT(WNDPROC proc, HWND hwnd, UINT uMsg,
} while (0) } while (0)
#define LISTVIEW_InvalidateList(infoPtr)\ #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) static inline BOOL LISTVIEW_GetItemW(LISTVIEW_INFO *infoPtr, LPLVITEMW lpLVItem, BOOL internal)
{ {
@ -1009,6 +1009,8 @@ static void LISTVIEW_UpdateHeaderSize(LISTVIEW_INFO *infoPtr, INT nNewScrollPos)
RECT winRect; RECT winRect;
POINT point[2]; POINT point[2];
TRACE("nNewScrollPos=%d", nNewScrollPos);
GetWindowRect(infoPtr->hwndHeader, &winRect); GetWindowRect(infoPtr->hwndHeader, &winRect);
point[0].x = winRect.left; point[0].x = winRect.left;
point[0].y = winRect.top; point[0].y = winRect.top;
@ -2937,12 +2939,10 @@ static INT LISTVIEW_GetTopIndex(LISTVIEW_INFO *infoPtr)
static inline BOOL LISTVIEW_FillBkgnd(LISTVIEW_INFO *infoPtr, HDC hdc, const RECT* lprcBox) static inline BOOL LISTVIEW_FillBkgnd(LISTVIEW_INFO *infoPtr, HDC hdc, const RECT* lprcBox)
{ {
if (!infoPtr->hBkBrush) return FALSE; 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 HWND LISTVIEW_EditLabelT(LISTVIEW_INFO *infoPtr, INT nItem, BOOL isW)
*/ */
static BOOL LISTVIEW_EnsureVisible(LISTVIEW_INFO *infoPtr, INT nItem, BOOL bPartial) static BOOL LISTVIEW_EnsureVisible(LISTVIEW_INFO *infoPtr, INT nItem, BOOL bPartial)
{ {
UINT uView = LISTVIEW_GetType(infoPtr); UINT uView = LISTVIEW_GetType(infoPtr);
INT nScrollPosHeight = 0; INT nScrollPosHeight = 0;
INT nScrollPosWidth = 0; INT nScrollPosWidth = 0;
SCROLLINFO scrollInfo; INT nPartialAdjust = 0;
RECT rcItem; INT nHorzDiff = 0;
BOOL bRedraw = FALSE; INT nVertDiff = 0;
RECT rcItem;
scrollInfo.cbSize = sizeof(SCROLLINFO); /* FIXME: ALWAYS bPartial == FALSE, FOR NOW! */
scrollInfo.fMask = SIF_POS;
/* ALWAYS bPartial == FALSE, FOR NOW! */ rcItem.left = LVIR_BOUNDS;
if (!LISTVIEW_GetItemRect(infoPtr, nItem, &rcItem)) return FALSE;
rcItem.left = LVIR_BOUNDS;
if (LISTVIEW_GetItemRect(infoPtr, nItem, &rcItem)) if (rcItem.left < infoPtr->rcList.left || rcItem.right > infoPtr->rcList.right)
{
if (rcItem.left < infoPtr->rcList.left)
{ {
if (GetScrollInfo(infoPtr->hwndSelf, SB_HORZ, &scrollInfo)) /* scroll left/right, but in LVS_REPORT mode */
{
/* scroll left */
bRedraw = TRUE;
if (uView == LVS_LIST) if (uView == LVS_LIST)
{ nScrollPosWidth = infoPtr->nItemWidth;
nScrollPosWidth = infoPtr->nItemWidth;
rcItem.left += infoPtr->rcList.left;
}
else if ((uView == LVS_SMALLICON) || (uView == LVS_ICON)) else if ((uView == LVS_SMALLICON) || (uView == LVS_ICON))
{ nScrollPosWidth = 1;
nScrollPosWidth = 1;
rcItem.left += infoPtr->rcList.left;
}
/* When in LVS_REPORT view, the scroll position should if (rcItem.left < infoPtr->rcList.left)
not be updated. */
if (nScrollPosWidth != 0)
{ {
if (rcItem.left % nScrollPosWidth == 0) nPartialAdjust = -1;
scrollInfo.nPos += rcItem.left / nScrollPosWidth; if (uView != LVS_REPORT) nHorzDiff = rcItem.left + infoPtr->rcList.left;
else
scrollInfo.nPos += rcItem.left / nScrollPosWidth - 1;
SetScrollInfo(infoPtr->hwndSelf, SB_HORZ, &scrollInfo, TRUE);
} }
} else
}
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)
{ {
if (rcItem.right % nScrollPosWidth == 0) nPartialAdjust = 1;
scrollInfo.nPos += rcItem.right / nScrollPosWidth; if (uView != LVS_REPORT) nHorzDiff = rcItem.right - infoPtr->rcList.right;
else
scrollInfo.nPos += rcItem.right / nScrollPosWidth + 1;
SetScrollInfo(infoPtr->hwndSelf, SB_HORZ, &scrollInfo, TRUE);
} }
}
} }
if (rcItem.top < infoPtr->rcList.top) if (rcItem.top < infoPtr->rcList.top || rcItem.bottom > infoPtr->rcList.bottom)
{ {
/* scroll up */ /* scroll up/down, but not in LVS_LIST mode */
bRedraw = TRUE;
if (GetScrollInfo(infoPtr->hwndSelf, SB_VERT, &scrollInfo))
{
if (uView == LVS_REPORT) if (uView == LVS_REPORT)
{ nScrollPosHeight = infoPtr->nItemHeight;
rcItem.top -= infoPtr->rcList.top;
nScrollPosHeight = infoPtr->nItemHeight;
}
else if ((uView == LVS_ICON) || (uView == LVS_SMALLICON)) else if ((uView == LVS_ICON) || (uView == LVS_SMALLICON))
{ nScrollPosHeight = 1;
nScrollPosHeight = 1;
rcItem.top += infoPtr->rcList.top;
}
if (nScrollPosHeight) if (rcItem.top < infoPtr->rcList.top)
{ {
if (rcItem.top % nScrollPosHeight == 0) nPartialAdjust = -1;
scrollInfo.nPos += rcItem.top / nScrollPosHeight; if (uView != LVS_LIST) nVertDiff = rcItem.top + infoPtr->rcList.top;
else }
scrollInfo.nPos += rcItem.top / nScrollPosHeight - 1; else
{
SetScrollInfo(infoPtr->hwndSelf, SB_VERT, &scrollInfo, TRUE); nPartialAdjust = 1;
if (uView != LVS_LIST) nVertDiff = rcItem.bottom - infoPtr->rcList.bottom;
} }
}
} }
else if (rcItem.bottom > infoPtr->rcList.bottom)
if (!nScrollPosWidth && !nScrollPosHeight) return TRUE;
if (nScrollPosWidth)
{ {
/* scroll down */ INT diff = nHorzDiff / nScrollPosWidth;
bRedraw = TRUE; if (rcItem.left % nScrollPosWidth) diff += nPartialAdjust;
if (GetScrollInfo(infoPtr->hwndSelf, SB_VERT, &scrollInfo)) LISTVIEW_HScroll(infoPtr, SB_INTERNAL, diff, 0);
{
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;
SetScrollInfo(infoPtr->hwndSelf, SB_VERT, &scrollInfo, TRUE);
}
}
} }
}
if(bRedraw) LISTVIEW_InvalidateList(infoPtr); if (nScrollPosHeight)
{
return TRUE; INT diff = nVertDiff / nScrollPosHeight;
if (rcItem.top % nScrollPosHeight) diff += nPartialAdjust;
LISTVIEW_VScroll(infoPtr, SB_INTERNAL, diff, 0);
}
return TRUE;
} }
/*** /***