implemented calculating of tracking thumb in scrollbars

svn path=/trunk/; revision=6014
This commit is contained in:
Thomas Bluemel 2003-09-08 15:08:56 +00:00
parent eca8e8ad7c
commit 205f58421e
3 changed files with 240 additions and 40 deletions

View file

@ -1,4 +1,4 @@
/* $Id: scrollbar.c,v 1.13 2003/09/08 02:14:20 weiden Exp $ /* $Id: scrollbar.c,v 1.14 2003/09/08 15:08:56 weiden Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -353,22 +353,6 @@ SCROLL_PtInRectEx( LPRECT lpRect, POINT pt, BOOL vertical )
return PtInRect( &rect, pt ); return PtInRect( &rect, pt );
} }
/*
DWORD FASTCALL
SCROLL_HitTest(HWND hwnd, LONG idObject, POINT Point)
{
RECT WindowRect;
GetWindowRect(hwnd, &WindowRect);
if (!PtInRect(&WindowRect, Point))
{
return(SCROLL_NOWHERE);
}
return SCROLL_NOWHERE;
}
*/
DWORD DWORD
SCROLL_HitTest( HWND hwnd, INT nBar, POINT pt, BOOL bDragging ) SCROLL_HitTest( HWND hwnd, INT nBar, POINT pt, BOOL bDragging )
{ {
@ -387,10 +371,12 @@ SCROLL_HitTest( HWND hwnd, INT nBar, POINT pt, BOOL bDragging )
if ( (bDragging && !SCROLL_PtInRectEx( &sbi.rcScrollBar, pt, vertical )) || if ( (bDragging && !SCROLL_PtInRectEx( &sbi.rcScrollBar, pt, vertical )) ||
(!PtInRect( &sbi.rcScrollBar, pt )) ) return SCROLL_NOWHERE; (!PtInRect( &sbi.rcScrollBar, pt )) ) return SCROLL_NOWHERE;
thumbPos = sbi.xyThumbTop;
thumbSize = sbi.xyThumbBottom - thumbPos;
arrowSize = sbi.dxyLineButton;
if (vertical) if (vertical)
{ {
arrowSize = GetSystemMetrics(SM_CYVSCROLL);
if (pt.y < sbi.rcScrollBar.top + arrowSize) return SCROLL_TOP_ARROW; if (pt.y < sbi.rcScrollBar.top + arrowSize) return SCROLL_TOP_ARROW;
if (pt.y >= sbi.rcScrollBar.bottom - arrowSize) return SCROLL_BOTTOM_ARROW; if (pt.y >= sbi.rcScrollBar.bottom - arrowSize) return SCROLL_BOTTOM_ARROW;
if (!thumbPos) return SCROLL_TOP_RECT; if (!thumbPos) return SCROLL_TOP_RECT;
@ -400,7 +386,6 @@ SCROLL_HitTest( HWND hwnd, INT nBar, POINT pt, BOOL bDragging )
} }
else /* horizontal */ else /* horizontal */
{ {
arrowSize = GetSystemMetrics(SM_CXHSCROLL);
if (pt.x < sbi.rcScrollBar.left + arrowSize) return SCROLL_TOP_ARROW; if (pt.x < sbi.rcScrollBar.left + arrowSize) return SCROLL_TOP_ARROW;
if (pt.x >= sbi.rcScrollBar.right - arrowSize) return SCROLL_BOTTOM_ARROW; if (pt.x >= sbi.rcScrollBar.right - arrowSize) return SCROLL_BOTTOM_ARROW;
if (!thumbPos) return SCROLL_TOP_RECT; if (!thumbPos) return SCROLL_TOP_RECT;
@ -416,13 +401,12 @@ SCROLL_HitTest( HWND hwnd, INT nBar, POINT pt, BOOL bDragging )
/* /*
* @unimplemented * @implemented
*/ */
WINBOOL STDCALL WINBOOL STDCALL
EnableScrollBar(HWND hWnd, UINT wSBflags, UINT wArrows) EnableScrollBar(HWND hWnd, UINT wSBflags, UINT wArrows)
{ {
UNIMPLEMENTED; return NtUserEnableScrollBar(hWnd, wSBflags, wArrows);
return FALSE;
} }
@ -444,7 +428,9 @@ GetScrollBarInfo(HWND hwnd, LONG idObject, PSCROLLBARINFO psbi)
RtlCopyMemory(&sbi, psbi, sizeof(SCROLLBARINFO)); RtlCopyMemory(&sbi, psbi, sizeof(SCROLLBARINFO));
ret = NtUserGetScrollBarInfo (hwnd, idObject, psbi); ret = NtUserGetScrollBarInfo (hwnd, idObject, psbi);
if(ret) if(ret)
{
RtlCopyMemory(psbi, &sbi, sizeof(SCROLLBARINFO)); RtlCopyMemory(psbi, &sbi, sizeof(SCROLLBARINFO));
}
return ret; return ret;
} }
@ -484,13 +470,20 @@ GetScrollRange (HWND hWnd, int nBar, LPINT lpMinPos, LPINT lpMaxPos)
/* /*
* @unimplemented * @implemented
*/ */
int STDCALL int STDCALL
SetScrollInfo (HWND hwnd, int fnBar, LPCSCROLLINFO lpsi, WINBOOL fRedraw) SetScrollInfo (HWND hwnd, int fnBar, LPCSCROLLINFO lpsi, WINBOOL fRedraw)
{ {
UNIMPLEMENTED; SCROLLINFO si;
if(!lpsi)
{
SetLastError(ERROR_INVALID_PARAMETER);
return 0; return 0;
}
RtlCopyMemory(&si, lpsi, lpsi->cbSize);
return (int)NtUserSetScrollInfo(hwnd, fnBar, &si, fRedraw);
} }

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
/* $Id: metric.c,v 1.12 2003/08/29 09:29:11 gvg Exp $ /* $Id: metric.c,v 1.13 2003/09/08 15:08:56 weiden Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -113,6 +113,7 @@ NtUserGetSystemMetrics(ULONG Index)
case SM_CXHSCROLL: case SM_CXHSCROLL:
case SM_CYHSCROLL: case SM_CYHSCROLL:
return(16); return(16);
case SM_CYVTHUMB:
case SM_CXHTHUMB: case SM_CXHTHUMB:
return(16); return(16);
case SM_CXICON: case SM_CXICON:
@ -192,7 +193,6 @@ NtUserGetSystemMetrics(ULONG Index)
return(19); return(19);
case SM_CYSMCAPTION: case SM_CYSMCAPTION:
return(16); return(16);
case SM_CYVTHUMB:
case SM_DBCSENABLED: case SM_DBCSENABLED:
case SM_DEBUG: case SM_DEBUG:
case SM_MENUDROPALIGNMENT: case SM_MENUDROPALIGNMENT:

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
/* $Id: scrollbar.c,v 1.11 2003/09/08 02:14:20 weiden Exp $ /* $Id: scrollbar.c,v 1.12 2003/09/08 15:08:56 weiden Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -52,6 +52,55 @@
#define SBRG_PAGEDOWNLEFT 4 /* the page down or page left region */ #define SBRG_PAGEDOWNLEFT 4 /* the page down or page left region */
#define SBRG_BOTTOMLEFTBTN 5 /* the bottom or left button */ #define SBRG_BOTTOMLEFTBTN 5 /* the bottom or left button */
/***********************************************************************
* MulDiv (copied from kernel32)
*/
static INT IntMulDiv(
INT nMultiplicand,
INT nMultiplier,
INT nDivisor)
{
#if SIZEOF_LONG_LONG >= 8
long long ret;
if (!nDivisor) return -1;
/* We want to deal with a positive divisor to simplify the logic. */
if (nDivisor < 0)
{
nMultiplicand = - nMultiplicand;
nDivisor = -nDivisor;
}
/* If the result is positive, we "add" to round. else, we subtract to round. */
if ( ( (nMultiplicand < 0) && (nMultiplier < 0) ) ||
( (nMultiplicand >= 0) && (nMultiplier >= 0) ) )
ret = (((long long)nMultiplicand * nMultiplier) + (nDivisor/2)) / nDivisor;
else
ret = (((long long)nMultiplicand * nMultiplier) - (nDivisor/2)) / nDivisor;
if ((ret > 2147483647) || (ret < -2147483647)) return -1;
return ret;
#else
if (!nDivisor) return -1;
/* We want to deal with a positive divisor to simplify the logic. */
if (nDivisor < 0)
{
nMultiplicand = - nMultiplicand;
nDivisor = -nDivisor;
}
/* If the result is positive, we "add" to round. else, we subtract to round. */
if ( ( (nMultiplicand < 0) && (nMultiplier < 0) ) ||
( (nMultiplicand >= 0) && (nMultiplier >= 0) ) )
return ((nMultiplicand * nMultiplier) + (nDivisor/2)) / nDivisor;
return ((nMultiplicand * nMultiplier) - (nDivisor/2)) / nDivisor;
#endif
}
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
@ -113,17 +162,107 @@ IntGetScrollBarRect (PWINDOW_OBJECT Window, INT nBar, PRECT lprect)
return vertical; return vertical;
} }
#define MINTRACKTHUMB (8)
BOOL FASTCALL
IntCalculateThumb(PWINDOW_OBJECT Window, LONG idObject, PSCROLLBARINFO psbi, LPSCROLLINFO psi)
{
INT xThumb, yThumb, ThumbBox, cxy;
switch(idObject)
{
case SB_HORZ:
xThumb = NtUserGetSystemMetrics(SM_CXHSCROLL);
cxy = psbi->rcScrollBar.right - psbi->rcScrollBar.left;
if(cxy < (2 * xThumb))
{
xThumb = cxy / 2;
psbi->xyThumbTop = 0;
psbi->xyThumbBottom = 0;
}
else
{
ThumbBox = psi->nPage ? MINTRACKTHUMB : NtUserGetSystemMetrics(SM_CXHTHUMB);
cxy -= (2 * xThumb);
if(cxy > ThumbBox)
{
if(psi->nPage)
{
DbgPrint("cxy = %d, max = %d, min = %d, page = %d\n", cxy, (UINT)psi->nMax, (UINT)psi->nMin, psi->nPage);
//ThumbBox = ((UINT)cxy / ((UINT)psi->nMax - (UINT)psi->nMin)) * psi->nPage;
ThumbBox = IntMulDiv(cxy, psi->nPage, psi->nMax - psi->nMin + 1);
DbgPrint("ThumbBox = %d\n", ThumbBox);
}
psbi->xyThumbTop = xThumb;
psbi->xyThumbBottom = xThumb + ThumbBox;
}
else
{
psbi->xyThumbTop = 0;
psbi->xyThumbBottom = 0;
}
}
psbi->dxyLineButton = xThumb;
return TRUE;
case SB_VERT:
yThumb = NtUserGetSystemMetrics(SM_CYVSCROLL);
cxy = psbi->rcScrollBar.bottom - psbi->rcScrollBar.top;
if(cxy < (2 * yThumb))
{
yThumb = cxy / 2;
psbi->xyThumbTop = 0;
psbi->xyThumbBottom = 0;
}
else
{
ThumbBox = psi->nPage ? MINTRACKTHUMB : NtUserGetSystemMetrics(SM_CYVTHUMB);
cxy -= (2 * yThumb);
if(cxy > ThumbBox)
{
if(psi->nPage)
{
//ThumbBox = ((UINT)cxy / ((UINT)psi->nMax - (UINT)psi->nMin)) * psi->nPage;
ThumbBox = IntMulDiv(cxy, psi->nPage, psi->nMax - psi->nMin + 1);
}
psbi->xyThumbTop = yThumb;
psbi->xyThumbBottom = yThumb + ThumbBox;
}
else
{
psbi->xyThumbTop = 0;
psbi->xyThumbBottom = 0;
}
}
psbi->dxyLineButton = yThumb;
return TRUE;
case SB_CTL:
/* FIXME */
return FALSE;
default:
return FALSE;
}
return FALSE;
}
DWORD FASTCALL DWORD FASTCALL
IntCreateScrollBar(PWINDOW_OBJECT Window, LONG idObject) IntCreateScrollBar(PWINDOW_OBJECT Window, LONG idObject)
{ {
PSCROLLBARINFO psbi; PSCROLLBARINFO psbi;
LPSCROLLINFO psi;
LRESULT Result; LRESULT Result;
INT i; INT i;
psbi = ExAllocatePool(PagedPool, sizeof(SCROLLBARINFO)); psbi = ExAllocatePool(PagedPool, sizeof(SCROLLBARINFO) + sizeof(SCROLLINFO));
if(!psbi) if(!psbi)
return FALSE; return FALSE;
psi = (LPSCROLLINFO)((PSCROLLBARINFO)(psbi + 1));
psi->cbSize = sizeof(LPSCROLLINFO);
psi->nMin = 0;
psi->nMax = 100;
psi->nPage = 0;
psi->nPos = 0;
psi->nTrackPos = 0;
Result = WinPosGetNonClientSize(Window->Self, Result = WinPosGetNonClientSize(Window->Self,
&Window->WindowRect, &Window->WindowRect,
&Window->ClientRect); &Window->ClientRect);
@ -136,12 +275,15 @@ IntCreateScrollBar(PWINDOW_OBJECT Window, LONG idObject)
switch(idObject) switch(idObject)
{ {
case SB_HORZ: case SB_HORZ:
//psbi->dxyLineButton = NtUserGetSystemMetrics(SM_CXHSCROLL);
Window->pHScroll = psbi; Window->pHScroll = psbi;
break; break;
case SB_VERT: case SB_VERT:
//psbi->dxyLineButton = NtUserGetSystemMetrics(SM_CYVSCROLL);
Window->pVScroll = psbi; Window->pVScroll = psbi;
break; break;
case SB_CTL: case SB_CTL:
/* FIXME - set psbi->dxyLineButton */
Window->wExtra = psbi; Window->wExtra = psbi;
break; break;
default: default:
@ -149,7 +291,8 @@ IntCreateScrollBar(PWINDOW_OBJECT Window, LONG idObject)
return FALSE; return FALSE;
} }
IntGetScrollBarRect (Window, idObject, &(psbi->rcScrollBar)); IntGetScrollBarRect(Window, idObject, &(psbi->rcScrollBar));
IntCalculateThumb(Window, idObject, psbi, psi);
return 0; return 0;
} }
@ -237,6 +380,8 @@ STDCALL
NtUserGetScrollBarInfo(HWND hWnd, LONG idObject, PSCROLLBARINFO psbi) NtUserGetScrollBarInfo(HWND hWnd, LONG idObject, PSCROLLBARINFO psbi)
{ {
PWINDOW_OBJECT Window; PWINDOW_OBJECT Window;
PSCROLLBARINFO sbi;
LPSCROLLINFO psi;
INT Bar; INT Bar;
if(!psbi || (psbi->cbSize != sizeof(SCROLLBARINFO))) if(!psbi || (psbi->cbSize != sizeof(SCROLLBARINFO)))
@ -259,7 +404,7 @@ NtUserGetScrollBarInfo(HWND hWnd, LONG idObject, PSCROLLBARINFO psbi)
if(Window->pHScroll) if(Window->pHScroll)
{ {
Bar = SB_HORZ; Bar = SB_HORZ;
memcpy(psbi, Window->pHScroll, sizeof(SCROLLBARINFO)); sbi = Window->pHScroll;
break; break;
} }
/* fall through */ /* fall through */
@ -267,7 +412,7 @@ NtUserGetScrollBarInfo(HWND hWnd, LONG idObject, PSCROLLBARINFO psbi)
if(Window->pVScroll) if(Window->pVScroll)
{ {
Bar = SB_VERT; Bar = SB_VERT;
memcpy(psbi, Window->pVScroll, sizeof(SCROLLBARINFO)); sbi = Window->pVScroll;
break; break;
} }
/* fall through */ /* fall through */
@ -275,7 +420,7 @@ NtUserGetScrollBarInfo(HWND hWnd, LONG idObject, PSCROLLBARINFO psbi)
if(Window->wExtra) if(Window->wExtra)
{ {
Bar = SB_CTL; Bar = SB_CTL;
memcpy(psbi, Window->wExtra, sizeof(SCROLLBARINFO)); sbi = Window->wExtra;
break; break;
} }
/* fall through */ /* fall through */
@ -285,7 +430,12 @@ NtUserGetScrollBarInfo(HWND hWnd, LONG idObject, PSCROLLBARINFO psbi)
return FALSE; return FALSE;
} }
IntGetScrollBarRect (Window, Bar, &(psbi->rcScrollBar)); psi = (LPSCROLLINFO)((PSCROLLBARINFO)(sbi + 1));
IntGetScrollBarRect(Window, Bar, &(sbi->rcScrollBar));
IntCalculateThumb(Window, Bar, sbi, psi);
memcpy(psbi, sbi, sizeof(SCROLLBARINFO));
IntReleaseWindowObject(Window); IntReleaseWindowObject(Window);
return TRUE; return TRUE;
@ -372,7 +522,7 @@ NtUserEnableScrollBar(
if(InfoH) if(InfoH)
Chg = (IntEnableScrollBar(TRUE, InfoH, wArrows) || Chg); Chg = (IntEnableScrollBar(TRUE, InfoH, wArrows) || Chg);
if(Chg) //if(Chg && (Window->Style & WS_VISIBLE))
/* FIXME - repaint scrollbars */ /* FIXME - repaint scrollbars */
IntReleaseWindowObject(Window); IntReleaseWindowObject(Window);
@ -406,6 +556,17 @@ NtUserSetScrollInfo(
{ {
PWINDOW_OBJECT Window; PWINDOW_OBJECT Window;
PSCROLLBARINFO Info = NULL; PSCROLLBARINFO Info = NULL;
LPSCROLLINFO psi;
BOOL Chg = FALSE;
UINT Mask;
DWORD Ret;
if(!lpsi || ((lpsi->cbSize != sizeof(SCROLLINFO)) &&
(lpsi->cbSize != sizeof(SCROLLINFO) - sizeof(lpsi->nTrackPos))))
{
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return 0;
}
Window = IntGetWindowObject(hwnd); Window = IntGetWindowObject(hwnd);
@ -419,20 +580,66 @@ NtUserSetScrollInfo(
{ {
case SB_HORZ: case SB_HORZ:
Info = Window->pHScroll; Info = Window->pHScroll;
if(Info)
break; break;
/* fall through */
case SB_VERT: case SB_VERT:
Info = Window->pVScroll; Info = Window->pVScroll;
if(Info)
break; break;
/* fall through */
case SB_CTL: case SB_CTL:
Info = Window->wExtra; Info = Window->wExtra;
if(Info)
break; break;
/* fall through */
default: default:
IntReleaseWindowObject(Window); IntReleaseWindowObject(Window);
return 0; return 0;
} }
psi = (LPSCROLLINFO)((PSCROLLBARINFO)(Info + 1));
if(lpsi->fMask == SIF_ALL)
Mask = SIF_DISABLENOSCROLL | SIF_PAGE | SIF_POS | SIF_RANGE | SIF_TRACKPOS;
else
Mask = lpsi->fMask;
if(Mask & SIF_DISABLENOSCROLL)
{
/* FIXME */
}
if((Mask & SIF_PAGE) && (psi->nPage != lpsi->nPage))
{
psi->nPage = lpsi->nPage;
Chg = TRUE;
}
if((Mask & SIF_POS) && (psi->nPos != lpsi->nPos))
{
psi->nPos = lpsi->nPos;
Chg = TRUE;
}
if((Mask & SIF_RANGE) && ((psi->nMin != lpsi->nMin) || (psi->nMax != lpsi->nMax)))
{
psi->nMin = lpsi->nMin;
psi->nMax = lpsi->nMax;
Chg = TRUE;
}
/* FIXME check assigned values */
if(fRedraw && Chg && (Window->Style & WS_VISIBLE))
{
/* FIXME - Redraw */
}
Ret = psi->nPos;
IntReleaseWindowObject(Window); IntReleaseWindowObject(Window);
return 0; return Ret;
} }
/* Ported from WINE20020904 (SCROLL_ShowScrollBar) */ /* Ported from WINE20020904 (SCROLL_ShowScrollBar) */