diff options
Diffstat (limited to 'macosx/ttkMacOSXTheme.c')
-rw-r--r-- | macosx/ttkMacOSXTheme.c | 145 |
1 files changed, 107 insertions, 38 deletions
diff --git a/macosx/ttkMacOSXTheme.c b/macosx/ttkMacOSXTheme.c index f1b7b8e..3541dd8 100644 --- a/macosx/ttkMacOSXTheme.c +++ b/macosx/ttkMacOSXTheme.c @@ -39,7 +39,7 @@ #define BEGIN_DRAWING(d) { \ TkMacOSXDrawingContext dc; \ - if (!TkMacOSXSetupDrawingContext((d), NULL, 1, &dc)) {return;} + if (!TkMacOSXSetupDrawingContext((d), NULL, &dc)) {return;} #define END_DRAWING \ TkMacOSXRestoreDrawingContext(&dc);} @@ -153,7 +153,7 @@ static inline CGRect BoxToRect( Drawable d, Ttk_Box b) { - MacDrawable *md = (MacDrawable *) d; + MacDrawable *md = (MacDrawable *)d; CGRect rect; rect.origin.y = b.y + md->yOff; @@ -242,31 +242,31 @@ static CGFloat blackRGBA[4] = {0.0, 0.0, 0.0, 1.0}; * GetBackgroundColor -- * * Fills the array rgba with the color coordinates for a background color. - * Start with the background color of a window's geometry master, or the - * standard ttk window background if there is no master. If the contrast - * parameter is nonzero, modify this color to be darker, for the aqua - * appearance, or lighter for the DarkAqua appearance. This is primarily - * used by the Fill and Background elements. + * Start with the background color of a window's geometry container, or + * the standard ttk window background if there is no container. If the + * contrast parameter is nonzero, modify this color to be darker, for the + * aqua appearance, or lighter for the DarkAqua appearance. This is + * primarily used by the Fill and Background elements. */ static void GetBackgroundColor( - CGContextRef context, + TCL_UNUSED(CGContextRef), Tk_Window tkwin, int contrast, CGFloat *rgba) { - TkWindow *winPtr = (TkWindow *) tkwin; - TkWindow *masterPtr = (TkWindow *) TkGetGeomMaster(tkwin); + TkWindow *winPtr = (TkWindow *)tkwin; + TkWindow *containerPtr = (TkWindow *)TkGetGeomMaster(tkwin); - while (masterPtr && masterPtr->privatePtr) { - if (masterPtr->privatePtr->flags & TTK_HAS_CONTRASTING_BG) { + while (containerPtr && containerPtr->privatePtr) { + if (containerPtr->privatePtr->flags & TTK_HAS_CONTRASTING_BG) { break; } - masterPtr = (TkWindow *) TkGetGeomMaster(masterPtr); + containerPtr = (TkWindow *)TkGetGeomMaster(containerPtr); } - if (masterPtr && masterPtr->privatePtr) { + if (containerPtr && containerPtr->privatePtr) { for (int i = 0; i < 4; i++) { - rgba[i] = masterPtr->privatePtr->fillRGBA[i]; + rgba[i] = containerPtr->privatePtr->fillRGBA[i]; } } else { if ([NSApp macOSVersion] > 101300) { @@ -303,9 +303,10 @@ static void GetBackgroundColor( /*---------------------------------------------------------------------- - * +++ Single Arrow Buttons -- + * +++ Single Arrow Images -- * - * Used in ListHeaders and Comboboxes. + * Used in ListHeaders and Comboboxes as well as disclosure triangles in + * macOS 11. */ static void DrawDownArrow( @@ -352,6 +353,48 @@ static void DrawUpArrow( CGContextStrokePath(context); } +static void DrawClosedDisclosure( + CGContextRef context, + CGRect bounds, + CGFloat inset, + CGFloat size, + CGFloat *rgba) +{ + CGFloat x, y; + + CGContextSetRGBStrokeColor(context, rgba[0], rgba[1], rgba[2], rgba[3]); + CGContextSetLineWidth(context, 1.5); + x = bounds.origin.x + inset; + y = bounds.origin.y + trunc(bounds.size.height / 2); + CGContextBeginPath(context); + CGPoint arrow[3] = { + {x, y - size / 4 - 1}, {x + size / 2, y}, {x, y + size / 4 + 1} + }; + CGContextAddLines(context, arrow, 3); + CGContextStrokePath(context); +} + +static void DrawOpenDisclosure( + CGContextRef context, + CGRect bounds, + CGFloat inset, + CGFloat size, + CGFloat *rgba) +{ + CGFloat x, y; + + CGContextSetRGBStrokeColor(context, rgba[0], rgba[1], rgba[2], rgba[3]); + CGContextSetLineWidth(context, 1.5); + x = bounds.origin.x + inset; + y = bounds.origin.y + trunc(bounds.size.height / 2); + CGContextBeginPath(context); + CGPoint arrow[3] = { + {x, y - size / 4}, {x + size / 2, y + size / 2}, {x + size, y - size / 4} + }; + CGContextAddLines(context, arrow, 3); + CGContextStrokePath(context); +} + /*---------------------------------------------------------------------- * +++ Double Arrow Buttons -- * @@ -501,10 +544,13 @@ static void SolidFillRoundedRectangle( NSColor *color) { CGPathRef path; - CHECK_RADIUS(radius, bounds) - CGContextSetFillColorWithColor(context, CGCOLOR(color)); + CHECK_RADIUS(radius, bounds) path = CGPathCreateWithRoundedRect(bounds, radius, radius, NULL); + if (!path) { + return; + } + CGContextSetFillColorWithColor(context, CGCOLOR(color)); CGContextBeginPath(context); CGContextAddPath(context, path); CGContextFillPath(context); @@ -547,7 +593,7 @@ static void DrawListHeader( * So we have to query the Apple window manager. */ - NSWindow *win = TkMacOSXDrawableWindow(Tk_WindowId(tkwin)); + NSWindow *win = TkMacOSXGetNSWindowForDrawable(Tk_WindowId(tkwin)); CGFloat *bgRGBA = [win isKeyWindow] ? activeBgRGBA : inactiveBgRGBA; CGFloat x = bounds.origin.x, y = bounds.origin.y; CGFloat w = bounds.size.width, h = bounds.size.height; @@ -1039,7 +1085,7 @@ static void DrawDarkTab( static void DrawDarkSeparator( CGRect bounds, CGContextRef context, - Tk_Window tkwin) + TCL_UNUSED(Tk_Window)) { static CGFloat fill[4] = {1.0, 1.0, 1.0, 0.3}; NSColorSpace *deviceRGB = [NSColorSpace deviceRGBColorSpace]; @@ -1165,7 +1211,7 @@ static void DrawDarkFrame( static void DrawDarkListHeader( CGRect bounds, CGContextRef context, - Tk_Window tkwin, + TCL_UNUSED(Tk_Window), int state) { NSColorSpace *deviceRGB = [NSColorSpace deviceRGBColorSpace]; @@ -1174,10 +1220,10 @@ static void DrawDarkListHeader( CGContextSetStrokeColorSpace(context, deviceRGB.CGColorSpace); CGFloat x = bounds.origin.x, y = bounds.origin.y; CGFloat w = bounds.size.width, h = bounds.size.height; - CGPoint top[2] = {{x, y}, {x + w, y}}; - CGPoint bottom[2] = {{x, y + h}, {x + w, y + h}}; - CGPoint separator[2] = {{x + w, y + 3}, {x + w, y + h - 3}}; + CGPoint top[2] = {{x, y + 1}, {x + w, y + 1}}; + CGPoint bottom[2] = {{x, y + h}, {x + w, y + h}}; + CGPoint separator[2] = {{x + w - 1, y + 3}, {x + w - 1, y + h - 3}}; CGContextSaveGState(context); CGContextSetShouldAntialias(context, false); stroke = [NSColor colorWithColorSpace: deviceRGB @@ -2098,10 +2144,16 @@ static void TrackElementDraw( Tcl_GetDoubleFromObj(NULL, elem->valueObj, &value); factor = RangeToFactor(to); + /* + * HIThemeTrackDrawInfo uses 2-byte alignment; assigning to a separate + * bounds variable avoids UBSan (-fsanitize=alignment) complaints. + */ + + CGRect bounds = BoxToRect(d, b); HIThemeTrackDrawInfo info = { .version = 0, .kind = data->kind, - .bounds = BoxToRect(d, b), + .bounds = bounds, .min = from * factor, .max = to * factor, .value = value * factor, @@ -2236,13 +2288,19 @@ static void PbarElementDraw( Tcl_GetIntFromObj(NULL, pbar->phaseObj, &phase); factor = RangeToFactor(maximum); + /* + * HIThemeTrackDrawInfo uses 2-byte alignment; assigning to a separate + * bounds variable avoids UBSan (-fsanitize=alignment) complaints. + */ + + CGRect bounds = BoxToRect(d, b); HIThemeTrackDrawInfo info = { .version = 0, .kind = (!strcmp("indeterminate", Tcl_GetString(pbar->modeObj)) && value) ? kThemeIndeterminateBar : kThemeProgressBar, - .bounds = BoxToRect(d, b), + .bounds = bounds, .min = 0, .max = maximum * factor, .value = value * factor, @@ -2448,7 +2506,7 @@ static void ThumbElementDraw( END_DRAWING } else { double thumbSize, trackSize, visibleSize, factor, fraction; - MacDrawable *macWin = (MacDrawable *) Tk_WindowId(tkwin); + MacDrawable *macWin = (MacDrawable *)Tk_WindowId(tkwin); CGRect troughBounds = {{macWin->xOff, macWin->yOff}, {Tk_Width(tkwin), Tk_Height(tkwin)}}; @@ -2998,8 +3056,21 @@ static void DisclosureElementDraw( }; BEGIN_DRAWING(d) - ChkErr(HIThemeDrawButton, &bounds, &info, dc.context, HIOrientation, + if ([NSApp macOSVersion] >= 110000) { + CGFloat rgba[4]; + NSColorSpace *deviceRGB = [NSColorSpace deviceRGBColorSpace]; + NSColor *stroke = [[NSColor textColor] + colorUsingColorSpace: deviceRGB]; + [stroke getComponents: rgba]; + if (state & TTK_TREEVIEW_STATE_OPEN) { + DrawOpenDisclosure(dc.context, bounds, 2, 8, rgba); + } else { + DrawClosedDisclosure(dc.context, bounds, 2, 12, rgba); + } + } else { + ChkErr(HIThemeDrawButton, &bounds, &info, dc.context, HIOrientation, NULL); + } END_DRAWING } } @@ -3049,20 +3120,20 @@ TTK_LAYOUT("TCombobox", /* Notebook tabs -- no focus ring */ TTK_LAYOUT("Tab", TTK_GROUP("Notebook.tab", TTK_FILL_BOTH, - TTK_GROUP("Notebook.padding", TTK_EXPAND | TTK_FILL_BOTH, - TTK_NODE("Notebook.label", TTK_EXPAND | TTK_FILL_BOTH)))) + TTK_GROUP("Notebook.padding", TTK_FILL_BOTH, + TTK_NODE("Notebook.label", TTK_FILL_BOTH)))) /* Spinbox -- buttons 2px to the right of the field. */ TTK_LAYOUT("TSpinbox", TTK_GROUP("Spinbox.buttons", TTK_PACK_RIGHT, TTK_NODE("Spinbox.uparrow", TTK_PACK_TOP | TTK_STICK_E) TTK_NODE("Spinbox.downarrow", TTK_PACK_BOTTOM | TTK_STICK_E)) - TTK_GROUP("Spinbox.field", TTK_EXPAND | TTK_FILL_X, - TTK_NODE("Spinbox.textarea", TTK_EXPAND | TTK_FILL_X))) + TTK_GROUP("Spinbox.field", TTK_FILL_X, + TTK_NODE("Spinbox.textarea", TTK_FILL_X))) /* Progress bars -- track only */ TTK_LAYOUT("TProgressbar", - TTK_NODE("Progressbar.track", TTK_EXPAND | TTK_FILL_BOTH)) + TTK_NODE("Progressbar.track", TTK_FILL_BOTH)) /* Treeview -- no border. */ TTK_LAYOUT("Treeview", @@ -3087,15 +3158,13 @@ TTK_LAYOUT("Item", TTK_LAYOUT("Vertical.TScrollbar", TTK_GROUP("Vertical.Scrollbar.trough", TTK_FILL_Y, - TTK_NODE("Vertical.Scrollbar.thumb", - TTK_PACK_TOP | TTK_EXPAND | TTK_FILL_BOTH) + TTK_NODE("Vertical.Scrollbar.thumb", TTK_FILL_BOTH) TTK_NODE("Vertical.Scrollbar.downarrow", TTK_PACK_BOTTOM) TTK_NODE("Vertical.Scrollbar.uparrow", TTK_PACK_BOTTOM))) TTK_LAYOUT("Horizontal.TScrollbar", TTK_GROUP("Horizontal.Scrollbar.trough", TTK_FILL_X, - TTK_NODE("Horizontal.Scrollbar.thumb", - TTK_PACK_LEFT | TTK_EXPAND | TTK_FILL_BOTH) + TTK_NODE("Horizontal.Scrollbar.thumb", TTK_FILL_BOTH) TTK_NODE("Horizontal.Scrollbar.rightarrow", TTK_PACK_RIGHT) TTK_NODE("Horizontal.Scrollbar.leftarrow", TTK_PACK_RIGHT))) |