summaryrefslogtreecommitdiffstats
path: root/macosx/ttkMacOSXTheme.c
diff options
context:
space:
mode:
Diffstat (limited to 'macosx/ttkMacOSXTheme.c')
-rw-r--r--macosx/ttkMacOSXTheme.c145
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)))