summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorcsaba <csaba>2023-05-08 15:22:56 (GMT)
committercsaba <csaba>2023-05-08 15:22:56 (GMT)
commitb738574434d8eafdc4fb1354369a499e82ad6751 (patch)
treecec54515242df1878fec245d5bbb75413099081e
parent902956916ce0188a66aa9a8f7094da2f46ad9040 (diff)
downloadtk-b738574434d8eafdc4fb1354369a499e82ad6751.zip
tk-b738574434d8eafdc4fb1354369a499e82ad6751.tar.gz
tk-b738574434d8eafdc4fb1354369a499e82ad6751.tar.bz2
Implementation of new, modern-looking ttk::checkbutton and ttk::radiobutton indicators for the "default" theme
-rw-r--r--generic/ttk/ttkClassicTheme.c162
-rw-r--r--generic/ttk/ttkElements.c341
-rw-r--r--library/ttk/defaults.tcl52
3 files changed, 411 insertions, 144 deletions
diff --git a/generic/ttk/ttkClassicTheme.c b/generic/ttk/ttkClassicTheme.c
index 4169a87..1c5e1a1 100644
--- a/generic/ttk/ttkClassicTheme.c
+++ b/generic/ttk/ttkClassicTheme.c
@@ -193,6 +193,163 @@ static const Ttk_ElementSpec ButtonBorderElementSpec =
};
/*----------------------------------------------------------------------
+ * +++ Indicator element.
+ *
+ * Draws the on/off indicator for checkbuttons and radiobuttons.
+ *
+ * Draws a 3-D square (or diamond), raised if off, sunken if on.
+ *
+ * This is actually a regression from Tk 8.5 back to the ugly old Motif
+ * style; use the "alt", "clam", or "default" theme" for newer, nicer
+ * versions.
+ */
+
+typedef struct {
+ Tcl_Obj *backgroundObj;
+ Tcl_Obj *reliefObj;
+ Tcl_Obj *colorObj;
+ Tcl_Obj *diameterObj;
+ Tcl_Obj *marginObj;
+ Tcl_Obj *borderWidthObj;
+} IndicatorElement;
+
+static const Ttk_ElementOptionSpec IndicatorElementOptions[] = {
+ { "-background", TK_OPTION_BORDER,
+ offsetof(IndicatorElement,backgroundObj), DEFAULT_BACKGROUND },
+ { "-indicatorcolor", TK_OPTION_BORDER,
+ offsetof(IndicatorElement,colorObj), DEFAULT_BACKGROUND },
+ { "-indicatorrelief", TK_OPTION_RELIEF,
+ offsetof(IndicatorElement,reliefObj), "raised" },
+ { "-indicatordiameter", TK_OPTION_PIXELS,
+ offsetof(IndicatorElement,diameterObj), "12" },
+ { "-indicatormargin", TK_OPTION_STRING,
+ offsetof(IndicatorElement,marginObj), "0 2 4 2" },
+ { "-borderwidth", TK_OPTION_PIXELS,
+ offsetof(IndicatorElement,borderWidthObj), DEFAULT_BORDERWIDTH },
+ { NULL, TK_OPTION_BOOLEAN, 0, NULL }
+};
+
+/*
+ * Checkbutton indicators: 3-D square.
+ */
+static void SquareIndicatorElementSize(
+ void *dummy, void *elementRecord, Tk_Window tkwin,
+ int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
+{
+ IndicatorElement *indicator = (IndicatorElement *)elementRecord;
+ Ttk_Padding margins;
+ int diameter = 0;
+ (void)dummy;
+ (void)paddingPtr;
+
+ Ttk_GetPaddingFromObj(NULL, tkwin, indicator->marginObj, &margins);
+ Tk_GetPixelsFromObj(NULL, tkwin, indicator->diameterObj, &diameter);
+ *widthPtr = diameter + Ttk_PaddingWidth(margins);
+ *heightPtr = diameter + Ttk_PaddingHeight(margins);
+}
+
+static void SquareIndicatorElementDraw(
+ void *dummy, void *elementRecord, Tk_Window tkwin,
+ Drawable d, Ttk_Box b, unsigned int state)
+{
+ IndicatorElement *indicator = (IndicatorElement *)elementRecord;
+ Tk_3DBorder border = 0, interior = 0;
+ int relief = TK_RELIEF_RAISED;
+ Ttk_Padding padding;
+ int borderWidth = 2;
+ int diameter;
+ (void)dummy;
+ (void)state;
+
+ interior = Tk_Get3DBorderFromObj(tkwin, indicator->colorObj);
+ border = Tk_Get3DBorderFromObj(tkwin, indicator->backgroundObj);
+ Tcl_GetIntFromObj(NULL,indicator->borderWidthObj,&borderWidth);
+ Tk_GetReliefFromObj(NULL,indicator->reliefObj,&relief);
+ Ttk_GetPaddingFromObj(NULL,tkwin,indicator->marginObj,&padding);
+
+ b = Ttk_PadBox(b, padding);
+
+ diameter = b.width < b.height ? b.width : b.height;
+ Tk_Fill3DRectangle(tkwin, d, interior, b.x, b.y,
+ diameter, diameter,borderWidth, TK_RELIEF_FLAT);
+ Tk_Draw3DRectangle(tkwin, d, border, b.x, b.y,
+ diameter, diameter, borderWidth, relief);
+}
+
+/*
+ * Radiobutton indicators: 3-D diamond.
+ */
+static void DiamondIndicatorElementSize(
+ void *dummy, void *elementRecord, Tk_Window tkwin,
+ int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
+{
+ IndicatorElement *indicator = (IndicatorElement *)elementRecord;
+ Ttk_Padding margins;
+ int diameter = 0;
+ (void)dummy;
+ (void)paddingPtr;
+
+ Ttk_GetPaddingFromObj(NULL, tkwin, indicator->marginObj, &margins);
+ Tk_GetPixelsFromObj(NULL, tkwin, indicator->diameterObj, &diameter);
+ *widthPtr = diameter + 3 + Ttk_PaddingWidth(margins);
+ *heightPtr = diameter + 3 + Ttk_PaddingHeight(margins);
+}
+
+static void DiamondIndicatorElementDraw(
+ void *dummy, void *elementRecord, Tk_Window tkwin,
+ Drawable d, Ttk_Box b, unsigned int state)
+{
+ IndicatorElement *indicator = (IndicatorElement *)elementRecord;
+ Tk_3DBorder border = 0, interior = 0;
+ int borderWidth = 2;
+ int relief = TK_RELIEF_RAISED;
+ int diameter, radius;
+ XPoint points[4];
+ Ttk_Padding padding;
+ (void)dummy;
+ (void)state;
+
+ interior = Tk_Get3DBorderFromObj(tkwin, indicator->colorObj);
+ border = Tk_Get3DBorderFromObj(tkwin, indicator->backgroundObj);
+ Tcl_GetIntFromObj(NULL,indicator->borderWidthObj,&borderWidth);
+ Tk_GetReliefFromObj(NULL,indicator->reliefObj,&relief);
+ Ttk_GetPaddingFromObj(NULL,tkwin,indicator->marginObj,&padding);
+
+ b = Ttk_PadBox(b, padding);
+
+ diameter = b.width < b.height ? b.width : b.height;
+ radius = diameter / 2;
+
+ points[0].x = b.x;
+ points[0].y = b.y + radius;
+ points[1].x = b.x + radius;
+ points[1].y = b.y + 2*radius;
+ points[2].x = b.x + 2*radius;
+ points[2].y = b.y + radius;
+ points[3].x = b.x + radius;
+ points[3].y = b.y;
+
+ Tk_Fill3DPolygon(tkwin,d,interior,points,4,borderWidth,TK_RELIEF_FLAT);
+ Tk_Draw3DPolygon(tkwin,d,border,points,4,borderWidth,relief);
+}
+
+static const Ttk_ElementSpec CheckbuttonIndicatorElementSpec = {
+ TK_STYLE_VERSION_2,
+ sizeof(IndicatorElement),
+ IndicatorElementOptions,
+ SquareIndicatorElementSize,
+ SquareIndicatorElementDraw
+};
+
+static const Ttk_ElementSpec RadiobuttonIndicatorElementSpec = {
+ TK_STYLE_VERSION_2,
+ sizeof(IndicatorElement),
+ IndicatorElementOptions,
+ DiamondIndicatorElementSize,
+ DiamondIndicatorElementDraw
+};
+
+/*----------------------------------------------------------------------
* +++ Arrow element(s).
*
* Draws a 3-D shaded triangle.
@@ -498,6 +655,11 @@ MODULE_SCOPE int TtkClassicTheme_Init(Tcl_Interp *interp)
Ttk_RegisterElement(interp, theme, "Button.border",
&ButtonBorderElementSpec, NULL);
+ Ttk_RegisterElement(interp, theme, "Checkbutton.indicator",
+ &CheckbuttonIndicatorElementSpec, NULL);
+ Ttk_RegisterElement(interp, theme, "Radiobutton.indicator",
+ &RadiobuttonIndicatorElementSpec, NULL);
+
Ttk_RegisterElement(interp, theme, "uparrow",
&ArrowElementSpec, INT2PTR(ARROW_UP));
Ttk_RegisterElement(interp, theme, "downarrow",
diff --git a/generic/ttk/ttkElements.c b/generic/ttk/ttkElements.c
index 2939003..d31ba64 100644
--- a/generic/ttk/ttkElements.c
+++ b/generic/ttk/ttkElements.c
@@ -538,156 +538,275 @@ static const Ttk_ElementSpec SizegripElementSpec = {
* +++ Indicator element.
*
* Draws the on/off indicator for checkbuttons and radiobuttons.
- *
- * Draws a 3-D square (or diamond), raised if off, sunken if on.
- *
- * This is actually a regression from Tk 8.5 back to the ugly old Motif
- * style; use "altTheme" for the newer, nicer version.
*/
+/*
+ * Indicator image descriptor:
+ */
+typedef struct {
+ int width; /* unscaled width */
+ int height; /* unscaled height */
+ const char *const offDataPtr;
+ const char *const onDataPtr;
+ const char *const triDataPtr;
+} IndicatorSpec;
+
+static const char checkbtnOffData[] = "\
+ <svg width='16' height='16' version='1.1' xmlns='http://www.w3.org/2000/svg'>\n\
+ <rect x='.5' y='.5' width='15' height='15' rx='1.5' fill='#ffffff' stroke='#888888'/>\n\
+ </svg>";
+
+static const char checkbtnOnData[] = "\
+ <svg width='16' height='16' version='1.1' xmlns='http://www.w3.org/2000/svg'>\n\
+ <rect x='0' y='0' width='16' height='16' fill='#4a6984' rx='2'/>\n\
+ <path d='m4.5 8 3 3 4-6' fill='none' stroke='#ffffff' stroke-linecap='round' stroke-linejoin='round' stroke-width='2'/>\n\
+ </svg>";
+
+static const char checkbtnTriData[] = "\
+ <svg width='16' height='16' version='1.1' xmlns='http://www.w3.org/2000/svg'>\n\
+ <rect x='0' y='0' width='16' height='16' fill='#4a6984' rx='2'/>\n\
+ <path d='m4 8h8' fill='none' stroke='#ffffff' stroke-width='2'/>\n\
+ </svg>";
+
+static const IndicatorSpec checkbutton_spec = {
+ 16, 16,
+ checkbtnOffData,
+ checkbtnOnData,
+ checkbtnTriData
+};
+
+static const char radiobtnOffData[] = "\
+ <svg width='16' height='16' version='1.1' xmlns='http://www.w3.org/2000/svg'>\n\
+ <circle cx='8' cy='8' r='7.5' fill='#ffffff' stroke='#888888'/>\n\
+ </svg>";
+
+static const char radiobtnOnData[] = "\
+ <svg width='16' height='16' version='1.1' xmlns='http://www.w3.org/2000/svg'>\n\
+ <circle cx='8' cy='8' r='8' fill='#4a6984'/>\n\
+ <circle cx='8' cy='8' r='3' fill='#ffffff'/>\n\
+ </svg>";
+
+static const char radiobtnTriData[] = "\
+ <svg width='16' height='16' version='1.1' xmlns='http://www.w3.org/2000/svg'>\n\
+ <circle cx='8' cy='8' r='8' fill='#4a6984'/>\n\
+ <path d='m4 8h8' fill='none' stroke='#ffffff' stroke-width='2'/>\n\
+ </svg>";
+
+static const IndicatorSpec radiobutton_spec = {
+ 16, 16,
+ radiobtnOffData,
+ radiobtnOnData,
+ radiobtnTriData
+};
+
typedef struct {
Tcl_Obj *backgroundObj;
- Tcl_Obj *reliefObj;
- Tcl_Obj *colorObj;
- Tcl_Obj *diameterObj;
+ Tcl_Obj *foregroundObj;
+ Tcl_Obj *borderColorObj;
Tcl_Obj *marginObj;
- Tcl_Obj *borderWidthObj;
} IndicatorElement;
+/*
+ * Note that the -indicatorbackground and -indicatorforeground options below
+ * have the same default value "#ffffff", but the -indicatorforeground option
+ * will only be used for the alternate and selected states, in which the
+ * -indicatorbackground option will have a different value (e.g., "#4a6984").
+ */
static const Ttk_ElementOptionSpec IndicatorElementOptions[] = {
- { "-background", TK_OPTION_BORDER,
- offsetof(IndicatorElement,backgroundObj), DEFAULT_BACKGROUND },
- { "-indicatorcolor", TK_OPTION_BORDER,
- offsetof(IndicatorElement,colorObj), DEFAULT_BACKGROUND },
- { "-indicatorrelief", TK_OPTION_RELIEF,
- offsetof(IndicatorElement,reliefObj), "raised" },
- { "-indicatordiameter", TK_OPTION_PIXELS,
- offsetof(IndicatorElement,diameterObj), "12" },
+ { "-indicatorbackground", TK_OPTION_COLOR,
+ offsetof(IndicatorElement,backgroundObj), "#ffffff" },
+ { "-indicatorforeground", TK_OPTION_COLOR,
+ offsetof(IndicatorElement,foregroundObj), "#ffffff" },
+ { "-bordercolor", TK_OPTION_COLOR,
+ offsetof(IndicatorElement,borderColorObj), "#888888" },
{ "-indicatormargin", TK_OPTION_STRING,
offsetof(IndicatorElement,marginObj), "0 2 4 2" },
- { "-borderwidth", TK_OPTION_PIXELS,
- offsetof(IndicatorElement,borderWidthObj), DEFAULT_BORDERWIDTH },
{ NULL, TK_OPTION_BOOLEAN, 0, NULL }
};
-/*
- * Checkbutton indicators (default): 3-D square.
- */
-static void SquareIndicatorElementSize(
- void *dummy, void *elementRecord, Tk_Window tkwin,
+static double scalingFactor;
+
+static void IndicatorElementSize(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
+ const IndicatorSpec *spec = (const IndicatorSpec *)clientData;
+ Tcl_Interp *interp = Tk_Interp(tkwin);
+ const char *scalingPctPtr;
IndicatorElement *indicator = (IndicatorElement *)elementRecord;
Ttk_Padding margins;
- int diameter = 0;
- (void)dummy;
(void)paddingPtr;
+ /*
+ * Retrieve the scaling factor (1.0, 1.25, 1.5, ...)
+ */
+ scalingPctPtr = Tcl_GetVar(interp, "::tk::scalingPct", TCL_GLOBAL_ONLY);
+ scalingFactor = (scalingPctPtr == NULL ? 1.0 : atof(scalingPctPtr) / 100);
+
Ttk_GetPaddingFromObj(NULL, tkwin, indicator->marginObj, &margins);
- Tk_GetPixelsFromObj(NULL, tkwin, indicator->diameterObj, &diameter);
- *widthPtr = diameter + Ttk_PaddingWidth(margins);
- *heightPtr = diameter + Ttk_PaddingHeight(margins);
+ *widthPtr = spec->width * scalingFactor + Ttk_PaddingWidth(margins);
+ *heightPtr = spec->height * scalingFactor + Ttk_PaddingHeight(margins);
}
-static void SquareIndicatorElementDraw(
- void *dummy, void *elementRecord, Tk_Window tkwin,
- Drawable d, Ttk_Box b, unsigned int state)
+static void ColorToStr(
+ const XColor *colorPtr, char *colorStr) /* in the format "RRGGBB" */
{
- IndicatorElement *indicator = (IndicatorElement *)elementRecord;
- Tk_3DBorder border = 0, interior = 0;
- int relief = TK_RELIEF_RAISED;
- Ttk_Padding padding;
- int borderWidth = 2;
- int diameter;
- (void)dummy;
- (void)state;
-
- interior = Tk_Get3DBorderFromObj(tkwin, indicator->colorObj);
- border = Tk_Get3DBorderFromObj(tkwin, indicator->backgroundObj);
- Tcl_GetIntFromObj(NULL,indicator->borderWidthObj,&borderWidth);
- Tk_GetReliefFromObj(NULL,indicator->reliefObj,&relief);
- Ttk_GetPaddingFromObj(NULL,tkwin,indicator->marginObj,&padding);
-
- b = Ttk_PadBox(b, padding);
-
- diameter = b.width < b.height ? b.width : b.height;
- Tk_Fill3DRectangle(tkwin, d, interior, b.x, b.y,
- diameter, diameter,borderWidth, TK_RELIEF_FLAT);
- Tk_Draw3DRectangle(tkwin, d, border, b.x, b.y,
- diameter, diameter, borderWidth, relief);
+ snprintf(colorStr, 7, "%02x%02x%02x",
+ colorPtr->red >> 8, colorPtr->green >> 8, colorPtr->blue >> 8);
}
-/*
- * Radiobutton indicators: 3-D diamond.
- */
-static void DiamondIndicatorElementSize(
- void *dummy, void *elementRecord, Tk_Window tkwin,
- int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
+static void ImageChanged( /* to be passed to Tk_GetImage() */
+ ClientData clientData,
+ int x, int y, int width, int height,
+ int imageWidth, int imageHeight)
{
- IndicatorElement *indicator = (IndicatorElement *)elementRecord;
- Ttk_Padding margins;
- int diameter = 0;
- (void)dummy;
- (void)paddingPtr;
-
- Ttk_GetPaddingFromObj(NULL, tkwin, indicator->marginObj, &margins);
- Tk_GetPixelsFromObj(NULL, tkwin, indicator->diameterObj, &diameter);
- *widthPtr = diameter + 3 + Ttk_PaddingWidth(margins);
- *heightPtr = diameter + 3 + Ttk_PaddingHeight(margins);
+ (void)clientData;
+ (void)x; (void)y; (void)width; (void)height;
+ (void)imageWidth; (void)imageHeight;
}
-static void DiamondIndicatorElementDraw(
- void *dummy, void *elementRecord, Tk_Window tkwin,
+static void IndicatorElementDraw(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
Drawable d, Ttk_Box b, unsigned int state)
{
IndicatorElement *indicator = (IndicatorElement *)elementRecord;
- Tk_3DBorder border = 0, interior = 0;
- int borderWidth = 2;
- int relief = TK_RELIEF_RAISED;
- int diameter, radius;
- XPoint points[4];
Ttk_Padding padding;
- (void)dummy;
- (void)state;
+ const IndicatorSpec *spec = (const IndicatorSpec *)clientData;
+
+ char bgColorStr[7], fgColorStr[7], borderColorStr[7];
+ unsigned int selected = (state & TTK_STATE_SELECTED);
+ unsigned int tristate = (state & TTK_STATE_ALTERNATE);
+ Tcl_Interp *interp = Tk_Interp(tkwin);
+ char imgName[60];
+ Tk_Image img;
+
+ const char *svgDataPtr;
+ size_t svgDataLen;
+ char *svgDataCopy;
+ char *bgColorPtr, *fgColorPtr, *borderColorPtr;
+ const char *cmdFmt;
+ size_t scriptSize;
+ char *script;
+ int code;
+
+ Ttk_GetPaddingFromObj(NULL, tkwin, indicator->marginObj, &padding);
+ b = Ttk_PadBox(b, padding);
- interior = Tk_Get3DBorderFromObj(tkwin, indicator->colorObj);
- border = Tk_Get3DBorderFromObj(tkwin, indicator->backgroundObj);
- Tcl_GetIntFromObj(NULL,indicator->borderWidthObj,&borderWidth);
- Tk_GetReliefFromObj(NULL,indicator->reliefObj,&relief);
- Ttk_GetPaddingFromObj(NULL,tkwin,indicator->marginObj,&padding);
+ /*
+ * Sanity check
+ */
+ if ( b.x < 0
+ || b.y < 0
+ || Tk_Width(tkwin) < b.x + spec->width * scalingFactor
+ || Tk_Height(tkwin) < b.y + spec->height * scalingFactor)
+ {
+ /* Oops! Not enough room to display the image.
+ * Don't draw anything.
+ */
+ return;
+ }
- b = Ttk_PadBox(b, padding);
+ /*
+ * Construct the color strings bgColorStr, fgColorStr, and borderColorStr
+ */
+ ColorToStr(Tk_GetColorFromObj(tkwin, indicator->backgroundObj),
+ bgColorStr);
+ ColorToStr(Tk_GetColorFromObj(tkwin, indicator->foregroundObj),
+ fgColorStr);
+ ColorToStr(Tk_GetColorFromObj(tkwin, indicator->borderColorObj),
+ borderColorStr);
- diameter = b.width < b.height ? b.width : b.height;
- radius = diameter / 2;
+ /*
+ * Check whether there is an SVG image for the indicator's
+ * type (0 = checkbtn, 1 = radiobtn), "state" (0 = off,
+ * 1 = on, 2 = tristate), and these color strings
+ */
+ snprintf(imgName, sizeof(imgName),
+ "::tk::icons::indicator_default%d,%d_%s_%s_%s",
+ spec->offDataPtr == radiobtnOffData,
+ tristate ? 2 : (selected ? 1 : 0),
+ bgColorStr,
+ selected || tristate ? fgColorStr : "XXXXXX",
+ selected || tristate ? "XXXXXX" : borderColorStr);
+ img = Tk_GetImage(interp, tkwin, imgName, ImageChanged, NULL);
+ if (img == NULL) {
+ /*
+ * Determine the SVG data to use for the photo image
+ */
+ svgDataPtr = (tristate ? spec->triDataPtr :
+ (selected ? spec->onDataPtr : spec->offDataPtr));
- points[0].x = b.x;
- points[0].y = b.y + radius;
- points[1].x = b.x + radius;
- points[1].y = b.y + 2*radius;
- points[2].x = b.x + 2*radius;
- points[2].y = b.y + radius;
- points[3].x = b.x + radius;
- points[3].y = b.y;
+ /*
+ * Copy the string pointed to by svgDataPtr to a newly allocated memory
+ * area svgDataCopy and assign the latter's address to svgDataPtr
+ */
+ svgDataLen = strlen(svgDataPtr);
+ svgDataCopy = (char *)attemptckalloc(svgDataLen + 1);
+ if (svgDataCopy == NULL) {
+ return;
+ }
+ memcpy(svgDataCopy, svgDataPtr, svgDataLen);
+ svgDataCopy[svgDataLen] = '\0';
+ svgDataPtr = svgDataCopy;
- Tk_Fill3DPolygon(tkwin,d,interior,points,4,borderWidth,TK_RELIEF_FLAT);
- Tk_Draw3DPolygon(tkwin,d,border,points,4,borderWidth,relief);
-}
+ /*
+ * Update the colors within svgDataCopy
+ */
+ if (selected || tristate) {
+ bgColorPtr = strstr(svgDataPtr, "4a6984");
+ fgColorPtr = strstr(svgDataPtr, "ffffff");
-static const Ttk_ElementSpec CheckbuttonIndicatorElementSpec = {
- TK_STYLE_VERSION_2,
- sizeof(IndicatorElement),
- IndicatorElementOptions,
- SquareIndicatorElementSize,
- SquareIndicatorElementDraw
-};
+ assert(bgColorPtr);
+ assert(fgColorPtr);
+
+ memcpy(bgColorPtr, bgColorStr, 6);
+ memcpy(fgColorPtr, fgColorStr, 6);
+ } else {
+ bgColorPtr = strstr(svgDataPtr, "ffffff");
+ borderColorPtr = strstr(svgDataPtr, "888888");
+
+ assert(bgColorPtr);
+ assert(borderColorPtr);
+
+ memcpy(bgColorPtr, bgColorStr, 6);
+ memcpy(borderColorPtr, borderColorStr, 6);
+ }
+
+ /*
+ * Create an SVG photo image from svgDataCopy
+ */
+ cmdFmt = "image create photo %s -format $::tk::svgFmt -data {%s}";
+ scriptSize = strlen(cmdFmt) + strlen(imgName) + svgDataLen;
+ script = (char *)attemptckalloc(scriptSize);
+ if (script == NULL) {
+ ckfree(svgDataCopy);
+ return;
+ }
+ snprintf(script, scriptSize, cmdFmt, imgName, svgDataCopy);
+ ckfree(svgDataCopy);
+ code = Tcl_EvalEx(interp, script, -1, TCL_EVAL_GLOBAL);
+ ckfree(script);
+ if (code != TCL_OK) {
+ Tcl_BackgroundException(interp, code);
+ return;
+ }
+ img = Tk_GetImage(interp, tkwin, imgName, ImageChanged, NULL);
+ }
+
+ /*
+ * Display the image
+ */
+ Tk_RedrawImage(img, 0, 0, spec->width * scalingFactor,
+ spec->height * scalingFactor, d, b.x, b.y);
+ Tk_FreeImage(img);
+}
-static const Ttk_ElementSpec RadiobuttonIndicatorElementSpec = {
+static const Ttk_ElementSpec IndicatorElementSpec = {
TK_STYLE_VERSION_2,
sizeof(IndicatorElement),
IndicatorElementOptions,
- DiamondIndicatorElementSize,
- DiamondIndicatorElementDraw
+ IndicatorElementSize,
+ IndicatorElementDraw
};
/*
@@ -1348,13 +1467,13 @@ void TtkElements_Init(Tcl_Interp *interp)
Ttk_RegisterElement(interp, theme, "padding", &PaddingElementSpec, NULL);
Ttk_RegisterElement(interp, theme, "Checkbutton.indicator",
- &CheckbuttonIndicatorElementSpec, NULL);
+ &IndicatorElementSpec, (void *)&checkbutton_spec);
Ttk_RegisterElement(interp, theme, "Radiobutton.indicator",
- &RadiobuttonIndicatorElementSpec, NULL);
+ &IndicatorElementSpec, (void *)&radiobutton_spec);
Ttk_RegisterElement(interp, theme, "Menubutton.indicator",
&MenuIndicatorElementSpec, NULL);
- Ttk_RegisterElement(interp, theme, "indicator", &ttkNullElementSpec,NULL);
+ Ttk_RegisterElement(interp, theme, "indicator", &ttkNullElementSpec, NULL);
Ttk_RegisterElement(interp, theme, "uparrow",
&ArrowElementSpec, INT2PTR(ARROW_UP));
diff --git a/library/ttk/defaults.tcl b/library/ttk/defaults.tcl
index ba851cb..6f46dfd 100644
--- a/library/ttk/defaults.tcl
+++ b/library/ttk/defaults.tcl
@@ -18,8 +18,7 @@ namespace eval ttk::theme::default {
-disabledfg "#a3a3a3"
-indicator "#4a6984"
-disabledindicator "#a3a3a3"
- -altindicator "#9fbdd8"
- -disabledaltindicator "#c0c0c0"
+ -pressedindicator "#5895bc"
}
# On X11, if the user specifies their own choice of colour scheme via
@@ -40,14 +39,12 @@ namespace eval ttk::theme::default {
{ selectBackground SelectBackground }
{ disabledForeground DisabledForeground }
{ selectBackground SelectBackground }
- { troughColor TroughColor }
{ windowColor Background } } \
colorName {
-frame -foreground -window -alternate -text
-activebg -selectbg -selectfg
-darker -disabledfg -indicator
- -disabledindicator -altindicator
- -disabledaltindicator -window } {
+ -disabledindicator -pressedindicator -window } {
set color [eval option get . $xResourceName]
if {$color ne ""} {
set colors($colorName) $color
@@ -64,9 +61,9 @@ namespace eval ttk::theme::default {
background {-frame -window -alternate}
foreground {-foreground -text}
activeBackground -activebg
- selectBackground {-selectbg -indicator -altindicator}
+ selectBackground {-selectbg -indicator -pressedindicator}
selectForeground -selectfg
- troughColor {-darker -disabledaltindicator}
+ troughColor -darker
disabledForeground {-disabledfg -disabledindicator}
}
}
@@ -97,7 +94,6 @@ proc ttk::theme::default::reconfigureDefaultTheme {} {
-selectbackground $colors(-selectbg) \
-selectforeground $colors(-selectfg) \
-insertwidth 1 \
- -indicatordiameter 10 \
;
ttk::style map "." -background \
@@ -114,31 +110,21 @@ proc ttk::theme::default::reconfigureDefaultTheme {} {
-relief raised -shiftrelief 1
ttk::style map TButton -relief [list {!disabled pressed} sunken]
- ttk::style configure TCheckbutton \
- -indicatorcolor $colors(-window) -indicatorrelief sunken \
- -indicatordiameter 7.5p -indicatormargin {0 1.5p 3p 1.5p} \
- -padding 0.75p
- ttk::style map TCheckbutton -indicatorcolor \
- [list pressed $colors(-activebg) \
- {!disabled alternate} $colors(-altindicator) \
- {disabled alternate} $colors(-disabledaltindicator) \
- {!disabled selected} $colors(-indicator) \
- {disabled selected} $colors(-disabledindicator)]
- ttk::style map TCheckbutton -indicatorrelief \
- [list alternate raised]
-
- ttk::style configure TRadiobutton \
- -indicatorcolor $colors(-window) -indicatorrelief sunken \
- -indicatordiameter 7.5p -indicatormargin {0 1.5p 3p 1.5p} \
- -padding 0.75p
- ttk::style map TRadiobutton -indicatorcolor \
- [list pressed $colors(-activebg) \
- {!disabled alternate} $colors(-altindicator) \
- {disabled alternate} $colors(-disabledaltindicator) \
- {!disabled selected} $colors(-indicator) \
- {disabled selected} $colors(-disabledindicator)]
- ttk::style map TRadiobutton -indicatorrelief \
- [list alternate raised]
+ foreach style {TCheckbutton TRadiobutton} {
+ ttk::style configure $style \
+ -indicatorbackground $colors(-window) \
+ -indicatorforeground $colors(-selectfg) \
+ -indicatormargin {0 1.5p 3p 1.5p} -padding 0.75p
+ ttk::style map $style -indicatorbackground \
+ [list {alternate disabled} $colors(-disabledindicator) \
+ {alternate pressed} $colors(-pressedindicator) \
+ alternate $colors(-indicator) \
+ {selected disabled} $colors(-disabledindicator) \
+ {selected pressed} $colors(-pressedindicator) \
+ selected $colors(-indicator) \
+ disabled $colors(-frame) \
+ pressed $colors(-darker)]
+ }
ttk::style configure TMenubutton \
-relief raised -indicatormargin {3.75p 0} -padding {7.5p 2.25p}