1/* $Id$ 2 * Copyright (c) 2003 Joe English. Freely redistributable. 3 * 4 * Declarations for Tk theme engine. 5 */ 6 7#ifndef _TTKTHEME 8#define _TTKTHEME 9 10#ifdef __cplusplus 11extern "C" { 12#endif 13 14#ifndef MODULE_SCOPE 15# ifdef __cplusplus 16# define MODULE_SCOPE extern "C" 17# else 18# define MODULE_SCOPE extern 19# endif 20#endif 21 22#define TTKAPI MODULE_SCOPE 23 24/* Ttk syncs to the Tk version & patchlevel */ 25#define TTK_VERSION TK_VERSION 26#define TTK_PATCH_LEVEL TK_PATCH_LEVEL 27 28/*------------------------------------------------------------------------ 29 * +++ Defaults for element option specifications. 30 */ 31#define DEFAULT_FONT "TkDefaultFont" 32#define DEFAULT_BACKGROUND "#d9d9d9" 33#define DEFAULT_FOREGROUND "black" 34 35/*------------------------------------------------------------------------ 36 * +++ Widget states. 37 * Keep in sync with stateNames[] in tkstate.c. 38 */ 39 40typedef unsigned int Ttk_State; 41 42#define TTK_STATE_ACTIVE (1<<0) 43#define TTK_STATE_DISABLED (1<<1) 44#define TTK_STATE_FOCUS (1<<2) 45#define TTK_STATE_PRESSED (1<<3) 46#define TTK_STATE_SELECTED (1<<4) 47#define TTK_STATE_BACKGROUND (1<<5) 48#define TTK_STATE_ALTERNATE (1<<6) 49#define TTK_STATE_INVALID (1<<7) 50#define TTK_STATE_READONLY (1<<8) 51#define TTK_STATE_HOVER (1<<9) 52#define TTK_STATE_USER6 (1<<10) 53#define TTK_STATE_USER5 (1<<11) 54#define TTK_STATE_USER4 (1<<12) 55#define TTK_STATE_USER3 (1<<13) 56#define TTK_STATE_USER2 (1<<14) 57#define TTK_STATE_USER1 (1<<15) 58 59/* Maintenance note: if you get all the way to "USER1", 60 * see tkstate.c 61 */ 62typedef struct 63{ 64 unsigned int onbits; /* bits to turn on */ 65 unsigned int offbits; /* bits to turn off */ 66} Ttk_StateSpec; 67 68#define Ttk_StateMatches(state, spec) \ 69 (((state) & ((spec)->onbits|(spec)->offbits)) == (spec)->onbits) 70 71#define Ttk_ModifyState(state, spec) \ 72 (((state) & ~(spec)->offbits) | (spec)->onbits) 73 74TTKAPI int Ttk_GetStateSpecFromObj(Tcl_Interp *, Tcl_Obj *, Ttk_StateSpec *); 75TTKAPI Tcl_Obj *Ttk_NewStateSpecObj(unsigned int onbits,unsigned int offbits); 76 77/*------------------------------------------------------------------------ 78 * +++ State maps and state tables. 79 */ 80typedef Tcl_Obj *Ttk_StateMap; 81 82TTKAPI Ttk_StateMap Ttk_GetStateMapFromObj(Tcl_Interp *, Tcl_Obj *); 83TTKAPI Tcl_Obj *Ttk_StateMapLookup(Tcl_Interp*, Ttk_StateMap, Ttk_State); 84 85/* 86 * Table for looking up an integer index based on widget state: 87 */ 88typedef struct 89{ 90 int index; /* Value to return if this entry matches */ 91 unsigned int onBits; /* Bits which must be set */ 92 unsigned int offBits; /* Bits which must be cleared */ 93} Ttk_StateTable; 94 95TTKAPI int Ttk_StateTableLookup(Ttk_StateTable map[], Ttk_State); 96 97/*------------------------------------------------------------------------ 98 * +++ Padding. 99 * Used to represent internal padding and borders. 100 */ 101typedef struct 102{ 103 short left; 104 short top; 105 short right; 106 short bottom; 107} Ttk_Padding; 108 109TTKAPI int Ttk_GetPaddingFromObj(Tcl_Interp*,Tk_Window,Tcl_Obj*,Ttk_Padding*); 110TTKAPI int Ttk_GetBorderFromObj(Tcl_Interp*,Tcl_Obj*,Ttk_Padding*); 111 112TTKAPI Ttk_Padding Ttk_MakePadding(short l, short t, short r, short b); 113TTKAPI Ttk_Padding Ttk_UniformPadding(short borderWidth); 114TTKAPI Ttk_Padding Ttk_AddPadding(Ttk_Padding, Ttk_Padding); 115TTKAPI Ttk_Padding Ttk_RelievePadding(Ttk_Padding, int relief, int n); 116 117#define Ttk_PaddingWidth(p) ((p).left + (p).right) 118#define Ttk_PaddingHeight(p) ((p).top + (p).bottom) 119 120#define Ttk_SetMargins(tkwin, pad) \ 121 Tk_SetInternalBorderEx(tkwin, pad.left, pad.right, pad.top, pad.bottom) 122 123/*------------------------------------------------------------------------ 124 * +++ Boxes. 125 * Used to represent rectangular regions 126 */ 127typedef struct /* Hey, this is an XRectangle! */ 128{ 129 int x; 130 int y; 131 int width; 132 int height; 133} Ttk_Box; 134 135TTKAPI Ttk_Box Ttk_MakeBox(int x, int y, int width, int height); 136TTKAPI int Ttk_BoxContains(Ttk_Box, int x, int y); 137 138#define Ttk_WinBox(tkwin) Ttk_MakeBox(0,0,Tk_Width(tkwin),Tk_Height(tkwin)) 139 140/*------------------------------------------------------------------------ 141 * +++ Layout utilities. 142 */ 143typedef enum { 144 TTK_SIDE_LEFT, TTK_SIDE_TOP, TTK_SIDE_RIGHT, TTK_SIDE_BOTTOM 145} Ttk_Side; 146 147typedef unsigned int Ttk_Sticky; 148 149/* 150 * -sticky bits for Ttk_StickBox: 151 */ 152#define TTK_STICK_W (0x1) 153#define TTK_STICK_E (0x2) 154#define TTK_STICK_N (0x4) 155#define TTK_STICK_S (0x8) 156 157/* 158 * Aliases and useful combinations: 159 */ 160#define TTK_FILL_X (0x3) /* -sticky ew */ 161#define TTK_FILL_Y (0xC) /* -sticky ns */ 162#define TTK_FILL_BOTH (0xF) /* -sticky nswe */ 163 164TTKAPI int Ttk_GetStickyFromObj(Tcl_Interp *, Tcl_Obj *, Ttk_Sticky *); 165TTKAPI Tcl_Obj *Ttk_NewStickyObj(Ttk_Sticky); 166 167/* 168 * Extra bits for position specifications (combine -side and -sticky) 169 */ 170 171typedef unsigned int Ttk_PositionSpec; /* See below */ 172 173#define TTK_PACK_LEFT (0x10) /* pack at left of current parcel */ 174#define TTK_PACK_RIGHT (0x20) /* pack at right of current parcel */ 175#define TTK_PACK_TOP (0x40) /* pack at top of current parcel */ 176#define TTK_PACK_BOTTOM (0x80) /* pack at bottom of current parcel */ 177#define TTK_EXPAND (0x100) /* use entire parcel */ 178#define TTK_BORDER (0x200) /* draw this element after children */ 179#define TTK_UNIT (0x400) /* treat descendants as a part of element */ 180 181/* 182 * Extra bits for layout specifications 183 */ 184#define _TTK_CHILDREN (0x1000)/* for LayoutSpecs -- children follow */ 185#define _TTK_LAYOUT_END (0x2000)/* for LayoutSpecs -- end of child list */ 186#define _TTK_LAYOUT (0x4000)/* for LayoutSpec tables -- define layout */ 187 188#define _TTK_MASK_STICK (0x0F) /* See Ttk_UnparseLayout() */ 189#define _TTK_MASK_PACK (0xF0) /* See Ttk_UnparseLayout(), packStrings */ 190 191TTKAPI Ttk_Box Ttk_PackBox(Ttk_Box *cavity, int w, int h, Ttk_Side side); 192TTKAPI Ttk_Box Ttk_StickBox(Ttk_Box parcel, int w, int h, Ttk_Sticky sticky); 193TTKAPI Ttk_Box Ttk_AnchorBox(Ttk_Box parcel, int w, int h, Tk_Anchor anchor); 194TTKAPI Ttk_Box Ttk_PadBox(Ttk_Box b, Ttk_Padding p); 195TTKAPI Ttk_Box Ttk_ExpandBox(Ttk_Box b, Ttk_Padding p); 196TTKAPI Ttk_Box Ttk_PlaceBox(Ttk_Box *cavity, int w,int h, Ttk_Side,Ttk_Sticky); 197TTKAPI Ttk_Box Ttk_PositionBox(Ttk_Box *cavity, int w, int h, Ttk_PositionSpec); 198 199/*------------------------------------------------------------------------ 200 * +++ Themes. 201 */ 202MODULE_SCOPE void Ttk_StylePkgInit(Tcl_Interp *); 203 204typedef struct Ttk_Theme_ *Ttk_Theme; 205typedef struct Ttk_ElementClass_ Ttk_ElementClass; 206typedef struct Ttk_Layout_ *Ttk_Layout; 207typedef struct Ttk_LayoutNode_ *Ttk_Element; 208typedef struct Ttk_Style_ *Ttk_Style; 209 210TTKAPI Ttk_Theme Ttk_GetTheme(Tcl_Interp *interp, const char *name); 211TTKAPI Ttk_Theme Ttk_GetDefaultTheme(Tcl_Interp *interp); 212TTKAPI Ttk_Theme Ttk_GetCurrentTheme(Tcl_Interp *interp); 213 214TTKAPI Ttk_Theme Ttk_CreateTheme( 215 Tcl_Interp *interp, const char *name, Ttk_Theme parent); 216 217typedef int (Ttk_ThemeEnabledProc)(Ttk_Theme theme, void *clientData); 218MODULE_SCOPE void Ttk_SetThemeEnabledProc(Ttk_Theme, Ttk_ThemeEnabledProc, void *); 219 220MODULE_SCOPE int Ttk_UseTheme(Tcl_Interp *, Ttk_Theme); 221 222typedef void (Ttk_CleanupProc)(void *clientData); 223TTKAPI void Ttk_RegisterCleanup( 224 Tcl_Interp *interp, void *deleteData, Ttk_CleanupProc *cleanupProc); 225 226/*------------------------------------------------------------------------ 227 * +++ Elements. 228 */ 229 230enum TTKStyleVersion2 { TK_STYLE_VERSION_2 = 2 }; 231 232typedef void (Ttk_ElementSizeProc)(void *clientData, void *elementRecord, 233 Tk_Window tkwin, int *widthPtr, int *heightPtr, Ttk_Padding*); 234typedef void (Ttk_ElementDrawProc)(void *clientData, void *elementRecord, 235 Tk_Window tkwin, Drawable d, Ttk_Box b, Ttk_State state); 236 237typedef struct Ttk_ElementOptionSpec 238{ 239 const char *optionName; /* Command-line name of the widget option */ 240 Tk_OptionType type; /* Accepted option types */ 241 int offset; /* Offset of Tcl_Obj* field in element record */ 242 const char *defaultValue; /* Default value to used if resource missing */ 243} Ttk_ElementOptionSpec; 244 245#define TK_OPTION_ANY TK_OPTION_STRING 246 247typedef struct Ttk_ElementSpec { 248 enum TTKStyleVersion2 version; /* Version of the style support. */ 249 size_t elementSize; /* Size of element record */ 250 Ttk_ElementOptionSpec *options; /* List of options, NULL-terminated */ 251 Ttk_ElementSizeProc *size; /* Compute min size and padding */ 252 Ttk_ElementDrawProc *draw; /* Draw the element */ 253} Ttk_ElementSpec; 254 255TTKAPI Ttk_ElementClass *Ttk_RegisterElement( 256 Tcl_Interp *interp, Ttk_Theme theme, const char *elementName, 257 Ttk_ElementSpec *, void *clientData); 258 259typedef int (*Ttk_ElementFactory) 260 (Tcl_Interp *, void *clientData, 261 Ttk_Theme, const char *elementName, int objc, Tcl_Obj *const objv[]); 262 263TTKAPI int Ttk_RegisterElementFactory( 264 Tcl_Interp *, const char *name, Ttk_ElementFactory, void *clientData); 265 266/* 267 * Null element implementation: 268 * has no geometry or layout; may be used as a stub or placeholder. 269 */ 270 271typedef struct { 272 Tcl_Obj *unused; 273} NullElement; 274 275MODULE_SCOPE void TtkNullElementSize 276 (void *, void *, Tk_Window, int *, int *, Ttk_Padding *); 277MODULE_SCOPE void TtkNullElementDraw 278 (void *, void *, Tk_Window, Drawable, Ttk_Box, Ttk_State); 279MODULE_SCOPE Ttk_ElementOptionSpec TtkNullElementOptions[]; 280MODULE_SCOPE Ttk_ElementSpec ttkNullElementSpec; 281 282/*------------------------------------------------------------------------ 283 * +++ Layout templates. 284 */ 285typedef struct { 286 const char * elementName; 287 unsigned opcode; 288} TTKLayoutInstruction, *Ttk_LayoutSpec; 289 290#define TTK_BEGIN_LAYOUT_TABLE(name) \ 291 static TTKLayoutInstruction name[] = { 292#define TTK_LAYOUT(name, content) \ 293 { name, _TTK_CHILDREN|_TTK_LAYOUT }, \ 294 content \ 295 { 0, _TTK_LAYOUT_END }, 296#define TTK_GROUP(name, flags, children) \ 297 { name, flags | _TTK_CHILDREN }, \ 298 children \ 299 { 0, _TTK_LAYOUT_END }, 300#define TTK_NODE(name, flags) { name, flags }, 301#define TTK_END_LAYOUT_TABLE { 0, _TTK_LAYOUT | _TTK_LAYOUT_END } }; 302 303#define TTK_BEGIN_LAYOUT(name) static TTKLayoutInstruction name[] = { 304#define TTK_END_LAYOUT { 0, _TTK_LAYOUT_END } }; 305 306TTKAPI void Ttk_RegisterLayout( 307 Ttk_Theme theme, const char *className, Ttk_LayoutSpec layoutSpec); 308 309TTKAPI void Ttk_RegisterLayouts( 310 Ttk_Theme theme, Ttk_LayoutSpec layoutTable); 311 312/*------------------------------------------------------------------------ 313 * +++ Layout instances. 314 */ 315 316MODULE_SCOPE Ttk_Layout Ttk_CreateLayout( 317 Tcl_Interp *, Ttk_Theme, const char *name, 318 void *recordPtr, Tk_OptionTable, Tk_Window tkwin); 319 320MODULE_SCOPE Ttk_Layout Ttk_CreateSublayout( 321 Tcl_Interp *, Ttk_Theme, Ttk_Layout, const char *name, Tk_OptionTable); 322 323MODULE_SCOPE void Ttk_FreeLayout(Ttk_Layout); 324 325MODULE_SCOPE void Ttk_LayoutSize(Ttk_Layout,Ttk_State,int *widthPtr,int *heightPtr); 326MODULE_SCOPE void Ttk_PlaceLayout(Ttk_Layout, Ttk_State, Ttk_Box); 327MODULE_SCOPE void Ttk_DrawLayout(Ttk_Layout, Ttk_State, Drawable); 328 329MODULE_SCOPE void Ttk_RebindSublayout(Ttk_Layout, void *recordPtr); 330 331MODULE_SCOPE Ttk_Element Ttk_IdentifyElement(Ttk_Layout, int x, int y); 332MODULE_SCOPE Ttk_Element Ttk_FindElement(Ttk_Layout, const char *nodeName); 333 334MODULE_SCOPE const char *Ttk_ElementName(Ttk_Element); 335MODULE_SCOPE Ttk_Box Ttk_ElementParcel(Ttk_Element); 336 337MODULE_SCOPE Ttk_Box Ttk_ClientRegion(Ttk_Layout, const char *elementName); 338 339MODULE_SCOPE Ttk_Box Ttk_LayoutNodeInternalParcel(Ttk_Layout,Ttk_Element); 340MODULE_SCOPE Ttk_Padding Ttk_LayoutNodeInternalPadding(Ttk_Layout,Ttk_Element); 341MODULE_SCOPE void Ttk_LayoutNodeReqSize(Ttk_Layout, Ttk_Element, int *w, int *h); 342 343MODULE_SCOPE void Ttk_PlaceElement(Ttk_Layout, Ttk_Element, Ttk_Box); 344MODULE_SCOPE void Ttk_ChangeElementState(Ttk_Element,unsigned set,unsigned clr); 345 346MODULE_SCOPE Tcl_Obj *Ttk_QueryOption(Ttk_Layout, const char *, Ttk_State); 347 348TTKAPI Ttk_Style Ttk_LayoutStyle(Ttk_Layout); 349TTKAPI Tcl_Obj *Ttk_StyleDefault(Ttk_Style, const char *optionName); 350TTKAPI Tcl_Obj *Ttk_StyleMap(Ttk_Style, const char *optionName, Ttk_State); 351 352/*------------------------------------------------------------------------ 353 * +++ Resource cache. 354 * See resource.c for explanation. 355 */ 356 357typedef struct Ttk_ResourceCache_ *Ttk_ResourceCache; 358MODULE_SCOPE Ttk_ResourceCache Ttk_CreateResourceCache(Tcl_Interp *); 359MODULE_SCOPE void Ttk_FreeResourceCache(Ttk_ResourceCache); 360 361MODULE_SCOPE Ttk_ResourceCache Ttk_GetResourceCache(Tcl_Interp*); 362MODULE_SCOPE Tcl_Obj *Ttk_UseFont(Ttk_ResourceCache, Tk_Window, Tcl_Obj *); 363MODULE_SCOPE Tcl_Obj *Ttk_UseColor(Ttk_ResourceCache, Tk_Window, Tcl_Obj *); 364MODULE_SCOPE Tcl_Obj *Ttk_UseBorder(Ttk_ResourceCache, Tk_Window, Tcl_Obj *); 365MODULE_SCOPE Tk_Image Ttk_UseImage(Ttk_ResourceCache, Tk_Window, Tcl_Obj *); 366 367MODULE_SCOPE void Ttk_RegisterNamedColor(Ttk_ResourceCache, const char *, XColor *); 368 369/*------------------------------------------------------------------------ 370 * +++ Image specifications. 371 */ 372 373typedef struct TtkImageSpec Ttk_ImageSpec; 374TTKAPI Ttk_ImageSpec *TtkGetImageSpec(Tcl_Interp *, Tk_Window, Tcl_Obj *); 375TTKAPI void TtkFreeImageSpec(Ttk_ImageSpec *); 376TTKAPI Tk_Image TtkSelectImage(Ttk_ImageSpec *, Ttk_State); 377 378/*------------------------------------------------------------------------ 379 * +++ Miscellaneous enumerations. 380 * Other stuff that element implementations need to know about. 381 */ 382typedef enum /* -default option values */ 383{ 384 TTK_BUTTON_DEFAULT_NORMAL, /* widget defaultable */ 385 TTK_BUTTON_DEFAULT_ACTIVE, /* currently the default widget */ 386 TTK_BUTTON_DEFAULT_DISABLED /* not defaultable */ 387} Ttk_ButtonDefaultState; 388 389TTKAPI int Ttk_GetButtonDefaultStateFromObj(Tcl_Interp *, Tcl_Obj *, int *); 390 391typedef enum /* -compound option values */ 392{ 393 TTK_COMPOUND_NONE, /* image if specified, otherwise text */ 394 TTK_COMPOUND_TEXT, /* text only */ 395 TTK_COMPOUND_IMAGE, /* image only */ 396 TTK_COMPOUND_CENTER, /* text overlays image */ 397 TTK_COMPOUND_TOP, /* image above text */ 398 TTK_COMPOUND_BOTTOM, /* image below text */ 399 TTK_COMPOUND_LEFT, /* image to left of text */ 400 TTK_COMPOUND_RIGHT /* image to right of text */ 401} Ttk_Compound; 402 403TTKAPI int Ttk_GetCompoundFromObj(Tcl_Interp *, Tcl_Obj *, int *); 404 405typedef enum { /* -orient option values */ 406 TTK_ORIENT_HORIZONTAL, 407 TTK_ORIENT_VERTICAL 408} Ttk_Orient; 409 410/*------------------------------------------------------------------------ 411 * +++ Utilities. 412 */ 413 414typedef struct TtkEnsemble { 415 const char *name; /* subcommand name */ 416 Tcl_ObjCmdProc *command; /* subcommand implementation, OR: */ 417 const struct TtkEnsemble *ensemble; /* subcommand ensemble */ 418} Ttk_Ensemble; 419 420MODULE_SCOPE int Ttk_InvokeEnsemble( /* Run an ensemble command */ 421 const Ttk_Ensemble *commands, int cmdIndex, 422 void *clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); 423 424MODULE_SCOPE int TtkEnumerateHashTable(Tcl_Interp *, Tcl_HashTable *); 425 426/*------------------------------------------------------------------------ 427 * +++ Stub table declarations. 428 */ 429 430#include "ttkDecls.h" 431 432/* 433 * Drawing utilities for theme code: 434 * (@@@ find a better home for this) 435 */ 436typedef enum { ARROW_UP, ARROW_DOWN, ARROW_LEFT, ARROW_RIGHT } ArrowDirection; 437MODULE_SCOPE void TtkArrowSize(int h, ArrowDirection, int *widthPtr, int *heightPtr); 438MODULE_SCOPE void TtkDrawArrow(Display *, Drawable, GC, Ttk_Box, ArrowDirection); 439MODULE_SCOPE void TtkFillArrow(Display *, Drawable, GC, Ttk_Box, ArrowDirection); 440 441#ifdef __cplusplus 442} 443#endif 444#endif /* _TTKTHEME */ 445