Trackbar size fixes, take 2

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Since no one else has submitted something, here is a second try, along with a long explanation of what was fixed and why.

The only difference from my previous patch is that the initial size of the thumb is limited to not be greater than "21". I tested on Win2K and found that the initial size of the thumb is always 21, though it can then be explicitely changed (which works correctly in Wine). However I have one application (earthquake) where this results in a thumb that is too big. I suspect there is an initialization bug in Wine relating to when the thumb size is set. Since shrinking the thumb size for narrow rectangles will likely always be desired, this hack should be fine until I figure out what is wrong in the initialization.

Some changes are cosmetic. Once the thumb length is set, all the rest of the dimensions of the thumb are determined from that. Wine has had several different versions of that recently, including the use of floating point arithmetic!, but none match Windows. This patch correctly sets the thumb width in proportion to the length, and correctly draws the bevels at 45 degrees.

The other main problem in the current code is that the channel length was assumed to be the difference between the first and last tic marks. This is incorrect. The channel length should be the length of the channel as drawn. The first and last tic marks then should be inset by half the width of the thumb. Most of this patch corrects all the places in the code where this problem exists.

Changelog:
	The initial size of the thumb should be a fixed number.
	Correctly draw the thumb as in Windows.
	The first and last tic marks should be inset from the
	channel length by half the thumb width.

Index: dlls/comctl32/trackbar.c
===================================================================
RCS file: /home/wine/wine/dlls/comctl32/trackbar.c,v
retrieving revision 1.49
diff -u -r1.49 trackbar.c
--- dlls/comctl32/trackbar.c	16 Jun 2003 19:39:27 -0000	1.49
+++ dlls/comctl32/trackbar.c	31 Jul 2003 17:47:15 -0000
@@ -139,15 +139,17 @@
 TRACKBAR_ConvertPlaceToPosition (TRACKBAR_INFO *infoPtr, int place,
                                  int vertical)
 {
-    double range, width, pos;
+    double range, width, pos, offsetthumb;
 
     range = infoPtr->lRangeMax - infoPtr->lRangeMin;
     if (vertical) {
-    	width = infoPtr->rcChannel.bottom - infoPtr->rcChannel.top;
-        pos = (range*(place - infoPtr->rcChannel.top)) / width;
+        offsetthumb = (infoPtr->rcThumb.bottom - infoPtr->rcThumb.top)/2 + 1;
+    	width = infoPtr->rcChannel.bottom - infoPtr->rcChannel.top - (offsetthumb * 2);
+        pos = (range*(place - infoPtr->rcChannel.top - offsetthumb)) / width;
     } else {
-    	width = infoPtr->rcChannel.right - infoPtr->rcChannel.left;
-        pos = (range*(place - infoPtr->rcChannel.left)) / width;
+        offsetthumb = (infoPtr->rcThumb.right - infoPtr->rcThumb.left)/2 + 1;
+    	width = infoPtr->rcChannel.right - infoPtr->rcChannel.left - (offsetthumb * 2);
+        pos = (range*(place - infoPtr->rcChannel.left - offsetthumb)) / width;
     }
     pos += infoPtr->lRangeMin;
     if (pos > infoPtr->lRangeMax)
@@ -224,22 +226,26 @@
 
     GetClientRect (infoPtr->hwndSelf, &lpRect);
 
-    offsetthumb = (int)(infoPtr->uThumbLen/4.5);
+    offsetthumb = infoPtr->uThumbLen / 4;
     offsetedge  = offsetthumb + 3;
     cyChannel   = (dwStyle & TBS_ENABLESELRANGE) ? (offsetthumb+1)*3 : 4;
     if (dwStyle & TBS_VERT) {
         channel->top    = lpRect.top + offsetedge;
         channel->bottom = lpRect.bottom - offsetedge;
-        channel->left = lpRect.left + offsetthumb - cyChannel;
-        if (dwStyle & (TBS_BOTH | TBS_LEFT))
-            channel->left += (lpRect.right-lpRect.left-offsetthumb-cyChannel)/2;
+        channel->left = lpRect.left + (infoPtr->uThumbLen / 2) - 1;
+        if (dwStyle & TBS_BOTH)
+            channel->left += 9;
+        else if (dwStyle & TBS_LEFT)
+            channel->left += 10;
         channel->right = channel->left + cyChannel;
     } else {
         channel->left = lpRect.left + offsetedge;
         channel->right = lpRect.right - offsetedge;
-        channel->top = lpRect.top + offsetedge;
-        if (dwStyle & (TBS_BOTH | TBS_TOP))
-            channel->top += (lpRect.bottom-lpRect.top-offsetedge-cyChannel)/2;
+        channel->top = lpRect.top + (infoPtr->uThumbLen / 2) - 1;
+        if (dwStyle & TBS_BOTH)
+            channel->top += 9;
+        else if (dwStyle & TBS_TOP)
+            channel->top += 10;
         channel->bottom   = channel->top + cyChannel;
     }
 }
