Trackbar updates

Dimitrie O. Paun dpaun at rogers.com
Tue Sep 10 01:53:39 CDT 2002


ChangeLog
  -- Implement autopaging
  -- remove incorrect FIXMEs
  -- small cleanups

Index: dlls/comctl32/trackbar.c
===================================================================
RCS file: /var/cvs/wine/dlls/comctl32/trackbar.c,v
retrieving revision 1.36
diff -u -r1.36 trackbar.c
--- dlls/comctl32/trackbar.c	9 Sep 2002 19:20:35 -0000	1.36
+++ dlls/comctl32/trackbar.c	10 Sep 2002 06:33:14 -0000
@@ -20,8 +20,6 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * TODO:
- *   - implement autorepeat for paging
- *   - possition buddy controls
  *   - custom draw notifications
  */
 
@@ -65,8 +63,8 @@
 
 DEFINE_COMMON_NOTIFICATIONS(TRACKBAR_INFO, hwndSelf);
 
-/* #define TB_REFRESH_TIMER       1 */
-/* #define TB_REFRESH_DELAY       1 */
+#define TB_REFRESH_TIMER	1
+#define TB_REFRESH_DELAY	500
 
 #define TOOLTIP_OFFSET		15   /* distance from thumb to tooltip */
 
@@ -78,6 +76,9 @@
 #define TB_THUMBCHANGED 	(TB_THUMBPOSCHANGED | TB_THUMBSIZECHANGED)
 #define TB_SELECTIONCHANGED     4
 #define TB_DRAG_MODE            8     /* we're dragging the slider */
+#define TB_AUTO_PAGE_LEFT	16
+#define TB_AUTO_PAGE_RIGHT	32
+#define TB_AUTO_PAGE		(TB_AUTO_PAGE_LEFT | TB_AUTO_PAGE_RIGHT)
 
 /* helper defines for TRACKBAR_DrawTic */
 #define TIC_EDGE                0x20
@@ -120,19 +121,19 @@
 /* converts from physical (mouse) position to logical position
    (in range of trackbar) */
 
-static inline double
+static inline LONG
 TRACKBAR_ConvertPlaceToPosition (TRACKBAR_INFO *infoPtr, int place,
                                  int vertical)
 {
     double range, width, pos;
 
-    range=infoPtr->lRangeMax - infoPtr->lRangeMin;
+    range = infoPtr->lRangeMax - infoPtr->lRangeMin;
     if (vertical) {
-    	width=infoPtr->rcChannel.bottom - infoPtr->rcChannel.top;
-        pos=(range*(place - infoPtr->rcChannel.top)) / width;
+    	width = infoPtr->rcChannel.bottom - infoPtr->rcChannel.top;
+        pos = (range*(place - infoPtr->rcChannel.top)) / width;
     } else {
-    	width=infoPtr->rcChannel.right - infoPtr->rcChannel.left;
-        pos=(range*(place - infoPtr->rcChannel.left)) / width;
+    	width = infoPtr->rcChannel.right - infoPtr->rcChannel.left;
+        pos = (range*(place - infoPtr->rcChannel.left)) / width;
     }
     pos += infoPtr->lRangeMin;
     if (pos > infoPtr->lRangeMax)
@@ -141,10 +142,65 @@
         pos = infoPtr->lRangeMin;
 
     TRACE("%.2f\n", pos);
-    return pos;
+    return (LONG)(pos + 0.5);
 }
 
 
