From 7bbf35d799607f27798c04e1a2292bdcf2d5e8e9 Mon Sep 17 00:00:00 2001 From: wolfsuit Date: Wed, 17 Dec 2003 18:08:29 +0000 Subject: Import fix for jerky scrollbar behavior from TOT. --- ChangeLog | 9 ++++ macosx/tkMacOSXScrlbr.c | 134 ++++++++++++++++++++++++++++++------------------ 2 files changed, 93 insertions(+), 50 deletions(-) diff --git a/ChangeLog b/ChangeLog index c53fa4d..1279bfa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2003-12-17 Jim Ingham + + * macosx/tkMacOSXScrlbr.c: Reworking Vince's fix to [Bug 842952]. + This version is clearer, and works helps keep the mouse better pinned to the + scrollbar. I also removed the glitch where the scrollbar would jump get + its middle over the mouse when you first moved it. + + Import from TOT. + 2003-12-11 David Gravereaux win/winMain.c: Backed-out yesterdays change. Reverted to 1.15 for diff --git a/macosx/tkMacOSXScrlbr.c b/macosx/tkMacOSXScrlbr.c index ecf7c59..f7e40e5 100644 --- a/macosx/tkMacOSXScrlbr.c +++ b/macosx/tkMacOSXScrlbr.c @@ -11,7 +11,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkMacOSXScrlbr.c,v 1.5 2002/11/20 05:21:08 wolfsuit Exp $ + * RCS: @(#) $Id: tkMacOSXScrlbr.c,v 1.5.2.1 2003/12/17 18:08:29 wolfsuit Exp $ */ #include "tkScrollbar.h" @@ -42,8 +42,8 @@ enum { #define MIN_SLIDER_LENGTH 5 #define MIN_SCROLLBAR_VALUE 0 -#define MAX_SCROLLBAR_VALUE 1000 -#define MAX_SCROLLBAR_DVALUE 1000.0 +#define SCROLLBAR_SCALING_VALUE 100000 +#define SCROLLBAR_SCALING_DVALUE 100000.0 /* * Declaration of Windows specific scrollbar structure. @@ -95,8 +95,12 @@ typedef struct MacScrollbar { */ static ControlActionUPP scrollActionProc = NULL; /* Pointer to func. */ static ThumbActionUPP thumbActionProc = NULL; /* Pointer to func. */ -static TkScrollbar *activeScrollPtr = NULL; /* Non-null when in thumb */ +static TkScrollbar *activeScrollPtr = NULL; /* Non-null when in thumb */ /* proc. */ +static Point activePoint; /* Used when + * activeScrollPtr is + * non-NULL */ + /* * Forward declarations for procedures defined later in this file: */ @@ -237,9 +241,9 @@ TkpDisplayScrollbar( if (macScrollPtr->sbHandle == NULL) { Rect r; - SInt16 initialValue; - SInt16 minValue; - SInt16 maxValue; + SInt32 initialValue; + SInt32 minValue; + SInt32 maxValue; SInt16 procID; WindowRef frontNonFloating; @@ -247,7 +251,7 @@ TkpDisplayScrollbar( r.right = r.bottom = 1; minValue = MIN_SCROLLBAR_VALUE; - maxValue = MAX_SCROLLBAR_VALUE; + maxValue = SCROLLBAR_SCALING_VALUE; initialValue = (minValue + maxValue)/2; procID = kControlScrollBarLiveProc; @@ -578,7 +582,7 @@ ThumbActionProc() register TkScrollbar *scrollPtr = activeScrollPtr; register MacScrollbar *macScrollPtr = (MacScrollbar *) activeScrollPtr; Tcl_DString cmdString; - int origValue, trackBarPin; + int origValue; double thumbWidth, newFirstFraction, trackBarSize; char valueString[40]; Point currentPoint = { 0, 0 }; @@ -603,21 +607,20 @@ ThumbActionProc() * Note: the arrowLength is equal to the thumb width of a Mac scrollbar. */ - origValue = GetControlValue(macScrollPtr->sbHandle); + origValue = GetControl32BitValue(macScrollPtr->sbHandle); GetControlBounds(macScrollPtr->sbHandle, &trackRect); + + thumbWidth = scrollPtr->lastFraction - scrollPtr->firstFraction; + if (scrollPtr->vertical == true) { trackBarSize = (double) (trackRect.bottom - trackRect.top - - (scrollPtr->arrowLength * 3)); - trackBarPin = trackRect.top + scrollPtr->arrowLength - + (scrollPtr->arrowLength / 2); - InsetRect(&trackRect, -25, -113); + - (scrollPtr->arrowLength * 3)); + InsetRect(&trackRect, -50, -226); } else { trackBarSize = (double) (trackRect.right - trackRect.left - - (scrollPtr->arrowLength * 3)); - trackBarPin = trackRect.left + scrollPtr->arrowLength - + (scrollPtr->arrowLength / 2); - InsetRect(&trackRect, -113, -25); + - (scrollPtr->arrowLength * 3)); + InsetRect(&trackRect, -226, -50); } /* @@ -638,24 +641,29 @@ ThumbActionProc() && ((trackingResult == kMouseTrackingMouseDragged) || (trackingResult == kMouseTrackingMouseMoved))) { /* - * Calculating this value is a little tricky. We need to calculate a - * value for where the thumb would be in a Motif widget (variable - * thumb). This value is what the "command" expects and is what will - * be resent to the scrollbar to update its value. + * Calculate where the scrollbar should move to, and reset the + * activePoint to where we are now. */ - thumbWidth = scrollPtr->lastFraction - scrollPtr->firstFraction; + newFirstFraction = scrollPtr->firstFraction; if (PtInRect(currentPoint, &trackRect)) { + double pixDiff; + double fracDelta; if (scrollPtr->vertical == true) { - newFirstFraction = (1.0 - thumbWidth) * - ((double) (currentPoint.v - trackBarPin) / trackBarSize); + pixDiff = (double)(currentPoint.v - activePoint.v); } else { - newFirstFraction = (1.0 - thumbWidth) * - ((double) (currentPoint.h - trackBarPin) / trackBarSize); + pixDiff = (double)(currentPoint.h - activePoint.h); } - } else { - newFirstFraction = ((double) origValue / MAX_SCROLLBAR_DVALUE) - * (1.0 - thumbWidth); - } + fracDelta = pixDiff/(trackBarSize); + newFirstFraction += fracDelta; + if (newFirstFraction > 1.0) { + newFirstFraction = 1.0; + } else if (newFirstFraction < 0.0) { + newFirstFraction = 0.0; + } + } + + activePoint = currentPoint; + sprintf(valueString, "%g", newFirstFraction); Tcl_DStringSetLength(&cmdString, 0); Tcl_DStringAppend(&cmdString, scrollPtr->command, @@ -763,10 +771,10 @@ ScrollbarBindProc( macScrollPtr->macFlags |= IN_MODAL_LOOP; if (eventPtr->type == ButtonPress) { - Point where; - Rect bounds; - int part, x, y, dummy; - unsigned int state; + Point where; + Rect bounds; + int part, x, y, dummy; + unsigned int state; CGrafPtr saveWorld; GDHandle saveDevice; GWorldPtr destPort; @@ -783,8 +791,8 @@ ScrollbarBindProc( TkMacOSXSetUpClippingRgn(Tk_WindowId(scrollPtr->tkwin)); TkMacOSXWinBounds((TkWindow *) scrollPtr->tkwin, &bounds); - where.h = eventPtr->xbutton.x + bounds.left; - where.v = eventPtr->xbutton.y + bounds.top; + where.h = eventPtr->xbutton.x + bounds.left; + where.v = eventPtr->xbutton.y + bounds.top; part = TestControl(macScrollPtr->sbHandle, where); if (part == kControlIndicatorPart && scrollPtr->jump == false) { /* @@ -794,6 +802,8 @@ ScrollbarBindProc( * so the callback may have access to it. */ activeScrollPtr = scrollPtr; + activePoint.h = where.h; + activePoint.v = where.v; part = TrackControl(macScrollPtr->sbHandle, where, (ControlActionUPP) thumbActionProc); activeScrollPtr = NULL; @@ -816,8 +826,9 @@ ScrollbarBindProc( */ thumbWidth = scrollPtr->lastFraction - scrollPtr->firstFraction; - newFirstFraction = (1.0 - thumbWidth) * - ((double) GetControlValue(macScrollPtr->sbHandle) / MAX_SCROLLBAR_DVALUE); + newFirstFraction = (1.0 - thumbWidth) * + ((double) GetControl32BitValue(macScrollPtr->sbHandle) / SCROLLBAR_SCALING_DVALUE); + sprintf(valueString, "%g", newFirstFraction); Tcl_DStringInit(&cmdString); @@ -931,8 +942,8 @@ UpdateControlValues( Tk_Window tkwin = scrollPtr->tkwin; MacDrawable * macDraw = (MacDrawable *) Tk_WindowId(scrollPtr->tkwin); WindowRef windowRef = GetControlOwner(macScrollPtr->sbHandle); - double middle; - SInt32 viewSize; + double dViewSize; + SInt32 viewSize, controlMax, controlValue; int flushRight = false; int flushBottom = false; Rect contrlRect, portRect; @@ -1066,23 +1077,46 @@ UpdateControlValues( /* * Given the Tk parameters for the fractions of the start and * end of the thumb, the following calculation determines the - * location for the fixed sized Macintosh thumb. + * location for the Macintosh thumb. + * The Aqua scroll control works as follows. + * The scrollbar's value is the position of the left (or top) side of + * the view area in the content area being scrolled. + * The maximum value of the control is therefore the dimension of + * the content area less the size of the view area. + * Since these values are all integers, and Tk gives the thumb position + * as fractions, we have introduced a scaling factor. + * */ - middle = scrollPtr->firstFraction / (scrollPtr->firstFraction + - (1.0 - scrollPtr->lastFraction)); + dViewSize = (scrollPtr->lastFraction - scrollPtr->firstFraction) + * SCROLLBAR_SCALING_DVALUE; - viewSize = (SInt32) ((scrollPtr->lastFraction - scrollPtr->firstFraction) - * MAX_SCROLLBAR_DVALUE); + viewSize = (SInt32) dViewSize; + controlMax = (SInt32) (SCROLLBAR_SCALING_DVALUE - dViewSize); + controlValue = (SInt32) (SCROLLBAR_SCALING_DVALUE * scrollPtr->firstFraction); + + SetControlViewSize(macScrollPtr->sbHandle,viewSize); + SetControl32BitValue(macScrollPtr->sbHandle, controlValue); + SetControl32BitMaximum(macScrollPtr->sbHandle, controlMax); + +#if 0 + middle = scrollPtr->firstFraction / + (1.0 - (scrollPtr->lastFraction - scrollPtr->firstFraction)); + viewSize = (SInt32) ((scrollPtr->lastFraction - scrollPtr->firstFraction) + * SCROLLBAR_SCALING_DVALUE + / (1.0 - (scrollPtr->lastFraction - scrollPtr->firstFraction))); + + SetControlViewSize(macScrollPtr->sbHandle,viewSize); - SetControlValue(macScrollPtr->sbHandle, - (short) (middle * MAX_SCROLLBAR_VALUE) ); + SetControl32BitValue(macScrollPtr->sbHandle, + (middle) ); +#endif contrlHilite = GetControlHilite(macScrollPtr->sbHandle); - SetControlMinimum(macScrollPtr->sbHandle, 0); + SetControl32BitMinimum(macScrollPtr->sbHandle, 0); if ( contrlHilite == 0 || contrlHilite == 255) { if (scrollPtr->firstFraction == 0.0 && scrollPtr->lastFraction == 1.0) { - SetControlMinimum(macScrollPtr->sbHandle, MAX_SCROLLBAR_VALUE); + SetControl32BitMinimum(macScrollPtr->sbHandle, SCROLLBAR_SCALING_VALUE); } else { HiliteControl(macScrollPtr->sbHandle, 0); } -- cgit v0.12