@@ -247,43 +253,42 @@
 static void
 TRACKBAR_CalcThumb (TRACKBAR_INFO *infoPtr, LONG lPos, RECT *thumb)
 {
-    int range, width, height, thumbdepth, ticOffset = 5 + 2; /* 5 is length of tic, 2 is extra indent */
+    int range, width, height, thumbwidth;
     DWORD dwStyle = GetWindowLongW (infoPtr->hwndSelf, GWL_STYLE);
     RECT lpRect;
 
     range = infoPtr->lRangeMax - infoPtr->lRangeMin;
-    thumbdepth = ((int)(infoPtr->uThumbLen / 4.5)) + 2;
+    /* This calculates the thumb width as on Win2K */
+    thumbwidth = (infoPtr->uThumbLen / 2) | 1;
 
     if (!range) range = 1;
 
     GetClientRect(infoPtr->hwndSelf, &lpRect);
     if (dwStyle & TBS_VERT)
     {
-    	height = infoPtr->rcChannel.bottom - infoPtr->rcChannel.top;
+    	height = infoPtr->rcChannel.bottom - infoPtr->rcChannel.top - thumbwidth - 1;
 
         if (dwStyle & (TBS_BOTH | TBS_LEFT))
-            thumb->left = (lpRect.right - lpRect.left - infoPtr->uThumbLen)/2 + ticOffset;
+            thumb->left = 10;
         else
             thumb->left = 2;
-        thumb->right = thumb->left + infoPtr->uThumbLen - (ticOffset * 2);
+        thumb->right = thumb->left + infoPtr->uThumbLen;
         thumb->top = infoPtr->rcChannel.top +
-                     (height*(lPos - infoPtr->lRangeMin))/range -
-                     thumbdepth/2;
-        thumb->bottom = thumb->top + thumbdepth;
+                     (height*(lPos - infoPtr->lRangeMin))/range;
+        thumb->bottom = thumb->top + thumbwidth;
     }
     else
     {
-    	width = infoPtr->rcChannel.right - infoPtr->rcChannel.left;
+    	width = infoPtr->rcChannel.right - infoPtr->rcChannel.left - thumbwidth - 1;
 
         thumb->left = infoPtr->rcChannel.left +
-                      (width*(lPos - infoPtr->lRangeMin))/range -
-                      thumbdepth/2;
-        thumb->right = thumb->left + thumbdepth;
+                      (width*(lPos - infoPtr->lRangeMin))/range;
+        thumb->right = thumb->left + thumbwidth;
         if (dwStyle & (TBS_BOTH | TBS_TOP))
-            thumb->top = (lpRect.bottom - lpRect.top - infoPtr->uThumbLen)/2;
+            thumb->top = 10;
         else
             thumb->top = 2;
-        thumb->bottom = thumb->top + infoPtr->uThumbLen - 20; /* double the bottom padding for the ticks, chosen to resemble native control */
+        thumb->bottom = thumb->top + infoPtr->uThumbLen;
     }
 }
 