+/* return: 0> prev, 0 none, >0 next */
+static LONG
+TRACKBAR_GetAutoPageDirection (TRACKBAR_INFO *infoPtr, POINT clickPoint)
+{
+    DWORD dwStyle = GetWindowLongW (infoPtr->hwndSelf, GWL_STYLE);
+    RECT pageRect;
+
+    if (dwStyle & TBS_VERT) {
+	pageRect.top = infoPtr->rcChannel.top;
+	pageRect.bottom = infoPtr->rcChannel.bottom;
+	pageRect.left = infoPtr->rcThumb.left;
+	pageRect.right = infoPtr->rcThumb.right;
+    } else {
+	pageRect.top = infoPtr->rcThumb.top;
+	pageRect.bottom = infoPtr->rcThumb.bottom;
+	pageRect.left = infoPtr->rcChannel.left;
+	pageRect.right = infoPtr->rcChannel.right;
+    }
+
+
+    if (PtInRect(&pageRect, clickPoint))
+    {
+	int clickPlace = (dwStyle & TBS_VERT) ? clickPoint.y : clickPoint.x;
+
+        LONG clickPos = TRACKBAR_ConvertPlaceToPosition(infoPtr, clickPlace,
+                                                        dwStyle & TBS_VERT);
+	return clickPos - infoPtr->lPos;
+    }
+
+    return 0;
+}
+
+static void inline
+TRACKBAR_PageUp (TRACKBAR_INFO *infoPtr)
+{
+    if (infoPtr->lPos == infoPtr->lRangeMax) return;
+
+    infoPtr->lPos += infoPtr->lPageSize;
+    if (infoPtr->lPos > infoPtr->lRangeMax)
+	infoPtr->lPos = infoPtr->lRangeMax;
+    TRACKBAR_SendNotify (infoPtr, TB_PAGEUP);
+}
+
+
+static void inline
+TRACKBAR_PageDown (TRACKBAR_INFO *infoPtr)
+{
+    if (infoPtr->lPos == infoPtr->lRangeMin) return;
+
+    infoPtr->lPos -= infoPtr->lPageSize;
+    if (infoPtr->lPos < infoPtr->lRangeMin)
+        infoPtr->lPos = infoPtr->lRangeMin;
+    TRACKBAR_SendNotify (infoPtr, TB_PAGEDOWN);
+}
+
 static void
 TRACKBAR_CalcChannel (TRACKBAR_INFO *infoPtr)
 {
@@ -272,6 +328,26 @@
 	   selection->left, selection->top, selection->right, selection->bottom);
 }
 
+static BOOL
+TRACKBAR_AutoPage (TRACKBAR_INFO *infoPtr, POINT clickPoint)
+{
+    LONG dir = TRACKBAR_GetAutoPageDirection(infoPtr, clickPoint);
+    LONG prevPos = infoPtr->lPos;
+
+    TRACE("x=%ld, y=%ld, dir=%ld\n", clickPoint.x, clickPoint.y, dir);
+
+    if (dir > 0 && (infoPtr->flags & TB_AUTO_PAGE_RIGHT))
+	TRACKBAR_PageUp(infoPtr);
+    else if (dir < 0 && (infoPtr->flags & TB_AUTO_PAGE_LEFT))
+	TRACKBAR_PageDown(infoPtr);
+    else return FALSE;
+
+    infoPtr->flags |= TB_THUMBPOSCHANGED;
+    TRACKBAR_InvalidateThumbMove (infoPtr, prevPos, infoPtr->lPos);
+
+    return TRUE;
+}
+
 /* Trackbar drawing code. I like my spaghetti done milanese.  */
 
 /* ticPos is in tic-units, not in pixels */
@@ -376,7 +452,7 @@
     static INT PointDepth = 4;
 
     oldbr = SelectObject (hdc, hbr);
-    SetPolyFillMode (hdc,WINDING);
+    SetPolyFillMode (hdc, WINDING);
 
     if (dwStyle & TBS_BOTH)
     {
@@ -489,7 +565,7 @@
     /*
      * White Part
      */
-    Polyline(hdc,&points[BlackUntil-1],PointCount+1-BlackUntil);
+    Polyline(hdc, &points[BlackUntil-1], PointCount+1-BlackUntil);
 
     /*
      * restore the brush and pen
@@ -772,15 +848,11 @@
 	/* buddy is left or above */
 	hwndTemp = infoPtr->hwndBuddyLA;
 	infoPtr->hwndBuddyLA = hwndBuddy;
-
-	FIXME("move buddy!\n");
     }
     else {
         /* buddy is right or below */
         hwndTemp = infoPtr->hwndBuddyRB;
         infoPtr->hwndBuddyRB = hwndBuddy;
-
-        FIXME("move buddy!\n");
     }
 
     TRACKBAR_AlignBuddies (infoPtr);
