diff options
author | das <das> | 2007-04-23 21:24:32 (GMT) |
---|---|---|
committer | das <das> | 2007-04-23 21:24:32 (GMT) |
commit | 11dbb8af58fd851913e5c781e3164e8211e93745 (patch) | |
tree | 1a0bc7c114e940c5e46d3704ac14fb34f4cc029e /macosx/tkMacOSXScrlbr.c | |
parent | 24b160e09ae3ca4b52502fe59ddcd5fc80e00713 (diff) | |
download | tk-11dbb8af58fd851913e5c781e3164e8211e93745.zip tk-11dbb8af58fd851913e5c781e3164e8211e93745.tar.gz tk-11dbb8af58fd851913e5c781e3164e8211e93745.tar.bz2 |
* macosx/tkMacOSXCarbonEvents.c: add window event target carbon event
* macosx/tkMacOSXEvent.c: handler for all kEventClassWindow and
* macosx/tkMacOSXEvent.h: kEventClassMouse events;
* macosx/tkMacOSXNotify.c: move all 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
* macosx/ttkMacOSXTheme.c: 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
* macosx/ttkMacOSXTheme.c: 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; always draw with CG; remove QD
dependent stippling algorithm; move most header declarations into the
source file (as they were not used anywhere else).
* macosx/tkMacOSXMenu.c: large-scale rewrite of custom
* macosx/tkMacOSXMenu.r (removed): MDEF and related code that
* macosx/Wish.xcode/project.pbxproj: restores many longtime-MIA
* macosx/Wish.xcodeproj/project.pbxproj: features to working order
* unix/Makefile.in: (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/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/ttkMacOSXTheme.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/Wish-Common.xcconfig: add Wish's Info.plist as __info_plist
section to tktest; enable more warnings.
* macosx/Wish.xcodeproj/project.pbxproj: add 'DebugMemCompile' build
configuration that calls configure with --enable-symbols=all; disable
configure check for __attribute__((__visibility__("hidden"))) in Debug
configuration to restore availability of ZeroLink.
* macosx/Wish-Common.xcconfig: fix whitespace.
* macosx/Wish-Debug.xcconfig:
* macosx/Wish-Release.xcconfig:
* macosx/tkMacOSXAETE.r:
* macosx/tkMacOSXConfig.c:
* macosx/tkMacOSXCursors.r:
* macosx/tkMacOSXKeyboard.c:
* macosx/tkMacOSXSend.c:
* macosx/ttkMacOSXTheme.c:
* macosx/tkMacOSXXCursors.r:
* macosx/README:
* macosx/GNUmakefile: fix/add copyright and license refs.
* macosx/Tk-Info.plist.in:
* macosx/Wish-Info.plist.in:
* macosx/Wish.xcode/project.pbxproj:
* macosx/Wish.xcodeproj/project.pbxproj:
* macosx/tkMacOSX.h:
Diffstat (limited to 'macosx/tkMacOSXScrlbr.c')
-rw-r--r-- | macosx/tkMacOSXScrlbr.c | 1253 |
1 files changed, 581 insertions, 672 deletions
diff --git a/macosx/tkMacOSXScrlbr.c b/macosx/tkMacOSXScrlbr.c index d096c03..48d153a 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.20 2006/08/24 05:22:27 das Exp $ + * RCS: @(#) $Id: tkMacOSXScrlbr.c,v 1.21 2007/04/23 21:24:34 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, - ¤tPoint, - NULL, - &trackingResult); - - if ((err == noErr) - && ((trackingResult == kMouseTrackingMouseDragged) - || (trackingResult == kMouseTrackingMouseMoved))) { + err = ChkErr(TrackMouseLocationWithOptions, NULL, + kTrackMouseLocationOptionDontConsumeMouseUp, + kEventDurationForever, ¤tPoint, 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); } |