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