summaryrefslogtreecommitdiffstats
path: root/generic/ttk/ttkElements.c
diff options
context:
space:
mode:
Diffstat (limited to 'generic/ttk/ttkElements.c')
-rw-r--r--generic/ttk/ttkElements.c1447
1 files changed, 1447 insertions, 0 deletions
diff --git a/generic/ttk/ttkElements.c b/generic/ttk/ttkElements.c
new file mode 100644
index 0000000..8cd5c6b
--- /dev/null
+++ b/generic/ttk/ttkElements.c
@@ -0,0 +1,1447 @@
+/* $Id: ttkElements.c,v 1.1 2006/10/31 01:42:26 hobbs Exp $
+ *
+ * Copyright (c) 2003, Joe English
+ *
+ * Default implementation for themed elements.
+ *
+ */
+
+#include <tcl.h>
+#include <tk.h>
+#include <string.h>
+#include "ttkTheme.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 NullElementOptions[] = { {NULL} };
+
+/* public */ void
+NullElementGeometry(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
+{
+}
+
+/* public */ void
+NullElementDraw(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ Drawable d, Ttk_Box b, unsigned int state)
+{
+}
+
+/* public */ Ttk_ElementSpec NullElementSpec =
+{
+ TK_STYLE_VERSION_2,
+ sizeof(NullElement),
+ NullElementOptions,
+ NullElementGeometry,
+ NullElementDraw
+};
+
+/*----------------------------------------------------------------------
+ * +++ Background element.
+ *
+ * This element simply clears the entire widget area
+ * with the background color. (NB: ignores parcel).
+ *
+ * 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}
+};
+
+static void
+BackgroundElementGeometry(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
+{
+}
+
+static void
+BackgroundElementDraw(
+ 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),
+ 0,0, Tk_Width(tkwin), Tk_Height(tkwin));
+}
+
+static Ttk_ElementSpec BackgroundElementSpec =
+{
+ TK_STYLE_VERSION_2,
+ sizeof(BackgroundElement),
+ BackgroundElementOptions,
+ BackgroundElementGeometry,
+ 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}
+};
+
+static void
+BorderElementGeometry(
+ 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,
+ BorderElementGeometry,
+ 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}
+};
+
+static void
+FieldElementGeometry(
+ 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,
+ FieldElementGeometry,
+ 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}
+};
+
+static void
+PaddingElementGeometry(
+ 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 void
+PaddingElementDraw(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ Drawable d, Ttk_Box b, unsigned int state)
+{
+ /* No-op */
+}
+
+static Ttk_ElementSpec PaddingElementSpec =
+{
+ TK_STYLE_VERSION_2,
+ sizeof(PaddingElement),
+ PaddingElementOptions,
+ PaddingElementGeometry,
+ PaddingElementDraw
+};
+
+/*----------------------------------------------------------------------
+ * +++ 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}
+};
+
+static void
+FocusElementGeometry(
+ 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,
+ FocusElementGeometry,
+ 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}
+};
+
+static void
+SeparatorElementGeometry(
+ 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,
+ SeparatorElementGeometry,
+ HorizontalSeparatorElementDraw
+};
+
+static Ttk_ElementSpec VerticalSeparatorElementSpec =
+{
+ TK_STYLE_VERSION_2,
+ sizeof(SeparatorElement),
+ SeparatorElementOptions,
+ SeparatorElementGeometry,
+ HorizontalSeparatorElementDraw
+};
+
+static Ttk_ElementSpec SeparatorElementSpec =
+{
+ TK_STYLE_VERSION_2,
+ sizeof(SeparatorElement),
+ SeparatorElementOptions,
+ SeparatorElementGeometry,
+ 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}
+};
+
+/*
+ * Checkbutton indicators (default): 3-D square.
+ */
+static void
+SquareIndicatorElementGeometry(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
+{
+ IndicatorElement *indicator = elementRecord;
+ int diameter = 0;
+ Ttk_GetPaddingFromObj(NULL, tkwin, indicator->marginObj, paddingPtr);
+ Tk_GetPixelsFromObj(NULL, tkwin, indicator->diameterObj, &diameter);
+ *widthPtr = *heightPtr = diameter;
+}
+
+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
+DiamondIndicatorElementGeometry(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
+{
+ IndicatorElement *indicator = elementRecord;
+ int diameter = 0;
+ Ttk_GetPaddingFromObj(NULL, tkwin, indicator->marginObj, paddingPtr);
+ Tk_GetPixelsFromObj(NULL, tkwin, indicator->diameterObj, &diameter);
+ *widthPtr = *heightPtr = diameter + 3;
+}
+
+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,
+ SquareIndicatorElementGeometry,
+ SquareIndicatorElementDraw
+};
+
+static Ttk_ElementSpec RadiobuttonIndicatorElementSpec =
+{
+ TK_STYLE_VERSION_2,
+ sizeof(IndicatorElement),
+ IndicatorElementOptions,
+ DiamondIndicatorElementGeometry,
+ 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 }
+};
+
+static void
+MenuIndicatorElementGeometry(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
+{
+ MenuIndicatorElement *mi = elementRecord;
+ Tk_GetPixelsFromObj(NULL, tkwin, mi->widthObj, widthPtr);
+ Tk_GetPixelsFromObj(NULL, tkwin, mi->heightObj, heightPtr);
+ Ttk_GetPaddingFromObj(NULL,tkwin,mi->marginObj,paddingPtr);
+}
+
+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,
+ MenuIndicatorElementGeometry,
+ 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 }
+};
+
+static Ttk_Padding ArrowPadding = { 3,3,3,3 };
+
+static void
+ArrowElementGeometry(
+ 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(ArrowPadding);
+ ArrowSize(width/2, direction, widthPtr, heightPtr);
+ *paddingPtr = ArrowPadding;
+}
+
+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);
+
+ FillArrow(Tk_Display(tkwin), d, Tk_GCForColor(arrowColor, d),
+ Ttk_PadBox(b, ArrowPadding), direction);
+}
+
+static Ttk_ElementSpec ArrowElementSpec =
+{
+ TK_STYLE_VERSION_2,
+ sizeof(ArrowElement),
+ ArrowElementOptions,
+ ArrowElementGeometry,
+ 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 }
+};
+
+static void
+TroughElementGeometry(
+ 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,
+ TroughElementGeometry,
+ 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 }
+};
+
+static void
+ThumbElementGeometry(
+ 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,
+ ThumbElementGeometry,
+ 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 }
+};
+
+static void
+SliderElementGeometry(
+ 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, borderWidth, 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,
+ SliderElementGeometry,
+ 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 }
+};
+
+static void PbarElementGeometry(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
+{
+ PbarElement *pbar = elementRecord;
+ int orient, thickness, length, borderWidth;
+
+ 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;
+ *heightPtr = thickness;
+ break;
+ case TTK_ORIENT_VERTICAL:
+ *widthPtr = thickness;
+ *heightPtr = length;
+ break;
+ }
+
+ *paddingPtr = Ttk_UniformPadding((short)borderWidth);
+}
+
+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, borderWidth;
+
+ 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,
+ PbarElementGeometry,
+ 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
+TabElementGeometry(
+ 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,
+ TabElementGeometry,
+ 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
+ClientElementGeometry(
+ 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,
+ ClientElementGeometry,
+ ClientElementDraw
+};
+
+
+/*------------------------------------------------------------------------
+ * +++ Widget layouts.
+ */
+
+TTK_BEGIN_LAYOUT(FrameLayout)
+ TTK_NODE("Frame.border", TTK_FILL_BOTH)
+TTK_END_LAYOUT
+
+TTK_BEGIN_LAYOUT(LabelframeLayout)
+ /* Note: labelframe widget does its own layout */
+ TTK_NODE("Labelframe.border", TTK_FILL_BOTH)
+ TTK_NODE("Labelframe.text", TTK_FILL_BOTH)
+TTK_END_LAYOUT
+
+TTK_BEGIN_LAYOUT(LabelLayout)
+ TTK_GROUP("Label.border", TTK_FILL_BOTH|TTK_BORDER,
+ TTK_GROUP("Label.padding", TTK_FILL_BOTH|TTK_BORDER,
+ TTK_NODE("Label.label", TTK_FILL_BOTH)))
+TTK_END_LAYOUT
+
+TTK_BEGIN_LAYOUT(ButtonLayout)
+ TTK_GROUP("Button.border", TTK_FILL_BOTH|TTK_BORDER,
+ TTK_GROUP("Button.focus", TTK_FILL_BOTH,
+ TTK_GROUP("Button.padding", TTK_FILL_BOTH,
+ TTK_NODE("Button.label", TTK_FILL_BOTH))))
+TTK_END_LAYOUT
+
+TTK_BEGIN_LAYOUT(CheckbuttonLayout)
+ TTK_GROUP("Checkbutton.padding", TTK_FILL_BOTH,
+ TTK_NODE("Checkbutton.indicator", TTK_PACK_LEFT)
+ TTK_GROUP("Checkbutton.focus", TTK_PACK_LEFT | TTK_STICK_W,
+ TTK_NODE("Checkbutton.label", TTK_FILL_BOTH)))
+TTK_END_LAYOUT
+
+TTK_BEGIN_LAYOUT(RadiobuttonLayout)
+ TTK_GROUP("Radiobutton.padding", TTK_FILL_BOTH,
+ TTK_NODE("Radiobutton.indicator", TTK_PACK_LEFT)
+ TTK_GROUP("Radiobutton.focus", TTK_PACK_LEFT,
+ TTK_NODE("Radiobutton.label", TTK_FILL_BOTH)))
+TTK_END_LAYOUT
+
+TTK_BEGIN_LAYOUT(MenubuttonLayout)
+ TTK_GROUP("Menubutton.border", TTK_FILL_BOTH,
+ TTK_GROUP("Menubutton.focus", TTK_FILL_BOTH,
+ TTK_NODE("Menubutton.indicator", TTK_PACK_RIGHT)
+ TTK_GROUP("Menubutton.padding", TTK_PACK_LEFT|TTK_EXPAND|TTK_FILL_X,
+ TTK_NODE("Menubutton.label", TTK_PACK_LEFT))))
+TTK_END_LAYOUT
+
+TTK_BEGIN_LAYOUT(VerticalScrollbarLayout)
+ TTK_GROUP("Vertical.Scrollbar.trough", TTK_FILL_Y,
+ TTK_NODE("Vertical.Scrollbar.uparrow", TTK_PACK_TOP)
+ TTK_NODE("Vertical.Scrollbar.downarrow", TTK_PACK_BOTTOM)
+ TTK_NODE(
+ "Vertical.Scrollbar.thumb", TTK_PACK_TOP|TTK_EXPAND|TTK_FILL_BOTH))
+TTK_END_LAYOUT
+
+TTK_BEGIN_LAYOUT(HorizontalScrollbarLayout)
+ TTK_GROUP("Horizontal.Scrollbar.trough", TTK_FILL_X,
+ TTK_NODE("Horizontal.Scrollbar.leftarrow", TTK_PACK_LEFT)
+ TTK_NODE("Horizontal.Scrollbar.rightarrow", TTK_PACK_RIGHT)
+ TTK_NODE(
+ "Horizontal.Scrollbar.thumb", TTK_PACK_LEFT|TTK_EXPAND|TTK_FILL_BOTH))
+TTK_END_LAYOUT
+
+TTK_BEGIN_LAYOUT(VerticalScaleLayout)
+ TTK_GROUP("Vertical.Scale.trough", TTK_FILL_BOTH,
+ TTK_NODE("Vertical.Scale.slider", TTK_PACK_TOP) )
+TTK_END_LAYOUT
+
+TTK_BEGIN_LAYOUT(HorizontalScaleLayout)
+ TTK_GROUP("Horizontal.Scale.trough", TTK_FILL_BOTH,
+ TTK_NODE("Horizontal.Scale.slider", TTK_PACK_LEFT) )
+TTK_END_LAYOUT
+
+TTK_BEGIN_LAYOUT(SeparatorLayout)
+ TTK_NODE("Separator.separator", TTK_FILL_BOTH)
+TTK_END_LAYOUT
+
+TTK_BEGIN_LAYOUT(SizegripLayout)
+ TTK_NODE("Sizegrip.sizegrip", TTK_PACK_BOTTOM|TTK_STICK_S|TTK_STICK_E)
+TTK_END_LAYOUT
+
+/*----------------------------------------------------------------------
+ * RegisterElements --
+ *
+ * Register all elements and layouts defined in this package.
+ */
+
+extern Ttk_ElementSpec TextElementSpec;
+extern Ttk_ElementSpec ImageElementSpec;
+extern Ttk_ElementSpec ImageTextElementSpec;
+extern Ttk_ElementSpec LabelElementSpec;
+
+void RegisterElements(Tcl_Interp *interp)
+{
+ Ttk_Theme theme = Ttk_GetDefaultTheme(interp);
+
+ /*
+ * Elements:
+ */
+ Ttk_RegisterElement(interp, theme, "background",
+ &BackgroundElementSpec,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, "text", &TextElementSpec, NULL);
+ Ttk_RegisterElement(interp, theme,
+ "Labelframe.text",&ImageTextElementSpec,NULL);
+ Ttk_RegisterElement(interp, theme, "image", &ImageElementSpec, interp);
+ Ttk_RegisterElement(interp, theme, "label", &LabelElementSpec, interp);
+ 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", &NullElementSpec,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);
+
+ /*
+ * Layouts:
+ */
+ Ttk_RegisterLayout(theme, "TFrame", FrameLayout);
+ Ttk_RegisterLayout(theme, "TLabelframe", LabelframeLayout);
+ Ttk_RegisterLayout(theme, "TLabel", LabelLayout);
+ Ttk_RegisterLayout(theme, "TButton", ButtonLayout);
+ Ttk_RegisterLayout(theme, "TCheckbutton", CheckbuttonLayout);
+ Ttk_RegisterLayout(theme, "TRadiobutton", RadiobuttonLayout);
+ Ttk_RegisterLayout(theme, "TMenubutton", MenubuttonLayout);
+ Ttk_RegisterLayout(theme,
+ "Vertical.TScrollbar", VerticalScrollbarLayout);
+ Ttk_RegisterLayout(theme,
+ "Horizontal.TScrollbar", HorizontalScrollbarLayout);
+ Ttk_RegisterLayout(theme, "Vertical.TScale", VerticalScaleLayout);
+ Ttk_RegisterLayout(theme, "Horizontal.TScale", HorizontalScaleLayout);
+ Ttk_RegisterLayout(theme, "TSeparator", SeparatorLayout);
+ Ttk_RegisterLayout(theme, "TSizegrip", SizegripLayout);
+}
+
+/*EOF*/