Files
cpython-source-deps/generic/ttk/ttkElements.c
2021-03-30 00:54:10 +01:00

1280 lines
40 KiB
C

/*
* Copyright (c) 2003, Joe English
*
* Default implementation for themed elements.
*
*/
#include "tkInt.h"
#include "ttkTheme.h"
#include "ttkWidget.h"
#define DEFAULT_BORDERWIDTH "2"
#define DEFAULT_ARROW_SIZE "15"
#define MIN_THUMB_SIZE 10
/*----------------------------------------------------------------------
* +++ Null element. Does nothing; used as a stub.
* Null element methods, option table and element spec are public,
* and may be used in other engines.
*/
/* public */ Ttk_ElementOptionSpec TtkNullElementOptions[] = { { NULL, 0, 0, NULL } };
/* public */ void
TtkNullElementSize(
void *clientData, void *elementRecord, Tk_Window tkwin,
int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
}
/* public */ void
TtkNullElementDraw(
void *clientData, void *elementRecord, Tk_Window tkwin,
Drawable d, Ttk_Box b, unsigned int state)
{
}
/* public */ Ttk_ElementSpec ttkNullElementSpec = {
TK_STYLE_VERSION_2,
sizeof(NullElement),
TtkNullElementOptions,
TtkNullElementSize,
TtkNullElementDraw
};
/*----------------------------------------------------------------------
* +++ Background and fill elements.
*
* The fill element fills its parcel with the background color.
* The background element ignores the parcel, and fills the entire window.
*
* Ttk_GetLayout() automatically includes a background element.
*/
typedef struct {
Tcl_Obj *backgroundObj;
} BackgroundElement;
static Ttk_ElementOptionSpec BackgroundElementOptions[] = {
{ "-background", TK_OPTION_BORDER,
Tk_Offset(BackgroundElement,backgroundObj), DEFAULT_BACKGROUND },
{ NULL, 0, 0, NULL }
};
static void FillElementDraw(
void *clientData, void *elementRecord, Tk_Window tkwin,
Drawable d, Ttk_Box b, unsigned int state)
{
BackgroundElement *bg = elementRecord;
Tk_3DBorder backgroundPtr = Tk_Get3DBorderFromObj(tkwin,bg->backgroundObj);
XFillRectangle(Tk_Display(tkwin), d,
Tk_3DBorderGC(tkwin, backgroundPtr, TK_3D_FLAT_GC),
b.x, b.y, b.width, b.height);
}
static void BackgroundElementDraw(
void *clientData, void *elementRecord, Tk_Window tkwin,
Drawable d, Ttk_Box b, unsigned int state)
{
FillElementDraw(
clientData, elementRecord, tkwin,
d, Ttk_WinBox(tkwin), state);
}
static Ttk_ElementSpec FillElementSpec = {
TK_STYLE_VERSION_2,
sizeof(BackgroundElement),
BackgroundElementOptions,
TtkNullElementSize,
FillElementDraw
};
static Ttk_ElementSpec BackgroundElementSpec = {
TK_STYLE_VERSION_2,
sizeof(BackgroundElement),
BackgroundElementOptions,
TtkNullElementSize,
BackgroundElementDraw
};
/*----------------------------------------------------------------------
* +++ Border element.
*/
typedef struct {
Tcl_Obj *borderObj;
Tcl_Obj *borderWidthObj;
Tcl_Obj *reliefObj;
} BorderElement;
static Ttk_ElementOptionSpec BorderElementOptions[] = {
{ "-background", TK_OPTION_BORDER,
Tk_Offset(BorderElement,borderObj), DEFAULT_BACKGROUND },
{ "-borderwidth", TK_OPTION_PIXELS,
Tk_Offset(BorderElement,borderWidthObj), DEFAULT_BORDERWIDTH },
{ "-relief", TK_OPTION_RELIEF,
Tk_Offset(BorderElement,reliefObj), "flat" },
{ NULL, 0, 0, NULL }
};
static void BorderElementSize(
void *clientData, void *elementRecord, Tk_Window tkwin,
int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
BorderElement *bd = elementRecord;
int borderWidth = 0;
Tcl_GetIntFromObj(NULL, bd->borderWidthObj, &borderWidth);
*paddingPtr = Ttk_UniformPadding((short)borderWidth);
}
static void BorderElementDraw(
void *clientData, void *elementRecord, Tk_Window tkwin,
Drawable d, Ttk_Box b, unsigned int state)
{
BorderElement *bd = elementRecord;
Tk_3DBorder border = NULL;
int borderWidth = 1, relief = TK_RELIEF_FLAT;
border = Tk_Get3DBorderFromObj(tkwin, bd->borderObj);
Tcl_GetIntFromObj(NULL, bd->borderWidthObj, &borderWidth);
Tk_GetReliefFromObj(NULL, bd->reliefObj, &relief);
if (border && borderWidth > 0 && relief != TK_RELIEF_FLAT) {
Tk_Draw3DRectangle(tkwin, d, border,
b.x, b.y, b.width, b.height, borderWidth,relief);
}
}
static Ttk_ElementSpec BorderElementSpec = {
TK_STYLE_VERSION_2,
sizeof(BorderElement),
BorderElementOptions,
BorderElementSize,
BorderElementDraw
};
/*----------------------------------------------------------------------
* +++ Field element.
* Used for editable fields.
*/
typedef struct {
Tcl_Obj *borderObj;
Tcl_Obj *borderWidthObj;
} FieldElement;
static Ttk_ElementOptionSpec FieldElementOptions[] = {
{ "-fieldbackground", TK_OPTION_BORDER,
Tk_Offset(FieldElement,borderObj), "white" },
{ "-borderwidth", TK_OPTION_PIXELS,
Tk_Offset(FieldElement,borderWidthObj), "2" },
{ NULL, 0, 0, NULL }
};
static void FieldElementSize(
void *clientData, void *elementRecord, Tk_Window tkwin,
int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
FieldElement *field = elementRecord;
int borderWidth = 2;
Tk_GetPixelsFromObj(NULL, tkwin, field->borderWidthObj, &borderWidth);
*paddingPtr = Ttk_UniformPadding((short)borderWidth);
}
static void FieldElementDraw(
void *clientData, void *elementRecord, Tk_Window tkwin,
Drawable d, Ttk_Box b, unsigned int state)
{
FieldElement *field = elementRecord;
Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, field->borderObj);
int borderWidth = 2;
Tk_GetPixelsFromObj(NULL, tkwin, field->borderWidthObj, &borderWidth);
Tk_Fill3DRectangle(tkwin, d, border,
b.x, b.y, b.width, b.height, borderWidth, TK_RELIEF_SUNKEN);
}
static Ttk_ElementSpec FieldElementSpec = {
TK_STYLE_VERSION_2,
sizeof(FieldElement),
FieldElementOptions,
FieldElementSize,
FieldElementDraw
};
/*
*----------------------------------------------------------------------
* +++ Padding element.
*
* This element has no visual representation, only geometry.
* It adds a (possibly non-uniform) internal border.
* In addition, if "-shiftrelief" is specified,
* adds additional pixels to shift child elements "in" or "out"
* depending on the -relief.
*/
typedef struct {
Tcl_Obj *paddingObj;
Tcl_Obj *reliefObj;
Tcl_Obj *shiftreliefObj;
} PaddingElement;
static Ttk_ElementOptionSpec PaddingElementOptions[] = {
{ "-padding", TK_OPTION_STRING,
Tk_Offset(PaddingElement,paddingObj), "0" },
{ "-relief", TK_OPTION_RELIEF,
Tk_Offset(PaddingElement,reliefObj), "flat" },
{ "-shiftrelief", TK_OPTION_INT,
Tk_Offset(PaddingElement,shiftreliefObj), "0" },
{ NULL, 0, 0, NULL }
};
static void PaddingElementSize(
void *clientData, void *elementRecord, Tk_Window tkwin,
int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
PaddingElement *padding = elementRecord;
int shiftRelief = 0;
int relief = TK_RELIEF_FLAT;
Ttk_Padding pad;
Tk_GetReliefFromObj(NULL, padding->reliefObj, &relief);
Tcl_GetIntFromObj(NULL, padding->shiftreliefObj, &shiftRelief);
Ttk_GetPaddingFromObj(NULL,tkwin,padding->paddingObj,&pad);
*paddingPtr = Ttk_RelievePadding(pad, relief, shiftRelief);
}
static Ttk_ElementSpec PaddingElementSpec = {
TK_STYLE_VERSION_2,
sizeof(PaddingElement),
PaddingElementOptions,
PaddingElementSize,
TtkNullElementDraw
};
/*----------------------------------------------------------------------
* +++ Focus ring element.
* Draws a dashed focus ring, if the widget has keyboard focus.
*/
typedef struct {
Tcl_Obj *focusColorObj;
Tcl_Obj *focusThicknessObj;
} FocusElement;
/*
* DrawFocusRing --
* Draw a dotted rectangle to indicate focus.
*/
static void DrawFocusRing(
Tk_Window tkwin, Drawable d, Tcl_Obj *colorObj, Ttk_Box b)
{
XColor *color = Tk_GetColorFromObj(tkwin, colorObj);
unsigned long mask = 0UL;
XGCValues gcvalues;
GC gc;
gcvalues.foreground = color->pixel;
gcvalues.line_style = LineOnOffDash;
gcvalues.line_width = 1;
gcvalues.dashes = 1;
gcvalues.dash_offset = 1;
mask = GCForeground | GCLineStyle | GCDashList | GCDashOffset | GCLineWidth;
gc = Tk_GetGC(tkwin, mask, &gcvalues);
XDrawRectangle(Tk_Display(tkwin), d, gc, b.x, b.y, b.width-1, b.height-1);
Tk_FreeGC(Tk_Display(tkwin), gc);
}
static Ttk_ElementOptionSpec FocusElementOptions[] = {
{ "-focuscolor",TK_OPTION_COLOR,
Tk_Offset(FocusElement,focusColorObj), "black" },
{ "-focusthickness",TK_OPTION_PIXELS,
Tk_Offset(FocusElement,focusThicknessObj), "1" },
{ NULL, 0, 0, NULL }
};
static void FocusElementSize(
void *clientData, void *elementRecord, Tk_Window tkwin,
int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
FocusElement *focus = elementRecord;
int focusThickness = 0;
Tcl_GetIntFromObj(NULL, focus->focusThicknessObj, &focusThickness);
*paddingPtr = Ttk_UniformPadding((short)focusThickness);
}
static void FocusElementDraw(
void *clientData, void *elementRecord, Tk_Window tkwin,
Drawable d, Ttk_Box b, unsigned int state)
{
FocusElement *focus = elementRecord;
int focusThickness = 0;
if (state & TTK_STATE_FOCUS) {
Tcl_GetIntFromObj(NULL,focus->focusThicknessObj,&focusThickness);
DrawFocusRing(tkwin, d, focus->focusColorObj, b);
}
}
static Ttk_ElementSpec FocusElementSpec = {
TK_STYLE_VERSION_2,
sizeof(FocusElement),
FocusElementOptions,
FocusElementSize,
FocusElementDraw
};
/*----------------------------------------------------------------------
* +++ Separator element.
* Just draws a horizontal or vertical bar.
* Three elements are defined: horizontal, vertical, and general;
* the general separator checks the "-orient" option.
*/
typedef struct {
Tcl_Obj *orientObj;
Tcl_Obj *borderObj;
} SeparatorElement;
static Ttk_ElementOptionSpec SeparatorElementOptions[] = {
{ "-orient", TK_OPTION_ANY,
Tk_Offset(SeparatorElement, orientObj), "horizontal" },
{ "-background", TK_OPTION_BORDER,
Tk_Offset(SeparatorElement,borderObj), DEFAULT_BACKGROUND },
{ NULL, 0, 0, NULL }
};
static void SeparatorElementSize(
void *clientData, void *elementRecord, Tk_Window tkwin,
int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
*widthPtr = *heightPtr = 2;
}
static void HorizontalSeparatorElementDraw(
void *clientData, void *elementRecord, Tk_Window tkwin,
Drawable d, Ttk_Box b, unsigned int state)
{
SeparatorElement *separator = elementRecord;
Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, separator->borderObj);
GC lightGC = Tk_3DBorderGC(tkwin, border, TK_3D_LIGHT_GC);
GC darkGC = Tk_3DBorderGC(tkwin, border, TK_3D_DARK_GC);
XDrawLine(Tk_Display(tkwin), d, darkGC, b.x, b.y, b.x + b.width, b.y);
XDrawLine(Tk_Display(tkwin), d, lightGC, b.x, b.y+1, b.x + b.width, b.y+1);
}
static void VerticalSeparatorElementDraw(
void *clientData, void *elementRecord, Tk_Window tkwin,
Drawable d, Ttk_Box b, unsigned int state)
{
SeparatorElement *separator = elementRecord;
Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, separator->borderObj);
GC lightGC = Tk_3DBorderGC(tkwin, border, TK_3D_LIGHT_GC);
GC darkGC = Tk_3DBorderGC(tkwin, border, TK_3D_DARK_GC);
XDrawLine(Tk_Display(tkwin), d, darkGC, b.x, b.y, b.x, b.y + b.height);
XDrawLine(Tk_Display(tkwin), d, lightGC, b.x+1, b.y, b.x+1, b.y+b.height);
}
static void GeneralSeparatorElementDraw(
void *clientData, void *elementRecord, Tk_Window tkwin,
Drawable d, Ttk_Box b, unsigned int state)
{
SeparatorElement *separator = elementRecord;
int orient;
Ttk_GetOrientFromObj(NULL, separator->orientObj, &orient);
switch (orient) {
case TTK_ORIENT_HORIZONTAL:
HorizontalSeparatorElementDraw(
clientData, elementRecord, tkwin, d, b, state);
break;
case TTK_ORIENT_VERTICAL:
VerticalSeparatorElementDraw(
clientData, elementRecord, tkwin, d, b, state);
break;
}
}
static Ttk_ElementSpec HorizontalSeparatorElementSpec = {
TK_STYLE_VERSION_2,
sizeof(SeparatorElement),
SeparatorElementOptions,
SeparatorElementSize,
HorizontalSeparatorElementDraw
};
static Ttk_ElementSpec VerticalSeparatorElementSpec = {
TK_STYLE_VERSION_2,
sizeof(SeparatorElement),
SeparatorElementOptions,
SeparatorElementSize,
HorizontalSeparatorElementDraw
};
static Ttk_ElementSpec SeparatorElementSpec = {
TK_STYLE_VERSION_2,
sizeof(SeparatorElement),
SeparatorElementOptions,
SeparatorElementSize,
GeneralSeparatorElementDraw
};
/*----------------------------------------------------------------------
* +++ Sizegrip: lower-right corner grip handle for resizing window.
*/
typedef struct {
Tcl_Obj *backgroundObj;
} SizegripElement;
static Ttk_ElementOptionSpec SizegripOptions[] = {
{ "-background", TK_OPTION_BORDER,
Tk_Offset(SizegripElement,backgroundObj), DEFAULT_BACKGROUND },
{0,0,0,0}
};
static void SizegripSize(
void *clientData, void *elementRecord, Tk_Window tkwin,
int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
int gripCount = 3, gripSpace = 2, gripThickness = 3;
*widthPtr = *heightPtr = gripCount * (gripSpace + gripThickness);
}
static void SizegripDraw(
void *clientData, void *elementRecord, Tk_Window tkwin,
Drawable d, Ttk_Box b, Ttk_State state)
{
SizegripElement *grip = elementRecord;
int gripCount = 3, gripSpace = 2;
Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, grip->backgroundObj);
GC lightGC = Tk_3DBorderGC(tkwin, border, TK_3D_LIGHT_GC);
GC darkGC = Tk_3DBorderGC(tkwin, border, TK_3D_DARK_GC);
int x1 = b.x + b.width-1, y1 = b.y + b.height-1, x2 = x1, y2 = y1;
while (gripCount--) {
x1 -= gripSpace; y2 -= gripSpace;
XDrawLine(Tk_Display(tkwin), d, darkGC, x1,y1, x2,y2); --x1; --y2;
XDrawLine(Tk_Display(tkwin), d, darkGC, x1,y1, x2,y2); --x1; --y2;
XDrawLine(Tk_Display(tkwin), d, lightGC, x1,y1, x2,y2); --x1; --y2;
}
}
static Ttk_ElementSpec SizegripElementSpec = {
TK_STYLE_VERSION_2,
sizeof(SizegripElement),
SizegripOptions,
SizegripSize,
SizegripDraw
};
/*----------------------------------------------------------------------
* +++ 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.
*/
typedef struct {
Tcl_Obj *backgroundObj;
Tcl_Obj *reliefObj;
Tcl_Obj *colorObj;
Tcl_Obj *diameterObj;
Tcl_Obj *marginObj;
Tcl_Obj *borderWidthObj;
} IndicatorElement;
static Ttk_ElementOptionSpec IndicatorElementOptions[] = {
{ "-background", TK_OPTION_BORDER,
Tk_Offset(IndicatorElement,backgroundObj), DEFAULT_BACKGROUND },
{ "-indicatorcolor", TK_OPTION_BORDER,
Tk_Offset(IndicatorElement,colorObj), DEFAULT_BACKGROUND },
{ "-indicatorrelief", TK_OPTION_RELIEF,
Tk_Offset(IndicatorElement,reliefObj), "raised" },
{ "-indicatordiameter", TK_OPTION_PIXELS,
Tk_Offset(IndicatorElement,diameterObj), "12" },
{ "-indicatormargin", TK_OPTION_STRING,
Tk_Offset(IndicatorElement,marginObj), "0 2 4 2" },
{ "-borderwidth", TK_OPTION_PIXELS,
Tk_Offset(IndicatorElement,borderWidthObj), DEFAULT_BORDERWIDTH },
{ NULL, 0, 0, NULL }
};
/*
* Checkbutton indicators (default): 3-D square.
*/
static void SquareIndicatorElementSize(
void *clientData, void *elementRecord, Tk_Window tkwin,
int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
IndicatorElement *indicator = elementRecord;
Ttk_Padding margins;
int diameter = 0;
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 *clientData, void *elementRecord, Tk_Window tkwin,
Drawable d, Ttk_Box b, unsigned int state)
{
IndicatorElement *indicator = elementRecord;
Tk_3DBorder border = 0, interior = 0;
int relief = TK_RELIEF_RAISED;
Ttk_Padding padding;
int borderWidth = 2;
int diameter;
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 *clientData, void *elementRecord, Tk_Window tkwin,
int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
IndicatorElement *indicator = elementRecord;
Ttk_Padding margins;
int diameter = 0;
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 *clientData, void *elementRecord, Tk_Window tkwin,
Drawable d, Ttk_Box b, unsigned int state)
{
IndicatorElement *indicator = elementRecord;
Tk_3DBorder border = 0, interior = 0;
int borderWidth = 2;
int relief = TK_RELIEF_RAISED;
int diameter, radius;
XPoint points[4];
Ttk_Padding 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);
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 Ttk_ElementSpec CheckbuttonIndicatorElementSpec = {
TK_STYLE_VERSION_2,
sizeof(IndicatorElement),
IndicatorElementOptions,
SquareIndicatorElementSize,
SquareIndicatorElementDraw
};
static Ttk_ElementSpec RadiobuttonIndicatorElementSpec = {
TK_STYLE_VERSION_2,
sizeof(IndicatorElement),
IndicatorElementOptions,
DiamondIndicatorElementSize,
DiamondIndicatorElementDraw
};
/*
*----------------------------------------------------------------------
* +++ Menubutton indicators.
*
* These aren't functional like radio/check indicators,
* they're just affordability indicators.
*
* Standard Tk sets the indicator size to 4.0 mm by 1.7 mm.
* I have no idea where these numbers came from.
*/
typedef struct {
Tcl_Obj *backgroundObj;
Tcl_Obj *widthObj;
Tcl_Obj *heightObj;
Tcl_Obj *borderWidthObj;
Tcl_Obj *reliefObj;
Tcl_Obj *marginObj;
} MenuIndicatorElement;
static Ttk_ElementOptionSpec MenuIndicatorElementOptions[] = {
{ "-background", TK_OPTION_BORDER,
Tk_Offset(MenuIndicatorElement,backgroundObj), DEFAULT_BACKGROUND },
{ "-indicatorwidth", TK_OPTION_PIXELS,
Tk_Offset(MenuIndicatorElement,widthObj), "4.0m" },
{ "-indicatorheight", TK_OPTION_PIXELS,
Tk_Offset(MenuIndicatorElement,heightObj), "1.7m" },
{ "-borderwidth", TK_OPTION_PIXELS,
Tk_Offset(MenuIndicatorElement,borderWidthObj), DEFAULT_BORDERWIDTH },
{ "-indicatorrelief", TK_OPTION_RELIEF,
Tk_Offset(MenuIndicatorElement,reliefObj),"raised" },
{ "-indicatormargin", TK_OPTION_STRING,
Tk_Offset(MenuIndicatorElement,marginObj), "5 0" },
{ NULL, 0, 0, NULL }
};
static void MenuIndicatorElementSize(
void *clientData, void *elementRecord, Tk_Window tkwin,
int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
MenuIndicatorElement *mi = elementRecord;
Ttk_Padding margins;
Tk_GetPixelsFromObj(NULL, tkwin, mi->widthObj, widthPtr);
Tk_GetPixelsFromObj(NULL, tkwin, mi->heightObj, heightPtr);
Ttk_GetPaddingFromObj(NULL,tkwin,mi->marginObj, &margins);
*widthPtr += Ttk_PaddingWidth(margins);
*heightPtr += Ttk_PaddingHeight(margins);
}
static void MenuIndicatorElementDraw(
void *clientData, void *elementRecord, Tk_Window tkwin,
Drawable d, Ttk_Box b, unsigned int state)
{
MenuIndicatorElement *mi = elementRecord;
Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, mi->backgroundObj);
Ttk_Padding margins;
int borderWidth = 2;
Ttk_GetPaddingFromObj(NULL,tkwin,mi->marginObj,&margins);
b = Ttk_PadBox(b, margins);
Tk_GetPixelsFromObj(NULL, tkwin, mi->borderWidthObj, &borderWidth);
Tk_Fill3DRectangle(tkwin, d, border, b.x, b.y, b.width, b.height,
borderWidth, TK_RELIEF_RAISED);
}
static Ttk_ElementSpec MenuIndicatorElementSpec = {
TK_STYLE_VERSION_2,
sizeof(MenuIndicatorElement),
MenuIndicatorElementOptions,
MenuIndicatorElementSize,
MenuIndicatorElementDraw
};
/*----------------------------------------------------------------------
* +++ Arrow elements.
*
* Draws a solid triangle inside a box.
* clientData is an enum ArrowDirection pointer.
*/
static int ArrowElements[] = { ARROW_UP, ARROW_DOWN, ARROW_LEFT, ARROW_RIGHT };
typedef struct {
Tcl_Obj *borderObj;
Tcl_Obj *borderWidthObj;
Tcl_Obj *reliefObj;
Tcl_Obj *sizeObj;
Tcl_Obj *colorObj;
} ArrowElement;
static Ttk_ElementOptionSpec ArrowElementOptions[] = {
{ "-background", TK_OPTION_BORDER,
Tk_Offset(ArrowElement,borderObj), DEFAULT_BACKGROUND },
{ "-relief",TK_OPTION_RELIEF,
Tk_Offset(ArrowElement,reliefObj),"raised"},
{ "-borderwidth", TK_OPTION_PIXELS,
Tk_Offset(ArrowElement,borderWidthObj), "1" },
{ "-arrowcolor",TK_OPTION_COLOR,
Tk_Offset(ArrowElement,colorObj),"black"},
{ "-arrowsize", TK_OPTION_PIXELS,
Tk_Offset(ArrowElement,sizeObj), "14" },
{ NULL, 0, 0, NULL }
};
static Ttk_Padding ArrowMargins = { 3,3,3,3 };
static void ArrowElementSize(
void *clientData, void *elementRecord, Tk_Window tkwin,
int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
ArrowElement *arrow = elementRecord;
int direction = *(int *)clientData;
int width = 14;
Tk_GetPixelsFromObj(NULL, tkwin, arrow->sizeObj, &width);
width -= Ttk_PaddingWidth(ArrowMargins);
TtkArrowSize(width/2, direction, widthPtr, heightPtr);
*widthPtr += Ttk_PaddingWidth(ArrowMargins);
*heightPtr += Ttk_PaddingWidth(ArrowMargins);
}
static void ArrowElementDraw(
void *clientData, void *elementRecord, Tk_Window tkwin,
Drawable d, Ttk_Box b, unsigned int state)
{
int direction = *(int *)clientData;
ArrowElement *arrow = elementRecord;
Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, arrow->borderObj);
XColor *arrowColor = Tk_GetColorFromObj(tkwin, arrow->colorObj);
int relief = TK_RELIEF_RAISED;
int borderWidth = 1;
Tk_GetReliefFromObj(NULL, arrow->reliefObj, &relief);
Tk_Fill3DRectangle(
tkwin, d, border, b.x, b.y, b.width, b.height, borderWidth, relief);
TtkFillArrow(Tk_Display(tkwin), d, Tk_GCForColor(arrowColor, d),
Ttk_PadBox(b, ArrowMargins), direction);
}
static Ttk_ElementSpec ArrowElementSpec = {
TK_STYLE_VERSION_2,
sizeof(ArrowElement),
ArrowElementOptions,
ArrowElementSize,
ArrowElementDraw
};
/*----------------------------------------------------------------------
* +++ Trough element.
*
* Used in scrollbars and scales in place of "border".
*/
typedef struct {
Tcl_Obj *colorObj;
Tcl_Obj *borderWidthObj;
Tcl_Obj *reliefObj;
} TroughElement;
static Ttk_ElementOptionSpec TroughElementOptions[] = {
{ "-borderwidth", TK_OPTION_PIXELS,
Tk_Offset(TroughElement,borderWidthObj), DEFAULT_BORDERWIDTH },
{ "-troughcolor", TK_OPTION_BORDER,
Tk_Offset(TroughElement,colorObj), DEFAULT_BACKGROUND },
{ "-troughrelief",TK_OPTION_RELIEF,
Tk_Offset(TroughElement,reliefObj), "sunken" },
{ NULL, 0, 0, NULL }
};
static void TroughElementSize(
void *clientData, void *elementRecord, Tk_Window tkwin,
int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
TroughElement *troughPtr = elementRecord;
int borderWidth = 2;
Tk_GetPixelsFromObj(NULL, tkwin, troughPtr->borderWidthObj, &borderWidth);
*paddingPtr = Ttk_UniformPadding((short)borderWidth);
}
static void TroughElementDraw(
void *clientData, void *elementRecord, Tk_Window tkwin,
Drawable d, Ttk_Box b, unsigned int state)
{
TroughElement *troughPtr = elementRecord;
Tk_3DBorder border = NULL;
int borderWidth = 2, relief = TK_RELIEF_SUNKEN;
border = Tk_Get3DBorderFromObj(tkwin, troughPtr->colorObj);
Tk_GetReliefFromObj(NULL, troughPtr->reliefObj, &relief);
Tk_GetPixelsFromObj(NULL, tkwin, troughPtr->borderWidthObj, &borderWidth);
Tk_Fill3DRectangle(tkwin, d, border, b.x, b.y, b.width, b.height,
borderWidth, relief);
}
static Ttk_ElementSpec TroughElementSpec = {
TK_STYLE_VERSION_2,
sizeof(TroughElement),
TroughElementOptions,
TroughElementSize,
TroughElementDraw
};
/*
*----------------------------------------------------------------------
* +++ Thumb element.
*
* Used in scrollbars.
*/
typedef struct {
Tcl_Obj *orientObj;
Tcl_Obj *thicknessObj;
Tcl_Obj *reliefObj;
Tcl_Obj *borderObj;
Tcl_Obj *borderWidthObj;
} ThumbElement;
static Ttk_ElementOptionSpec ThumbElementOptions[] = {
{ "-orient", TK_OPTION_ANY,
Tk_Offset(ThumbElement, orientObj), "horizontal" },
{ "-width", TK_OPTION_PIXELS,
Tk_Offset(ThumbElement,thicknessObj), DEFAULT_ARROW_SIZE },
{ "-relief", TK_OPTION_RELIEF,
Tk_Offset(ThumbElement,reliefObj), "raised" },
{ "-background", TK_OPTION_BORDER,
Tk_Offset(ThumbElement,borderObj), DEFAULT_BACKGROUND },
{ "-borderwidth", TK_OPTION_PIXELS,
Tk_Offset(ThumbElement,borderWidthObj), DEFAULT_BORDERWIDTH },
{ NULL, 0, 0, NULL }
};
static void ThumbElementSize(
void *clientData, void *elementRecord, Tk_Window tkwin,
int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
ThumbElement *thumb = elementRecord;
int orient, thickness;
Tk_GetPixelsFromObj(NULL, tkwin, thumb->thicknessObj, &thickness);
Ttk_GetOrientFromObj(NULL, thumb->orientObj, &orient);
if (orient == TTK_ORIENT_VERTICAL) {
*widthPtr = thickness;
*heightPtr = MIN_THUMB_SIZE;
} else {
*widthPtr = MIN_THUMB_SIZE;
*heightPtr = thickness;
}
}
static void ThumbElementDraw(
void *clientData, void *elementRecord, Tk_Window tkwin,
Drawable d, Ttk_Box b, unsigned int state)
{
ThumbElement *thumb = elementRecord;
Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, thumb->borderObj);
int borderWidth = 2, relief = TK_RELIEF_RAISED;
Tk_GetPixelsFromObj(NULL, tkwin, thumb->borderWidthObj, &borderWidth);
Tk_GetReliefFromObj(NULL, thumb->reliefObj, &relief);
Tk_Fill3DRectangle(tkwin, d, border, b.x, b.y, b.width, b.height,
borderWidth, relief);
}
static Ttk_ElementSpec ThumbElementSpec = {
TK_STYLE_VERSION_2,
sizeof(ThumbElement),
ThumbElementOptions,
ThumbElementSize,
ThumbElementDraw
};
/*
*----------------------------------------------------------------------
* +++ Slider element.
*
* This is the moving part of the scale widget. Drawn as a raised box.
*/
typedef struct {
Tcl_Obj *orientObj; /* orientation of overall slider */
Tcl_Obj *lengthObj; /* slider length */
Tcl_Obj *thicknessObj; /* slider thickness */
Tcl_Obj *reliefObj; /* the relief for this object */
Tcl_Obj *borderObj; /* the background color */
Tcl_Obj *borderWidthObj; /* the size of the border */
} SliderElement;
static Ttk_ElementOptionSpec SliderElementOptions[] = {
{ "-sliderlength", TK_OPTION_PIXELS, Tk_Offset(SliderElement,lengthObj),
"30" },
{ "-sliderthickness",TK_OPTION_PIXELS,Tk_Offset(SliderElement,thicknessObj),
"15" },
{ "-sliderrelief", TK_OPTION_RELIEF, Tk_Offset(SliderElement,reliefObj),
"raised" },
{ "-borderwidth", TK_OPTION_PIXELS, Tk_Offset(SliderElement,borderWidthObj),
DEFAULT_BORDERWIDTH },
{ "-background", TK_OPTION_BORDER, Tk_Offset(SliderElement,borderObj),
DEFAULT_BACKGROUND },
{ "-orient", TK_OPTION_ANY, Tk_Offset(SliderElement,orientObj),
"horizontal" },
{ NULL, 0, 0, NULL }
};
static void SliderElementSize(
void *clientData, void *elementRecord, Tk_Window tkwin,
int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
SliderElement *slider = elementRecord;
int orient, length, thickness;
Ttk_GetOrientFromObj(NULL, slider->orientObj, &orient);
Tk_GetPixelsFromObj(NULL, tkwin, slider->lengthObj, &length);
Tk_GetPixelsFromObj(NULL, tkwin, slider->thicknessObj, &thickness);
switch (orient) {
case TTK_ORIENT_VERTICAL:
*widthPtr = thickness;
*heightPtr = length;
break;
case TTK_ORIENT_HORIZONTAL:
*widthPtr = length;
*heightPtr = thickness;
break;
}
}
static void SliderElementDraw(
void *clientData, void *elementRecord, Tk_Window tkwin,
Drawable d, Ttk_Box b, unsigned int state)
{
SliderElement *slider = elementRecord;
Tk_3DBorder border = NULL;
int relief = TK_RELIEF_RAISED, borderWidth = 2, orient;
border = Tk_Get3DBorderFromObj(tkwin, slider->borderObj);
Ttk_GetOrientFromObj(NULL, slider->orientObj, &orient);
Tk_GetPixelsFromObj(NULL, tkwin, slider->borderWidthObj, &borderWidth);
Tk_GetReliefFromObj(NULL, slider->reliefObj, &relief);
Tk_Fill3DRectangle(tkwin, d, border,
b.x, b.y, b.width, b.height,
borderWidth, relief);
if (relief != TK_RELIEF_FLAT) {
if (orient == TTK_ORIENT_HORIZONTAL) {
if (b.width > 4) {
b.x += b.width/2;
XDrawLine(Tk_Display(tkwin), d,
Tk_3DBorderGC(tkwin, border, TK_3D_DARK_GC),
b.x-1, b.y+borderWidth, b.x-1, b.y+b.height-borderWidth);
XDrawLine(Tk_Display(tkwin), d,
Tk_3DBorderGC(tkwin, border, TK_3D_LIGHT_GC),
b.x, b.y+borderWidth, b.x, b.y+b.height-borderWidth);
}
} else {
if (b.height > 4) {
b.y += b.height/2;
XDrawLine(Tk_Display(tkwin), d,
Tk_3DBorderGC(tkwin, border, TK_3D_DARK_GC),
b.x+borderWidth, b.y-1, b.x+b.width-borderWidth, b.y-1);
XDrawLine(Tk_Display(tkwin), d,
Tk_3DBorderGC(tkwin, border, TK_3D_LIGHT_GC),
b.x+borderWidth, b.y, b.x+b.width-borderWidth, b.y);
}
}
}
}
static Ttk_ElementSpec SliderElementSpec = {
TK_STYLE_VERSION_2,
sizeof(SliderElement),
SliderElementOptions,
SliderElementSize,
SliderElementDraw
};
/*------------------------------------------------------------------------
* +++ Progress bar element:
* Draws the moving part of the progress bar.
*
* -thickness specifies the size along the short axis of the bar.
* -length specifies the default size along the long axis;
* the bar will be this long in indeterminate mode.
*/
#define DEFAULT_PBAR_THICKNESS "15"
#define DEFAULT_PBAR_LENGTH "30"
typedef struct {
Tcl_Obj *orientObj; /* widget orientation */
Tcl_Obj *thicknessObj; /* the height/width of the bar */
Tcl_Obj *lengthObj; /* default width/height of the bar */
Tcl_Obj *reliefObj; /* border relief for this object */
Tcl_Obj *borderObj; /* background color */
Tcl_Obj *borderWidthObj; /* thickness of the border */
} PbarElement;
static Ttk_ElementOptionSpec PbarElementOptions[] = {
{ "-orient", TK_OPTION_ANY, Tk_Offset(PbarElement,orientObj),
"horizontal" },
{ "-thickness", TK_OPTION_PIXELS, Tk_Offset(PbarElement,thicknessObj),
DEFAULT_PBAR_THICKNESS },
{ "-barsize", TK_OPTION_PIXELS, Tk_Offset(PbarElement,lengthObj),
DEFAULT_PBAR_LENGTH },
{ "-pbarrelief", TK_OPTION_RELIEF, Tk_Offset(PbarElement,reliefObj),
"raised" },
{ "-borderwidth", TK_OPTION_PIXELS, Tk_Offset(PbarElement,borderWidthObj),
DEFAULT_BORDERWIDTH },
{ "-background", TK_OPTION_BORDER, Tk_Offset(PbarElement,borderObj),
DEFAULT_BACKGROUND },
{ NULL, 0, 0, NULL }
};
static void PbarElementSize(
void *clientData, void *elementRecord, Tk_Window tkwin,
int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
PbarElement *pbar = elementRecord;
int orient, thickness = 15, length = 30, borderWidth = 2;
Ttk_GetOrientFromObj(NULL, pbar->orientObj, &orient);
Tk_GetPixelsFromObj(NULL, tkwin, pbar->thicknessObj, &thickness);
Tk_GetPixelsFromObj(NULL, tkwin, pbar->lengthObj, &length);
Tk_GetPixelsFromObj(NULL, tkwin, pbar->borderWidthObj, &borderWidth);
switch (orient) {
case TTK_ORIENT_HORIZONTAL:
*widthPtr = length + 2 * borderWidth;
*heightPtr = thickness + 2 * borderWidth;
break;
case TTK_ORIENT_VERTICAL:
*widthPtr = thickness + 2 * borderWidth;
*heightPtr = length + 2 * borderWidth;
break;
}
}
static void PbarElementDraw(
void *clientData, void *elementRecord, Tk_Window tkwin,
Drawable d, Ttk_Box b, Ttk_State state)
{
PbarElement *pbar = elementRecord;
Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, pbar->borderObj);
int relief = TK_RELIEF_RAISED, borderWidth = 2;
Tk_GetPixelsFromObj(NULL, tkwin, pbar->borderWidthObj, &borderWidth);
Tk_GetReliefFromObj(NULL, pbar->reliefObj, &relief);
Tk_Fill3DRectangle(tkwin, d, border,
b.x, b.y, b.width, b.height,
borderWidth, relief);
}
static Ttk_ElementSpec PbarElementSpec = {
TK_STYLE_VERSION_2,
sizeof(PbarElement),
PbarElementOptions,
PbarElementSize,
PbarElementDraw
};
/*------------------------------------------------------------------------
* +++ Notebook tabs and client area.
*/
typedef struct {
Tcl_Obj *borderWidthObj;
Tcl_Obj *backgroundObj;
} TabElement;
static Ttk_ElementOptionSpec TabElementOptions[] = {
{ "-borderwidth", TK_OPTION_PIXELS,
Tk_Offset(TabElement,borderWidthObj),"1" },
{ "-background", TK_OPTION_BORDER,
Tk_Offset(TabElement,backgroundObj), DEFAULT_BACKGROUND },
{0,0,0,0}
};
static void TabElementSize(
void *clientData, void *elementRecord, Tk_Window tkwin,
int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
TabElement *tab = elementRecord;
int borderWidth = 1;
Tk_GetPixelsFromObj(0, tkwin, tab->borderWidthObj, &borderWidth);
paddingPtr->top = paddingPtr->left = paddingPtr->right = borderWidth;
paddingPtr->bottom = 0;
}
static void TabElementDraw(
void *clientData, void *elementRecord, Tk_Window tkwin,
Drawable d, Ttk_Box b, unsigned int state)
{
TabElement *tab = elementRecord;
Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, tab->backgroundObj);
int borderWidth = 1;
int cut = 2;
XPoint pts[6];
int n = 0;
Tcl_GetIntFromObj(NULL, tab->borderWidthObj, &borderWidth);
if (state & TTK_STATE_SELECTED) {
/*
* Draw slightly outside of the allocated parcel,
* to overwrite the client area border.
*/
b.height += borderWidth;
}
pts[n].x = b.x; pts[n].y = b.y + b.height - 1; ++n;
pts[n].x = b.x; pts[n].y = b.y + cut; ++n;
pts[n].x = b.x + cut; pts[n].y = b.y; ++n;
pts[n].x = b.x + b.width-1-cut; pts[n].y = b.y; ++n;
pts[n].x = b.x + b.width-1; pts[n].y = b.y + cut; ++n;
pts[n].x = b.x + b.width-1; pts[n].y = b.y + b.height; ++n;
XFillPolygon(Tk_Display(tkwin), d,
Tk_3DBorderGC(tkwin, border, TK_3D_FLAT_GC),
pts, 6, Convex, CoordModeOrigin);
#ifndef _WIN32
/*
* Account for whether XDrawLines draws endpoints by platform
*/
--pts[5].y;
#endif
while (borderWidth--) {
XDrawLines(Tk_Display(tkwin), d,
Tk_3DBorderGC(tkwin, border, TK_3D_LIGHT_GC),
pts, 4, CoordModeOrigin);
XDrawLines(Tk_Display(tkwin), d,
Tk_3DBorderGC(tkwin, border, TK_3D_DARK_GC),
pts+3, 3, CoordModeOrigin);
++pts[0].x; ++pts[1].x; ++pts[2].x; --pts[4].x; --pts[5].x;
++pts[2].y; ++pts[3].y;
}
}
static Ttk_ElementSpec TabElementSpec = {
TK_STYLE_VERSION_2,
sizeof(TabElement),
TabElementOptions,
TabElementSize,
TabElementDraw
};
/*
* Client area element:
* Uses same resources as tab element.
*/
typedef TabElement ClientElement;
#define ClientElementOptions TabElementOptions
static void ClientElementDraw(
void *clientData, void *elementRecord, Tk_Window tkwin,
Drawable d, Ttk_Box b, unsigned int state)
{
ClientElement *ce = elementRecord;
Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, ce->backgroundObj);
int borderWidth = 1;
Tcl_GetIntFromObj(NULL, ce->borderWidthObj, &borderWidth);
Tk_Fill3DRectangle(tkwin, d, border,
b.x, b.y, b.width, b.height, borderWidth,TK_RELIEF_RAISED);
}
static void ClientElementSize(
void *clientData, void *elementRecord, Tk_Window tkwin,
int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
ClientElement *ce = elementRecord;
int borderWidth = 1;
Tk_GetPixelsFromObj(0, tkwin, ce->borderWidthObj, &borderWidth);
*paddingPtr = Ttk_UniformPadding((short)borderWidth);
}
static Ttk_ElementSpec ClientElementSpec = {
TK_STYLE_VERSION_2,
sizeof(ClientElement),
ClientElementOptions,
ClientElementSize,
ClientElementDraw
};
/*----------------------------------------------------------------------
* TtkElements_Init --
* Register default element implementations.
*/
MODULE_SCOPE
void TtkElements_Init(Tcl_Interp *interp)
{
Ttk_Theme theme = Ttk_GetDefaultTheme(interp);
/*
* Elements:
*/
Ttk_RegisterElement(interp, theme, "background",
&BackgroundElementSpec,NULL);
Ttk_RegisterElement(interp, theme, "fill", &FillElementSpec, NULL);
Ttk_RegisterElement(interp, theme, "border", &BorderElementSpec, NULL);
Ttk_RegisterElement(interp, theme, "field", &FieldElementSpec, NULL);
Ttk_RegisterElement(interp, theme, "focus", &FocusElementSpec, NULL);
Ttk_RegisterElement(interp, theme, "padding", &PaddingElementSpec, NULL);
Ttk_RegisterElement(interp, theme, "Checkbutton.indicator",
&CheckbuttonIndicatorElementSpec, NULL);
Ttk_RegisterElement(interp, theme, "Radiobutton.indicator",
&RadiobuttonIndicatorElementSpec, NULL);
Ttk_RegisterElement(interp, theme, "Menubutton.indicator",
&MenuIndicatorElementSpec, NULL);
Ttk_RegisterElement(interp, theme, "indicator", &ttkNullElementSpec,NULL);
Ttk_RegisterElement(interp, theme, "uparrow",
&ArrowElementSpec, &ArrowElements[0]);
Ttk_RegisterElement(interp, theme, "downarrow",
&ArrowElementSpec, &ArrowElements[1]);
Ttk_RegisterElement(interp, theme, "leftarrow",
&ArrowElementSpec, &ArrowElements[2]);
Ttk_RegisterElement(interp, theme, "rightarrow",
&ArrowElementSpec, &ArrowElements[3]);
Ttk_RegisterElement(interp, theme, "arrow",
&ArrowElementSpec, &ArrowElements[0]);
Ttk_RegisterElement(interp, theme, "trough", &TroughElementSpec, NULL);
Ttk_RegisterElement(interp, theme, "thumb", &ThumbElementSpec, NULL);
Ttk_RegisterElement(interp, theme, "slider", &SliderElementSpec, NULL);
Ttk_RegisterElement(interp, theme, "pbar", &PbarElementSpec, NULL);
Ttk_RegisterElement(interp, theme, "separator",
&SeparatorElementSpec, NULL);
Ttk_RegisterElement(interp, theme, "hseparator",
&HorizontalSeparatorElementSpec, NULL);
Ttk_RegisterElement(interp, theme, "vseparator",
&VerticalSeparatorElementSpec, NULL);
Ttk_RegisterElement(interp, theme, "sizegrip", &SizegripElementSpec, NULL);
Ttk_RegisterElement(interp, theme, "tab", &TabElementSpec, NULL);
Ttk_RegisterElement(interp, theme, "client", &ClientElementSpec, NULL);
/*
* Register "default" as a user-loadable theme (for now):
*/
Tcl_PkgProvideEx(interp, "ttk::theme::default", TTK_VERSION, NULL);
}
/*EOF*/