diff options
author | culler <culler> | 2018-10-30 03:56:32 (GMT) |
---|---|---|
committer | culler <culler> | 2018-10-30 03:56:32 (GMT) |
commit | a16d0e701b1b7c030d0e434a5a1161c95e49b044 (patch) | |
tree | 5d6339bc1a8ff9e716809395e54fd725e60c913c /macosx | |
parent | e105b149f982ff16a6397783bbcb3a62de4a5323 (diff) | |
download | tk-a16d0e701b1b7c030d0e434a5a1161c95e49b044.zip tk-a16d0e701b1b7c030d0e434a5a1161c95e49b044.tar.gz tk-a16d0e701b1b7c030d0e434a5a1161c95e49b044.tar.bz2 |
Fixed scrollbar behavior. Added some padding in buttons for 10.6 only.
Diffstat (limited to 'macosx')
-rw-r--r-- | macosx/tkMacOSXButton.c | 3 | ||||
-rw-r--r-- | macosx/tkMacOSXScrlbr.c | 193 |
2 files changed, 139 insertions, 57 deletions
diff --git a/macosx/tkMacOSXButton.c b/macosx/tkMacOSXButton.c index 6930a36..14b8872 100644 --- a/macosx/tkMacOSXButton.c +++ b/macosx/tkMacOSXButton.c @@ -420,6 +420,9 @@ TkpComputeButtonGeometry( width += butPtr->inset*2; height += butPtr->inset*2; + if ([NSApp macMinorVersion] == 6) { + width += 12; + } Tk_GeometryRequest(butPtr->tkwin, width, height); Tk_SetInternalBorder(butPtr->tkwin, butPtr->inset); diff --git a/macosx/tkMacOSXScrlbr.c b/macosx/tkMacOSXScrlbr.c index f15146d..51c9e0c 100644 --- a/macosx/tkMacOSXScrlbr.c +++ b/macosx/tkMacOSXScrlbr.c @@ -40,9 +40,12 @@ */ typedef struct MacScrollbar { - TkScrollbar information; /* Generic scrollbar info. */ + TkScrollbar information; /* Generic scrollbar info. */ GC troughGC; /* For drawing trough. */ GC copyGC; /* Used for copying from pixmap onto screen. */ + Bool buttonDown; /* Is the mouse button down? */ + Bool mouseOver; /* Is the pointer over the scrollbar. */ + HIThemeTrackDrawInfo info; /* Controls how the scrollbar is drawn. */ } MacScrollbar; /* @@ -71,7 +74,7 @@ static ScrollbarMetrics metrics = { 15, 54, 26, 14, 14, kControlSizeNormal /* kThemeScrollBarMedium */ }; -HIThemeTrackDrawInfo info = { +HIThemeTrackDrawInfo defaultInfo = { .version = 0, .min = 0.0, .max = 100.0, @@ -84,7 +87,7 @@ HIThemeTrackDrawInfo info = { */ static void ScrollbarEventProc(ClientData clientData, XEvent *eventPtr); -static int ScrollbarPress(TkScrollbar *scrollPtr, XEvent *eventPtr); +static int ScrollbarEvent(TkScrollbar *scrollPtr, XEvent *eventPtr); static void UpdateControlValues(TkScrollbar *scrollPtr); /* @@ -112,8 +115,19 @@ TkpCreateScrollbar( scrollPtr->troughGC = None; scrollPtr->copyGC = None; - - Tk_CreateEventHandler(tkwin,ExposureMask|StructureNotifyMask|FocusChangeMask|ButtonPressMask|ButtonReleaseMask|EnterWindowMask|LeaveWindowMask|VisibilityChangeMask, ScrollbarEventProc, scrollPtr); + scrollPtr->info = defaultInfo; + scrollPtr->buttonDown = false; + + Tk_CreateEventHandler(tkwin, + ExposureMask | + StructureNotifyMask | + FocusChangeMask | + ButtonPressMask | + ButtonReleaseMask | + EnterWindowMask | + LeaveWindowMask | + VisibilityChangeMask, + ScrollbarEventProc, scrollPtr); return (TkScrollbar *) scrollPtr; } @@ -141,6 +155,7 @@ TkpDisplayScrollbar( ClientData clientData) /* Information about window. */ { register TkScrollbar *scrollPtr = (TkScrollbar *) clientData; + MacScrollbar *msPtr = (MacScrollbar *) scrollPtr; register Tk_Window tkwin = scrollPtr->tkwin; TkWindow *winPtr = (TkWindow *) tkwin; TkMacOSXDrawingContext dc; @@ -191,9 +206,9 @@ TkpDisplayScrollbar( /*Update values and draw in native rect.*/ UpdateControlValues(scrollPtr); if (MOUNTAIN_LION_STYLE) { - HIThemeDrawTrack (&info, 0, dc.context, kHIThemeOrientationInverted); + HIThemeDrawTrack (&(msPtr->info), 0, dc.context, kHIThemeOrientationInverted); } else { - HIThemeDrawTrack (&info, 0, dc.context, kHIThemeOrientationNormal); + HIThemeDrawTrack (&(msPtr->info), 0, dc.context, kHIThemeOrientationNormal); } TkMacOSXRestoreDrawingContext(&dc); @@ -228,12 +243,14 @@ TkpComputeScrollbarGeometry( { /* - * Using code from tkUnixScrlbr.c because Unix scroll bindings are - * driving the display at the script level. All the Mac scrollbar - * has to do is re-draw itself. - * There is a difference with Unix however: on macOS later than 10.6 - * (Snow Leopard) the scrollbars have no arrows at all. This is - * handled by having scrollPtr->arrowLength set to zero. + * Using code from tkUnixScrlbr.c because Unix scroll bindings are driving + * the display at the script level. All the Mac scrollbar has to do is + * re-draw itself. But we must account for some differences from Unix: on + * macOS versions newer than 10.6 (Snow Leopard) the scrollbars have no + * arrows at all. This is handled by having scrollPtr->arrowLength set to + * zero. Also on 10.6 both arrows are at the bottom. This is handled by + * shifting the scrollbar up by the arrowLength, which only has an effect on + * 10.6 since the arrowLength is 0 on newer systems. */ int fieldLength; @@ -242,7 +259,11 @@ TkpComputeScrollbarGeometry( scrollPtr->highlightWidth = 0; } scrollPtr->inset = scrollPtr->highlightWidth + scrollPtr->borderWidth; - scrollPtr->arrowLength = 0; + if ([NSApp macMinorVersion] == 6) { + scrollPtr->arrowLength = scrollPtr->width; + } else { + scrollPtr->arrowLength = 0; + } fieldLength = (scrollPtr->vertical ? Tk_Height(scrollPtr->tkwin) : Tk_Width(scrollPtr->tkwin)) - 2*(scrollPtr->arrowLength + scrollPtr->inset); @@ -270,8 +291,8 @@ TkpComputeScrollbarGeometry( if (scrollPtr->sliderLast > fieldLength) { scrollPtr->sliderLast = fieldLength; } - scrollPtr->sliderFirst += scrollPtr->arrowLength + scrollPtr->inset; - scrollPtr->sliderLast += scrollPtr->arrowLength + scrollPtr->inset; + scrollPtr->sliderFirst += -scrollPtr->arrowLength + scrollPtr->inset; + scrollPtr->sliderLast += scrollPtr->inset; /* * Register the desired geometry for the window (leave enough space for @@ -397,7 +418,8 @@ TkpScrollbarPosition( width = Tk_Height(scrollPtr->tkwin); } - if (x<inset || x>=width-inset || y<inset || y>=length-inset) { + if (x < inset || x >= width - inset || + y < inset || y >= length - inset) { return OUTSIDE; } @@ -406,21 +428,19 @@ TkpScrollbarPosition( * TkpDisplayScrollbar. Be sure to keep the two consistent. */ - if (y < inset + scrollPtr->arrowLength) { - return TOP_ARROW; - } - if (y < scrollPtr->sliderFirst) { + if (y < scrollPtr->sliderFirst + scrollPtr->arrowLength) { return TOP_GAP; - } - if (y < scrollPtr->sliderLast) { + } + if (y < scrollPtr->sliderLast) { return SLIDER; - } - if (y >= length - (scrollPtr->arrowLength + inset)) { - return BOTTOM_ARROW; - } - - return BOTTOM_GAP; - + } + if (y < length - (2*scrollPtr->arrowLength + inset)) { + return BOTTOM_GAP; + } + if (y < length - (scrollPtr->arrowLength + inset)) { + return TOP_ARROW; + } + return BOTTOM_ARROW; } /* @@ -447,6 +467,7 @@ static void UpdateControlValues( TkScrollbar *scrollPtr) /* Scrollbar data struct. */ { + MacScrollbar *msPtr = (MacScrollbar *)scrollPtr; Tk_Window tkwin = scrollPtr->tkwin; MacDrawable *macWin = (MacDrawable *) Tk_WindowId(scrollPtr->tkwin); double dViewSize; @@ -462,7 +483,7 @@ UpdateControlValues( frame.origin.y = viewHeight - (frame.origin.y + frame.size.height); contrlRect = NSRectToCGRect(frame); - info.bounds = contrlRect; + msPtr->info.bounds = contrlRect; width = contrlRect.size.width; height = contrlRect.size.height; @@ -472,11 +493,11 @@ UpdateControlValues( * have been computed. */ - info.bounds = contrlRect; + msPtr->info.bounds = contrlRect; if (scrollPtr->vertical) { - info.attributes &= ~kThemeTrackHorizontal; + msPtr->info.attributes &= ~kThemeTrackHorizontal; } else { - info.attributes |= kThemeTrackHorizontal; + msPtr->info.attributes |= kThemeTrackHorizontal; } /* @@ -493,25 +514,25 @@ UpdateControlValues( factor = RangeToFactor(maximum); dViewSize = (scrollPtr->lastFraction - scrollPtr->firstFraction) * factor; - info.max = MIN_SCROLLBAR_VALUE + + msPtr->info.max = MIN_SCROLLBAR_VALUE + factor - dViewSize; - info.trackInfo.scrollbar.viewsize = dViewSize; + msPtr->info.trackInfo.scrollbar.viewsize = dViewSize; if (scrollPtr->vertical) { if (MOUNTAIN_LION_STYLE) { - info.value = factor * scrollPtr->firstFraction; + msPtr->info.value = factor * scrollPtr->firstFraction; } else { - info.value = info.max - factor * scrollPtr->firstFraction; + msPtr->info.value = msPtr->info.max - factor * scrollPtr->firstFraction; } } else { - info.value = MIN_SCROLLBAR_VALUE + factor * scrollPtr->firstFraction; + msPtr->info.value = MIN_SCROLLBAR_VALUE + factor * scrollPtr->firstFraction; } if((scrollPtr->firstFraction <= 0.0 && scrollPtr->lastFraction >= 1.0) || height <= metrics.minHeight) { - info.enableState = kThemeTrackHideTrack; + msPtr->info.enableState = kThemeTrackHideTrack; } else { - info.enableState = kThemeTrackActive; - info.attributes = kThemeTrackShowThumb | kThemeTrackThumbRgnIsNotGhost; + msPtr->info.enableState = kThemeTrackActive; + msPtr->info.attributes = kThemeTrackShowThumb | kThemeTrackThumbRgnIsNotGhost; } } @@ -519,29 +540,78 @@ UpdateControlValues( /* *-------------------------------------------------------------- * - * ScrollbarPress -- + * ScrollbarEvent -- * * This procedure is invoked in response to <ButtonPress>, <ButtonRelease>, - * <EnterNotify>, and <LeaveNotify> events. Scrollbar appearance is modified. + * <EnterNotify>, and <LeaveNotify> events. The Scrollbar appearance is + * modified for each event. * *-------------------------------------------------------------- */ static int -ScrollbarPress(TkScrollbar *scrollPtr, XEvent *eventPtr) +ScrollbarEvent(TkScrollbar *scrollPtr, XEvent *eventPtr) { + MacScrollbar *msPtr = (MacScrollbar *)scrollPtr; + + /* The pressState does not indicate whether the moused button was + * pressed at some location in the Scrollbar. Rather, it indicates + * that the scrollbar should appear as if it were pressed in that + * location. The standard Mac behavior is that once the button is + * pressed inside the Scrollbar the appearance should not change until + * the button is released, even if the mouse moves outside of the + * scrollbar. However, if the mouse lies over the scrollbar but the + * button is not pressed then the appearance should be the same as if + * the button had been pressed on the slider, i.e. kThemeThumbPressed. + */ - if (eventPtr->type == ButtonPress) { - UpdateControlValues(scrollPtr); - info.trackInfo.scrollbar.pressState = 1; - } - if (eventPtr->type == EnterNotify) { - info.trackInfo.scrollbar.pressState = 1; - } - if (eventPtr->type == ButtonRelease || eventPtr->type == LeaveNotify) { - info.trackInfo.scrollbar.pressState = 0; - } - return TCL_OK; + if (eventPtr->type == ButtonPress) { + msPtr->buttonDown = true; + UpdateControlValues(scrollPtr); + int where = TkpScrollbarPosition(scrollPtr, + eventPtr->xbutton.x, + eventPtr->xbutton.y); + switch(where) { + case OUTSIDE: + msPtr->info.trackInfo.scrollbar.pressState = 0; + break; + case TOP_GAP: + msPtr->info.trackInfo.scrollbar.pressState = kThemeTopTrackPressed; + break; + case SLIDER: + msPtr->info.trackInfo.scrollbar.pressState = kThemeThumbPressed; + break; + case BOTTOM_GAP: + msPtr->info.trackInfo.scrollbar.pressState = kThemeBottomTrackPressed; + break; + case TOP_ARROW: + /* This looks wrong and the docs say it is wrong but it works. */ + msPtr->info.trackInfo.scrollbar.pressState = kThemeTopInsideArrowPressed; + break; + case BOTTOM_ARROW: + msPtr->info.trackInfo.scrollbar.pressState = kThemeBottomOutsideArrowPressed; + break; + } + } + if (eventPtr->type == ButtonRelease) { + msPtr->buttonDown = false; + if (!msPtr->mouseOver) { + msPtr->info.trackInfo.scrollbar.pressState = 0; + } + } + if (eventPtr->type == EnterNotify) { + msPtr->mouseOver = true; + if (!msPtr->buttonDown) { + msPtr->info.trackInfo.scrollbar.pressState = kThemeThumbPressed; + } + } + if (eventPtr->type == LeaveNotify) { + msPtr->mouseOver = false; + if (!msPtr->buttonDown) { + msPtr->info.trackInfo.scrollbar.pressState = 0; + } + } + return TCL_OK; } @@ -583,9 +653,18 @@ ScrollbarEventProc( case ButtonRelease: case EnterNotify: case LeaveNotify: - ScrollbarPress(clientData, eventPtr); + ScrollbarEvent(clientData, eventPtr); break; default: TkScrollbarEventProc(clientData, eventPtr); } } + +/* + * Local Variables: + * mode: objc + * c-basic-offset: 4 + * fill-column: 79 + * coding: utf-8 + * End: + */ |