summaryrefslogtreecommitdiffstats
path: root/macosx/tkMacOSXScrlbr.c
diff options
context:
space:
mode:
authordas <das>2007-04-29 02:26:47 (GMT)
committerdas <das>2007-04-29 02:26:47 (GMT)
commit0537d1c70efd92c5bd39a4047c02524d70ad7a58 (patch)
treed8296fa62af852c5f2e743159973d854366b69fa /macosx/tkMacOSXScrlbr.c
parent9025e3c799817de9b380db2644dd47a61924c5eb (diff)
downloadtk-0537d1c70efd92c5bd39a4047c02524d70ad7a58.zip
tk-0537d1c70efd92c5bd39a4047c02524d70ad7a58.tar.gz
tk-0537d1c70efd92c5bd39a4047c02524d70ad7a58.tar.bz2
* macosx/tkMacOSXCarbonEvents.c: add window event target carbon event
* macosx/tkMacOSXEvent.c: handler for all kEventClassWindow and * macosx/tkMacOSXEvent.h: kEventClassMouse events; move all * macosx/tkMacOSXNotify.c: remaining events except for * macosx/tkMacOSXWindowEvent.c: kEventClassKeyboard from dispatcher to application event handler; pass event handler callRef downstream; fix debug event tracing; process all tcl event types in carbon event timer; delay carbon event timer first fire; add TkMacOSXTrackingLoop() to mark enter/exit of event tracking loop during which all tcl events but only carbon update events should be processed by the timer (replaces various calls to Tcl_SetServiceMode()); rename TkMacOSXReceiveAndProcessEvent() to TkMacOSXReceiveAndDispatchEvent(), move it from tkMacOSXEvent.c to tkMacOSXCarbonEvents.c and modify it to dequeue only update events during a tracking loop; add TkMacOSXRunTclEventLoop() to standardize the various ways in use to run the tcl event loop; add handling of kEventClassAppearance events (for ScrollBarVariantChanged event). * macosx/tkMacOSXDialog.c: use new TkMacOSXTrackingLoop() around * macosx/tkMacOSXEvent.c: blocking API that puts up modal dialogs * macosx/tkMacOSXMenu.c: or when entering/exiting menu/control * macosx/tkMacOSXMouseEvent.c: tracking, window dragging and other * macosx/tkMacOSXScale.c: mouse tracking loops. * macosx/tkMacOSXScrlbr.c: * macosx/tkMacOSXWindowEvent.c: * macosx/tkMacOSXWm.c: * macosx/tkMacOSXDialog.c: use new TkMacOSXRunTclEventLoop() * macosx/tkMacOSXScale.c: instead of Tcl_DoOneEvent(), * macosx/tkMacOSXScrlbr.c: Tcl_ServiceAll(), TclServiceIdle() * macosx/tkMacOSXWindowEvent.c: and Tcl_GlobalEval("update idletasks"). * macosx/tkMacOSXColor.c: make available as Tk system colors all * macosx/tkMacOSXPort.h: appearance manager brushes, text colors and backgrounds with new and legacy names, as well as the fully transparent color "systemTransparent"; add TkMacOSXSetColorIn{Port,Context}() to directly set an X pixel color value in the current QD port resp. the given CG context without requiring passage through rgb representation (lossy for most system colors); modernize/remove Classic-era code; replace crufty strcmp() elseifs by Tcl_GetIndexFromObjStruct(). * macosx/tkMacOSXButton.c: use new TkMacOSXSetColorInPort() * macosx/tkMacOSXDraw.c: instead of setting rgb color directly * macosx/tkMacOSXMenubutton.c: to allow for non-rgb system colors. * macosx/tkMacOSXCursor.c: implement "none" cursor as on other platforms [Patch 1615427]; add all missing appearance manager cursors. * macosx/tkMacOSXDefault.h: set SELECT_FG_COLORs to None to match aqua L&F; use standard system color names; use new 'menu' system font; correct default scrollbar width. * macosx/tkMacOSXDraw.c: standardize initialization, use and * macosx/tkMacOSXInt.h: emptying of various static temp rgns * macosx/tkMacOSXRegion.c: onto two global RgnHandles; in debug * macosx/tkMacOSXSubwindows.c: builds, verify emptiness of these temp * macosx/tkMacOSXWindowEvent.c: rgns before use. * macosx/tkMacOSXDraw.c: add TkMacOSX{Setup,Restore}DrawingContext() to * macosx/tkMacOSXInt.h: abstract common setup & teardown of drawing environment (for both CG and QD); save/restore QD theme drawing state; handle GC clip region; add TkpClipDrawableToRect() to allow clipped drawing into drawable regardless of GC used; use new system color "systemWindowHeaderBackground" to setup background in themed toplevels; correct implementation of TkMacOSXMakeStippleMap(). * macosx/tkMacOSXEntry.c: use new TkMacOSXSetupDrawingContext() and * macosx/tkMacOSXFont.c: TkMacOSXRestoreDrawingContext() instead of various setup/teardown procs like TkMacOSX{SetUp,Release}CGContext(), TkMacOSXQuarz{Start,End}Draw(), TkMacOSXSetUpGraphicsPort() etc. * macosx/tkMacOSXEmbed.c: add CG context and drawable clip rgn fields * macosx/tkMacOSXInt.h: to MacDrawable struct. * macosx/tkMacOSXSubwindows.c: * macosx/tkMacOSXDialog.c: make -parent option of tk_getOpenFile et al. use the sheet version of NavServices dialogs; ensure native parent win exists before using StandardSheet API for tk_messageBox [Bug 1677611]; force sheets to behave like app-modal dialogs via WindowModality() API; use more modern ColorPicker API. * macosx/tkAboutDlg.r: use themed movable modal dialog, fix (c) year. * macosx/tkMacOSXEntry.c: take xOff/yOff of MacDrawable into account when computing locations/bounds to ensure correct posititioning when not drawing into intermediate pixmap. * macosx/tkMacOSXFont.c: use appearance manager API to map system font * macosx/tkMacOSXFont.h: names to TkFonts; add "menu" system font for menu item text drawing from MDEF; disable broken QD stippling. * macosx/tkMacOSXMenu.c: large-scale rewrite of custom * macosx/tkMacOSXMenu.r (removed): MDEF and related code that * unix/Makefile.in: restores many longtime-MIA features to working order (e.g. images, custom colors & fonts in menus etc); implement compound menu items; use Appearance Mgr and ThemeText APIs to mimic native MDEF as closely as possible when default "menu" system font is used; remove now obsolete SICN drawing code and resources. * macosx/tkMacOSXCarbonEvents.c: handle additional menu carbon events * macosx/tkMacOSXEvent.c: in order to support <<MenuSelect>> in * macosx/tkMacOSXMenu.c: the menubar and in menus that are not * macosx/tkMacOSXMenus.c: using the custom MDEF [Bug 1620826]; fix early and missing clearing of current Tk active menu entry; fix extraneous sending of <<MenuSelect>> during active menu entry clearing. * macosx/tkMacOSXMouseEvent.c: add support for async window dragging by the window server; set the corresponding window attribute by default. * macosx/tkMacOSXMouseEvent.c: rationalized handling order of non-mousedown events; add TkMacOSXModifierState() to retrieve the current key modifiers in carbon format. * macosx/tkMacOSXScrlbr.c: use appearance manager API to retrieve scrollbar component metrics; add awareness of multiple possibilites for scrollbar arrow position in aqua and handle user changes to arrow position pref; handle difference in metrics of small & large scrollbar variants; handle aqua "jump to here" scrollbar behaviour; correct computation of scroll view size and position; enforce min scrollbar height to avoid scrollbar component overlap; erase scrollbar area outside of standard width; remove broken auto-adjust code; account for window class when leaving space for grow box; remove code to manually draw grow box; use modern API for thumb scroll proc; replace HiliteControl() by modern API; replace control mgr constants with appearance mgr equivalents. * macosx/tkMacOSXSubwindows.c: use SetWindowBounds() API instead of SizeWindow(); invalidate clip regions after X{Map,Unmap}Window as fix for [Bug 940117] made them dependent on mapping state; remove unneeded calls to TkMacOSXInvalClipRgns() and unnecessary setting of QD port; use native-endian pixmap on intel; remove obsolete pixmap pix locking. * macosx/tkMacOSXWindowEvent.c: handle only the first of a batch of kEventAppAvailableWindowBoundsChanged events sent per transaction; handle kEventWindowBoundsChanged event to support live window resizing and centralized sending of location/size changed ConfigureNotify events; ensure HIGrowBox is redrawn after bounds change; constrain window after dragging to ensure titlebar is not inacessible offscreen or under dock/menubar; handle kEventWindowGetRegion and kEventWindowDrawContent for transparent windows to mark resp. paint content region as transparent; handle kEventWindowConstrain for fullscreen windows to ensure bounds match new screen size; enter/exit fullscreen UIMode upon activation/deactivation of fullscreen window. * macosx/tkMacOSXWm.c: use live-resize and async-drag carbon window * macosx/tkMacOSXWm.h: attributes for toplevels by default; implement new [wm attributes] -topmost, -transparent and -fullscreen; refactor WmAttributesCmd() parallelling the tkUnixWm.c implementation, use thus factored proc to set proxy icon from [wm iconbitmap]; dynamically determine default values for toplevel min and max sizes (similar to tkWinWm.c impl): min sizes depend on window class & attributes to ensure visibility of all titlebar widgets and grow box, max sizes depend on maximal window bounds for all active displays; factor out code that puts into effect changes to master or override_redirect; use RepositionWindow() API to determine staggered initial window bounds; correct resize limit calculations, handle gridding and use modern resize API in TkMacOSXGrowToplevel(); remove sending of ConfigureNotify after resize or zoom (now handled by BoundsChanged handler); correct composite carbon window attribute handling, remove currently unusable attributes and add new attributes in [tk::unsupported::MacWindowStyle]; ensure validity of window class and attributes before use; apply changes to window class when handling carbon window attribute changes (if HIWindowChangeClass() API available); add debug build warning message when deprecated window style is used instead of window class; use transparent HIGrowBox for resizable windows; avoid unnecessary calls to window structure width API; use tcl time API in TkpGetMS(); add TkMacOSXEnterExitFullscreen() to enter/exit UIMode with dock and menubar hidden; restrict wmTracing output to debug builds; remove unneeded calls to TkMacOSXInvalClipRgns() and unnecessary setting of QD port; workaround GetWindowStructureWidths() Carbon bug (bogus results for never-mapped floating windows). * macosx/tkMacOSXXStubs.c (TkMacOSXDisplayChanged): add maximal window bounds field to Screen record (in ext_data), computed as the union of available window positioning bounds of all graphics devices (displays). * macosx/tkMacOSXBitmap.c: fix macRoman encoding leak. * macosx/tkMacOSXCursor.c: * macosx/tkMacOSXDebug.c (TkMacOSXCarbonEventToAscii): use static * macosx/tkMacOSXDebug.h: buffer to simplify callers; const fixes. * macosx/tkMacOSXBitmap.c: use more efficient QDSwapPort() instead of * macosx/tkMacOSXButton.c: GetPort()/SetPort()/GetGWorld()/SetGWorld(). * macosx/tkMacOSXDraw.c: * macosx/tkMacOSXFont.c: * macosx/tkMacOSXMenubutton.c: * macosx/tkMacOSXScale.c: * macosx/tkMacOSXScrlbr.c: * macosx/tkMacOSXXStubs.c: * macosx/tkMacOSXColor.c: use kHIToolboxVersionNumber for runtime OS * macosx/tkMacOSXEntry.c: version check rather than Gestalt() etc. * macosx/tkMacOSXInt.h: * macosx/tkMacOSXWm.c: * macosx/tkMacOSXDraw.c: remove obsolete and now incorrect * macosx/tkMacOSXInt.h: tkMenuCascadeRgn clipping code. * macosx/tkMacOSXMenu.c: * macosx/tkMacOSXHLEvents.c: replace Tcl_GlobalEval() resp. Tcl_Eval() * macosx/tkMacOSXScrlbr.c: by Tcl_EvalEx(). * macosx/tkMacOSXInit.c: * macosx/tkMacOSXInit.c (TkpInit): reorder initialization steps. * macosx/tkMacOSXKeyEvent.c: remove pre-10.2 support. * macosx/tkMacOSXMenus.c: remove now useless call to TkMacOSXHandleTearoffMenu(); use \x.. quoting for non-latin1 macroman literar chars to allow file to be edited as utf-8. * macosx/tkMacOSXScale.c: replace TrackControl() by modern * macosx/tkMacOSXScrlbr.c: HandleControlClick() API (using new TkMacOSXModifierState()). * macosx/tkMacOSXInt.h: move all constant #defines needed to * macosx/tkMacOSXColor.c: support building on older OS X releases * macosx/tkMacOSXEvent.h: to a central location in tkMacOSXInt.h. * macosx/tkMacOSXFont.c: * macosx/tkMacOSXMenu.c: * macosx/tkMacOSXMenubutton.c: * macosx/tkMacOSXMenus.c: * macosx/tkMacOSXMouseEvent.c: * macosx/tkMacOSXWm.c: * macosx/tkMacOSXInt.h: add ChkErr() macro to factor out * macosx/tkMacOSXButton.c: Carbon OSStatus return value checking * macosx/tkMacOSXCarbonEvents.c: and TkMacOSXDbgMsg() macro to factour * macosx/tkMacOSXClipboard.c: out debug message output; use these * macosx/tkMacOSXColor.c: macros to replace #ifdef TK_MAC_DEBUG * macosx/tkMacOSXCursor.c: blocks & direct printing to stderr, * macosx/tkMacOSXDebug.c: and to do additional OSStatus return * macosx/tkMacOSXDialog.c: checking, and to standardize OSStatus * macosx/tkMacOSXDraw.c: usage. * macosx/tkMacOSXEntry.c: * macosx/tkMacOSXEvent.c: * macosx/tkMacOSXFont.c: * macosx/tkMacOSXHLEvents.c: * macosx/tkMacOSXInit.c: * macosx/tkMacOSXKeyEvent.c: * macosx/tkMacOSXMenu.c: * macosx/tkMacOSXMenubutton.c: * macosx/tkMacOSXMenus.c: * macosx/tkMacOSXMouseEvent.c: * macosx/tkMacOSXScrlbr.c: * macosx/tkMacOSXSubwindows.c: * macosx/tkMacOSXWindowEvent.c: * macosx/tkMacOSXWm.c: * macosx/tkMacOSXXStubs.c: * macosx/tkMacOSXSend.c: remove duplicate/unused declarations. * macosx/tkMacOSXXStubs.c: * macosx/tkMacOSXDebug.c: const fixes. * macosx/tkMacOSXInit.c: * macosx/tkMacOSXTest.c: * macosx/tkMacOSXWm.c: * macosx/tkMacOSXXStubs.c: * macosx/Wish-Info.plist.in: add tcl document extensions/mime types and LSMinimumSystemVersion, LSRequiresCarbon & NSAppleScriptEnabled keys. * macosx/tkMacOSXAETE.r: fix whitespace. * macosx/tkMacOSXConfig.c: * macosx/tkMacOSXCursors.r: * macosx/tkMacOSXKeyboard.c: * macosx/tkMacOSXSend.c: * macosx/tkMacOSXXCursors.r: * macosx/README: * macosx/Makefile: fix/add copyright and license refs. * macosx/Tk-Info.plist.in: * macosx/Wish-Info.plist.in: * macosx/tkMacOSX.h:
Diffstat (limited to 'macosx/tkMacOSXScrlbr.c')
-rw-r--r--macosx/tkMacOSXScrlbr.c1253
1 files changed, 581 insertions, 672 deletions
diff --git a/macosx/tkMacOSXScrlbr.c b/macosx/tkMacOSXScrlbr.c
index 011b565..0fa6561 100644
--- a/macosx/tkMacOSXScrlbr.c
+++ b/macosx/tkMacOSXScrlbr.c
@@ -1,172 +1,206 @@
-/*
+/*
* tkMacOSXScrollbar.c --
*
- * This file implements the Macintosh specific portion of the scrollbar
- * widget. The Macintosh scrollbar may also draw a windows grow
- * region under certain cases.
+ * This file implements the Macintosh specific portion of the scrollbar
+ * widget. The Macintosh scrollbar may also draw a windows grow
+ * region under certain cases.
*
* Copyright (c) 1996 by Sun Microsystems, Inc.
* Copyright 2001, Apple Computer, Inc.
+ * Copyright (c) 2006-2007 Daniel A. Steffen <das@users.sourceforge.net>
*
* 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.2.10 2006/08/24 05:22:33 das Exp $
+ * RCS: @(#) $Id: tkMacOSXScrlbr.c,v 1.5.2.11 2007/04/29 02:26:50 das Exp $
*/
#include "tkMacOSXInt.h"
#include "tkScrollbar.h"
#include "tkMacOSXDebug.h"
-#include "tclInt.h" /* for TclServiceIdle() */
+#define MIN_SCROLLBAR_VALUE 0
+#define SCROLLBAR_SCALING_VALUE ((float)LONG_MAX)
/*
- * The following definitions should really be in MacOS
- * header files. They are included here as this is the only
- * file that needs the declarations.
+ * Declaration of Mac specific scrollbar structure.
*/
-typedef pascal void (*ThumbActionFunc)(void);
-
-typedef ThumbActionFunc ThumbActionUPP;
-
-enum {
- uppThumbActionProcInfo = kPascalStackBased
-};
-#define NewThumbActionProc(userRoutine) ((ThumbActionUPP) (userRoutine))
+typedef struct MacScrollbar {
+ TkScrollbar info; /* Generic scrollbar info */
+ ControlRef sbHandle; /* Scrollbar control */
+ int macFlags; /* Various flags; see below */
+ Rect eraseRect; /* Rect to erase before drawing control */
+} MacScrollbar;
/*
- * Minimum slider length, in pixels (designed to make sure that the slider
- * is always easy to grab with the mouse).
+ * Flag bits for scrollbars on the Mac:
+ *
+ * ALREADY_DEAD: Non-zero means this scrollbar has been
+ * destroyed, but has not been cleaned up.
+ * IN_MODAL_LOOP: Non-zero means this scrollbar is in the middle
+ * of a modal loop.
+ * ACTIVE: Non-zero means this window is currently
+ * active (in the foreground).
*/
-#define MIN_SLIDER_LENGTH 5
-#define MIN_SCROLLBAR_VALUE 0
-#define SCROLLBAR_SCALING_VALUE 100000
-#define SCROLLBAR_SCALING_DVALUE 100000.0
+#define ALREADY_DEAD 1
+#define IN_MODAL_LOOP 2
+#define ACTIVE 4
/*
- * Declaration of Windows specific scrollbar structure.
+ * Globals uses locally in this file.
*/
-
-typedef struct MacScrollbar {
- TkScrollbar info; /* Generic scrollbar info */
- ControlRef sbHandle; /* Opaque handle to the Scrollbar contol struct */
- int macFlags; /* Various flags; see below */
-} MacScrollbar;
-
-/* Handle to the Scrollbar control structure */
-
+static ControlActionUPP scrollActionProc = NULL; /* Pointer to func. */
+static ControlActionUPP thumbActionProc = NULL; /* Pointer to func. */
+static Point mouseDownPoint; /* Used to store the coordinates where the */
+ /* mouse was first pressed to begin */
+ /* dragging the thumb, because */
+ /* ThumbActionProc can't take any args. */
+
+typedef struct ScrollbarMetrics {
+ SInt32 width, minHeight, minThumbHeight;
+ short topArrowHeight, bottomArrowHeight;
+ ControlSize size;
+} ScrollbarMetrics;
+
+static ScrollbarMetrics metrics[2] = {
+ {15, 54, 26, 14, 14, kControlSizeNormal}, /* kThemeScrollBarMedium */
+ {11, 40, 20, 10, 10, kControlSizeSmall}, /* kThemeScrollBarSmall */
+};
/*
- * Flag bits for scrollbars on the Mac:
- *
- * ALREADY_DEAD: Non-zero means this scrollbar has been
- * destroyed, but has not been cleaned up.
- * IN_MODAL_LOOP: Non-zero means this scrollbar is in the middle
- * of a modal loop.
- * ACTIVE: Non-zero means this window is currently
- * active (in the foreground).
- * FLUSH_TOP: Flush with top of Mac window.
- * FLUSH_BOTTOM: Flush with bottom of Mac window.
- * FLUSH_RIGHT: Flush with right of Mac window.
- * FLUSH_LEFT: Flush with left of Mac window.
- * SCROLLBAR_GROW: Non-zero means this window draws the grow
- * region for the toplevel window.
- * AUTO_ADJUST: Non-zero means we automatically adjust
- * the size of the widget to align correctly
- * along a Mac window.
- * DRAW_GROW: Non-zero means we draw the grow region.
+ * This variable holds the default width for a scrollbar in string form for
+ * use in a Tk_ConfigSpec.
*/
-#define ALREADY_DEAD 1
-#define IN_MODAL_LOOP 2
-#define ACTIVE 4
-#define FLUSH_TOP 8
-#define FLUSH_BOTTOM 16
-#define FLUSH_RIGHT 32
-#define FLUSH_LEFT 64
-#define SCROLLBAR_GROW 128
-#define AUTO_ADJUST 256
-#define DRAW_GROW 512
+static char defWidth[TCL_INTEGER_SPACE];
/*
- * Globals uses locally in this file.
- */
-static ControlActionUPP scrollActionProc = NULL; /* Pointer to func. */
-static ThumbActionUPP thumbActionProc = NULL; /* Pointer to func. */
-static TkScrollbar *activeScrollPtr = NULL; /* Non-null when in thumb */
- /* proc. */
-static Point mouseDownPoint; /* Used when activeScrollPtr is non-NULL */
- /* to store the coordinates where the */
- /* mouse was first pressed to begin */
- /* dragging the thumb, because */
- /* ThumbActionProc can't take any args. */
-
-/*
* Forward declarations for procedures defined later in this file:
*/
-static pascal void ScrollbarActionProc _ANSI_ARGS_((ControlRef theControl, ControlPartCode partCode));
-static int ScrollbarBindProc _ANSI_ARGS_((ClientData clientData,
- Tcl_Interp *interp, XEvent *eventPtr,
- Tk_Window tkwin, KeySym keySym));
-static void ScrollbarEventProc _ANSI_ARGS_(( ClientData clientData, XEvent *eventPtr));
-static pascal void ThumbActionProc _ANSI_ARGS_((void));
-static void UpdateControlValues _ANSI_ARGS_((MacScrollbar *macScrollPtr));
-
+static pascal void ScrollbarActionProc(ControlRef theControl,
+ ControlPartCode partCode);
+static pascal void ThumbActionProc(ControlRef theControl,
+ ControlPartCode partCode);
+static int ScrollbarBindProc(ClientData clientData, Tcl_Interp *interp,
+ XEvent *eventPtr, Tk_Window tkwin, KeySym keySym);
+static void ScrollbarEventProc(ClientData clientData, XEvent *eventPtr);
+static void UpdateControlValues(MacScrollbar *macScrollPtr);
+
/*
- * The class procedure table for the scrollbar widget. Leave the proc fields
+ * The class procedure table for the scrollbar widget. Leave the proc fields
* initialized to NULL, which should happen automatically because of the scope
* at which the variable is declared.
*/
Tk_ClassProcs tkpScrollbarProcs = {
- sizeof(Tk_ClassProcs) /* size */
+ sizeof(Tk_ClassProcs) /* size */
};
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkMacOSXInitScrollbarMetrics --
+ *
+ * This function initializes the current system metrics for a
+ * scrollbar.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Updates the geometry cache info for all scrollbars.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkMacOSXInitScrollbarMetrics(void)
+{
+ const short height = 100, width = 50;
+ ThemeTrackDrawInfo info = {0, {0, 0, height, width}, 0, 1, 0, 0,
+ kThemeTrackShowThumb, kThemeTrackActive, 0, {{1, 0}}};
+ Rect bounds;
+ Tk_ConfigSpec *specPtr;
+
+ ChkErr(GetThemeMetric, kThemeMetricScrollBarWidth, &metrics[0].width);
+ ChkErr(GetThemeMetric, kThemeMetricScrollBarMinThumbHeight,
+ &metrics[0].minThumbHeight);
+ info.kind = kThemeScrollBarMedium;
+ ChkErr(GetThemeTrackDragRect, &info, &bounds);
+ metrics[0].topArrowHeight = bounds.top;
+ metrics[0].bottomArrowHeight = height - bounds.bottom;
+ metrics[0].minHeight = metrics[0].minThumbHeight +
+ metrics[0].topArrowHeight + metrics[0].bottomArrowHeight;
+ ChkErr(GetThemeMetric, kThemeMetricSmallScrollBarWidth, &metrics[1].width);
+ ChkErr(GetThemeMetric, kThemeMetricSmallScrollBarMinThumbHeight,
+ &metrics[1].minThumbHeight);
+ info.kind = kThemeScrollBarSmall;
+ ChkErr(GetThemeTrackDragRect, &info, &bounds);
+ metrics[1].topArrowHeight = bounds.top;
+ metrics[1].bottomArrowHeight = height - bounds.bottom;
+ metrics[1].minHeight = metrics[1].minThumbHeight +
+ metrics[1].topArrowHeight + metrics[1].bottomArrowHeight;
+
+ sprintf(defWidth, "%ld", metrics[0].width);
+ for (specPtr = tkpScrollbarConfigSpecs; specPtr->type != TK_CONFIG_END;
+ specPtr++) {
+ if (specPtr->offset == Tk_Offset(TkScrollbar, width)) {
+ specPtr->defValue = defWidth;
+ }
+ }
+}
/*
*----------------------------------------------------------------------
*
* TkpCreateScrollbar --
*
- * Allocate a new TkScrollbar structure.
+ * Allocate a new TkScrollbar structure.
*
* Results:
- * Returns a newly allocated TkScrollbar structure.
+ * Returns a newly allocated TkScrollbar structure.
*
* Side effects:
- * None.
+ * None.
*
*----------------------------------------------------------------------
*/
TkScrollbar *
TkpCreateScrollbar(
- Tk_Window tkwin) /* New Tk Window. */
+ Tk_Window tkwin) /* New Tk Window. */
{
+ static int initialized = 0;
MacScrollbar * macScrollPtr;
TkWindow *winPtr = (TkWindow *)tkwin;
-
+
if (scrollActionProc == NULL) {
- scrollActionProc = NewControlActionUPP (ScrollbarActionProc);
- thumbActionProc = NewThumbActionProc(ThumbActionProc);
+ scrollActionProc = NewControlActionUPP(ScrollbarActionProc);
+ thumbActionProc = NewControlActionUPP(ThumbActionProc);
+ }
+ if (!initialized) {
+ TkMacOSXInitScrollbarMetrics();
+ initialized = 1;
}
-
macScrollPtr = (MacScrollbar *) ckalloc(sizeof(MacScrollbar));
macScrollPtr->sbHandle = NULL;
macScrollPtr->macFlags = 0;
+ SetRect(&macScrollPtr->eraseRect, 0, 0, 0, 0);
Tk_CreateEventHandler(tkwin, ActivateMask|ExposureMask|
- StructureNotifyMask|FocusChangeMask,
- ScrollbarEventProc, (ClientData) macScrollPtr);
+ StructureNotifyMask|FocusChangeMask,
+ ScrollbarEventProc, (ClientData) macScrollPtr);
if (!Tcl_GetAssocData(winPtr->mainPtr->interp, "TkScrollbar", NULL)) {
- Tcl_SetAssocData(winPtr->mainPtr->interp, "TkScrollbar", NULL, (ClientData)1);
- TkCreateBindingProcedure(winPtr->mainPtr->interp,
- winPtr->mainPtr->bindingTable,
- (ClientData)Tk_GetUid("Scrollbar"), "<ButtonPress>",
- ScrollbarBindProc, NULL, NULL);
+ Tcl_SetAssocData(winPtr->mainPtr->interp, "TkScrollbar", NULL,
+ (ClientData)1);
+ TkCreateBindingProcedure(winPtr->mainPtr->interp,
+ winPtr->mainPtr->bindingTable,
+ (ClientData)Tk_GetUid("Scrollbar"), "<ButtonPress>",
+ ScrollbarBindProc, NULL, NULL);
}
return (TkScrollbar *) macScrollPtr;
}
@@ -176,142 +210,111 @@ TkpCreateScrollbar(
*
* TkpDisplayScrollbar --
*
- * This procedure redraws the contents of a scrollbar window.
- * It is invoked as a do-when-idle handler, so it only runs
- * when there's nothing else for the application to do.
+ * This procedure redraws the contents of a scrollbar window.
+ * It is invoked as a do-when-idle handler, so it only runs
+ * when there's nothing else for the application to do.
*
* Results:
- * None.
+ * None.
*
* Side effects:
- * Information appears on the screen.
+ * Information appears on the screen.
*
*--------------------------------------------------------------
*/
void
TkpDisplayScrollbar(
- ClientData clientData) /* Information about window. */
+ ClientData clientData) /* Information about window. */
{
TkScrollbar *scrollPtr = (TkScrollbar *) clientData;
MacScrollbar *macScrollPtr = (MacScrollbar *) clientData;
Tk_Window tkwin = scrollPtr->tkwin;
-
MacDrawable *macDraw;
- CGrafPtr saveWorld;
- GDHandle saveDevice;
- GWorldPtr destPort;
+ CGrafPtr destPort, savePort;
+ Boolean portChanged;
WindowRef windowRef;
-
+
if ((scrollPtr->tkwin == NULL) || !Tk_IsMapped(tkwin)) {
- goto done;
+ goto done;
}
/*
* Draw the focus or any 3D relief we may have.
*/
if (scrollPtr->highlightWidth != 0) {
- GC fgGC, bgGC;
-
- bgGC = Tk_GCForColor(scrollPtr->highlightBgColorPtr,
- Tk_WindowId(tkwin));
-
- if (scrollPtr->flags & GOT_FOCUS) {
- fgGC = Tk_GCForColor(scrollPtr->highlightColorPtr,
- Tk_WindowId(tkwin));
- TkpDrawHighlightBorder(tkwin, fgGC, bgGC, scrollPtr->highlightWidth,
- Tk_WindowId(tkwin));
- } else {
- TkpDrawHighlightBorder(tkwin, bgGC, bgGC, scrollPtr->highlightWidth,
- Tk_WindowId(tkwin));
- }
+ GC fgGC, bgGC;
+
+ bgGC = Tk_GCForColor(scrollPtr->highlightBgColorPtr,
+ Tk_WindowId(tkwin));
+
+ if (scrollPtr->flags & GOT_FOCUS) {
+ fgGC = Tk_GCForColor(scrollPtr->highlightColorPtr,
+ Tk_WindowId(tkwin));
+ TkpDrawHighlightBorder(tkwin, fgGC, bgGC, scrollPtr->highlightWidth,
+ Tk_WindowId(tkwin));
+ } else {
+ TkpDrawHighlightBorder(tkwin, bgGC, bgGC, scrollPtr->highlightWidth,
+ Tk_WindowId(tkwin));
+ }
}
Tk_Draw3DRectangle(tkwin, Tk_WindowId(tkwin), scrollPtr->bgBorder,
- scrollPtr->highlightWidth, scrollPtr->highlightWidth,
- Tk_Width(tkwin) - 2*scrollPtr->highlightWidth,
- Tk_Height(tkwin) - 2*scrollPtr->highlightWidth,
- scrollPtr->borderWidth, scrollPtr->relief);
+ scrollPtr->highlightWidth, scrollPtr->highlightWidth,
+ Tk_Width(tkwin) - 2*scrollPtr->highlightWidth,
+ Tk_Height(tkwin) - 2*scrollPtr->highlightWidth,
+ scrollPtr->borderWidth, scrollPtr->relief);
/*
* Set up port for drawing Macintosh control.
*/
macDraw = (MacDrawable *) Tk_WindowId(tkwin);
destPort = TkMacOSXGetDrawablePort(Tk_WindowId(tkwin));
- GetGWorld(&saveWorld, &saveDevice);
- SetGWorld(destPort, NULL);
+ portChanged = QDSwapPort(destPort, &savePort);
TkMacOSXSetUpClippingRgn(Tk_WindowId(tkwin));
if (macScrollPtr->sbHandle == NULL) {
- Rect r;
- SInt32 initialValue;
- SInt32 minValue;
- SInt32 maxValue;
- SInt16 procID;
- WindowRef frontNonFloating;
-
- r.left = r.top = 0;
- r.right = r.bottom = 1;
-
- minValue = MIN_SCROLLBAR_VALUE;
- maxValue = SCROLLBAR_SCALING_VALUE;
- initialValue = (minValue + maxValue)/2;
- procID = kControlScrollBarLiveProc;
-
- windowRef = GetWindowFromPort(destPort);
- CreateScrollBarControl(windowRef, &r, initialValue,
- minValue, maxValue,
- maxValue - minValue, true,
- NULL, &(macScrollPtr->sbHandle));
- SetControlReference(macScrollPtr->sbHandle, (SInt32) scrollPtr);
-
- /*
- * If we are foremost then make us active.
- */
-
- frontNonFloating = ActiveNonFloatingWindow();
-
- if ((windowRef == FrontWindow()) || TkpIsWindowFloating(windowRef)) {
- macScrollPtr->macFlags |= ACTIVE;
- }
+ Rect r = {0, 0, 1, 1};
+ WindowRef frontNonFloating;
+
+ windowRef = GetWindowFromPort(destPort);
+ CreateScrollBarControl(windowRef, &r, MIN_SCROLLBAR_VALUE +
+ SCROLLBAR_SCALING_VALUE/2, MIN_SCROLLBAR_VALUE,
+ SCROLLBAR_SCALING_VALUE, SCROLLBAR_SCALING_VALUE -
+ MIN_SCROLLBAR_VALUE, true, NULL, &(macScrollPtr->sbHandle));
+ SetControlReference(macScrollPtr->sbHandle, (SInt32) scrollPtr);
+
+ /*
+ * If we are foremost then make us active.
+ */
+
+ frontNonFloating = ActiveNonFloatingWindow();
+
+ if ((windowRef == FrontWindow()) || TkpIsWindowFloating(windowRef)) {
+ macScrollPtr->macFlags |= ACTIVE;
+ }
}
/*
- * Adjust the control size based on its width...
+ * Update the control values before we draw.
*/
- if (macScrollPtr->info.width < 13) {
- SetControlData(macScrollPtr->sbHandle, kControlNoPart, kControlSizeTag,
- sizeof(kControlSizeSmall), (void *) kControlSizeSmall);
- } else {
- SetControlData(macScrollPtr->sbHandle, kControlNoPart, kControlSizeTag,
- sizeof(kControlSizeSmall), (void *) kControlSizeLarge);
- }
-
+ UpdateControlValues(macScrollPtr);
+
/*
- * Update the control values before we draw.
+ * Scrollbars do not erase the complete control bounds if they are wider
+ * than the standard width, so manually erase the extra space.
*/
- windowRef = GetControlOwner (macScrollPtr->sbHandle);
- UpdateControlValues(macScrollPtr);
-
- if (macScrollPtr->macFlags & ACTIVE) {
- Draw1Control(macScrollPtr->sbHandle);
- if (macScrollPtr->macFlags & DRAW_GROW) {
- DrawGrowIcon(windowRef);
- }
- } else {
- HiliteControl (macScrollPtr->sbHandle, 255 );
- Draw1Control(macScrollPtr->sbHandle);
- if (macScrollPtr->macFlags & DRAW_GROW) {
- DrawGrowIcon(windowRef);
- Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin), scrollPtr->bgBorder,
- Tk_Width(tkwin) - 13, Tk_Height(tkwin) - 13,
- Tk_Width(tkwin), Tk_Height(tkwin),
- 0, TK_RELIEF_FLAT);
- }
+
+ if (!EmptyRect(&macScrollPtr->eraseRect)) {
+ EraseRect(&macScrollPtr->eraseRect);
+ }
+
+ Draw1Control(macScrollPtr->sbHandle);
+
+ if (portChanged) {
+ QDSwapPort(savePort, NULL);
}
-
- SetGWorld(saveWorld, saveDevice);
-
+
done:
scrollPtr->flags &= ~REDRAW_PENDING;
}
@@ -321,24 +324,24 @@ TkpDisplayScrollbar(
*
* TkpConfigureScrollbar --
*
- * This procedure is called after the generic code has finished
- * processing configuration options, in order to configure
- * platform specific options.
+ * This procedure is called after the generic code has finished
+ * processing configuration options, in order to configure
+ * platform specific options.
*
* Results:
- * None.
+ * None.
*
* Side effects:
- * None.
+ * None.
*
*----------------------------------------------------------------------
*/
void
TkpConfigureScrollbar(scrollPtr)
- register TkScrollbar *scrollPtr; /* Information about widget; may or
- * may not already have values for
- * some fields. */
+ register TkScrollbar *scrollPtr; /* Information about widget; may or
+ * may not already have values for
+ * some fields. */
{
}
@@ -347,39 +350,40 @@ TkpConfigureScrollbar(scrollPtr)
*
* TkpComputeScrollbarGeometry --
*
- * After changes in a scrollbar's size or configuration, this
- * procedure recomputes various geometry information used in
- * displaying the scrollbar.
+ * After changes in a scrollbar's size or configuration, this
+ * procedure recomputes various geometry information used in
+ * displaying the scrollbar.
*
* Results:
- * None.
+ * None.
*
* Side effects:
- * The scrollbar will be displayed differently.
+ * The scrollbar will be displayed differently.
*
*----------------------------------------------------------------------
*/
void
TkpComputeScrollbarGeometry(
- register TkScrollbar *scrollPtr) /* Scrollbar whose geometry may
- * have changed. */
+ register TkScrollbar *scrollPtr) /* Scrollbar whose geometry may
+ * have changed. */
{
- MacScrollbar *macScrollPtr = (MacScrollbar *) scrollPtr;
- int width, fieldLength, adjust = 0;
+ int variant, fieldLength;
if (scrollPtr->highlightWidth < 0) {
- scrollPtr->highlightWidth = 0;
+ scrollPtr->highlightWidth = 0;
}
scrollPtr->inset = scrollPtr->highlightWidth + scrollPtr->borderWidth;
- width = (scrollPtr->vertical) ? Tk_Width(scrollPtr->tkwin)
- : Tk_Height(scrollPtr->tkwin);
- scrollPtr->arrowLength = width - 2*scrollPtr->inset + 1;
+ variant = ((scrollPtr->vertical ? Tk_Width(scrollPtr->tkwin) :
+ Tk_Height(scrollPtr->tkwin)) - 2 * scrollPtr->inset
+ < metrics[0].width) ? 1 : 0;
+ scrollPtr->arrowLength = (metrics[variant].topArrowHeight +
+ metrics[variant].bottomArrowHeight) / 2;
fieldLength = (scrollPtr->vertical ? Tk_Height(scrollPtr->tkwin)
- : Tk_Width(scrollPtr->tkwin))
- - 2*(scrollPtr->arrowLength + scrollPtr->inset);
+ : Tk_Width(scrollPtr->tkwin))
+ - 2 * (scrollPtr->arrowLength + scrollPtr->inset);
if (fieldLength < 0) {
- fieldLength = 0;
+ fieldLength = 0;
}
scrollPtr->sliderFirst = fieldLength * scrollPtr->firstFraction;
scrollPtr->sliderLast = fieldLength * scrollPtr->lastFraction;
@@ -391,45 +395,41 @@ TkpComputeScrollbarGeometry(
*/
if (scrollPtr->sliderFirst > (fieldLength - 2*scrollPtr->borderWidth)) {
- scrollPtr->sliderFirst = fieldLength - 2*scrollPtr->borderWidth;
+ scrollPtr->sliderFirst = fieldLength - 2*scrollPtr->borderWidth;
}
if (scrollPtr->sliderFirst < 0) {
- scrollPtr->sliderFirst = 0;
+ scrollPtr->sliderFirst = 0;
}
- if (scrollPtr->sliderLast < (scrollPtr->sliderFirst
- + MIN_SLIDER_LENGTH)) {
- scrollPtr->sliderLast = scrollPtr->sliderFirst + MIN_SLIDER_LENGTH;
+ if (scrollPtr->sliderLast < (scrollPtr->sliderFirst +
+ metrics[variant].minThumbHeight)) {
+ scrollPtr->sliderLast = scrollPtr->sliderFirst +
+ metrics[variant].minThumbHeight;
}
if (scrollPtr->sliderLast > fieldLength) {
- scrollPtr->sliderLast = fieldLength;
+ scrollPtr->sliderLast = fieldLength;
}
- scrollPtr->sliderFirst += scrollPtr->arrowLength + scrollPtr->inset;
- scrollPtr->sliderLast += scrollPtr->arrowLength + scrollPtr->inset;
+ scrollPtr->sliderFirst += scrollPtr->inset +
+ metrics[variant].topArrowHeight;
+ scrollPtr->sliderLast += scrollPtr->inset +
+ metrics[variant].bottomArrowHeight;
/*
* Register the desired geometry for the window (leave enough space
* for the two arrows plus a minimum-size slider, plus border around
- * the whole window, if any). Then arrange for the window to be
+ * the whole window, if any). Then arrange for the window to be
* redisplayed.
*/
if (scrollPtr->vertical) {
- if ((macScrollPtr->macFlags & AUTO_ADJUST) &&
- (macScrollPtr->macFlags & (FLUSH_RIGHT|FLUSH_LEFT))) {
- adjust--;
- }
- Tk_GeometryRequest(scrollPtr->tkwin,
- scrollPtr->width + 2*scrollPtr->inset + adjust,
- 2*(scrollPtr->arrowLength + scrollPtr->borderWidth
- + scrollPtr->inset));
+ Tk_GeometryRequest(scrollPtr->tkwin, scrollPtr->width +
+ 2 * scrollPtr->inset, 2 * (scrollPtr->arrowLength +
+ scrollPtr->borderWidth + scrollPtr->inset) +
+ metrics[variant].minThumbHeight);
} else {
- if ((macScrollPtr->macFlags & AUTO_ADJUST) &&
- (macScrollPtr->macFlags & (FLUSH_TOP|FLUSH_BOTTOM))) {
- adjust--;
- }
- Tk_GeometryRequest(scrollPtr->tkwin,
- 2*(scrollPtr->arrowLength + scrollPtr->borderWidth
- + scrollPtr->inset), scrollPtr->width + 2*scrollPtr->inset + adjust);
+ Tk_GeometryRequest(scrollPtr->tkwin, 2 * (scrollPtr->arrowLength +
+ scrollPtr->borderWidth + scrollPtr->inset) +
+ metrics[variant].minThumbHeight, scrollPtr->width +
+ 2 * scrollPtr->inset);
}
Tk_SetInternalBorder(scrollPtr->tkwin, scrollPtr->inset);
}
@@ -439,28 +439,28 @@ TkpComputeScrollbarGeometry(
*
* TkpDestroyScrollbar --
*
- * Free data structures associated with the scrollbar control.
+ * Free data structures associated with the scrollbar control.
*
* Results:
- * None.
+ * None.
*
* Side effects:
- * None.
+ * None.
*
*----------------------------------------------------------------------
*/
void
TkpDestroyScrollbar(
- TkScrollbar *scrollPtr) /* Scrollbar to destroy. */
+ TkScrollbar *scrollPtr) /* Scrollbar to destroy. */
{
MacScrollbar *macScrollPtr = (MacScrollbar *)scrollPtr;
if (macScrollPtr->sbHandle != NULL) {
- if (!(macScrollPtr->macFlags & IN_MODAL_LOOP)) {
- DisposeControl(macScrollPtr->sbHandle);
- macScrollPtr->sbHandle = NULL;
- }
+ if (!(macScrollPtr->macFlags & IN_MODAL_LOOP)) {
+ DisposeControl(macScrollPtr->sbHandle);
+ macScrollPtr->sbHandle = NULL;
+ }
}
macScrollPtr->macFlags |= ALREADY_DEAD;
}
@@ -470,90 +470,79 @@ TkpDestroyScrollbar(
*
* TkpScrollbarPosition --
*
- * Determine the scrollbar element corresponding to a
- * given position.
+ * Determine the scrollbar element corresponding to a
+ * given position.
*
* Results:
- * One of TOP_ARROW, TOP_GAP, etc., indicating which element
- * of the scrollbar covers the position given by (x, y). If
- * (x,y) is outside the scrollbar entirely, then OUTSIDE is
- * returned.
+ * One of TOP_ARROW, TOP_GAP, etc., indicating which element
+ * of the scrollbar covers the position given by (x, y). If
+ * (x,y) is outside the scrollbar entirely, then OUTSIDE is
+ * returned.
*
* Side effects:
- * None.
+ * None.
*
*--------------------------------------------------------------
*/
int
TkpScrollbarPosition(
- TkScrollbar *scrollPtr, /* Scrollbar widget record. */
- int x, int y) /* Coordinates within scrollPtr's
- * window. */
+ TkScrollbar *scrollPtr, /* Scrollbar widget record. */
+ int x, int y) /* Coordinates within scrollPtr's
+ * window. */
{
MacScrollbar *macScrollPtr = (MacScrollbar *) scrollPtr;
- GWorldPtr destPort;
- int length, width, tmp, inactive = false;
+ CGrafPtr destPort, savePort;
+ Boolean portChanged;
+ int inactive = 0;
ControlPartCode part;
- Point where;
+ Point where = {y, x};
Rect bounds;
- int x0, y0;
-
- x0 = x;
- y0 = y;
-
- if (scrollPtr->vertical) {
- length = Tk_Height(scrollPtr->tkwin);
- width = Tk_Width(scrollPtr->tkwin);
- } else {
- tmp = x;
- x = y;
- y = tmp;
- length = Tk_Width(scrollPtr->tkwin);
- width = Tk_Height(scrollPtr->tkwin);
- }
- if ((x < scrollPtr->inset) || (x >= (width - scrollPtr->inset))
- || (y < scrollPtr->inset) || (y >= (length - scrollPtr->inset))) {
- return OUTSIDE;
+ if ((x < scrollPtr->inset) || (x >= (Tk_Width(scrollPtr->tkwin) -
+ scrollPtr->inset)) || (y < scrollPtr->inset) ||
+ (y >= (Tk_Height(scrollPtr->tkwin) - scrollPtr->inset))) {
+ return OUTSIDE;
}
/*
* All of the calculations in this procedure mirror those in
- * DisplayScrollbar. Be sure to keep the two consistent. On the
+ * DisplayScrollbar. Be sure to keep the two consistent. On the
* Macintosh we use the OS call TestControl to do this mapping.
* For TestControl to work, the scrollbar must be active and must
* be in the current port.
*/
destPort = TkMacOSXGetDrawablePort(Tk_WindowId(scrollPtr->tkwin));
- SetGWorld(destPort, NULL);
+ portChanged = QDSwapPort(destPort, &savePort);
UpdateControlValues(macScrollPtr);
- if ( GetControlHilite(macScrollPtr->sbHandle) == 255 ) {
- inactive = true;
- HiliteControl(macScrollPtr->sbHandle, 0 );
+ if (!IsControlActive(macScrollPtr->sbHandle)) {
+ inactive = true;
+ ActivateControl(macScrollPtr->sbHandle);
}
-
- TkMacOSXWinBounds((TkWindow *) scrollPtr->tkwin, &bounds);
- where.h = x0 + bounds.left;
- where.v = y0 + bounds.top;
+ TkMacOSXWinBounds((TkWindow *) scrollPtr->tkwin, &bounds);
+ where.h += bounds.left;
+ where.v += bounds.top;
part = TestControl(((MacScrollbar *) scrollPtr)->sbHandle, where);
if (inactive) {
- HiliteControl(macScrollPtr->sbHandle, 255 );
+ DeactivateControl(macScrollPtr->sbHandle);
+ }
+ if (portChanged) {
+ QDSwapPort(savePort, NULL);
}
switch (part) {
- case kControlUpButtonPart:
- return TOP_ARROW;
- case kControlPageUpPart:
- return TOP_GAP;
- case kControlIndicatorPart:
- return SLIDER;
- case kControlPageDownPart:
- return BOTTOM_GAP;
- case kControlDownButtonPart:
- return BOTTOM_ARROW;
- default:
- return OUTSIDE;
+ case kAppearancePartUpButton:
+ return TOP_ARROW;
+ case kAppearancePartPageUpArea:
+ return TOP_GAP;
+ case kAppearancePartIndicator:
+ return SLIDER;
+ case kAppearancePartPageDownArea:
+ return BOTTOM_GAP;
+ case kAppearancePartDownButton:
+ return BOTTOM_ARROW;
+ default:
+ return OUTSIDE;
}
}
@@ -562,144 +551,132 @@ TkpScrollbarPosition(
*
* ThumbActionProc --
*
- * Callback procedure used by the Macintosh toolbox call
- * TrackControl. This call is used to track the thumb of
- * the scrollbar. Unlike the ScrollbarActionProc function
- * this function is called once and basically takes over
- * tracking the scrollbar from the control. This is done
- * to avoid conflicts with what the control plans to draw.
+ * Callback procedure used by the Macintosh toolbox call
+ * HandleControlClick. This call is used to track the
+ * thumb of the scrollbar. Unlike the
+ * ScrollbarActionProc function this function is called
+ * once and basically takes over tracking the scrollbar
+ * from the control. This is done to avoid conflicts with
+ * what the control plans to draw.
*
* Results:
- * None.
+ * None.
*
* Side effects:
- * May change the display.
+ * May change the display.
*
*--------------------------------------------------------------
*/
static pascal void
-ThumbActionProc()
+ThumbActionProc(ControlRef theControl, ControlPartCode partCode)
{
- register TkScrollbar *scrollPtr = activeScrollPtr;
- register MacScrollbar *macScrollPtr = (MacScrollbar *) activeScrollPtr;
+ TkScrollbar *scrollPtr = (TkScrollbar *)(intptr_t)GetControlReference(
+ theControl);
+ MacScrollbar *macScrollPtr = (MacScrollbar *) scrollPtr;
Tcl_DString cmdString;
- int origValue;
- double thumbWidth, oldFirstFraction, newFirstFraction, trackBarSize;
+ int origValue, variant;
+ short trackBarSize;
+ double oldFirstFraction, newFirstFraction;
char valueString[40];
Point currentPoint = { 0, 0 };
Rect trackRect;
Tcl_Interp *interp;
MouseTrackingResult trackingResult;
- OSErr err;
-
+ OSStatus err;
+
if (scrollPtr == NULL) {
- return;
+ return;
}
Tcl_DStringInit(&cmdString);
-
- /*
- * First compute values that will remain constant during the tracking
- * of the thumb. The variable trackBarSize is the length of the scrollbar
- * minus the 2 arrows and half the width of the thumb on both sides
- * (3 * arrowLength). The variable trackBarPin is the lower starting point
- * of the drag region.
- *
- * Note: the arrowLength is equal to the thumb width of a Mac scrollbar.
- */
-
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));
- InsetRect(&trackRect, -50, -226);
-
+
+ if (scrollPtr->vertical) {
+ variant = (trackRect.right - trackRect.left) < metrics[0].width ? 1 : 0;
+ trackBarSize = trackRect.bottom - trackRect.top -
+ metrics[variant].topArrowHeight -
+ metrics[variant].bottomArrowHeight;
+ InsetRect(&trackRect, -25, -113);
} else {
- trackBarSize = (double) (trackRect.right - trackRect.left
- - (scrollPtr->arrowLength * 3));
- InsetRect(&trackRect, -226, -50);
+ variant = (trackRect.bottom - trackRect.top) < metrics[0].width ? 1 : 0;
+ trackBarSize = trackRect.right - trackRect.left -
+ metrics[variant].topArrowHeight -
+ metrics[variant].bottomArrowHeight;
+ InsetRect(&trackRect, -113, -25);
}
/*
- * Track the mouse while the button is held down. If the mouse is moved,
+ * Track the mouse while the button is held down. If the mouse is moved,
* we calculate the value that should be passed to the "command" part of
- * the scrollbar. Since the mouse may move a distance too small to
+ * the scrollbar. Since the mouse may move a distance too small to
* cause a change to the first fraction, each calculation must be done
* versus what the first fraction was when the mouse button was
- * initially pressed. Otherwise, moving the mouse too slowly will
+ * initially pressed. Otherwise, moving the mouse too slowly will
* cause the calculated fraction delta to be zero and the scrollbar
* won't respond.
*/
oldFirstFraction = scrollPtr->firstFraction;
+ TkMacOSXTrackingLoop(1);
do {
- err = TrackMouseLocationWithOptions(NULL,
- kTrackMouseLocationOptionDontConsumeMouseUp,
- kEventDurationForever,
- &currentPoint,
- NULL,
- &trackingResult);
-
- if ((err == noErr)
- && ((trackingResult == kMouseTrackingMouseDragged)
- || (trackingResult == kMouseTrackingMouseMoved))) {
+ err = ChkErr(TrackMouseLocationWithOptions, NULL,
+ kTrackMouseLocationOptionDontConsumeMouseUp,
+ kEventDurationForever, &currentPoint, NULL, &trackingResult);
+ if ((err == noErr) && ((trackingResult == kMouseTrackingMouseDragged)
+ || (trackingResult == kMouseTrackingMouseMoved))) {
/*
- * Calculate where the scrollbar should move to, based on
- * where the mouse button was pressed and where the scrollbar
- * initially was at that time. Note that PtInRect() will
+ * Calculate where the scrollbar should move to, based on
+ * where the mouse button was pressed and where the scrollbar
+ * initially was at that time. Note that PtInRect() will
* return false if currentPoint or trackRect are not in
* is not in current graphics port, which may happen if any
- * of the waiting idle events change the port (e.g. with
+ * of the waiting idle events change the port (e.g. with
* SetPort()) but fail to restore it before returning and the
* scrollbar will lock in place.
- */
+ */
newFirstFraction = oldFirstFraction;
- if (PtInRect(currentPoint, &trackRect)) {
- double pixDiff;
- double fracDelta;
- if (scrollPtr->vertical == true) {
- pixDiff = (double)(currentPoint.v - mouseDownPoint.v);
- } else {
- pixDiff = (double)(currentPoint.h - mouseDownPoint.h);
- }
- fracDelta = pixDiff/(trackBarSize);
- newFirstFraction += fracDelta;
+ if (PtInRect(currentPoint, &trackRect)) {
+ short pixDiff;
+
+ if (scrollPtr->vertical) {
+ pixDiff = currentPoint.v - mouseDownPoint.v;
+ } else {
+ pixDiff = currentPoint.h - mouseDownPoint.h;
+ }
+ newFirstFraction += (double)pixDiff / trackBarSize;
if (newFirstFraction > 1.0) {
newFirstFraction = 1.0;
} else if (newFirstFraction < 0.0) {
newFirstFraction = 0.0;
}
}
-
+
/*
* Move the scrollbar thumb to the new first fraction given
* its position when initially pressed and how far the mouse
- * has moved. Process waiting idle tasks afterward to allow
+ * has moved. Process waiting idle tasks afterward to allow
* for the display to update.
*/
- sprintf(valueString, "%g", newFirstFraction);
- Tcl_DStringSetLength(&cmdString, 0);
- Tcl_DStringAppend(&cmdString, scrollPtr->command,
- scrollPtr->commandSize);
- Tcl_DStringAppendElement(&cmdString, "moveto");
- Tcl_DStringAppendElement(&cmdString, valueString);
- interp = scrollPtr->interp;
- Tcl_Preserve((ClientData) interp);
- Tcl_GlobalEval(interp, cmdString.string);
- Tcl_Release((ClientData) interp);
-
- TclServiceIdle();
- }
+ sprintf(valueString, "%g", newFirstFraction);
+ Tcl_DStringSetLength(&cmdString, 0);
+ Tcl_DStringAppend(&cmdString, scrollPtr->command,
+ scrollPtr->commandSize);
+ Tcl_DStringAppendElement(&cmdString, "moveto");
+ Tcl_DStringAppendElement(&cmdString, valueString);
+ interp = scrollPtr->interp;
+ Tcl_Preserve((ClientData) interp);
+ Tcl_EvalEx(interp, Tcl_DStringValue(&cmdString),
+ Tcl_DStringLength(&cmdString), TCL_EVAL_GLOBAL);
+ Tcl_Release((ClientData) interp);
+ TkMacOSXRunTclEventLoop();
+ }
} while ((err == noErr) && trackingResult != kMouseTrackingMouseReleased);
-
+ TkMacOSXTrackingLoop(0);
Tcl_DStringFree(&cmdString);
return;
}
@@ -709,50 +686,60 @@ ThumbActionProc()
*
* ScrollbarActionProc --
*
- * Callback procedure used by the Macintosh toolbox call
- * TrackControl. This call will update the display while
- * the scrollbar is being manipulated by the user.
+ * Callback procedure used by the Macintosh toolbox call
+ * HandleControlClick. This call will update the display
+ * while the scrollbar is being manipulated by the user.
*
* Results:
- * None.
+ * None.
*
* Side effects:
- * May change the display.
+ * May change the display.
*
*--------------------------------------------------------------
*/
static pascal void
ScrollbarActionProc(
- ControlRef theControl, /* Handle to scrollbat control */
- ControlPartCode partCode) /* Part of scrollbar that was "hit" */
+ ControlRef theControl, /* Handle to scrollbat control */
+ ControlPartCode partCode) /* Part of scrollbar that was "hit" */
{
- TkScrollbar *scrollPtr = (TkScrollbar *) GetControlReference(theControl);
+ TkScrollbar *scrollPtr = (TkScrollbar *)(intptr_t)GetControlReference(
+ theControl);
+ MacScrollbar *macScrollPtr = (MacScrollbar *) scrollPtr;
Tcl_DString cmdString;
-
+
Tcl_DStringInit(&cmdString);
Tcl_DStringAppend(&cmdString, scrollPtr->command,
- scrollPtr->commandSize);
-
- if ( partCode == kControlUpButtonPart ||
- partCode == kControlDownButtonPart ) {
- Tcl_DStringAppendElement(&cmdString, "scroll");
- Tcl_DStringAppendElement(&cmdString,
- (partCode == kControlUpButtonPart ) ? "-1" : "1");
- Tcl_DStringAppendElement(&cmdString, "unit");
- } else if (partCode == kControlPageUpPart || partCode == kControlPageDownPart ) {
- Tcl_DStringAppendElement(&cmdString, "scroll");
- Tcl_DStringAppendElement(&cmdString,
- (partCode == kControlPageUpPart ) ? "-1" : "1");
- Tcl_DStringAppendElement(&cmdString, "page");
+ scrollPtr->commandSize);
+
+ if ( partCode == kAppearancePartUpButton ||
+ partCode == kAppearancePartDownButton ) {
+ Tcl_DStringAppendElement(&cmdString, "scroll");
+ Tcl_DStringAppendElement(&cmdString,
+ (partCode == kAppearancePartUpButton) ? "-1" : "1");
+ Tcl_DStringAppendElement(&cmdString, "unit");
+ } else if (partCode == kAppearancePartPageUpArea ||
+ partCode == kAppearancePartPageDownArea ) {
+ Tcl_DStringAppendElement(&cmdString, "scroll");
+ Tcl_DStringAppendElement(&cmdString,
+ (partCode == kAppearancePartPageUpArea) ? "-1" : "1");
+ Tcl_DStringAppendElement(&cmdString, "page");
+ } else if (partCode == kAppearancePartIndicator) {
+ char valueString[TCL_DOUBLE_SPACE];
+
+ sprintf(valueString, "%g",
+ (GetControl32BitValue(macScrollPtr->sbHandle) -
+ MIN_SCROLLBAR_VALUE) / SCROLLBAR_SCALING_VALUE);
+ Tcl_DStringAppendElement(&cmdString, "moveto");
+ Tcl_DStringAppendElement(&cmdString, valueString);
}
Tcl_Preserve((ClientData) scrollPtr->interp);
- Tcl_DStringAppend(&cmdString, "; update idletasks",
- strlen("; update idletasks"));
- Tcl_GlobalEval(scrollPtr->interp, cmdString.string);
+ Tcl_EvalEx(scrollPtr->interp, Tcl_DStringValue(&cmdString),
+ Tcl_DStringLength(&cmdString), TCL_EVAL_GLOBAL);
Tcl_Release((ClientData) scrollPtr->interp);
-
Tcl_DStringFree(&cmdString);
+ TkMacOSXRunTclEventLoop();
}
/*
@@ -760,25 +747,25 @@ ScrollbarActionProc(
*
* ScrollbarBindProc --
*
- * This procedure is invoked when the default <ButtonPress>
- * binding on the Scrollbar bind tag fires.
+ * This procedure is invoked when the default <ButtonPress>
+ * binding on the Scrollbar bind tag fires.
*
* Results:
- * None.
+ * None.
*
* Side effects:
- * The event enters a modal loop.
+ * The event enters a modal loop.
*
*--------------------------------------------------------------
*/
static int
ScrollbarBindProc(
- ClientData clientData, /* Not used. */
- Tcl_Interp *interp, /* Interp with binding. */
- XEvent *eventPtr, /* X event that triggered binding. */
- Tk_Window tkwin, /* Target window for event. */
- KeySym keySym) /* The KeySym if a key event. */
+ ClientData clientData, /* Not used. */
+ Tcl_Interp *interp, /* Interp with binding. */
+ XEvent *eventPtr, /* X event that triggered binding. */
+ Tk_Window tkwin, /* Target window for event. */
+ KeySym keySym) /* The KeySym if a key event. */
{
TkWindow *winPtr = (TkWindow*)tkwin;
TkScrollbar *scrollPtr = (TkScrollbar *) winPtr->instanceData;
@@ -786,108 +773,103 @@ ScrollbarBindProc(
Tcl_Preserve((ClientData)scrollPtr);
macScrollPtr->macFlags |= IN_MODAL_LOOP;
-
+
if (eventPtr->type == ButtonPress) {
Point where;
Rect bounds;
int part;
- CGrafPtr saveWorld;
- GDHandle saveDevice;
- GWorldPtr destPort;
- Window window;
-
- /*
- * To call Macintosh control routines we must have the port
- * set to the window containing the control. We will then test
- * which part of the control was hit and act accordingly.
- */
- destPort = TkMacOSXGetDrawablePort(Tk_WindowId(scrollPtr->tkwin));
- GetGWorld(&saveWorld, &saveDevice);
- SetGWorld(destPort, NULL);
- TkMacOSXSetUpClippingRgn(Tk_WindowId(scrollPtr->tkwin));
-
- TkMacOSXWinBounds((TkWindow *) scrollPtr->tkwin, &bounds);
+ CGrafPtr destPort, savePort;
+ Boolean portChanged;
+ Window window;
+
+ /*
+ * To call Macintosh control routines we must have the port
+ * set to the window containing the control. We will then test
+ * which part of the control was hit and act accordingly.
+ */
+ destPort = TkMacOSXGetDrawablePort(Tk_WindowId(scrollPtr->tkwin));
+ portChanged = QDSwapPort(destPort, &savePort);
+ TkMacOSXSetUpClippingRgn(Tk_WindowId(scrollPtr->tkwin));
+
+ TkMacOSXWinBounds((TkWindow *) scrollPtr->tkwin, &bounds);
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) {
- /*
- * Case 1: In thumb, no jump scrolling. Call track control
- * with the thumb action proc which will do most of the work.
- * Set the global activeScrollPtr to the current control
- * so the callback may have access to it.
- */
- activeScrollPtr = scrollPtr;
+ part = TestControl(macScrollPtr->sbHandle, where);
+ TkMacOSXTrackingLoop(1);
+ if (part == kAppearancePartIndicator && scrollPtr->jump == false) {
+ /*
+ * Case 1: In thumb, no jump scrolling. Call track control
+ * with the thumb action proc which will do most of the work.
+ */
mouseDownPoint.h = where.h;
mouseDownPoint.v = where.v;
- part = TrackControl(macScrollPtr->sbHandle, where,
- (ControlActionUPP) thumbActionProc);
- activeScrollPtr = NULL;
- } else if (part == kControlIndicatorPart) {
- /*
- * Case 2: in thumb with jump scrolling. Call TrackControl
- * with a NULL action proc. Use the new value of the control
- * to set update the control.
- */
- part = TrackControl(macScrollPtr->sbHandle, where, NULL);
- if (part == kControlIndicatorPart) {
- double newFirstFraction, thumbWidth;
- Tcl_DString cmdString;
- char valueString[TCL_DOUBLE_SPACE];
-
- /*
- * The following calculation takes the new control
- * value and maps it to what Tk needs for its variable
- * thumb size representation.
- */
- thumbWidth = scrollPtr->lastFraction
- - scrollPtr->firstFraction;
- newFirstFraction = (1.0 - thumbWidth) *
- ((double) GetControl32BitValue(macScrollPtr->sbHandle) / SCROLLBAR_SCALING_DVALUE);
-
- sprintf(valueString, "%g", newFirstFraction);
-
- Tcl_DStringInit(&cmdString);
- Tcl_DStringAppend(&cmdString, scrollPtr->command,
- strlen(scrollPtr->command));
- Tcl_DStringAppendElement(&cmdString, "moveto");
- Tcl_DStringAppendElement(&cmdString, valueString);
- Tcl_DStringAppend(&cmdString, "; update idletasks",
- strlen("; update idletasks"));
-
- interp = scrollPtr->interp;
- Tcl_Preserve((ClientData) interp);
- Tcl_GlobalEval(interp, cmdString.string);
- Tcl_Release((ClientData) interp);
- Tcl_DStringFree(&cmdString);
- }
- } else if (part != 0) {
- /*
- * Case 3: in any other part of the scrollbar. We call
- * TrackControl with the scrollActionProc which will do
- * most all the work.
- */
- TrackControl(macScrollPtr->sbHandle, where, scrollActionProc);
- HiliteControl(macScrollPtr->sbHandle, 0);
- }
-
- /*
- * The TrackControl call will "eat" the ButtonUp event. We now
- * generate a ButtonUp event so Tk will unset implicit grabs etc.
- */
- window = Tk_WindowId(scrollPtr->tkwin);
- TkGenerateButtonEventForXPointer(window);
-
- SetGWorld(saveWorld, saveDevice);
+ part = HandleControlClick(macScrollPtr->sbHandle, where,
+ TkMacOSXModifierState(), thumbActionProc);
+ } else if (part == kAppearancePartIndicator) {
+ /*
+ * Case 2: in thumb with jump scrolling. Call HandleControlClick
+ * with a NULL action proc. Use the new value of the control
+ * to set update the control.
+ */
+ part = HandleControlClick(macScrollPtr->sbHandle, where,
+ TkMacOSXModifierState(), NULL);
+ if (part == kAppearancePartIndicator) {
+ Tcl_DString cmdString;
+ char valueString[TCL_DOUBLE_SPACE];
+
+ sprintf(valueString, "%g",
+ (GetControl32BitValue(macScrollPtr->sbHandle) -
+ MIN_SCROLLBAR_VALUE) / SCROLLBAR_SCALING_VALUE);
+ Tcl_DStringInit(&cmdString);
+ Tcl_DStringAppend(&cmdString, scrollPtr->command,
+ strlen(scrollPtr->command));
+ Tcl_DStringAppendElement(&cmdString, "moveto");
+ Tcl_DStringAppendElement(&cmdString, valueString);
+
+ interp = scrollPtr->interp;
+ Tcl_Preserve((ClientData) interp);
+ Tcl_EvalEx(interp, Tcl_DStringValue(&cmdString),
+ Tcl_DStringLength(&cmdString), TCL_EVAL_GLOBAL);
+ Tcl_Release((ClientData) interp);
+ Tcl_DStringFree(&cmdString);
+ TkMacOSXRunTclEventLoop();
+ }
+ } else if (part != 0) {
+ /*
+ * Case 3: in any other part of the scrollbar. We call
+ * HandleControlClick with the scrollActionProc which will do
+ * most all the work.
+ */
+ HandleControlClick(macScrollPtr->sbHandle, where,
+ TkMacOSXModifierState(), scrollActionProc);
+ /*
+ * Workaround for Carbon bug where the scrollbar down arrow
+ * sometimes gets "stuck" after the mousebutton has been released.
+ */
+ TkMacOSXSetUpClippingRgn(Tk_WindowId(scrollPtr->tkwin));
+ Draw1Control(macScrollPtr->sbHandle);
+ }
+ TkMacOSXTrackingLoop(0);
+
+ /*
+ * The HandleControlClick call will "eat" the ButtonUp event. We now
+ * generate a ButtonUp event so Tk will unset implicit grabs etc.
+ */
+ window = Tk_WindowId(scrollPtr->tkwin);
+ TkGenerateButtonEventForXPointer(window);
+
+ if (portChanged) {
+ QDSwapPort(savePort, NULL);
+ }
}
if (macScrollPtr->sbHandle && (macScrollPtr->macFlags & ALREADY_DEAD)) {
- DisposeControl(macScrollPtr->sbHandle);
- macScrollPtr->sbHandle = NULL;
+ DisposeControl(macScrollPtr->sbHandle);
+ macScrollPtr->sbHandle = NULL;
}
macScrollPtr->macFlags &= ~IN_MODAL_LOOP;
Tcl_Release((ClientData)scrollPtr);
-
+
return TCL_OK;
}
@@ -896,37 +878,37 @@ ScrollbarBindProc(
*
* ScrollbarEventProc --
*
- * This procedure is invoked by the Tk dispatcher for various
- * events on scrollbars.
+ * This procedure is invoked by the Tk dispatcher for various
+ * events on scrollbars.
*
* Results:
- * None.
+ * None.
*
* Side effects:
- * When the window gets deleted, internal structures get
- * cleaned up. When it gets exposed, it is redisplayed.
+ * When the window gets deleted, internal structures get
+ * cleaned up. When it gets exposed, it is redisplayed.
*
*--------------------------------------------------------------
*/
static void
ScrollbarEventProc(
- ClientData clientData, /* Information about window. */
- XEvent *eventPtr) /* Information about event. */
+ ClientData clientData, /* Information about window. */
+ XEvent *eventPtr) /* Information about event. */
{
TkScrollbar *scrollPtr = (TkScrollbar *) clientData;
MacScrollbar *macScrollPtr = (MacScrollbar *) clientData;
if (eventPtr->type == UnmapNotify) {
- TkMacOSXSetScrollbarGrow((TkWindow *) scrollPtr->tkwin, false);
+ TkMacOSXSetScrollbarGrow((TkWindow *) scrollPtr->tkwin, false);
} else if (eventPtr->type == ActivateNotify) {
- macScrollPtr->macFlags |= ACTIVE;
- TkScrollbarEventuallyRedraw((ClientData) scrollPtr);
+ macScrollPtr->macFlags |= ACTIVE;
+ TkScrollbarEventuallyRedraw((ClientData) scrollPtr);
} else if (eventPtr->type == DeactivateNotify) {
- macScrollPtr->macFlags &= ~ACTIVE;
- TkScrollbarEventuallyRedraw((ClientData) scrollPtr);
+ macScrollPtr->macFlags &= ~ACTIVE;
+ TkScrollbarEventuallyRedraw((ClientData) scrollPtr);
} else {
- TkScrollbarEventProc(clientData, eventPtr);
+ TkScrollbarEventProc(clientData, eventPtr);
}
}
@@ -935,151 +917,91 @@ ScrollbarEventProc(
*
* UpdateControlValues --
*
- * This procedure updates the Macintosh scrollbar control
- * to display the values defined by the Tk scrollbar.
+ * This procedure updates the Macintosh scrollbar control
+ * to display the values defined by the Tk scrollbar.
*
* Results:
- * None.
+ * None.
*
* Side effects:
- * The Macintosh control is updated.
+ * The Macintosh control is updated.
*
*--------------------------------------------------------------
*/
static void
UpdateControlValues(
- MacScrollbar *macScrollPtr) /* Scrollbar data struct. */
+ MacScrollbar *macScrollPtr) /* Scrollbar data struct. */
{
TkScrollbar *scrollPtr = (TkScrollbar *) macScrollPtr;
Tk_Window tkwin = scrollPtr->tkwin;
MacDrawable * macDraw = (MacDrawable *) Tk_WindowId(scrollPtr->tkwin);
- WindowRef windowRef = GetControlOwner(macScrollPtr->sbHandle);
double dViewSize;
- SInt32 viewSize, controlMax, controlValue;
- int flushRight = false;
- int flushBottom = false;
Rect contrlRect, portRect;
- UInt8 contrlHilite;
-
- /*
- * We can't use the Macintosh commands SizeControl and MoveControl as these
- * calls will also cause a redraw which in our case will also cause
- * flicker. To avoid this we adjust the control record directly. The
- * Draw1Control command appears to just draw where ever the control says to
- * draw so this seems right.
- */
+ int variant, active;
+ short width, height;
contrlRect.left = macDraw->xOff + scrollPtr->inset;
contrlRect.top = macDraw->yOff + scrollPtr->inset;
contrlRect.right = macDraw->xOff + Tk_Width(tkwin) - scrollPtr->inset;
contrlRect.bottom = macDraw->yOff + Tk_Height(tkwin) - scrollPtr->inset;
+ GetPortBounds (GetWindowPort(GetControlOwner(macScrollPtr->sbHandle)),
+ &portRect);
+
/*
- * To make Tk applications look more like Macintosh applications without
- * requiring additional work by the Tk developer we do some cute tricks.
- * The first trick plays with the size of the widget to get it to overlap
- * with the side of the window by one pixel (we don't do this if the placer
- * is the geometry manager). The second trick shrinks the scrollbar if it
- * it covers the area of the grow region ao the scrollbar can also draw
- * the grow region if need be.
+ * If the scrollbar is flush against the bottom right hand corner then
+ * we leave space to draw the grow region for the window.
*/
- if ((macDraw->winPtr->geomMgrPtr != NULL)
- && !strcmp(macDraw->winPtr->geomMgrPtr->name, "place")) {
- macScrollPtr->macFlags &= ~AUTO_ADJUST;
+ if (portRect.bottom == contrlRect.bottom &&
+ portRect.right == contrlRect.right) {
+ TkMacOSXSetScrollbarGrow((TkWindow *) tkwin, true);
+ if (TkMacOSXResizable(macDraw->toplevel->winPtr)) {
+ int growSize;
+
+ switch (TkMacOSXWindowClass(macDraw->toplevel->winPtr)) {
+ case kFloatingWindowClass:
+ case kUtilityWindowClass:
+ growSize = metrics[1].width - 1;
+ break;
+ case kDocumentWindowClass:
+ case kMovableAlertWindowClass:
+ case kMovableModalWindowClass:
+ default:
+ growSize = metrics[0].width - 1;
+ break;
+ }
+ if (scrollPtr->vertical) {
+ contrlRect.bottom -= growSize;
+ } else {
+ contrlRect.right -= growSize;
+ }
+ }
} else {
- macScrollPtr->macFlags |= AUTO_ADJUST;
- }
- GetPortBounds ( GetWindowPort ( windowRef ), &portRect );
- if ( portRect.left == contrlRect.left ) {
- if (macScrollPtr->macFlags & AUTO_ADJUST) {
- contrlRect.left--;
- }
- if (!(macScrollPtr->macFlags & FLUSH_LEFT)) {
- macScrollPtr->macFlags |= FLUSH_LEFT;
- if (scrollPtr->vertical) {
- TkpComputeScrollbarGeometry(scrollPtr);
- }
- }
- } else if (macScrollPtr->macFlags & FLUSH_LEFT) {
- macScrollPtr->macFlags &= ~FLUSH_LEFT;
- if (scrollPtr->vertical) {
- TkpComputeScrollbarGeometry(scrollPtr);
- }
+ TkMacOSXSetScrollbarGrow((TkWindow *) tkwin, false);
}
- if (portRect.top == contrlRect.top) {
- if (macScrollPtr->macFlags & AUTO_ADJUST) {
- contrlRect.top--;
- }
- if (!(macScrollPtr->macFlags & FLUSH_TOP)) {
- macScrollPtr->macFlags |= FLUSH_TOP;
- if (! scrollPtr->vertical) {
- TkpComputeScrollbarGeometry(scrollPtr);
- }
- }
- } else if (macScrollPtr->macFlags & FLUSH_TOP) {
- macScrollPtr->macFlags &= ~FLUSH_TOP;
- if (! scrollPtr->vertical) {
- TkpComputeScrollbarGeometry(scrollPtr);
- }
+ if (IsControlVisible (macScrollPtr->sbHandle)) {
+ SetControlVisibility(macScrollPtr->sbHandle, false, false);
}
- if (portRect.right == contrlRect.right) {
- flushRight = true;
- if (macScrollPtr->macFlags & AUTO_ADJUST) {
- contrlRect.right++;
- }
- if (!(macScrollPtr->macFlags & FLUSH_RIGHT)) {
- macScrollPtr->macFlags |= FLUSH_RIGHT;
- if (scrollPtr->vertical) {
- TkpComputeScrollbarGeometry(scrollPtr);
- }
- }
- } else if (macScrollPtr->macFlags & FLUSH_RIGHT) {
- macScrollPtr->macFlags &= ~FLUSH_RIGHT;
- if (scrollPtr->vertical) {
- TkpComputeScrollbarGeometry(scrollPtr);
- }
- }
-
- if (portRect.bottom == contrlRect.bottom) {
- flushBottom = true;
- if (macScrollPtr->macFlags & AUTO_ADJUST) {
- contrlRect.bottom++;
- }
- if (!(macScrollPtr->macFlags & FLUSH_BOTTOM)) {
- macScrollPtr->macFlags |= FLUSH_BOTTOM;
- if (! scrollPtr->vertical) {
- TkpComputeScrollbarGeometry(scrollPtr);
- }
- }
- } else if (macScrollPtr->macFlags & FLUSH_BOTTOM) {
- macScrollPtr->macFlags &= ~FLUSH_BOTTOM;
- if (! scrollPtr->vertical) {
- TkpComputeScrollbarGeometry(scrollPtr);
- }
+ if (scrollPtr->vertical) {
+ width = contrlRect.right - contrlRect.left;
+ height = contrlRect.bottom - contrlRect.top;
+ } else {
+ width = contrlRect.bottom - contrlRect.top;
+ height = contrlRect.right - contrlRect.left;
}
+ variant = width < metrics[0].width ? 1 : 0;
+ SetControlData(macScrollPtr->sbHandle, kControlEntireControl,
+ kControlSizeTag, sizeof(ControlSize),
+ &(metrics[variant].size));
- /*
- * If the scrollbar is flush against the bottom right hand corner then
- * it may need to draw the grow region for the window so we let the
- * wm code know about this scrollbar. We don't actually draw the grow
- * region, however, unless we are currently resizable.
- */
- macScrollPtr->macFlags &= ~DRAW_GROW;
- if (flushBottom && flushRight) {
- TkMacOSXSetScrollbarGrow((TkWindow *) tkwin, true);
- if (TkMacOSXResizable(macDraw->toplevel->winPtr)) {
- if (scrollPtr->vertical) {
- contrlRect.bottom -= 14;
- } else {
- contrlRect.right -= 14;
- }
- macScrollPtr->macFlags |= DRAW_GROW;
- }
+ macScrollPtr->eraseRect = contrlRect;
+ if (scrollPtr->vertical) {
+ macScrollPtr->eraseRect.left += metrics[variant].width;
} else {
- TkMacOSXSetScrollbarGrow((TkWindow *) tkwin, false);
+ macScrollPtr->eraseRect.top += metrics[variant].width;
}
/*
@@ -1092,50 +1014,37 @@ UpdateControlValues(
/*
* Given the Tk parameters for the fractions of the start and
* end of the thumb, the following calculation determines the
- * location for the 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 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.
*/
- dViewSize = (scrollPtr->lastFraction - scrollPtr->firstFraction)
- * SCROLLBAR_SCALING_DVALUE;
-
- viewSize = (SInt32) dViewSize;
- controlMax = (SInt32) (SCROLLBAR_SCALING_DVALUE - dViewSize);
- controlValue = (SInt32) (SCROLLBAR_SCALING_DVALUE * scrollPtr->firstFraction);
-
- SetControlViewSize(macScrollPtr->sbHandle,viewSize);
- 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);
- SetControl32BitValue(macScrollPtr->sbHandle,
- (middle) );
-#endif
- contrlHilite = GetControlHilite(macScrollPtr->sbHandle);
- SetControl32BitMinimum(macScrollPtr->sbHandle, 0);
- if ( contrlHilite == 0 || contrlHilite == 255) {
- if (scrollPtr->firstFraction == 0.0 &&
- scrollPtr->lastFraction == 1.0) {
- SetControl32BitMinimum(macScrollPtr->sbHandle, SCROLLBAR_SCALING_VALUE);
- } else {
- HiliteControl(macScrollPtr->sbHandle, 0);
- }
- }
- SetControl32BitValue(macScrollPtr->sbHandle, controlValue);
- if ( !IsControlVisible (macScrollPtr -> sbHandle) ) {
- SetControlVisibility(macScrollPtr->sbHandle,TRUE,FALSE);
+ dViewSize = (scrollPtr->lastFraction - scrollPtr->firstFraction)
+ * SCROLLBAR_SCALING_VALUE;
+ SetControlViewSize(macScrollPtr->sbHandle, dViewSize);
+ SetControl32BitMinimum(macScrollPtr->sbHandle, MIN_SCROLLBAR_VALUE);
+ SetControl32BitMaximum(macScrollPtr->sbHandle, MIN_SCROLLBAR_VALUE +
+ SCROLLBAR_SCALING_VALUE - dViewSize);
+ SetControl32BitValue(macScrollPtr->sbHandle, MIN_SCROLLBAR_VALUE +
+ SCROLLBAR_SCALING_VALUE * scrollPtr->firstFraction);
+
+ if((scrollPtr->firstFraction <= 0.0 && scrollPtr->lastFraction >= 1.0)
+ || height <= metrics[variant].minHeight) {
+ /* Disable scrollbar */
+ SetControl32BitMaximum(macScrollPtr->sbHandle, MIN_SCROLLBAR_VALUE);
+ }
+ active = ((macScrollPtr->macFlags & ACTIVE) != 0);
+ if (active != IsControlActive(macScrollPtr->sbHandle)) {
+ if (active) {
+ ActivateControl(macScrollPtr->sbHandle);
+ } else {
+ DeactivateControl(macScrollPtr->sbHandle);
+ }
}
+ SetControlVisibility(macScrollPtr->sbHandle, true, false);
}