@@ -381,16 +386,6 @@
 TRACKBAR_DrawChannel (TRACKBAR_INFO *infoPtr, HDC hdc, DWORD dwStyle)
 {
     RECT rcChannel = infoPtr->rcChannel;
-    int runOver = 5;
-
-    /* make the channel slightly overrun the last tick, to make it look more like the native control, and less "clunky" */
-    if (dwStyle & TBS_VERT) {
-	rcChannel.top -= runOver;
-	rcChannel.bottom += runOver;
-    } else {
-	rcChannel.left -= runOver;
-	rcChannel.right += runOver;
-    }
 
     DrawEdge (hdc, &rcChannel, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
     if (dwStyle & TBS_ENABLESELRANGE) {		 /* fill the channel */
@@ -403,19 +398,22 @@
 static void
 TRACKBAR_DrawOneTic (TRACKBAR_INFO *infoPtr, HDC hdc, LONG ticPos, int flags)
 {
-    int x, y, ox, oy, range, side, offset = 5, indent = 0, len = 3;
+    int x, y, ox, oy, range, side, indent = 0, len = 3;
+    int offsetthumb;
     RECT rcTics;
 
-    TRACE("\n");
-
-    GetClientRect(infoPtr->hwndSelf, &rcTics);
     if (flags & TBS_VERT) {
-	rcTics.top    = infoPtr->rcChannel.top;
-	rcTics.bottom = infoPtr->rcChannel.bottom;
+        offsetthumb = (infoPtr->rcThumb.bottom - infoPtr->rcThumb.top)/2 + 1;
+	rcTics.left = infoPtr->rcThumb.left - 2;
+	rcTics.right = infoPtr->rcThumb.right + 2;
+	rcTics.top    = infoPtr->rcChannel.top + offsetthumb;
+	rcTics.bottom = infoPtr->rcChannel.bottom - offsetthumb;
     } else {
-	rcTics.left   = infoPtr->rcChannel.left;
-	rcTics.right  = infoPtr->rcChannel.right;
-	rcTics.bottom -= 10; /* value obtained by guesswork and experimentation */
+        offsetthumb = (infoPtr->rcThumb.right - infoPtr->rcThumb.left)/2 + 1;
+	rcTics.left   = infoPtr->rcChannel.left + offsetthumb;
+	rcTics.right  = infoPtr->rcChannel.right - offsetthumb;
+	rcTics.top = infoPtr->rcThumb.top - 2;
+	rcTics.bottom = infoPtr->rcThumb.bottom + 2;
     }
 
     if (flags & (TBS_TOP | TBS_LEFT)) {
@@ -441,13 +439,13 @@
     if (flags & TBS_VERT) {
 	int height = rcTics.bottom - rcTics.top;
 	y = rcTics.top + (height*(ticPos - infoPtr->lRangeMin))/range;
-	x -= (offset + 2) * side;
-	y += indent;
+/*	x -= (offset + 2) * side;
+	y += indent;*/
     } else {
         int width = rcTics.right - rcTics.left;
         x = rcTics.left + (width*(ticPos - infoPtr->lRangeMin))/range;
-	x += indent;
-	y -= (offset + 2) * side;
+/*	x += indent;
+	y -= (offset + 2) * side;*/
     }
 
     ox = x;
@@ -483,7 +481,7 @@
         TRACKBAR_DrawOneTic (infoPtr, hdc, ticPos, flags | TBS_LEFT);
 
     if (!(flags & (TBS_LEFT | TBS_TOP)) || (flags & TBS_BOTH))
-        TRACKBAR_DrawOneTic (infoPtr, hdc, ticPos, flags);
+        TRACKBAR_DrawOneTic (infoPtr, hdc, ticPos, flags & ~TBS_LEFT);
 }
 
 static void
@@ -528,8 +526,8 @@
     int PointCount = 6;
     POINT points[6];
     int fillClr;
+    int PointDepth;
 
-    static INT PointDepth = 4;
     fillClr = infoPtr->flags & TB_DRAG_MODE ? COLOR_BTNHILIGHT : COLOR_BTNFACE;
     oldbr = SelectObject (hdc, GetSysColorBrush(fillClr));
     SetPolyFillMode (hdc, WINDING);
@@ -553,6 +551,7 @@
     {
         if (dwStyle & TBS_VERT)
         {
+          PointDepth = (thumb.bottom - thumb.top) / 2;
           if (dwStyle & TBS_LEFT)
           {
             points[0].x=thumb.right;
@@ -562,7 +561,7 @@
             points[2].x=thumb.left + PointDepth;
             points[2].y=thumb.bottom;
             points[3].x=thumb.left;
-            points[3].y=(thumb.bottom - thumb.top) / 2 + thumb.top;
+            points[3].y=(thumb.bottom - thumb.top) / 2 + thumb.top + 1;
             points[4].x=thumb.left + PointDepth;
             points[4].y=thumb.top;
             points[5].x=points[0].x;
@@ -572,7 +571,7 @@
           else
           {
             points[0].x=thumb.right;
-            points[0].y=(thumb.bottom - thumb.top) / 2 + thumb.top;
+            points[0].y=(thumb.bottom - thumb.top) / 2 + thumb.top + 1;
             points[1].x=thumb.right - PointDepth;
             points[1].y=thumb.bottom;
             points[2].x=thumb.left;
@@ -587,9 +586,10 @@
         }
         else
         {
+          PointDepth = (thumb.right - thumb.left) / 2;
           if (dwStyle & TBS_TOP)
           {
-            points[0].x=(thumb.right - thumb.left) / 2 + thumb.left ;
+            points[0].x=(thumb.right - thumb.left) / 2 + thumb.left + 1;
             points[0].y=thumb.top;
             points[1].x=thumb.right;
             points[1].y=thumb.top + PointDepth;
@@ -609,7 +609,7 @@
             points[0].y=thumb.top;
             points[1].x=thumb.right;
             points[1].y=thumb.bottom - PointDepth;
-            points[2].x=(thumb.right - thumb.left) / 2 + thumb.left ;
+            points[2].x=(thumb.right - thumb.left) / 2 + thumb.left + 1;
             points[2].y=thumb.bottom;
             points[3].x=thumb.left;
             points[3].y=thumb.bottom - PointDepth;
@@ -1234,8 +1234,10 @@
     if (dwStyle & TBS_VERT) {
 	infoPtr->uThumbLen = (rect.right - rect.left - 6);
     } else {
-	infoPtr->uThumbLen = (rect.bottom - rect.top);
+	infoPtr->uThumbLen = (rect.bottom - rect.top - 6);
     }
+    if (infoPtr->uThumbLen > 21)
+        infoPtr->uThumbLen = 21;
 
     TRACKBAR_CalcChannel (infoPtr);
     TRACKBAR_UpdateThumb (infoPtr);

[Index of Archives]     [Gimp for Windows]     [Red Hat]     [Samba]     [Yosemite Camping]     [Graphics Cards]     [Wine Home]

  Powered by Linux