@@ -1158,66 +1230,25 @@
     return 0;
 }
 
-
 static LRESULT
 TRACKBAR_LButtonDown (TRACKBAR_INFO *infoPtr, DWORD fwKeys, POINTS pts)
 {
-    DWORD dwStyle = GetWindowLongW (infoPtr->hwndSelf, GWL_STYLE);
     POINT clickPoint = { pts.x, pts.y };
-    RECT pageRect;
 
     SetFocus(infoPtr->hwndSelf);
 
-    if (PtInRect(&infoPtr->rcThumb, clickPoint))
-    {
+    if (PtInRect(&infoPtr->rcThumb, clickPoint)) {
         infoPtr->flags |= TB_DRAG_MODE;
         SetCapture (infoPtr->hwndSelf);
 	TRACKBAR_UpdateToolTip (infoPtr);
 	TRACKBAR_ActivateToolTip (infoPtr, TRUE);
-        return 0;
-    }
-
-    if (dwStyle & TBS_VERT) {
-	pageRect.top = infoPtr->rcChannel.top;
-	pageRect.bottom = infoPtr->rcChannel.bottom;
-	pageRect.left = infoPtr->rcThumb.left;
-	pageRect.right = infoPtr->rcThumb.right;
     } else {
-	pageRect.top = infoPtr->rcThumb.top;
-	pageRect.bottom = infoPtr->rcThumb.bottom;
-	pageRect.left = infoPtr->rcChannel.left;
-	pageRect.right = infoPtr->rcChannel.right;
-    }
-
-    if (PtInRect(&pageRect, clickPoint))
-    {
-        int clickPlace, prevPos;
-        DOUBLE clickPos;
-
-	clickPlace = (dwStyle & TBS_VERT) ? pts.x : pts.y;
-
-        clickPos = TRACKBAR_ConvertPlaceToPosition(infoPtr, clickPlace,
-                                                   dwStyle & TBS_VERT);
-        prevPos = infoPtr->lPos;
-        if (clickPos > (int)prevPos)
-        {  /* similar to VK_NEXT */
-            infoPtr->lPos += infoPtr->lPageSize;
-            if (infoPtr->lPos > infoPtr->lRangeMax)
-                infoPtr->lPos = infoPtr->lRangeMax;
-            TRACKBAR_SendNotify (infoPtr, TB_PAGEUP);
-        }
-        else
-        {
-            infoPtr->lPos -= infoPtr->lPageSize;  /* similar to VK_PRIOR */
-            if (infoPtr->lPos < infoPtr->lRangeMin)
-                infoPtr->lPos = infoPtr->lRangeMin;
-            TRACKBAR_SendNotify (infoPtr, TB_PAGEDOWN);
-        }
-
-        if (prevPos != infoPtr->lPos) {
-            infoPtr->flags |= TB_THUMBPOSCHANGED;
-	    TRACKBAR_InvalidateThumbMove (infoPtr, prevPos, infoPtr->lPos);
-        }
+	LONG dir = TRACKBAR_GetAutoPageDirection(infoPtr, clickPoint);
+	if (dir == 0) return 0;
+	infoPtr->flags |= (dir < 0) ? TB_AUTO_PAGE_LEFT : TB_AUTO_PAGE_RIGHT;
+	TRACKBAR_AutoPage (infoPtr, clickPoint);
+        SetCapture (infoPtr->hwndSelf);
+        SetTimer(infoPtr->hwndSelf, TB_REFRESH_TIMER, TB_REFRESH_DELAY, 0);
     }
 
     return 0;
@@ -1227,16 +1258,19 @@
 static LRESULT
 TRACKBAR_LButtonUp (TRACKBAR_INFO *infoPtr, DWORD fwKeys, POINTS pts)
 {
-    TRACKBAR_SendNotify (infoPtr, TB_ENDTRACK);
-
-    if (infoPtr->flags & TB_DRAG_MODE)
-    {
+    if (infoPtr->flags & TB_DRAG_MODE) {
+        TRACKBAR_SendNotify (infoPtr, TB_ENDTRACK);
         infoPtr->flags &= ~TB_DRAG_MODE;
         ReleaseCapture ();
 	notify_releasedcapture(infoPtr);
+        TRACKBAR_ActivateToolTip(infoPtr, FALSE);
+    }
+    if (infoPtr->flags & TB_AUTO_PAGE) {
+	KillTimer (infoPtr->hwndSelf, TB_REFRESH_TIMER);
+        infoPtr->flags &= ~TB_AUTO_PAGE;
+        ReleaseCapture ();
+	notify_releasedcapture(infoPtr);
     }
-
-    TRACKBAR_ActivateToolTip(infoPtr, FALSE);
 
     return 0;
 }
@@ -1287,6 +1321,19 @@
 }
 
 
+static LRESULT
+TRACKBAR_Timer (TRACKBAR_INFO *infoPtr, INT wTimerID, TIMERPROC *tmrpc)
+{
+    if (infoPtr->flags & TB_AUTO_PAGE) {
+	POINT pt;
+	if (GetCursorPos(&pt))
+	    if (ScreenToClient(infoPtr->hwndSelf, &pt))
+		TRACKBAR_AutoPage(infoPtr, pt);
+    }
+    return 0;
+}
+
+
 static BOOL
 TRACKBAR_SendNotify (TRACKBAR_INFO *infoPtr, UINT code)
 {
@@ -1309,8 +1356,14 @@
 
     TRACE("(x=%d. y=%d)\n", pts.x, pts.y);
 
-    if (!(infoPtr->flags & TB_DRAG_MODE))
+    if (infoPtr->flags & TB_AUTO_PAGE) {
+	POINT pt;
+	POINTSTOPOINT(pt, pts);
+	TRACKBAR_AutoPage (infoPtr, pt);
 	return TRUE;
+    }
+
+    if (!(infoPtr->flags & TB_DRAG_MODE)) return TRUE;
 
     dragPos = TRACKBAR_ConvertPlaceToPosition (infoPtr, clickPlace,
                                                dwStyle & TBS_VERT);
@@ -1363,20 +1416,12 @@
     case VK_NEXT:
 	if (downIsLeft) goto page_left;
     page_right:
-        if (infoPtr->lPos == infoPtr->lRangeMax) return FALSE;
-        infoPtr->lPos += infoPtr->lPageSize;
-        if (infoPtr->lPos > infoPtr->lRangeMax)
-            infoPtr->lPos = infoPtr->lRangeMax;
-        TRACKBAR_SendNotify (infoPtr, TB_PAGEUP);
+	TRACKBAR_PageUp(infoPtr);
         break;
     case VK_PRIOR:
 	if (downIsLeft) goto page_right;
     page_left:
-        if (infoPtr->lPos == infoPtr->lRangeMin) return FALSE;
-        infoPtr->lPos -= infoPtr->lPageSize;
-        if (infoPtr->lPos < infoPtr->lRangeMin)
-            infoPtr->lPos = infoPtr->lRangeMin;
-        TRACKBAR_SendNotify (infoPtr, TB_PAGEDOWN);
+	TRACKBAR_PageDown(infoPtr);
         break;
     case VK_HOME:
         if (infoPtr->lPos == infoPtr->lRangeMin) return FALSE;
@@ -1579,7 +1624,8 @@
     case WM_SIZE:
         return TRACKBAR_Size (infoPtr, wParam, LOWORD(lParam), HIWORD(lParam));
 
-/*	case WM_TIMER: */
+    case WM_TIMER:
+	return TRACKBAR_Timer (infoPtr, (INT)wParam, (TIMERPROC *)lParam);
 
     case WM_WININICHANGE:
         return TRACKBAR_InitializeThumb (infoPtr);




More information about the wine-patches mailing list