diff options
Diffstat (limited to 'generic/ttk/ttkClamTheme.c')
-rw-r--r-- | generic/ttk/ttkClamTheme.c | 550 |
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); |