summaryrefslogtreecommitdiffstats
path: root/generic/ttk/ttkClamTheme.c
diff options
context:
space:
mode:
Diffstat (limited to 'generic/ttk/ttkClamTheme.c')
-rw-r--r--generic/ttk/ttkClamTheme.c550
1 files changed, 307 insertions, 243 deletions
diff --git a/generic/ttk/ttkClamTheme.c b/generic/ttk/ttkClamTheme.c
index 8c2b33b..d13462d 100644
--- a/generic/ttk/ttkClamTheme.c
+++ b/generic/ttk/ttkClamTheme.c
@@ -1,11 +1,11 @@
/*
- * Copyright (C) 2004 Joe English
+ * Copyright © 2004 Joe English
*
* "clam" theme; inspired by the XFCE family of Gnome themes.
*/
#include "tkInt.h"
-#include "ttkTheme.h"
+#include "ttkThemeInt.h"
/*
* Under windows, the Tk-provided XDrawLine and XDrawArc have an
@@ -106,17 +106,17 @@ typedef struct {
Tcl_Obj *borderWidthObj; /* See <<NOTE-BORDERWIDTH>> */
} BorderElement;
-static Ttk_ElementOptionSpec BorderElementOptions[] = {
+static const Ttk_ElementOptionSpec BorderElementOptions[] = {
{ "-bordercolor", TK_OPTION_COLOR,
- Tk_Offset(BorderElement,borderColorObj), DARKEST_COLOR },
+ offsetof(BorderElement,borderColorObj), DARKEST_COLOR },
{ "-lightcolor", TK_OPTION_COLOR,
- Tk_Offset(BorderElement,lightColorObj), LIGHT_COLOR },
+ offsetof(BorderElement,lightColorObj), LIGHT_COLOR },
{ "-darkcolor", TK_OPTION_COLOR,
- Tk_Offset(BorderElement,darkColorObj), DARK_COLOR },
+ offsetof(BorderElement,darkColorObj), DARK_COLOR },
{ "-relief", TK_OPTION_RELIEF,
- Tk_Offset(BorderElement,reliefObj), "flat" },
+ offsetof(BorderElement,reliefObj), "flat" },
{ "-borderwidth", TK_OPTION_PIXELS,
- Tk_Offset(BorderElement,borderWidthObj), "2" },
+ offsetof(BorderElement,borderWidthObj), "2" },
{ NULL, TK_OPTION_BOOLEAN, 0, NULL }
};
@@ -186,7 +186,7 @@ static void BorderElementDraw(
DrawSmoothBorder(tkwin, d, b, outer, upper, lower);
}
-static Ttk_ElementSpec BorderElementSpec = {
+static const Ttk_ElementSpec BorderElementSpec = {
TK_STYLE_VERSION_2,
sizeof(BorderElement),
BorderElementOptions,
@@ -204,13 +204,13 @@ typedef struct {
Tcl_Obj *backgroundObj;
} FieldElement;
-static Ttk_ElementOptionSpec FieldElementOptions[] = {
+static const Ttk_ElementOptionSpec FieldElementOptions[] = {
{ "-bordercolor", TK_OPTION_COLOR,
- Tk_Offset(FieldElement,borderColorObj), DARKEST_COLOR },
+ offsetof(FieldElement,borderColorObj), DARKEST_COLOR },
{ "-lightcolor", TK_OPTION_COLOR,
- Tk_Offset(FieldElement,lightColorObj), LIGHT_COLOR },
+ offsetof(FieldElement,lightColorObj), LIGHT_COLOR },
{ "-fieldbackground", TK_OPTION_BORDER,
- Tk_Offset(FieldElement,backgroundObj), "white" },
+ offsetof(FieldElement,backgroundObj), "white" },
{ NULL, TK_OPTION_BOOLEAN, 0, NULL }
};
@@ -244,7 +244,7 @@ static void FieldElementDraw(
tkwin, d, bg, f.x, f.y, f.width, f.height, 0, TK_RELIEF_SUNKEN);
}
-static Ttk_ElementSpec FieldElementSpec = {
+static const Ttk_ElementSpec FieldElementSpec = {
TK_STYLE_VERSION_2,
sizeof(FieldElement),
FieldElementOptions,
@@ -271,7 +271,7 @@ static void ComboboxFieldElementDraw(
b.x + b.width - 1, b.y + b.height - 1 + WIN32_XDRAWLINE_HACK);
}
-static Ttk_ElementSpec ComboboxFieldElementSpec = {
+static const Ttk_ElementSpec ComboboxFieldElementSpec = {
TK_STYLE_VERSION_2,
sizeof(FieldElement),
FieldElementOptions,
@@ -283,8 +283,69 @@ static Ttk_ElementSpec ComboboxFieldElementSpec = {
* +++ Indicator elements for check and radio buttons.
*/
+/*
+ * Indicator image descriptor:
+ */
+typedef struct {
+ int width; /* unscaled width */
+ int height; /* unscaled height */
+ const char *const offDataPtr;
+ const char *const onDataPtr;
+} IndicatorSpec;
+
+static const char checkbtnOffData[] = "\
+ <svg width='16' height='16' version='1.1' xmlns='http://www.w3.org/2000/svg'>\n\
+ <path d='m0 0v16h1v-15h15v-1z' fill='#9e9a91'/>\n\
+ <path d='m15 1v14h-14v1h15v-15z' fill='#cfcdc8'/>\n\
+ <rect x='1' y='1' width='14' height='14' fill='#ffffff'/>\n\
+ </svg>";
+
+static const char checkbtnOnData[] = "\
+ <svg width='16' height='16' version='1.1' xmlns='http://www.w3.org/2000/svg'>\n\
+ <path d='m0 0v16h1v-15h15v-1z' fill='#9e9a91'/>\n\
+ <path d='m15 1v14h-14v1h15v-15z' fill='#cfcdc8'/>\n\
+ <rect x='1' y='1' width='14' height='14' fill='#ffffff'/>\n\
+ <path d='m5 5 6 6m0-6-6 6' fill='none' stroke='#000000' stroke-linecap='round' stroke-width='2'/>\n\
+ </svg>";
+
+static const IndicatorSpec checkbutton_spec = {
+ 16, 16,
+ checkbtnOffData,
+ checkbtnOnData
+};
+
+static const char radiobtnOffData[] = "\
+ <svg width='16' height='16' version='1.1' xmlns='http://www.w3.org/2000/svg'>\n\
+ <defs>\n\
+ <linearGradient id='linearGradient' x1='5' y1='5' x2='11' y2='11' gradientUnits='userSpaceOnUse'>\n\
+ <stop stop-color='#9e9a91' offset='0'/>\n\
+ <stop stop-color='#cfcdc8' offset='1'/>\n\
+ </linearGradient>\n\
+ </defs>\n\
+ <circle cx='8' cy='8' r='8' fill='url(#linearGradient)'/>\n\
+ <circle cx='8' cy='8' r='7' fill='#ffffff'/>\n\
+ </svg>";
+
+static const char radiobtnOnData[] = "\
+ <svg width='16' height='16' version='1.1' xmlns='http://www.w3.org/2000/svg'>\n\
+ <defs>\n\
+ <linearGradient id='linearGradient' x1='5' y1='5' x2='11' y2='11' gradientUnits='userSpaceOnUse'>\n\
+ <stop stop-color='#9e9a91' offset='0'/>\n\
+ <stop stop-color='#cfcdc8' offset='1'/>\n\
+ </linearGradient>\n\
+ </defs>\n\
+ <circle cx='8' cy='8' r='8' fill='url(#linearGradient)'/>\n\
+ <circle cx='8' cy='8' r='7' fill='#ffffff'/>\n\
+ <circle cx='8' cy='8' r='4' fill='#000000'/>\n\
+ </svg>";
+
+static const IndicatorSpec radiobutton_spec = {
+ 16, 16,
+ radiobtnOffData,
+ radiobtnOnData
+};
+
typedef struct {
- Tcl_Obj *sizeObj;
Tcl_Obj *marginObj;
Tcl_Obj *backgroundObj;
Tcl_Obj *foregroundObj;
@@ -292,185 +353,191 @@ typedef struct {
Tcl_Obj *lowerColorObj;
} IndicatorElement;
-static Ttk_ElementOptionSpec IndicatorElementOptions[] = {
- { "-indicatorsize", TK_OPTION_PIXELS,
- Tk_Offset(IndicatorElement,sizeObj), "10" },
+static const Ttk_ElementOptionSpec IndicatorElementOptions[] = {
{ "-indicatormargin", TK_OPTION_STRING,
- Tk_Offset(IndicatorElement,marginObj), "1" },
+ offsetof(IndicatorElement,marginObj), "1" },
{ "-indicatorbackground", TK_OPTION_COLOR,
- Tk_Offset(IndicatorElement,backgroundObj), "white" },
+ offsetof(IndicatorElement,backgroundObj), "white" },
{ "-indicatorforeground", TK_OPTION_COLOR,
- Tk_Offset(IndicatorElement,foregroundObj), "black" },
+ offsetof(IndicatorElement,foregroundObj), "black" },
{ "-upperbordercolor", TK_OPTION_COLOR,
- Tk_Offset(IndicatorElement,upperColorObj), DARKEST_COLOR },
+ offsetof(IndicatorElement,upperColorObj), DARKEST_COLOR },
{ "-lowerbordercolor", TK_OPTION_COLOR,
- Tk_Offset(IndicatorElement,lowerColorObj), DARK_COLOR },
+ offsetof(IndicatorElement,lowerColorObj), DARK_COLOR },
{ NULL, TK_OPTION_BOOLEAN, 0, NULL }
};
static void IndicatorElementSize(
- TCL_UNUSED(void *), void *elementRecord, Tk_Window tkwin,
+ void *clientData, void *elementRecord, Tk_Window tkwin,
int *widthPtr, int *heightPtr,
TCL_UNUSED(Ttk_Padding *))
{
+ const IndicatorSpec *spec = (const IndicatorSpec *)clientData;
IndicatorElement *indicator = (IndicatorElement *)elementRecord;
Ttk_Padding margins;
- int size = 10;
+ double scalingLevel = TkScalingLevel(tkwin);
Ttk_GetPaddingFromObj(NULL, tkwin, indicator->marginObj, &margins);
- Tk_GetPixelsFromObj(NULL, tkwin, indicator->sizeObj, &size);
- *widthPtr = size + Ttk_PaddingWidth(margins);
- *heightPtr = size + Ttk_PaddingHeight(margins);
+ *widthPtr = spec->width * scalingLevel + Ttk_PaddingWidth(margins);
+ *heightPtr = spec->height * scalingLevel + Ttk_PaddingHeight(margins);
}
-static void RadioIndicatorElementDraw(
- TCL_UNUSED(void *), void *elementRecord, Tk_Window tkwin,
- Drawable d, Ttk_Box b, unsigned state)
+static void ColorToStr(
+ const XColor *colorPtr, char *colorStr) /* in the format "RRGGBB" */
{
- IndicatorElement *indicator = (IndicatorElement *)elementRecord;
- GC gcb=Ttk_GCForColor(tkwin,indicator->backgroundObj,d);
- GC gcf=Ttk_GCForColor(tkwin,indicator->foregroundObj,d);
- GC gcu=Ttk_GCForColor(tkwin,indicator->upperColorObj,d);
- GC gcl=Ttk_GCForColor(tkwin,indicator->lowerColorObj,d);
- Ttk_Padding padding;
-
- Ttk_GetPaddingFromObj(NULL, tkwin, indicator->marginObj, &padding);
- b = Ttk_PadBox(b, padding);
-
- XFillArc(Tk_Display(tkwin),d,gcb, b.x,b.y,b.width,b.height, 0,360*64);
- XDrawArc(Tk_Display(tkwin),d,gcl, b.x,b.y,b.width,b.height, 225*64,180*64);
- XDrawArc(Tk_Display(tkwin),d,gcu, b.x,b.y,b.width,b.height, 45*64,180*64);
+ snprintf(colorStr, 7, "%02x%02x%02x",
+ colorPtr->red >> 8, colorPtr->green >> 8, colorPtr->blue >> 8);
+}
- if (state & TTK_STATE_SELECTED) {
- b = Ttk_PadBox(b,Ttk_UniformPadding(3));
- XFillArc(Tk_Display(tkwin),d,gcf, b.x,b.y,b.width,b.height, 0,360*64);
- XDrawArc(Tk_Display(tkwin),d,gcf, b.x,b.y,b.width,b.height, 0,360*64);
-#if WIN32_XDRAWLINE_HACK
- XDrawArc(Tk_Display(tkwin),d,gcf, b.x,b.y,b.width,b.height, 300*64,360*64);
-#endif
- }
+static void ImageChanged( /* to be passed to Tk_GetImage() */
+ TCL_UNUSED(void *),
+ TCL_UNUSED(int),
+ TCL_UNUSED(int),
+ TCL_UNUSED(int),
+ TCL_UNUSED(int),
+ TCL_UNUSED(int),
+ TCL_UNUSED(int))
+{
}
-static void CheckIndicatorElementDraw(
- TCL_UNUSED(void *), void *elementRecord, Tk_Window tkwin,
+static void IndicatorElementDraw(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
Drawable d, Ttk_Box b, Ttk_State state)
{
- Display *display = Tk_Display(tkwin);
IndicatorElement *indicator = (IndicatorElement *)elementRecord;
-
- GC gcb=Ttk_GCForColor(tkwin,indicator->backgroundObj,d);
- GC gcf=Ttk_GCForColor(tkwin,indicator->foregroundObj,d);
- GC gcu=Ttk_GCForColor(tkwin,indicator->upperColorObj,d);
- GC gcl=Ttk_GCForColor(tkwin,indicator->lowerColorObj,d);
Ttk_Padding padding;
- const int w = WIN32_XDRAWLINE_HACK;
+ const IndicatorSpec *spec = (const IndicatorSpec *)clientData;
+ double scalingLevel = TkScalingLevel(tkwin);
+ int width = spec->width * scalingLevel;
+ int height = spec->height * scalingLevel;
+
+ char upperBdColorStr[7], lowerBdColorStr[7], bgColorStr[7], fgColorStr[7];
+ unsigned int selected = (state & TTK_STATE_SELECTED);
+ Tcl_Interp *interp = Tk_Interp(tkwin);
+ char imgName[60];
+ Tk_Image img;
+
+ const char *svgDataPtr;
+ size_t svgDataLen;
+ char *svgDataCopy;
+ char *upperBdColorPtr, *lowerBdColorPtr, *bgColorPtr, *fgColorPtr;
+ const char *cmdFmt;
+ size_t scriptSize;
+ char *script;
+ int code;
Ttk_GetPaddingFromObj(NULL, tkwin, indicator->marginObj, &padding);
b = Ttk_PadBox(b, padding);
- XFillRectangle(display,d,gcb, b.x,b.y,b.width,b.height);
- XDrawLine(display,d,gcl,b.x,b.y+b.height,b.x+b.width+w,b.y+b.height);/*S*/
- XDrawLine(display,d,gcl,b.x+b.width,b.y,b.x+b.width,b.y+b.height+w); /*E*/
- XDrawLine(display,d,gcu,b.x,b.y, b.x,b.y+b.height+w); /*W*/
- XDrawLine(display,d,gcu,b.x,b.y, b.x+b.width+w,b.y); /*N*/
-
- if (state & TTK_STATE_SELECTED) {
- int p,q,r,s;
+ /*
+ * Sanity check
+ */
+ if ( b.x < 0
+ || b.y < 0
+ || Tk_Width(tkwin) < b.x + width
+ || Tk_Height(tkwin) < b.y + height)
+ {
+ /* Oops! Not enough room to display the image.
+ * Don't draw anything.
+ */
+ return;
+ }
- b = Ttk_PadBox(b,Ttk_UniformPadding(2));
- p = b.x, q = b.y, r = b.x+b.width, s = b.y+b.height;
+ /*
+ * Construct the color strings upperBdColorStr, lowerBdColorStr,
+ * bgColorStr, and fgColorStr
+ */
+ ColorToStr(Tk_GetColorFromObj(tkwin, indicator->upperColorObj),
+ upperBdColorStr);
+ ColorToStr(Tk_GetColorFromObj(tkwin, indicator->lowerColorObj),
+ lowerBdColorStr);
+ ColorToStr(Tk_GetColorFromObj(tkwin, indicator->backgroundObj),
+ bgColorStr);
+ ColorToStr(Tk_GetColorFromObj(tkwin, indicator->foregroundObj),
+ fgColorStr);
- r+=w, s+=w;
- XDrawLine(display, d, gcf, p, q, r, s);
- XDrawLine(display, d, gcf, p+1, q, r, s-1);
- XDrawLine(display, d, gcf, p, q+1, r-1, s);
+ /*
+ * Check whether there is an SVG image of this size for the indicator's
+ * type (0 = checkbtn, 1 = radiobtn) and these color strings
+ */
+ snprintf(imgName, sizeof(imgName),
+ "::tk::icons::indicator_clam%d_%d_%s_%s_%s_%s",
+ width, spec->offDataPtr == radiobtnOffData,
+ upperBdColorStr, lowerBdColorStr, bgColorStr,
+ selected ? fgColorStr : "XXXXXX");
+ img = Tk_GetImage(interp, tkwin, imgName, ImageChanged, NULL);
+ if (img == NULL) {
+ /*
+ * Determine the SVG data to use for the photo image
+ */
+ svgDataPtr = (selected ? spec->onDataPtr : spec->offDataPtr);
+
+ /*
+ * Copy the string pointed to by svgDataPtr to
+ * a newly allocated memory area svgDataCopy
+ */
+ svgDataLen = strlen(svgDataPtr);
+ svgDataCopy = (char *)attemptckalloc(svgDataLen + 1);
+ if (svgDataCopy == NULL) {
+ return;
+ }
+ memcpy(svgDataCopy, svgDataPtr, svgDataLen);
+ svgDataCopy[svgDataLen] = '\0';
+
+ /*
+ * Update the colors within svgDataCopy
+ */
+
+ upperBdColorPtr = strstr(svgDataCopy, "9e9a91");
+ lowerBdColorPtr = strstr(svgDataCopy, "cfcdc8");
+ bgColorPtr = strstr(svgDataCopy, "ffffff");
+ fgColorPtr = strstr(svgDataCopy, "000000");
+
+ assert(upperBdColorPtr);
+ assert(lowerBdColorPtr);
+ assert(bgColorPtr);
+
+ memcpy(upperBdColorPtr, upperBdColorStr, 6);
+ memcpy(lowerBdColorPtr, lowerBdColorStr, 6);
+ memcpy(bgColorPtr, bgColorStr, 6);
+ if (fgColorPtr != NULL) {
+ memcpy(fgColorPtr, fgColorStr, 6);
+ }
- s-=w, q-=w;
- XDrawLine(display, d, gcf, p, s, r, q);
- XDrawLine(display, d, gcf, p+1, s, r, q+1);
- XDrawLine(display, d, gcf, p, s-1, r-1, q);
+ /*
+ * 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);
}
-}
-static Ttk_ElementSpec RadioIndicatorElementSpec = {
- TK_STYLE_VERSION_2,
- sizeof(IndicatorElement),
- IndicatorElementOptions,
- IndicatorElementSize,
- RadioIndicatorElementDraw
-};
+ /*
+ * Display the image
+ */
+ Tk_RedrawImage(img, 0, 0, width, height, d, b.x, b.y);
+ Tk_FreeImage(img);
+}
-static Ttk_ElementSpec CheckIndicatorElementSpec = {
+static const Ttk_ElementSpec IndicatorElementSpec = {
TK_STYLE_VERSION_2,
sizeof(IndicatorElement),
IndicatorElementOptions,
IndicatorElementSize,
- CheckIndicatorElementDraw
-};
-
-#define MENUBUTTON_ARROW_SIZE 5
-
-typedef struct {
- Tcl_Obj *sizeObj;
- Tcl_Obj *colorObj;
- Tcl_Obj *paddingObj;
-} MenuIndicatorElement;
-
-static Ttk_ElementOptionSpec MenuIndicatorElementOptions[] =
-{
- { "-arrowsize", TK_OPTION_PIXELS,
- Tk_Offset(MenuIndicatorElement,sizeObj),
- STR(MENUBUTTON_ARROW_SIZE)},
- { "-arrowcolor",TK_OPTION_COLOR,
- Tk_Offset(MenuIndicatorElement,colorObj),
- "black" },
- { "-arrowpadding",TK_OPTION_STRING,
- Tk_Offset(MenuIndicatorElement,paddingObj),
- "3" },
- { NULL, TK_OPTION_BOOLEAN, 0, NULL }
-};
-
-static void MenuIndicatorElementSize(
- TCL_UNUSED(void *), void *elementRecord, Tk_Window tkwin,
- int *widthPtr, int *heightPtr,
- TCL_UNUSED(Ttk_Padding *))
-{
- MenuIndicatorElement *indicator = (MenuIndicatorElement *)elementRecord;
- Ttk_Padding margins;
- int size = MENUBUTTON_ARROW_SIZE;
-
- Tk_GetPixelsFromObj(NULL, tkwin, indicator->sizeObj, &size);
- Ttk_GetPaddingFromObj(NULL, tkwin, indicator->paddingObj, &margins);
- TtkArrowSize(size, ARROW_DOWN, widthPtr, heightPtr);
- *widthPtr += Ttk_PaddingWidth(margins);
- *heightPtr += Ttk_PaddingHeight(margins);
-}
-
-static void MenuIndicatorElementDraw(
- TCL_UNUSED(void *), void *elementRecord, Tk_Window tkwin,
- Drawable d, Ttk_Box b,
- TCL_UNUSED(Ttk_State))
-{
- MenuIndicatorElement *indicator = (MenuIndicatorElement *)elementRecord;
- XColor *arrowColor = Tk_GetColorFromObj(tkwin, indicator->colorObj);
- GC gc = Tk_GCForColor(arrowColor, d);
- int size = MENUBUTTON_ARROW_SIZE;
- int width, height;
-
- Tk_GetPixelsFromObj(NULL, tkwin, indicator->sizeObj, &size);
-
- TtkArrowSize(size, ARROW_DOWN, &width, &height);
- b = Ttk_StickBox(b, width, height, 0);
- TtkFillArrow(Tk_Display(tkwin), d, gc, b, ARROW_DOWN);
-}
-
-static Ttk_ElementSpec MenuIndicatorElementSpec =
-{
- TK_STYLE_VERSION_2,
- sizeof(MenuIndicatorElement),
- MenuIndicatorElementOptions,
- MenuIndicatorElementSize,
- MenuIndicatorElementDraw
+ IndicatorElementDraw
};
/*------------------------------------------------------------------------
@@ -479,23 +546,19 @@ static Ttk_ElementSpec MenuIndicatorElementSpec =
* TODO: factor this with ThumbElementDraw
*/
-static Ttk_Orient GripClientData[] = {
- TTK_ORIENT_HORIZONTAL, TTK_ORIENT_VERTICAL
-};
-
typedef struct {
Tcl_Obj *lightColorObj;
Tcl_Obj *borderColorObj;
Tcl_Obj *gripCountObj;
} GripElement;
-static Ttk_ElementOptionSpec GripElementOptions[] = {
+static const Ttk_ElementOptionSpec GripElementOptions[] = {
{ "-lightcolor", TK_OPTION_COLOR,
- Tk_Offset(GripElement,lightColorObj), LIGHT_COLOR },
+ offsetof(GripElement,lightColorObj), LIGHT_COLOR },
{ "-bordercolor", TK_OPTION_COLOR,
- Tk_Offset(GripElement,borderColorObj), DARKEST_COLOR },
+ offsetof(GripElement,borderColorObj), DARKEST_COLOR },
{ "-gripcount", TK_OPTION_PIXELS,
- Tk_Offset(GripElement,gripCountObj), "5" },
+ offsetof(GripElement,gripCountObj), "5" },
{ NULL, TK_OPTION_BOOLEAN, 0, NULL }
};
@@ -504,15 +567,16 @@ static void GripElementSize(
int *widthPtr, int *heightPtr,
TCL_UNUSED(Ttk_Padding *))
{
- int horizontal = *((Ttk_Orient*)clientData) == TTK_ORIENT_HORIZONTAL;
+ Ttk_Orient orient = (Ttk_Orient)PTR2INT(clientData);
GripElement *grip = (GripElement *)elementRecord;
- int gripCount = 0;
+ int gripSize = 0;
- Tk_GetPixelsFromObj(NULL, tkwin, grip->gripCountObj, &gripCount);
- if (horizontal) {
- *widthPtr = 2*gripCount;
+ Tk_GetPixelsFromObj(NULL, tkwin, grip->gripCountObj, &gripSize);
+ gripSize *= 2;
+ if (orient == TTK_ORIENT_HORIZONTAL) {
+ *widthPtr = gripSize;
} else {
- *heightPtr = 2*gripCount;
+ *heightPtr = gripSize;
}
}
@@ -522,33 +586,34 @@ static void GripElementDraw(
TCL_UNUSED(Ttk_State))
{
const int w = WIN32_XDRAWLINE_HACK;
- int horizontal = *((Ttk_Orient*)clientData) == TTK_ORIENT_HORIZONTAL;
+ Ttk_Orient orient = (Ttk_Orient)PTR2INT(clientData);
GripElement *grip = (GripElement *)elementRecord;
GC lightGC = Ttk_GCForColor(tkwin,grip->lightColorObj,d);
GC darkGC = Ttk_GCForColor(tkwin,grip->borderColorObj,d);
- int gripPad = 1, gripCount = 0;
+ int gripPad = 1, gripSize = 0;
int i;
- Tk_GetPixelsFromObj(NULL, tkwin, grip->gripCountObj, &gripCount);
+ Tk_GetPixelsFromObj(NULL, tkwin, grip->gripCountObj, &gripSize);
+ gripSize *= 2;
- if (horizontal) {
- int x = b.x + b.width / 2 - gripCount;
+ if (orient == TTK_ORIENT_HORIZONTAL) {
+ int x = b.x + (b.width - gripSize) / 2;
int y1 = b.y + gripPad, y2 = b.y + b.height - gripPad - 1 + w;
- for (i=0; i<gripCount; ++i) {
- XDrawLine(Tk_Display(tkwin), d, darkGC, x,y1, x,y2); ++x;
- XDrawLine(Tk_Display(tkwin), d, lightGC, x,y1, x,y2); ++x;
+ for (i=0; i<gripSize; ++i) {
+ XDrawLine(Tk_Display(tkwin), d, (i&1)?lightGC:darkGC, x,y1, x,y2);
+ ++x;
}
} else {
- int y = b.y + b.height / 2 - gripCount;
+ int y = b.y + (b.height - gripSize) / 2;
int x1 = b.x + gripPad, x2 = b.x + b.width - gripPad - 1 + w;
- for (i=0; i<gripCount; ++i) {
- XDrawLine(Tk_Display(tkwin), d, darkGC, x1,y, x2,y); ++y;
- XDrawLine(Tk_Display(tkwin), d, lightGC, x1,y, x2,y); ++y;
+ for (i=0; i<gripSize; ++i) {
+ XDrawLine(Tk_Display(tkwin), d, (i&1)?lightGC:darkGC, x1,y, x2,y);
+ ++y;
}
}
}
-static Ttk_ElementSpec GripElementSpec = {
+static const Ttk_ElementSpec GripElementSpec = {
TK_STYLE_VERSION_2,
sizeof(GripElement),
GripElementOptions,
@@ -576,27 +641,27 @@ typedef struct { /* Common element record for scrollbar elements */
Tcl_Obj *sliderlengthObj;
} ScrollbarElement;
-static Ttk_ElementOptionSpec ScrollbarElementOptions[] = {
+static const Ttk_ElementOptionSpec ScrollbarElementOptions[] = {
{ "-orient", TK_OPTION_ANY,
- Tk_Offset(ScrollbarElement, orientObj), "horizontal" },
+ offsetof(ScrollbarElement, orientObj), "horizontal" },
{ "-background", TK_OPTION_BORDER,
- Tk_Offset(ScrollbarElement,backgroundObj), FRAME_COLOR },
+ offsetof(ScrollbarElement,backgroundObj), FRAME_COLOR },
{ "-bordercolor", TK_OPTION_COLOR,
- Tk_Offset(ScrollbarElement,borderColorObj), DARKEST_COLOR },
+ offsetof(ScrollbarElement,borderColorObj), DARKEST_COLOR },
{ "-troughcolor", TK_OPTION_COLOR,
- Tk_Offset(ScrollbarElement,troughColorObj), DARKER_COLOR },
+ offsetof(ScrollbarElement,troughColorObj), DARKER_COLOR },
{ "-lightcolor", TK_OPTION_COLOR,
- Tk_Offset(ScrollbarElement,lightColorObj), LIGHT_COLOR },
+ offsetof(ScrollbarElement,lightColorObj), LIGHT_COLOR },
{ "-darkcolor", TK_OPTION_COLOR,
- Tk_Offset(ScrollbarElement,darkColorObj), DARK_COLOR },
+ offsetof(ScrollbarElement,darkColorObj), DARK_COLOR },
{ "-arrowcolor", TK_OPTION_COLOR,
- Tk_Offset(ScrollbarElement,arrowColorObj), "#000000" },
+ offsetof(ScrollbarElement,arrowColorObj), "#000000" },
{ "-arrowsize", TK_OPTION_PIXELS,
- Tk_Offset(ScrollbarElement,arrowSizeObj), STR(SCROLLBAR_THICKNESS) },
+ offsetof(ScrollbarElement,arrowSizeObj), STR(SCROLLBAR_THICKNESS) },
{ "-gripcount", TK_OPTION_PIXELS,
- Tk_Offset(ScrollbarElement,gripCountObj), "5" },
+ offsetof(ScrollbarElement,gripCountObj), "5" },
{ "-sliderlength", TK_OPTION_PIXELS,
- Tk_Offset(ScrollbarElement,sliderlengthObj), "30" },
+ offsetof(ScrollbarElement,sliderlengthObj), "30" },
{ NULL, TK_OPTION_BOOLEAN, 0, NULL }
};
@@ -616,7 +681,7 @@ static void TroughElementDraw(
XDrawRectangle(Tk_Display(tkwin), d, gcb, b.x, b.y, b.width-1, b.height-1);
}
-static Ttk_ElementSpec TroughElementSpec = {
+static const Ttk_ElementSpec TroughElementSpec = {
TK_STYLE_VERSION_2,
sizeof(ScrollbarElement),
ScrollbarElementOptions,
@@ -648,8 +713,8 @@ static void ThumbElementDraw(
TCL_UNUSED(Ttk_State))
{
ScrollbarElement *sb = (ScrollbarElement *)elementRecord;
- int gripCount = 0;
- int orient = TTK_ORIENT_HORIZONTAL;
+ int gripSize = 0;
+ Ttk_Orient orient = TTK_ORIENT_HORIZONTAL;
GC lightGC, darkGC;
int x1, y1, x2, y2, dx, dy, i;
const int w = WIN32_XDRAWLINE_HACK;
@@ -663,32 +728,32 @@ static void ThumbElementDraw(
/*
* Draw grip:
*/
- Ttk_GetOrientFromObj(NULL, sb->orientObj, &orient);
- Tk_GetPixelsFromObj(NULL, tkwin, sb->gripCountObj, &gripCount);
+ TtkGetOrientFromObj(NULL, sb->orientObj, &orient);
+ Tk_GetPixelsFromObj(NULL, tkwin, sb->gripCountObj, &gripSize);
+ gripSize *= 2;
lightGC = Ttk_GCForColor(tkwin,sb->lightColorObj,d);
darkGC = Ttk_GCForColor(tkwin,sb->borderColorObj,d);
if (orient == TTK_ORIENT_HORIZONTAL) {
dx = 1; dy = 0;
- x1 = x2 = b.x + b.width / 2 - gripCount;
+ x1 = x2 = b.x + (b.width - gripSize) / 2;
y1 = b.y + 2;
y2 = b.y + b.height - 3 + w;
} else {
dx = 0; dy = 1;
- y1 = y2 = b.y + b.height / 2 - gripCount;
+ y1 = y2 = b.y + (b.height - gripSize) / 2;
x1 = b.x + 2;
x2 = b.x + b.width - 3 + w;
}
- for (i=0; i<gripCount; ++i) {
- XDrawLine(Tk_Display(tkwin), d, darkGC, x1,y1, x2,y2);
- x1 += dx; x2 += dx; y1 += dy; y2 += dy;
- XDrawLine(Tk_Display(tkwin), d, lightGC, x1,y1, x2,y2);
+ for (i=0; i<gripSize; ++i) {
+ XDrawLine(Tk_Display(tkwin), d, (i&1)?lightGC:darkGC, x1,y1, x2,y2);
x1 += dx; x2 += dx; y1 += dy; y2 += dy;
+
}
}
-static Ttk_ElementSpec ThumbElementSpec = {
+static const Ttk_ElementSpec ThumbElementSpec = {
TK_STYLE_VERSION_2,
sizeof(ScrollbarElement),
ScrollbarElementOptions,
@@ -709,10 +774,10 @@ static void SliderElementSize(
{
ScrollbarElement *sb = (ScrollbarElement *)elementRecord;
int length, thickness;
- int orient;
+ Ttk_Orient orient;
length = thickness = SCROLLBAR_THICKNESS;
- Ttk_GetOrientFromObj(NULL, sb->orientObj, &orient);
+ TtkGetOrientFromObj(NULL, sb->orientObj, &orient);
Tk_GetPixelsFromObj(NULL, tkwin, sb->arrowSizeObj, &thickness);
Tk_GetPixelsFromObj(NULL, tkwin, sb->sliderlengthObj, &length);
if (orient == TTK_ORIENT_VERTICAL) {
@@ -724,7 +789,7 @@ static void SliderElementSize(
}
}
-static Ttk_ElementSpec SliderElementSpec = {
+static const Ttk_ElementSpec SliderElementSpec = {
TK_STYLE_VERSION_2,
sizeof(ScrollbarElement),
ScrollbarElementOptions,
@@ -766,7 +831,7 @@ static void PbarElementDraw(
}
}
-static Ttk_ElementSpec PbarElementSpec = {
+static const Ttk_ElementSpec PbarElementSpec = {
TK_STYLE_VERSION_2,
sizeof(ScrollbarElement),
ScrollbarElementOptions,
@@ -777,16 +842,15 @@ static Ttk_ElementSpec PbarElementSpec = {
/*------------------------------------------------------------------------
* +++ Scrollbar arrows.
*/
-static int ArrowElements[] = { ARROW_UP, ARROW_DOWN, ARROW_LEFT, ARROW_RIGHT };
-
static void ArrowElementSize(
void *clientData, void *elementRecord, Tk_Window tkwin,
int *widthPtr, int *heightPtr,
TCL_UNUSED(Ttk_Padding *))
{
ScrollbarElement *sb = (ScrollbarElement *)elementRecord;
- ArrowDirection direction = *(ArrowDirection*)clientData;
- Ttk_Padding padding = Ttk_UniformPadding(3);
+ ArrowDirection direction = (ArrowDirection)PTR2INT(clientData);
+ double scalingLevel = TkScalingLevel(tkwin);
+ Ttk_Padding padding = Ttk_UniformPadding(round(3 * scalingLevel));
int size = SCROLLBAR_THICKNESS;
Tk_GetPixelsFromObj(NULL, tkwin, sb->arrowSizeObj, &size);
@@ -807,8 +871,9 @@ static void ArrowElementDraw(
TCL_UNUSED(Ttk_State))
{
ScrollbarElement *sb = (ScrollbarElement *)elementRecord;
- ArrowDirection direction = *(ArrowDirection*)clientData;
- Ttk_Padding padding = Ttk_UniformPadding(3);
+ ArrowDirection direction = (ArrowDirection)PTR2INT(clientData);
+ double scalingLevel = TkScalingLevel(tkwin);
+ Ttk_Padding padding = Ttk_UniformPadding(round(3 * scalingLevel));
int cx, cy;
GC gc = Ttk_GCForColor(tkwin, sb->arrowColorObj, d);
@@ -843,7 +908,7 @@ static void ArrowElementDraw(
TtkFillArrow(Tk_Display(tkwin), d, gc, b, direction);
}
-static Ttk_ElementSpec ArrowElementSpec = {
+static const Ttk_ElementSpec ArrowElementSpec = {
TK_STYLE_VERSION_2,
sizeof(ScrollbarElement),
ScrollbarElementOptions,
@@ -861,8 +926,9 @@ static void SpinboxArrowElementSize(
TCL_UNUSED(Ttk_Padding *))
{
ScrollbarElement *sb = (ScrollbarElement *)elementRecord;
- ArrowDirection direction = *(ArrowDirection*)clientData;
- Ttk_Padding padding = Ttk_UniformPadding(3);
+ ArrowDirection direction = (ArrowDirection)PTR2INT(clientData);
+ double scalingLevel = TkScalingLevel(tkwin);
+ Ttk_Padding padding = Ttk_UniformPadding(round(3 * scalingLevel));
int size = 10;
Tk_GetPixelsFromObj(NULL, tkwin, sb->arrowSizeObj, &size);
@@ -872,7 +938,7 @@ static void SpinboxArrowElementSize(
*heightPtr += Ttk_PaddingHeight(padding);
}
-static Ttk_ElementSpec SpinboxArrowElementSpec = {
+static const Ttk_ElementSpec SpinboxArrowElementSpec = {
TK_STYLE_VERSION_2,
sizeof(ScrollbarElement),
ScrollbarElementOptions,
@@ -894,15 +960,15 @@ typedef struct {
Tcl_Obj *darkColorObj;
} NotebookElement;
-static Ttk_ElementOptionSpec NotebookElementOptions[] = {
+static const Ttk_ElementOptionSpec NotebookElementOptions[] = {
{ "-background", TK_OPTION_BORDER,
- Tk_Offset(NotebookElement,backgroundObj), FRAME_COLOR },
+ offsetof(NotebookElement,backgroundObj), FRAME_COLOR },
{ "-bordercolor", TK_OPTION_COLOR,
- Tk_Offset(NotebookElement,borderColorObj), DARKEST_COLOR },
+ offsetof(NotebookElement,borderColorObj), DARKEST_COLOR },
{ "-lightcolor", TK_OPTION_COLOR,
- Tk_Offset(NotebookElement,lightColorObj), LIGHT_COLOR },
+ offsetof(NotebookElement,lightColorObj), LIGHT_COLOR },
{ "-darkcolor", TK_OPTION_COLOR,
- Tk_Offset(NotebookElement,darkColorObj), DARK_COLOR },
+ offsetof(NotebookElement,darkColorObj), DARK_COLOR },
{ NULL, TK_OPTION_BOOLEAN, 0, NULL }
};
@@ -969,7 +1035,7 @@ static void TabElementDraw(
switch (nbTabsStickBit) {
default:
case TTK_STICK_S:
- if (state & TTK_STATE_USER2) { /* rightmost tab */
+ if (state & TTK_STATE_LAST) { /* rightmost tab */
--b.width;
}
@@ -991,7 +1057,7 @@ static void TabElementDraw(
break;
case TTK_STICK_N:
- if (state & TTK_STATE_USER2) { /* rightmost tab */
+ if (state & TTK_STATE_LAST) { /* rightmost tab */
--b.width;
}
@@ -1013,7 +1079,7 @@ static void TabElementDraw(
break;
case TTK_STICK_E:
- if (state & TTK_STATE_USER2) { /* bottommost tab */
+ if (state & TTK_STATE_LAST) { /* bottommost tab */
--b.height;
}
@@ -1035,7 +1101,7 @@ static void TabElementDraw(
break;
case TTK_STICK_W:
- if (state & TTK_STATE_USER2) { /* bottommost tab */
+ if (state & TTK_STATE_LAST) { /* bottommost tab */
--b.height;
}
@@ -1058,7 +1124,7 @@ static void TabElementDraw(
}
}
-static Ttk_ElementSpec TabElementSpec =
+static const Ttk_ElementSpec TabElementSpec =
{
TK_STYLE_VERSION_2,
sizeof(NotebookElement),
@@ -1098,7 +1164,7 @@ static void ClientElementDraw(
ce->borderColorObj, ce->lightColorObj, ce->darkColorObj);
}
-static Ttk_ElementSpec ClientElementSpec =
+static const Ttk_ElementSpec ClientElementSpec =
{
TK_STYLE_VERSION_2,
sizeof(NotebookElement),
@@ -1153,26 +1219,24 @@ TtkClamTheme_Init(Tcl_Interp *interp)
Ttk_RegisterElement(interp, theme, "thumb",
&ThumbElementSpec, NULL);
Ttk_RegisterElement(interp, theme, "uparrow",
- &ArrowElementSpec, &ArrowElements[0]);
+ &ArrowElementSpec, INT2PTR(ARROW_UP));
Ttk_RegisterElement(interp, theme, "Spinbox.uparrow",
- &SpinboxArrowElementSpec, &ArrowElements[0]);
+ &SpinboxArrowElementSpec, INT2PTR(ARROW_UP));
Ttk_RegisterElement(interp, theme, "downarrow",
- &ArrowElementSpec, &ArrowElements[1]);
+ &ArrowElementSpec, INT2PTR(ARROW_DOWN));
Ttk_RegisterElement(interp, theme, "Spinbox.downarrow",
- &SpinboxArrowElementSpec, &ArrowElements[1]);
+ &SpinboxArrowElementSpec, INT2PTR(ARROW_DOWN));
Ttk_RegisterElement(interp, theme, "leftarrow",
- &ArrowElementSpec, &ArrowElements[2]);
+ &ArrowElementSpec, INT2PTR(ARROW_LEFT));
Ttk_RegisterElement(interp, theme, "rightarrow",
- &ArrowElementSpec, &ArrowElements[3]);
+ &ArrowElementSpec, INT2PTR(ARROW_RIGHT));
Ttk_RegisterElement(interp, theme, "arrow",
- &ArrowElementSpec, &ArrowElements[0]);
+ &ArrowElementSpec, INT2PTR(ARROW_UP));
Ttk_RegisterElement(interp, theme, "Checkbutton.indicator",
- &CheckIndicatorElementSpec, NULL);
+ &IndicatorElementSpec, (void *)&checkbutton_spec);
Ttk_RegisterElement(interp, theme, "Radiobutton.indicator",
- &RadioIndicatorElementSpec, NULL);
- Ttk_RegisterElement(interp, theme, "Menubutton.indicator",
- &MenuIndicatorElementSpec, NULL);
+ &IndicatorElementSpec, (void *)&radiobutton_spec);
Ttk_RegisterElement(interp, theme, "tab", &TabElementSpec, NULL);
Ttk_RegisterElement(interp, theme, "client", &ClientElementSpec, NULL);
@@ -1182,9 +1246,9 @@ TtkClamTheme_Init(Tcl_Interp *interp)
Ttk_RegisterElement(interp, theme, "pbar", &PbarElementSpec, NULL);
Ttk_RegisterElement(interp, theme, "hgrip",
- &GripElementSpec, &GripClientData[0]);
+ &GripElementSpec, INT2PTR(TTK_ORIENT_HORIZONTAL));
Ttk_RegisterElement(interp, theme, "vgrip",
- &GripElementSpec, &GripClientData[1]);
+ &GripElementSpec, INT2PTR(TTK_ORIENT_VERTICAL));
Ttk_RegisterLayouts(theme, LayoutTable);