[UXTHEME] -Rename WND_CONTEXT to WND_DATA to avoid confusion with the DRAW_CONTEXT...
[reactos.git] / reactos / dll / win32 / uxtheme / ncscrollbar.c
index 4835dd2..27299f8 100644 (file)
  */
  
 #include "uxthemep.h"
-#include <wine/debug.h>
 
-WINE_DEFAULT_DEBUG_CHANNEL(uxtheme);
+#include <assert.h>
 
-static BOOL SCROLL_trackVertical;
-static enum SCROLL_HITTEST SCROLL_trackHitTest;
-/* Is the moving thumb being displayed? */
-static BOOL SCROLL_MovingThumb = FALSE;
-static HWND SCROLL_TrackingWin = 0;
-static INT  SCROLL_TrackingBar = 0;
-static INT  SCROLL_TrackingPos = 0;
-static INT  SCROLL_TrackingVal = 0;
-
-void static ScreenToWindow( HWND hWnd, POINT* pt)
+static void ScreenToWindow( HWND hWnd, POINT* pt)
 {
     RECT rcWnd;
     GetWindowRect(hWnd, &rcWnd);
@@ -114,7 +104,7 @@ static enum SCROLL_HITTEST SCROLL_HitTest( HWND hwnd, SCROLLBARINFO* psbi, BOOL
         pt.y -= psbi->rcScrollBar.top;
         if (pt.y < psbi->xyThumbTop) 
             return SCROLL_TOP_RECT;
-        if (pt.y >= psbi->xyThumbTop + psbi->dxyLineButton
+        if (pt.y >= psbi->xyThumbBottom
             return SCROLL_BOTTOM_RECT;
     }
     else  /* horizontal */
@@ -128,7 +118,7 @@ static enum SCROLL_HITTEST SCROLL_HitTest( HWND hwnd, SCROLLBARINFO* psbi, BOOL
         pt.x -= psbi->rcScrollBar.left;
         if (pt.x < psbi->xyThumbTop) 
             return SCROLL_TOP_RECT;
-        if (pt.x >= psbi->xyThumbTop + psbi->dxyLineButton
+        if (pt.x >= psbi->xyThumbBottom
             return SCROLL_BOTTOM_RECT;
     }
     return SCROLL_THUMB;
@@ -192,14 +182,18 @@ static void SCROLL_DrawInterior( PDRAW_CONTEXT pcontext, SCROLLBARINFO* psbi,
 {
     RECT r, rcPart;
 
+    /* thumbPos is relative to the edge of the scrollbar */
+
     r = psbi->rcScrollBar;
     if (vertical)
     {
+        thumbPos += pcontext->wi.rcClient.top - pcontext->wi.rcWindow.top;
         r.top    += psbi->dxyLineButton;
         r.bottom -= (psbi->dxyLineButton);
     }
     else
     {
+        thumbPos += pcontext->wi.rcClient.left - pcontext->wi.rcWindow.left;
         r.left  += psbi->dxyLineButton;
         r.right -= psbi->dxyLineButton;
     }
@@ -216,12 +210,12 @@ static void SCROLL_DrawInterior( PDRAW_CONTEXT pcontext, SCROLLBARINFO* psbi,
     if (vertical)
     { 
         rcPart = r;
-        rcPart.bottom = rcPart.top + thumbPos - psbi->dxyLineButton;
+        rcPart.bottom = thumbPos;
         SCROLL_ThemeDrawPart(pcontext, SBP_UPPERTRACKVERT, BUTTON_NORMAL, psbi, SCROLL_TOP_RECT, htDown, htHot, &rcPart);
         r.top = rcPart.bottom;
 
         rcPart = r;
-        rcPart.top += psbi->dxyLineButton;
+        rcPart.top += psbi->xyThumbBottom - psbi->xyThumbTop;
         SCROLL_ThemeDrawPart(pcontext, SBP_LOWERTRACKVERT, BUTTON_NORMAL, psbi, SCROLL_BOTTOM_RECT, htDown, htHot, &rcPart); 
         r.bottom = rcPart.top;
 
@@ -231,12 +225,12 @@ static void SCROLL_DrawInterior( PDRAW_CONTEXT pcontext, SCROLLBARINFO* psbi,
     else  /* horizontal */
     {
         rcPart = r;
-        rcPart.right = rcPart.left + thumbPos - psbi->dxyLineButton;
+        rcPart.right = thumbPos;
         SCROLL_ThemeDrawPart(pcontext, SBP_UPPERTRACKHORZ, BUTTON_NORMAL, psbi, SCROLL_TOP_RECT, htDown, htHot, &rcPart);
         r.left = rcPart.right;
 
         rcPart = r;
-        rcPart.left += psbi->dxyLineButton;
+        rcPart.left += psbi->xyThumbBottom - psbi->xyThumbTop;
         SCROLL_ThemeDrawPart(pcontext, SBP_LOWERTRACKHORZ, BUTTON_NORMAL, psbi, SCROLL_BOTTOM_RECT, htDown, htHot, &rcPart);
         r.right = rcPart.left;
 
@@ -245,26 +239,26 @@ static void SCROLL_DrawInterior( PDRAW_CONTEXT pcontext, SCROLLBARINFO* psbi,
     }
 }
 
-static void SCROLL_DrawMovingThumb( PDRAW_CONTEXT pcontext, SCROLLBARINFO* psbi,  BOOL vertical)
+static void SCROLL_DrawMovingThumb(PWND_DATA pwndData, PDRAW_CONTEXT pcontext, SCROLLBARINFO* psbi,  BOOL vertical)
 {
-  INT pos = SCROLL_TrackingPos;
+  INT pos = pwndData->SCROLL_TrackingPos;
   INT max_size;
 
   if( vertical )
       max_size = psbi->rcScrollBar.bottom - psbi->rcScrollBar.top;
   else
-    max_size = psbi->rcScrollBar.right - psbi->rcScrollBar.left;
+      max_size = psbi->rcScrollBar.right - psbi->rcScrollBar.left;
 
-  max_size -= (psbi->dxyLineButton -SCROLL_ARROW_THUMB_OVERLAP) + psbi->dxyLineButton;
+  max_size -= psbi->xyThumbBottom - psbi->xyThumbTop + psbi->dxyLineButton;
 
-  if( pos < (psbi->dxyLineButton-SCROLL_ARROW_THUMB_OVERLAP) )
-    pos = (psbi->dxyLineButton-SCROLL_ARROW_THUMB_OVERLAP);
+  if( pos < (psbi->dxyLineButton) )
+    pos = (psbi->dxyLineButton);
   else if( pos > max_size )
     pos = max_size;
 
   SCROLL_DrawInterior(pcontext, psbi, pos, vertical, SCROLL_THUMB, 0);  
 
-  SCROLL_MovingThumb = !SCROLL_MovingThumb;
+  pwndData->SCROLL_MovingThumb = !pwndData->SCROLL_MovingThumb;
 }
 
 
@@ -275,6 +269,16 @@ ThemeDrawScrollBar(PDRAW_CONTEXT pcontext, INT nBar, POINT* pt)
     SCROLLBARINFO sbi;
     BOOL vertical;
     enum SCROLL_HITTEST htHot = SCROLL_NOWHERE;
+    PWND_DATA pwndData;
+
+    if (((nBar == SB_VERT) && !(pcontext->wi.dwStyle & WS_VSCROLL)) ||
+        ((nBar == SB_HORZ) && !(pcontext->wi.dwStyle & WS_HSCROLL))) return;
+
+    if (!(pwndData = ThemeGetWndData(pcontext->hWnd)))
+        return;
+
+    if (pwndData->SCROLL_TrackingWin)
+        return;
 
     /* Retrieve scrollbar info */
     sbi.cbSize = sizeof(sbi);
@@ -289,19 +293,14 @@ ThemeDrawScrollBar(PDRAW_CONTEXT pcontext, INT nBar, POINT* pt)
         sbi.xyThumbTop = 0;
     }
 
-#ifndef ROS_SUCKS
     /* The scrollbar rect is in screen coordinates */
-//    OffsetRect(&sbi.rcScrollBar, -pcontext->wi.rcWindow.left, -pcontext->wi.rcWindow.top);
-#endif
+    OffsetRect(&sbi.rcScrollBar, -pcontext->wi.rcWindow.left, -pcontext->wi.rcWindow.top);
 
     if(pt)
     {
         ScreenToWindow(pcontext->hWnd, pt);
         htHot = SCROLL_HitTest(pcontext->hWnd, &sbi, vertical, *pt, FALSE);
     }
-    
-    if (((nBar == SB_VERT) && !(pcontext->wi.dwStyle & WS_VSCROLL)) ||
-        ((nBar == SB_HORZ) && !(pcontext->wi.dwStyle & WS_HSCROLL))) return;
 
     /* do not draw if the scrollbar rectangle is empty */
     if(IsRectEmpty(&sbi.rcScrollBar)) return;
@@ -372,7 +371,7 @@ static UINT SCROLL_GetThumbVal( SCROLLINFO *psi, RECT *rect,
 }
 
 static void 
-SCROLL_HandleScrollEvent( HWND hwnd, INT nBar, UINT msg, POINT pt)
+SCROLL_HandleScrollEvent(PWND_DATA pwndData, HWND hwnd, INT nBar, UINT msg, POINT pt)
 {
       /* Previous mouse position for timer events */
     static POINT prevPt;
@@ -401,16 +400,15 @@ SCROLL_HandleScrollEvent( HWND hwnd, INT nBar, UINT msg, POINT pt)
     {
         return;
     }
+
+    if ((pwndData->SCROLL_trackHitTest == SCROLL_NOWHERE) && (msg != WM_LBUTTONDOWN))
+                 return;
+    
     ThemeInitDrawContext(&context, hwnd, 0);
 
-#ifndef ROS_SUCKS
     /* The scrollbar rect is in screen coordinates */
-//    OffsetRect(&sbi.rcScrollBar, -context.wi.rcWindow.left, -context.wi.rcWindow.top);
-#endif
+    OffsetRect(&sbi.rcScrollBar, -context.wi.rcWindow.left, -context.wi.rcWindow.top);
 
-    if ((SCROLL_trackHitTest == SCROLL_NOWHERE) && (msg != WM_LBUTTONDOWN))
-                 return;
-    
     hwndOwner = (nBar == SB_CTL) ? GetParent(hwnd) : hwnd;
     hwndCtl   = (nBar == SB_CTL) ? hwnd : 0;
 
@@ -418,8 +416,8 @@ SCROLL_HandleScrollEvent( HWND hwnd, INT nBar, UINT msg, POINT pt)
     {
       case WM_LBUTTONDOWN:  /* Initialise mouse tracking */
           HideCaret(hwnd);  /* hide caret while holding down LBUTTON */
-          SCROLL_trackVertical = vertical;
-          SCROLL_trackHitTest  = hittest = SCROLL_HitTest( hwnd, &sbi, vertical, pt, FALSE );
+          pwndData->SCROLL_trackVertical = vertical;
+          pwndData->SCROLL_trackHitTest  = hittest = SCROLL_HitTest( hwnd, &sbi, vertical, pt, FALSE );
           lastClickPos  = vertical ? (pt.y - sbi.rcScrollBar.top) : (pt.x - sbi.rcScrollBar.left);
           lastMousePos  = lastClickPos;
           trackThumbPos = sbi.xyThumbTop;
@@ -452,15 +450,15 @@ SCROLL_HandleScrollEvent( HWND hwnd, INT nBar, UINT msg, POINT pt)
     //TRACE("Event: hwnd=%p bar=%d msg=%s pt=%d,%d hit=%d\n",
     //      hwnd, nBar, SPY_GetMsgName(msg,hwnd), pt.x, pt.y, hittest );
 
-    switch(SCROLL_trackHitTest)
+    switch(pwndData->SCROLL_trackHitTest)
     {
     case SCROLL_NOWHERE:  /* No tracking in progress */
         break;
 
     case SCROLL_TOP_ARROW:
-        if (hittest == SCROLL_trackHitTest)
+        if (hittest == pwndData->SCROLL_trackHitTest)
         {
-            SCROLL_DrawArrows( &context, &sbi, vertical, SCROLL_trackHitTest, 0 );
+            SCROLL_DrawArrows( &context, &sbi, vertical, pwndData->SCROLL_trackHitTest, 0 );
             if ((msg == WM_LBUTTONDOWN) || (msg == WM_SYSTIMER))
             {
                 SendMessageW( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
@@ -479,8 +477,8 @@ SCROLL_HandleScrollEvent( HWND hwnd, INT nBar, UINT msg, POINT pt)
         break;
 
     case SCROLL_TOP_RECT:
-        SCROLL_DrawInterior( &context, &sbi, sbi.xyThumbTop, vertical, SCROLL_trackHitTest, 0);
-        if (hittest == SCROLL_trackHitTest)
+        SCROLL_DrawInterior( &context, &sbi, sbi.xyThumbTop, vertical, pwndData->SCROLL_trackHitTest, 0);
+        if (hittest == pwndData->SCROLL_trackHitTest)
         {
             if ((msg == WM_LBUTTONDOWN) || (msg == WM_SYSTIMER))
             {
@@ -496,20 +494,20 @@ SCROLL_HandleScrollEvent( HWND hwnd, INT nBar, UINT msg, POINT pt)
     case SCROLL_THUMB:
         if (msg == WM_LBUTTONDOWN)
         {
-            SCROLL_TrackingWin = hwnd;
-            SCROLL_TrackingBar = nBar;
-            SCROLL_TrackingPos = trackThumbPos + lastMousePos - lastClickPos;
-            SCROLL_TrackingVal = SCROLL_GetThumbVal( &si, &sbi.rcScrollBar, 
-                                                     vertical, SCROLL_TrackingPos );
-               if (!SCROLL_MovingThumb)
-                       SCROLL_DrawMovingThumb(&context, &sbi, vertical);
+            pwndData->SCROLL_TrackingWin = hwnd;
+            pwndData->SCROLL_TrackingBar = nBar;
+            pwndData->SCROLL_TrackingPos = trackThumbPos + lastMousePos - lastClickPos;
+            pwndData->SCROLL_TrackingVal = SCROLL_GetThumbVal( &si, &sbi.rcScrollBar, 
+                                                     vertical, pwndData->SCROLL_TrackingPos );
+               if (!pwndData->SCROLL_MovingThumb)
+                       SCROLL_DrawMovingThumb(pwndData, &context, &sbi, vertical);
         }
         else if (msg == WM_LBUTTONUP)
         {
-               if (SCROLL_MovingThumb)
-                       SCROLL_DrawMovingThumb(&context, &sbi, vertical);
+               if (pwndData->SCROLL_MovingThumb)
+                       SCROLL_DrawMovingThumb(pwndData, &context, &sbi, vertical);
 
-            SCROLL_DrawInterior(  &context, &sbi, sbi.xyThumbTop, vertical, 0, SCROLL_trackHitTest );
+            SCROLL_DrawInterior(  &context, &sbi, sbi.xyThumbTop, vertical, 0, pwndData->SCROLL_trackHitTest );
         }
         else  /* WM_MOUSEMOVE */
         {
@@ -522,28 +520,28 @@ SCROLL_HandleScrollEvent( HWND hwnd, INT nBar, UINT msg, POINT pt)
                 pt = SCROLL_ClipPos( &sbi.rcScrollBar, pt );
                 pos = vertical ? (pt.y - sbi.rcScrollBar.top) : (pt.x - sbi.rcScrollBar.left);
             }
-            if ( (pos != lastMousePos) || (!SCROLL_MovingThumb) )
+            if ( (pos != lastMousePos) || (!pwndData->SCROLL_MovingThumb) )
             {
-                if (SCROLL_MovingThumb)
-                    SCROLL_DrawMovingThumb( &context, &sbi, vertical);
+                if (pwndData->SCROLL_MovingThumb)
+                    SCROLL_DrawMovingThumb(pwndData, &context, &sbi, vertical);
                 lastMousePos = pos;
-                SCROLL_TrackingPos = trackThumbPos + pos - lastClickPos;
-                SCROLL_TrackingVal = SCROLL_GetThumbVal( &si, &sbi.rcScrollBar,
+                pwndData->SCROLL_TrackingPos = trackThumbPos + pos - lastClickPos;
+                pwndData->SCROLL_TrackingVal = SCROLL_GetThumbVal( &si, &sbi.rcScrollBar,
                                                          vertical,
-                                                         SCROLL_TrackingPos );
+                                                         pwndData->SCROLL_TrackingPos );
                 SendMessageW( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
-                                MAKEWPARAM( SB_THUMBTRACK, SCROLL_TrackingVal),
+                                MAKEWPARAM( SB_THUMBTRACK, pwndData->SCROLL_TrackingVal),
                                 (LPARAM)hwndCtl );
-                if (!SCROLL_MovingThumb)
-                    SCROLL_DrawMovingThumb( &context, &sbi, vertical);
+                if (!pwndData->SCROLL_MovingThumb)
+                    SCROLL_DrawMovingThumb(pwndData, &context, &sbi, vertical);
             }
         }
         break;
 
     case SCROLL_BOTTOM_RECT:
-        if (hittest == SCROLL_trackHitTest)
+        if (hittest == pwndData->SCROLL_trackHitTest)
         {
-            SCROLL_DrawInterior(  &context, &sbi, sbi.xyThumbTop, vertical, SCROLL_trackHitTest, 0 );
+            SCROLL_DrawInterior(  &context, &sbi, sbi.xyThumbTop, vertical, pwndData->SCROLL_trackHitTest, 0 );
             if ((msg == WM_LBUTTONDOWN) || (msg == WM_SYSTIMER))
             {
                 SendMessageW( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
@@ -560,9 +558,9 @@ SCROLL_HandleScrollEvent( HWND hwnd, INT nBar, UINT msg, POINT pt)
         break;
 
     case SCROLL_BOTTOM_ARROW:
-        if (hittest == SCROLL_trackHitTest)
+        if (hittest == pwndData->SCROLL_trackHitTest)
         {
-            SCROLL_DrawArrows(  &context, &sbi, vertical, SCROLL_trackHitTest, 0 );
+            SCROLL_DrawArrows(  &context, &sbi, vertical, pwndData->SCROLL_trackHitTest, 0 );
             if ((msg == WM_LBUTTONDOWN) || (msg == WM_SYSTIMER))
             {
                 SendMessageW( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
@@ -594,8 +592,8 @@ SCROLL_HandleScrollEvent( HWND hwnd, INT nBar, UINT msg, POINT pt)
 
     if (msg == WM_LBUTTONUP)
     {
-        hittest = SCROLL_trackHitTest;
-        SCROLL_trackHitTest = SCROLL_NOWHERE;  /* Terminate tracking */
+        hittest = pwndData->SCROLL_trackHitTest;
+        pwndData->SCROLL_trackHitTest = SCROLL_NOWHERE;  /* Terminate tracking */
 
         if (hittest == SCROLL_THUMB)
         {
@@ -609,7 +607,7 @@ SCROLL_HandleScrollEvent( HWND hwnd, INT nBar, UINT msg, POINT pt)
                           SB_ENDSCROLL, (LPARAM)hwndCtl );
 
         /* Terminate tracking */
-        SCROLL_TrackingWin = 0;
+        pwndData->SCROLL_TrackingWin = 0;
     }
 
     ThemeCleanupDrawContext(&context);
@@ -619,10 +617,13 @@ static void
 SCROLL_TrackScrollBar( HWND hwnd, INT scrollbar, POINT pt )
 {
     MSG msg;
+    PWND_DATA pwndData = ThemeGetWndData(hwnd);
+    if(!pwndData)
+        return;
 
     ScreenToWindow(hwnd, &pt);
 
-    SCROLL_HandleScrollEvent( hwnd, scrollbar, WM_LBUTTONDOWN, pt );
+    SCROLL_HandleScrollEvent(pwndData, hwnd, scrollbar, WM_LBUTTONDOWN, pt );
 
     do
     {
@@ -636,7 +637,7 @@ SCROLL_TrackScrollBar( HWND hwnd, INT scrollbar, POINT pt )
             pt.y = GET_Y_LPARAM(msg.lParam);
             ClientToScreen(hwnd, &pt);
             ScreenToWindow(hwnd, &pt);
-            SCROLL_HandleScrollEvent( hwnd, scrollbar, msg.message, pt );
+            SCROLL_HandleScrollEvent(pwndData, hwnd, scrollbar, msg.message, pt );
         }
         else
         {