summaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
authorcsaba <csaba>2023-01-31 19:53:27 (GMT)
committercsaba <csaba>2023-01-31 19:53:27 (GMT)
commit78b317b274c134bd778015cfffac2288ee6ef075 (patch)
treeccb3057a589027b15db93a0ad0a7bfbfbda0c9e5 /generic
parentc41c244e7701ad4fb83800220a56e05b9bd5e645 (diff)
downloadtk-78b317b274c134bd778015cfffac2288ee6ef075.zip
tk-78b317b274c134bd778015cfffac2288ee6ef075.tar.gz
tk-78b317b274c134bd778015cfffac2288ee6ef075.tar.bz2
Made the ttk::checkbutton and ttk::radiobutton indicators of the alt theme scaling-aware, preserving their 3D look
Diffstat (limited to 'generic')
-rw-r--r--generic/ttk/ttkDefaultTheme.c364
1 files changed, 212 insertions, 152 deletions
diff --git a/generic/ttk/ttkDefaultTheme.c b/generic/ttk/ttkDefaultTheme.c
index 1acdcbc..7be808b 100644
--- a/generic/ttk/ttkDefaultTheme.c
+++ b/generic/ttk/ttkDefaultTheme.c
@@ -375,8 +375,11 @@ static const Ttk_ElementSpec FieldElementSpec = {
/*------------------------------------------------------------------------
* Indicators --
*
- * Code derived (probably incorrectly) from TIP 109 implementation,
- * unix/tkUnixButton.c r 1.15.
+ * The SVG images used here are partly based on some icons provided by
+ * the official open source SVG icon library for the Bootstrap project,
+ * licensed under the MIT license (https://opensource.org/licenses/MIT).
+ *
+ * See https://github.com/twbs/icons.
*/
/*
@@ -385,28 +388,11 @@ static const Ttk_ElementSpec FieldElementSpec = {
typedef struct {
int width; /* Width of each image */
int height; /* Height of each image */
- int nimages; /* #images / row */
- const char *const *pixels; /* array[height] of char[width*nimage] */
+ const char *offDataPtr;
+ const char *onDataPtr;
const Ttk_StateTable *map;/* used to look up image index by state */
} IndicatorSpec;
-#if 0
-/*XPM*/
-static const char *const button_images[] = {
- /* width height ncolors chars_per_pixel */
- "52 13 8 1",
- /* colors */
- "A c #808000000000 s shadow",
- "B c #000080800000 s highlight",
- "C c #808080800000 s 3dlight",
- "D c #000000008080 s window",
- "E c #808000008080 s 3ddark",
- "F c #000080808080 s frame",
- "G c #000000000000 s foreground",
- "H c #000080800000 s disabledfg",
-};
-#endif
-
static const Ttk_StateTable checkbutton_states[] = {
{ 0, 0, TTK_STATE_SELECTED|TTK_STATE_DISABLED },
{ 1, TTK_STATE_SELECTED, TTK_STATE_DISABLED },
@@ -415,25 +401,33 @@ static const Ttk_StateTable checkbutton_states[] = {
{ 0, 0, 0 }
};
-static const char *const checkbutton_pixels[] = {
- "AAAAAAAAAAAABAAAAAAAAAAAABAAAAAAAAAAAABAAAAAAAAAAAAB",
- "AEEEEEEEEEECBAEEEEEEEEEECBAEEEEEEEEEECBAEEEEEEEEEECB",
- "AEDDDDDDDDDCBAEDDDDDDDDDCBAEFFFFFFFFFCBAEFFFFFFFFFCB",
- "AEDDDDDDDDDCBAEDDDDDDDGDCBAEFFFFFFFFFCBAEFFFFFFFHFCB",
- "AEDDDDDDDDDCBAEDDDDDDGGDCBAEFFFFFFFFFCBAEFFFFFFHHFCB",
- "AEDDDDDDDDDCBAEDGDDDGGGDCBAEFFFFFFFFFCBAEFHFFFHHHFCB",
- "AEDDDDDDDDDCBAEDGGDGGGDDCBAEFFFFFFFFFCBAEFHHFHHHFFCB",
- "AEDDDDDDDDDCBAEDGGGGGDDDCBAEFFFFFFFFFCBAEFHHHHHFFFCB",
- "AEDDDDDDDDDCBAEDDGGGDDDDCBAEFFFFFFFFFCBAEFFHHHFFFFCB",
- "AEDDDDDDDDDCBAEDDDGDDDDDCBAEFFFFFFFFFCBAEFFFHFFFFFCB",
- "AEDDDDDDDDDCBAEDDDDDDDDDCBAEFFFFFFFFFCBAEFFFFFFFFFCB",
- "ACCCCCCCCCCCBACCCCCCCCCCCBACCCCCCCCCCCBACCCCCCCCCCCB",
- "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB",
-};
+static const char *const checkbtnOffData = "\
+ <svg width='16' height='16' version='1.1' xmlns='http://www.w3.org/2000/svg'>\n\
+ <g>\n\
+ <path d='m0 0v15h1v-14h14v-1z' fill='#888888'/>\n\
+ <path d='m1 1v13h1v-12h12v-1z' fill='#414141'/>\n\
+ <path d='m14 1v13h-13v1h14v-14z' fill='#d9d9d9'/>\n\
+ <path d='m15 0v15h-15v1h16v-16z' fill='#eeeeee'/>\n\
+ <rect x='2' y='2' width='12' height='12' fill='#ffffff'/>\n\
+ </g>\n\
+ </svg>";
+
+static const char *const checkbtnOnData = "\
+ <svg width='16' height='16' version='1.1' xmlns='http://www.w3.org/2000/svg'>\n\
+ <g>\n\
+ <path d='m0 0v15h1v-14h14v-1z' fill='#888888'/>\n\
+ <path d='m1 1v13h1v-12h12v-1z' fill='#414141'/>\n\
+ <path d='m14 1v13h-13v1h14v-14z' fill='#d9d9d9'/>\n\
+ <path d='m15 0v15h-15v1h16v-16z' fill='#eeeeee'/>\n\
+ <rect x='2' y='2' width='12' height='12' fill='#ffffff'/>\n\
+ <path d='m10.803 4.969a0.75002 0.75002 0 0 1 1.071 1.05l-3.992 4.9901a0.75002 0.75002 0 0 1-1.08 0.01999l-2.645-2.646a0.75002 0.75002 0 1 1 1.06-1.06l2.094 2.093 3.473-4.4251a0.235 0.235 0 0 1 0.01999-0.021997z' fill='#000000'/>\n\
+ </g>\n\
+ </svg>";
static IndicatorSpec checkbutton_spec = {
- 13, 13, 4, /* width, height, nimages */
- checkbutton_pixels,
+ 16, 16,
+ checkbtnOffData,
+ checkbtnOnData,
checkbutton_states
};
@@ -445,25 +439,45 @@ static const Ttk_StateTable radiobutton_states[] = {
{ 0, 0, 0 }
};
-static const char *const radiobutton_pixels[] = {
- "FFFFAAAAFFFFFFFFFAAAAFFFFFFFFFAAAAFFFFFFFFFAAAAFFFFF",
- "FFAAEEEEAAFFFFFAAEEEEAAFFFFFAAEEEEAAFFFFFAAEEEEAAFFF",
- "FAEEDDDDEEBFFFAEEDDDDEEBFFFAEEFFFFEEBFFFAEEFFFFEEBFF",
- "FAEDDDDDDCBFFFAEDDDDDDCBFFFAEFFFFFFCBFFFAEFFFFFFCBFF",
- "AEDDDDDDDDCBFAEDDDGGDDDCBFAEFFFFFFFFCBFAEFFFHHFFFCBF",
- "AEDDDDDDDDCBFAEDDGGGGDDCBFAEFFFFFFFFCBFAEFFHHHHFFCBF",
- "AEDDDDDDDDCBFAEDDGGGGDDCBFAEFFFFFFFFCBFAEFFHHHHFFCBF",
- "AEDDDDDDDDCBFAEDDDGGDDDCBFAEFFFFFFFFCBFAEFFFHHFFFCBF",
- "FAEDDDDDDCBFFFAEDDDDDDCBFFFAEFFFFFFCBFFFAEFFFFFFCBFF",
- "FACCDDDDCCBFFFACCDDDDCCBFFFACCFFFFCCBFFFACCFFFFCCBFF",
- "FFBBCCCCBBFFFFFBBCCCCBBFFFFFBBCCCCBBFFFFFBBCCCCBBFFF",
- "FFFFBBBBFFFFFFFFFBBBBFFFFFFFFFBBBBFFFFFFFFFBBBBFFFFF",
- "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
-};
+static const char *const radiobtnOffData = "\
+ <svg width='16' height='16' version='1.1' xmlns='http://www.w3.org/2000/svg'>\n\
+ <defs>\n\
+ <linearGradient id='linearGradient1319' x1='7' x2='9' y1='8' y2='8' gradientTransform='rotate(45,8,8)' gradientUnits='userSpaceOnUse'>\n\
+ <stop stop-color='#888888' offset='0'/>\n\
+ <stop stop-color='#eeeeee' offset='1'/>\n\
+ </linearGradient>\n\
+ <linearGradient id='linearGradient2819' x1='7' x2='9' y1='8' y2='8' gradientTransform='rotate(45,8,8)' gradientUnits='userSpaceOnUse'>\n\
+ <stop stop-color='#414141' offset='0'/>\n\
+ <stop stop-color='#d9d9d9' offset='1'/>\n\
+ </linearGradient>\n\
+ </defs>\n\
+ <path d='m7.6149 14.979c-0.95143-0.052435-1.8251-0.28345-2.6955-0.71278-1.2049-0.59425-2.1287-1.4307-2.865-2.5939-0.17549-0.27726-0.48912-0.91628-0.60706-1.2369-0.78448-2.1325-0.50124-4.4748 0.76831-6.3538 1.0215-1.5118 2.623-2.5782 4.4077-2.9349 1.8284-0.36541 3.7204 0.011412 5.2659 1.0488 1.5781 1.0592 2.6631 2.7202 2.993 4.5816 0.13747 0.77566 0.13747 1.6696 0 2.4452-0.44509 2.5113-2.2593 4.6096-4.6777 5.4101-0.82562 0.2733-1.7275 0.39395-2.5897 0.34644z' fill='#ffffff' stroke-width='.019254'/>\n\
+ <path d='m3.0503 12.95a7 7 0 1 1 9.8995-9.8995 7 7 0 0 1-9.8995 9.8995zm-0.70711 0.70711a8 8 0 1 0 11.314-11.314 8 8 0 0 0-11.314 11.314z' fill='url(#linearGradient1319)'/>\n\
+ <path d='m12.95 3.0503c-2.7294-2.7294-7.1701-2.7294-9.8995 0s-2.7294 7.1701 0 9.8995 7.1701 2.7294 9.8995 0 2.7294-7.1701 0-9.8995zm-0.70711 0.70711c2.3476 2.3476 2.3476 6.1377 0 8.4853s-6.1377 2.3476-8.4853 0-2.3476-6.1377 0-8.4853 6.1377-2.3476 8.4853 0z' fill='url(#linearGradient2819)'/>\n\
+ </svg>";
+
+static const char *const radiobtnOnData = "\
+ <svg width='16' height='16' version='1.1' xmlns='http://www.w3.org/2000/svg'>\n\
+ <defs>\n\
+ <linearGradient id='linearGradient1319' x1='7' x2='9' y1='8' y2='8' gradientTransform='rotate(45,8,8)' gradientUnits='userSpaceOnUse'>\n\
+ <stop stop-color='#888888' offset='0'/>\n\
+ <stop stop-color='#eeeeee' offset='1'/>\n\
+ </linearGradient>\n\
+ <linearGradient id='linearGradient2819' x1='7' x2='9' y1='8' y2='8' gradientTransform='rotate(45,8,8)' gradientUnits='userSpaceOnUse'>\n\
+ <stop stop-color='#414141' offset='0'/>\n\
+ <stop stop-color='#d9d9d9' offset='1'/>\n\
+ </linearGradient>\n\
+ </defs>\n\
+ <path d='m7.6149 14.979c-0.95143-0.052435-1.8251-0.28345-2.6955-0.71278-1.2049-0.59425-2.1287-1.4307-2.865-2.5939-0.17549-0.27726-0.48912-0.91628-0.60706-1.2369-0.78448-2.1325-0.50124-4.4748 0.76831-6.3538 1.0215-1.5118 2.623-2.5782 4.4077-2.9349 1.8284-0.36541 3.7204 0.011412 5.2659 1.0488 1.5781 1.0592 2.6631 2.7202 2.993 4.5816 0.13747 0.77566 0.13747 1.6696 0 2.4452-0.44509 2.5113-2.2593 4.6096-4.6777 5.4101-0.82562 0.2733-1.7275 0.39395-2.5897 0.34644z' fill='#ffffff' stroke-width='.019254'/>\n\
+ <path d='m3.0503 12.95a7 7 0 1 1 9.8995-9.8995 7 7 0 0 1-9.8995 9.8995zm-0.70711 0.70711a8 8 0 1 0 11.314-11.314 8 8 0 0 0-11.314 11.314z' fill='url(#linearGradient1319)'/>\n\
+ <path d='m12.95 3.0503c-2.7294-2.7294-7.1701-2.7294-9.8995 0s-2.7294 7.1701 0 9.8995 7.1701 2.7294 9.8995 0 2.7294-7.1701 0-9.8995zm-0.70711 0.70711c2.3476 2.3476 2.3476 6.1377 0 8.4853s-6.1377 2.3476-8.4853 0-2.3476-6.1377 0-8.4853 6.1377-2.3476 8.4853 0z' fill='url(#linearGradient2819)'/>\n\
+ <path d='m11 8a3 3 0 1 1-6 0 3 3 0 0 1 6 0z' fill='#000000'/>\n\
+ </svg>";
static IndicatorSpec radiobutton_spec = {
- 13, 13, 4, /* width, height, nimages */
- radiobutton_pixels,
+ 16, 16,
+ radiobtnOffData,
+ radiobtnOnData,
radiobutton_states
};
@@ -500,38 +514,87 @@ static void IndicatorElementSize(
int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
IndicatorSpec *spec = (IndicatorSpec *)clientData;
+ Tcl_Interp *interp = Tk_Interp(tkwin);
+ const char *scalingPctPtr;
+ double scalingFactor;
IndicatorElement *indicator = (IndicatorElement *)elementRecord;
Ttk_Padding margins;
(void)paddingPtr;
+ /*
+ * Retrieve the scaling factor (1.0, 1.25, 1.5, ...)
+ */
+ scalingPctPtr = Tcl_GetVar(interp, "::tk::scalingPct", TCL_GLOBAL_ONLY);
+ scalingFactor = atof(scalingPctPtr) / 100;
+
Ttk_GetPaddingFromObj(NULL, tkwin, indicator->marginObj, &margins);
- *widthPtr = spec->width + Ttk_PaddingWidth(margins);
- *heightPtr = spec->height + Ttk_PaddingHeight(margins);
+ *widthPtr = spec->width * scalingFactor + Ttk_PaddingWidth(margins);
+ *heightPtr = spec->height * scalingFactor + Ttk_PaddingHeight(margins);
+}
+
+static void ColorToStr(
+ const XColor *colorPtr, char *colorStr) /* in the format "RRGGBB" */
+{
+ char str[13];
+
+ snprintf(str, sizeof(str), "%04x%04x%04x",
+ colorPtr->red, colorPtr->green, colorPtr->blue);
+ snprintf(colorStr, 7, "%.2s%.2s%.2s", str, str + 4, str + 8);
+}
+
+static void ImageChanged( /* to be passed to Tk_GetImage() */
+ ClientData clientData,
+ int x, int y, int width, int height,
+ int imageWidth, int imageHeight)
+{
+ (void)clientData;
+ (void)x; (void)y; (void)width; (void)height;
+ (void)imageWidth; (void)imageHeight;
}
static void IndicatorElementDraw(
void *clientData, void *elementRecord, Tk_Window tkwin,
Drawable d, Ttk_Box b, unsigned int state)
{
- IndicatorSpec *spec = (IndicatorSpec *)clientData;
IndicatorElement *indicator = (IndicatorElement *)elementRecord;
- Display *display = Tk_Display(tkwin);
Ttk_Padding padding;
- XColor *fgColor, *frameColor, *shadeColor, *indicatorColor, *borderColor;
+ Tcl_Interp *interp = Tk_Interp(tkwin);
+ const char *scalingPctPtr;
+ double scalingFactor;
+ IndicatorSpec *spec = (IndicatorSpec *)clientData;
- int index, ix, iy;
- XGCValues gcValues;
- GC copyGC;
- unsigned long imgColors[8];
- XImage *img = NULL;
+ int index;
+ const char *svgDataPtr;
+ char bgColorStr[7], fgColorStr[7], indicatorColorStr[7],
+ shadeColorStr[7], borderColorStr[7];
+ char imgName[70];
+ Tk_Image img;
+
+ size_t svgDataLen;
+ char *svgDataCopy;
+ char *shadeColorPtr, *highlightColorPtr, *borderColorPtr, *bgColorPtr,
+ *indicatorColorPtr, *fgColorPtr;
+ const char *cmdFmt;
+ size_t scriptSize;
+ char *script;
+ int code;
Ttk_GetPaddingFromObj(NULL, tkwin, indicator->marginObj, &padding);
b = Ttk_PadBox(b, padding);
+ /*
+ * Retrieve the scaling factor (1.0, 1.25, 1.5, ...)
+ */
+ scalingPctPtr = Tcl_GetVar(interp, "::tk::scalingPct", TCL_GLOBAL_ONLY);
+ scalingFactor = atof(scalingPctPtr) / 100;
+
+ /*
+ * Sanity check
+ */
if ( b.x < 0
|| b.y < 0
- || Tk_Width(tkwin) < b.x + spec->width
- || Tk_Height(tkwin) < b.y + spec->height)
+ || 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.
@@ -540,106 +603,103 @@ static void IndicatorElementDraw(
}
/*
- * Fill in imgColors palette:
- *
- * (SHOULD: take light and shade colors from the border object,
- * but Tk doesn't provide easy access to these in the public API.)
+ * Determine the SVG data to use for the photo image
*/
- fgColor = Tk_GetColorFromObj(tkwin, indicator->foregroundObj);
- frameColor = Tk_GetColorFromObj(tkwin, indicator->backgroundObj);
- shadeColor = Tk_GetColorFromObj(tkwin, indicator->shadeColorObj);
- indicatorColor = Tk_GetColorFromObj(tkwin, indicator->colorObj);
- borderColor = Tk_GetColorFromObj(tkwin, indicator->borderColorObj);
-
- imgColors[0 /*A*/] = shadeColor->pixel;
- imgColors[1 /*B*/] = indicatorColor->pixel;
- imgColors[2 /*C*/] = frameColor->pixel;
- imgColors[3 /*D*/] = indicatorColor->pixel;
- imgColors[4 /*E*/] = borderColor->pixel;
- imgColors[5 /*F*/] = frameColor->pixel;
- imgColors[6 /*G*/] = fgColor->pixel;
- imgColors[7 /*H*/] = fgColor->pixel;
-
- /*
- * Create a scratch buffer to store the image:
- */
-
-#if defined(IGNORES_VISUAL)
+ index = Ttk_StateTableLookup(spec->map, state);
+ svgDataPtr = (index % 2 == 0 ? spec->offDataPtr : spec->onDataPtr);
/*
- * Platforms which ignore the VisualInfo can use XCreateImage to get the
- * scratch image. This is essential on macOS, where it is not safe to call
- * XGetImage in a display procedure.
+ * Construct the color strings bgColorStr, fgColorStr,
+ * indicatorColorStr, shadeColorStr, and borderColorStr
*/
-
- img = XCreateImage(display, NULL, 32, ZPixmap, 0, NULL,
- (unsigned int)spec->width, (unsigned int)spec->height,
- 0, 0);
-#else
+ ColorToStr(Tk_GetColorFromObj(tkwin, indicator->backgroundObj),
+ bgColorStr);
+ ColorToStr(Tk_GetColorFromObj(tkwin, indicator->foregroundObj),
+ fgColorStr);
+ ColorToStr(Tk_GetColorFromObj(tkwin, indicator->colorObj),
+ indicatorColorStr);
+ ColorToStr(Tk_GetColorFromObj(tkwin, indicator->shadeColorObj),
+ shadeColorStr);
+ ColorToStr(Tk_GetColorFromObj(tkwin, indicator->borderColorObj),
+ borderColorStr);
/*
- * This trick allows creating the scratch XImage without having to
- * construct a VisualInfo.
+ * Check whether there is an SVG image for the indicator's
+ * type (0 = checkbtn, 1 = radiobtn) and these color strings
*/
-
- img = XGetImage(display, d, 0, 0,
- (unsigned int)spec->width, (unsigned int)spec->height,
- AllPlanes, ZPixmap);
-#endif
-
+ snprintf(imgName, sizeof(imgName),
+ "::tk::icons::alt_indicator%d_%s_%s_%s_%s_%s",
+ spec->offDataPtr == radiobtnOffData,
+ shadeColorStr, indicatorColorStr, borderColorStr, bgColorStr,
+ index % 2 == 1 ? fgColorStr : "XXXXXX");
+ img = Tk_GetImage(interp, tkwin, imgName, ImageChanged, NULL);
if (img == NULL) {
- return;
- }
-
-#if defined(IGNORES_VISUAL)
-
- img->data = (char *)ckalloc(img->bytes_per_line * img->height);
- if (img->data == NULL) {
- XDestroyImage(img);
- return;
- }
+ /*
+ * 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;
-#endif
+ /*
+ * Update the colors within svgDataCopy
+ */
- /*
- * Create the image, painting it into the XImage one pixel at a time.
- */
+ shadeColorPtr = strstr(svgDataPtr, "888888");
+ highlightColorPtr = strstr(svgDataPtr, "eeeeee");
+ borderColorPtr = strstr(svgDataPtr, "414141");
+ bgColorPtr = strstr(svgDataPtr, "d9d9d9");
+ indicatorColorPtr = strstr(svgDataPtr, "ffffff");
+ fgColorPtr = strstr(svgDataPtr, "000000");
+
+ assert(shadeColorPtr);
+ assert(highlightColorPtr);
+ assert(borderColorPtr);
+ assert(bgColorPtr);
+ assert(indicatorColorPtr);
+
+ memcpy(shadeColorPtr, shadeColorStr, 6);
+ memcpy(highlightColorPtr, indicatorColorStr, 6);
+ memcpy(borderColorPtr, borderColorStr, 6);
+ memcpy(bgColorPtr, bgColorStr, 6);
+ memcpy(indicatorColorPtr, indicatorColorStr, 6);
+ if (fgColorPtr != NULL) {
+ memcpy(fgColorPtr, fgColorStr, 6);
+ }
- index = Ttk_StateTableLookup(spec->map, state);
- for (iy=0 ; iy<spec->height ; iy++) {
- for (ix=0 ; ix<spec->width ; ix++) {
- XPutPixel(img, ix, iy,
- imgColors[spec->pixels[iy][index*spec->width+ix] - 'A'] );
+ /*
+ * 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);
}
/*
- * Copy the image onto our target drawable surface.
- */
-
- memset(&gcValues, 0, sizeof(gcValues));
- copyGC = Tk_GetGC(tkwin, 0, &gcValues);
- TkPutImage(NULL, 0, display, d, copyGC, img, 0, 0, b.x, b.y,
- spec->width, spec->height);
-
- /*
- * Tidy up.
+ * Display the image
*/
-
- Tk_FreeGC(display, copyGC);
-
- /*
- * Protect against the possibility that some future platform might
- * not use the Tk memory manager in its implementation of XDestroyImage,
- * even though that would be an extremely strange thing to do.
- */
-
-#if defined(IGNORES_VISUAL)
- ckfree(img->data);
- img->data = NULL;
-#endif
-
- XDestroyImage(img);
+ Tk_RedrawImage(img, 0, 0, spec->width * scalingFactor,
+ spec->height * scalingFactor, d, b.x, b.y);
+ Tk_FreeImage(img);
}
static const Ttk_ElementSpec IndicatorElementSpec = {
@@ -1017,7 +1077,7 @@ typedef struct {
static const Ttk_ElementOptionSpec SliderElementOptions[] = {
{ "-sliderlength", TK_OPTION_PIXELS, offsetof(SliderElement,lengthObj),
- "15" },
+ "11.25p" },
{ "-sliderthickness",TK_OPTION_PIXELS, offsetof(SliderElement,thicknessObj),
"15" },
{ "-sliderrelief", TK_OPTION_RELIEF, offsetof(SliderElement,reliefObj),