1 /*
2  * Copyright © 2003 Joe English
3  *
4  * Ttk package: initialization routine and miscellaneous utilities.
5  */
6 
7 #include "tkInt.h"
8 #include "ttkTheme.h"
9 #include "ttkWidget.h"
10 
11 /*
12  * Legal values for the button -default option.
13  * See also: enum Ttk_ButtonDefaultState.
14  */
15 const char *const ttkDefaultStrings[] = {
16     "normal", "active", "disabled", NULL
17 };
18 
Ttk_GetButtonDefaultStateFromObj(Tcl_Interp * interp,Tcl_Obj * objPtr,Ttk_ButtonDefaultState * statePtr)19 int Ttk_GetButtonDefaultStateFromObj(
20     Tcl_Interp *interp, Tcl_Obj *objPtr, Ttk_ButtonDefaultState *statePtr)
21 {
22     int state = (int)TTK_BUTTON_DEFAULT_DISABLED;
23     int result = Tcl_GetIndexFromObjStruct(interp, objPtr, ttkDefaultStrings,
24 	    sizeof(char *), "default state", 0, &state);
25 
26     *statePtr = (Ttk_ButtonDefaultState)state;
27     return result;
28 }
29 
30 /*
31  * Legal values for the -compound option.
32  * See also: enum Ttk_Compound.
33  */
34 const char *const ttkCompoundStrings[] = {
35     "none", "text", "image", "center",
36     "top", "bottom", "left", "right", NULL
37 };
38 
Ttk_GetCompoundFromObj(Tcl_Interp * interp,Tcl_Obj * objPtr,Ttk_Compound * compoundPtr)39 int Ttk_GetCompoundFromObj(
40     Tcl_Interp *interp, Tcl_Obj *objPtr, Ttk_Compound *compoundPtr)
41 {
42     int compound = (int)TTK_COMPOUND_NONE;
43     int result = Tcl_GetIndexFromObjStruct(interp, objPtr, ttkCompoundStrings,
44 	    sizeof(char *), "compound layout", 0, &compound);
45 
46     *compoundPtr = (Ttk_Compound)compound;
47     return result;
48 }
49 
50 /*
51  * Legal values for the -orient option.
52  * See also: enum Ttk_Orient.
53  */
54 const char *const ttkOrientStrings[] = {
55     "horizontal", "vertical", NULL
56 };
57 
58 #if !defined(TK_NO_DEPRECATED) && TK_MAJOR_VERSION < 9
Ttk_GetOrientFromObj(Tcl_Interp * interp,Tcl_Obj * objPtr,int * resultPtr)59 int Ttk_GetOrientFromObj(
60     Tcl_Interp *interp, Tcl_Obj *objPtr, int *resultPtr)
61 {
62     *resultPtr = TTK_ORIENT_HORIZONTAL;
63     return Tcl_GetIndexFromObjStruct(interp, objPtr, ttkOrientStrings,
64 	    sizeof(char *), "orientation", 0, resultPtr);
65 }
66 #endif
67 
TtkGetOrientFromObj(Tcl_Interp * interp,Tcl_Obj * objPtr,Ttk_Orient * resultPtr)68 int TtkGetOrientFromObj(
69     Tcl_Interp *interp, Tcl_Obj *objPtr, Ttk_Orient *resultPtr)
70 {
71     int orient = (int)TTK_ORIENT_HORIZONTAL;
72     int result = Tcl_GetIndexFromObjStruct(interp, objPtr, ttkOrientStrings,
73     	    sizeof(char *), "orientation", 0, &orient);
74 
75     *resultPtr = (Ttk_Orient)orient;
76     return result;
77 }
78 
79 /*
80  * Recognized values for the -state compatibility option.
81  * Other options are accepted and interpreted as synonyms for "normal".
82  */
83 static const char *const ttkStateStrings[] = {
84     "normal", "readonly", "disabled", "active", NULL
85 };
86 enum {
87     TTK_COMPAT_STATE_NORMAL,
88     TTK_COMPAT_STATE_READONLY,
89     TTK_COMPAT_STATE_DISABLED,
90     TTK_COMPAT_STATE_ACTIVE
91 };
92 
93 /* TtkCheckStateOption --
94  * 	Handle -state compatibility option.
95  *
96  *	NOTE: setting -state disabled / -state enabled affects the
97  *	widget state, but the internal widget state does *not* affect
98  *	the value of the -state option.
99  *	This option is present for compatibility only.
100  */
TtkCheckStateOption(WidgetCore * corePtr,Tcl_Obj * objPtr)101 void TtkCheckStateOption(WidgetCore *corePtr, Tcl_Obj *objPtr)
102 {
103     int stateOption = TTK_COMPAT_STATE_NORMAL;
104     unsigned all = TTK_STATE_DISABLED|TTK_STATE_READONLY|TTK_STATE_ACTIVE;
105 #   define SETFLAGS(f) TtkWidgetChangeState(corePtr, f, all^f)
106 
107     (void)Tcl_GetIndexFromObjStruct(NULL, objPtr, ttkStateStrings,
108 	    sizeof(char *), "", 0, &stateOption);
109     switch (stateOption) {
110 	case TTK_COMPAT_STATE_NORMAL:
111 	default:
112 	    SETFLAGS(0);
113 	    break;
114 	case TTK_COMPAT_STATE_READONLY:
115 	    SETFLAGS(TTK_STATE_READONLY);
116 	    break;
117 	case TTK_COMPAT_STATE_DISABLED:
118 	    SETFLAGS(TTK_STATE_DISABLED);
119 	    break;
120 	case TTK_COMPAT_STATE_ACTIVE:
121 	    SETFLAGS(TTK_STATE_ACTIVE);
122 	    break;
123     }
124 #   undef SETFLAGS
125 }
126 
127 /* TtkEnumerateOptions, TtkGetOptionValue --
128  *	Common factors for data accessor commands.
129  */
TtkEnumerateOptions(Tcl_Interp * interp,void * recordPtr,const Tk_OptionSpec * specPtr,Tk_OptionTable optionTable,Tk_Window tkwin)130 int TtkEnumerateOptions(
131     Tcl_Interp *interp, void *recordPtr, const Tk_OptionSpec *specPtr,
132     Tk_OptionTable optionTable, Tk_Window tkwin)
133 {
134     Tcl_Obj *result = Tcl_NewListObj(0,0);
135     while (specPtr->type != TK_OPTION_END)
136     {
137 	Tcl_Obj *optionName = Tcl_NewStringObj(specPtr->optionName, -1);
138 	Tcl_Obj *optionValue =
139 	    Tk_GetOptionValue(interp,recordPtr,optionTable,optionName,tkwin);
140 	if (optionValue) {
141 	    Tcl_ListObjAppendElement(interp, result, optionName);
142 	    Tcl_ListObjAppendElement(interp, result, optionValue);
143 	}
144 	++specPtr;
145 
146 	if (specPtr->type == TK_OPTION_END && specPtr->clientData != NULL) {
147 	    /* Chain to next option spec array: */
148 	    specPtr = (const Tk_OptionSpec *)specPtr->clientData;
149 	}
150     }
151     Tcl_SetObjResult(interp, result);
152     return TCL_OK;
153 }
154 
TtkGetOptionValue(Tcl_Interp * interp,void * recordPtr,Tcl_Obj * optionName,Tk_OptionTable optionTable,Tk_Window tkwin)155 int TtkGetOptionValue(
156     Tcl_Interp *interp, void *recordPtr, Tcl_Obj *optionName,
157     Tk_OptionTable optionTable, Tk_Window tkwin)
158 {
159     Tcl_Obj *result =
160 	Tk_GetOptionValue(interp,recordPtr,optionTable,optionName,tkwin);
161     if (result) {
162 	Tcl_SetObjResult(interp, result);
163 	return TCL_OK;
164     }
165     return TCL_ERROR;
166 }
167 
168 
169 /*------------------------------------------------------------------------
170  * Core Option specifications:
171  * type name dbName dbClass default objOffset intOffset flags clientData mask
172  */
173 
174 /* public */
175 const Tk_OptionSpec ttkCoreOptionSpecs[] =
176 {
177     {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor", NULL,
178 	offsetof(WidgetCore, cursorObj), TCL_INDEX_NONE, TK_OPTION_NULL_OK,0,0 },
179     {TK_OPTION_STRING, "-style", "style", "Style", "",
180 	offsetof(WidgetCore,styleObj), TCL_INDEX_NONE, 0,0,STYLE_CHANGED},
181     {TK_OPTION_STRING, "-class", "", "", NULL,
182 	offsetof(WidgetCore,classObj), TCL_INDEX_NONE, 0,0,READONLY_OPTION},
183     {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0}
184 };
185 
186 /*------------------------------------------------------------------------
187  * +++ Initialization: elements and element factories.
188  */
189 
190 extern void TtkElements_Init(Tcl_Interp *);
191 extern void TtkLabel_Init(Tcl_Interp *);
192 extern void TtkImage_Init(Tcl_Interp *);
193 
RegisterElements(Tcl_Interp * interp)194 static void RegisterElements(Tcl_Interp *interp)
195 {
196     TtkElements_Init(interp);
197     TtkLabel_Init(interp);
198     TtkImage_Init(interp);
199 }
200 
201 /*------------------------------------------------------------------------
202  * +++ Initialization: Widget definitions.
203  */
204 
205 extern void TtkButton_Init(Tcl_Interp *);
206 extern void TtkEntry_Init(Tcl_Interp *);
207 extern void TtkFrame_Init(Tcl_Interp *);
208 extern void TtkNotebook_Init(Tcl_Interp *);
209 extern void TtkPanedwindow_Init(Tcl_Interp *);
210 extern void TtkProgressbar_Init(Tcl_Interp *);
211 extern void TtkScale_Init(Tcl_Interp *);
212 extern void TtkScrollbar_Init(Tcl_Interp *);
213 extern void TtkSeparator_Init(Tcl_Interp *);
214 extern void TtkTreeview_Init(Tcl_Interp *);
215 
216 #ifdef TTK_SQUARE_WIDGET
217 extern int TtkSquareWidget_Init(Tcl_Interp *);
218 #endif
219 
RegisterWidgets(Tcl_Interp * interp)220 static void RegisterWidgets(Tcl_Interp *interp)
221 {
222     TtkButton_Init(interp);
223     TtkEntry_Init(interp);
224     TtkFrame_Init(interp);
225     TtkNotebook_Init(interp);
226     TtkPanedwindow_Init(interp);
227     TtkProgressbar_Init(interp);
228     TtkScale_Init(interp);
229     TtkScrollbar_Init(interp);
230     TtkSeparator_Init(interp);
231     TtkTreeview_Init(interp);
232 #ifdef TTK_SQUARE_WIDGET
233     TtkSquareWidget_Init(interp);
234 #endif
235 }
236 
237 /*------------------------------------------------------------------------
238  * +++ Initialization: Built-in themes.
239  */
240 
241 extern int TtkAltTheme_Init(Tcl_Interp *);
242 extern int TtkClassicTheme_Init(Tcl_Interp *);
243 extern int TtkClamTheme_Init(Tcl_Interp *);
244 
RegisterThemes(Tcl_Interp * interp)245 static void RegisterThemes(Tcl_Interp *interp)
246 {
247 
248     TtkAltTheme_Init(interp);
249     TtkClassicTheme_Init(interp);
250     TtkClamTheme_Init(interp);
251 }
252 
253 /*
254  * Ttk initialization.
255  */
256 
257 extern const TtkStubs ttkStubs;
258 
259 MODULE_SCOPE int
Ttk_Init(Tcl_Interp * interp)260 Ttk_Init(Tcl_Interp *interp)
261 {
262     /*
263      * This will be run for both safe and regular interp init.
264      * Use Tcl_IsSafe if necessary to not initialize unsafe bits.
265      */
266     Ttk_StylePkgInit(interp);
267 
268     RegisterElements(interp);
269     RegisterWidgets(interp);
270     RegisterThemes(interp);
271 
272     Ttk_PlatformInit(interp);
273 
274 #ifndef TK_NO_DEPRECATED
275     Tcl_PkgProvideEx(interp, "Ttk", TTK_PATCH_LEVEL, (void *)&ttkStubs);
276 #endif
277     Tcl_PkgProvideEx(interp, "ttk", TTK_PATCH_LEVEL, (void *)&ttkStubs);
278 
279     return TCL_OK;
280 }
281 
282 /*EOF*/
283