/* * Register a new layout specification with a style. * @@@ TODO: Make sure layoutName is not ".", root style must not have a layout */ MODULE_SCOPE void Ttk_RegisterLayoutTemplate( Ttk_Theme theme, /* Target theme */ const char *layoutName, /* Name of new layout */ Ttk_LayoutTemplate layoutTemplate) /* Template */ { Ttk_Style style = Ttk_GetStyle(theme, layoutName); if (style->layoutTemplate) { Ttk_FreeLayoutTemplate(style->layoutTemplate); } style->layoutTemplate = layoutTemplate; }
/* + style configure $style -option ?value... */ static int StyleConfigureCmd( ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { StylePackageData *pkgPtr = clientData; Ttk_Theme theme = pkgPtr->currentTheme; const char *styleName; Style *stylePtr; int i; if (objc < 3) { usage: Tcl_WrongNumArgs(interp,2,objv,"style ?-option ?value...??"); return TCL_ERROR; } styleName = Tcl_GetString(objv[2]); stylePtr = Ttk_GetStyle(theme, styleName); if (objc == 3) { /* style default $styleName */ Tcl_SetObjResult(interp, HashTableToDict(&stylePtr->defaultsTable)); return TCL_OK; } else if (objc == 4) { /* style default $styleName -option */ const char *optionName = Tcl_GetString(objv[3]); Tcl_HashEntry *entryPtr = Tcl_FindHashEntry(&stylePtr->defaultsTable, optionName); if (entryPtr) { Tcl_SetObjResult(interp, (Tcl_Obj*)Tcl_GetHashValue(entryPtr)); } return TCL_OK; } else if (objc % 2 != 1) { goto usage; } for (i = 3; i < objc; i += 2) { const char *optionName = Tcl_GetString(objv[i]); Tcl_Obj *value = objv[i+1]; Tcl_HashEntry *entryPtr; int newEntry; entryPtr = Tcl_CreateHashEntry( &stylePtr->defaultsTable,optionName,&newEntry); Tcl_IncrRefCount(value); if (!newEntry) { Tcl_DecrRefCount((Tcl_Obj*)Tcl_GetHashValue(entryPtr)); } Tcl_SetHashValue(entryPtr, value); } ThemeChanged(pkgPtr); return TCL_OK; }
/* FindLayoutTemplate -- * Locate a layout template in the layout table, checking * generic names to specific names first, then looking for * the full name in the parent theme. */ Ttk_LayoutTemplate Ttk_FindLayoutTemplate(Ttk_Theme themePtr, const char *layoutName) { while (themePtr) { Ttk_Style stylePtr = Ttk_GetStyle(themePtr, layoutName); while (stylePtr) { if (stylePtr->layoutTemplate) { return stylePtr->layoutTemplate; } stylePtr = stylePtr->parentStyle; } themePtr = themePtr->parentPtr; } return NULL; }
/* + style lookup $style -option ?statespec? ?defaultValue? */ static int StyleLookupCmd( ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { StylePackageData *pkgPtr = clientData; Ttk_Theme theme = pkgPtr->currentTheme; Ttk_Style style = NULL; const char *optionName; Ttk_State state = 0ul; Tcl_Obj *result; if (objc < 4 || objc > 6) { Tcl_WrongNumArgs(interp, 2, objv, "style -option ?state? ?default?"); return TCL_ERROR; } style = Ttk_GetStyle(theme, Tcl_GetString(objv[2])); if (!style) { return TCL_ERROR; } optionName = Tcl_GetString(objv[3]); if (objc >= 5) { Ttk_StateSpec stateSpec; /* @@@ SB: Ttk_GetStateFromObj(); 'offbits' spec is ignored */ if (Ttk_GetStateSpecFromObj(interp, objv[4], &stateSpec) != TCL_OK) { return TCL_ERROR; } state = stateSpec.onbits; } result = Ttk_QueryStyle(style, NULL,NULL, optionName, state); if (result == NULL && objc >= 6) { /* Use caller-supplied fallback */ result = objv[5]; } if (result) { Tcl_SetObjResult(interp, result); } return TCL_OK; }
/* * Ttk_GetStyle -- * Look up a Style from a Theme, create new style if not found. */ Ttk_Style Ttk_GetStyle(Ttk_Theme themePtr, const char *styleName) { Tcl_HashEntry *entryPtr; int newStyle; entryPtr = Tcl_CreateHashEntry(&themePtr->styleTable, styleName, &newStyle); if (newStyle) { Ttk_Style stylePtr = NewStyle(); const char *dot = strchr(styleName, '.'); if (dot) { stylePtr->parentStyle = Ttk_GetStyle(themePtr, dot + 1); } else { stylePtr->parentStyle = themePtr->rootStyle; } stylePtr->styleName = Tcl_GetHashKey(&themePtr->styleTable, entryPtr); stylePtr->cache = stylePtr->parentStyle->cache; Tcl_SetHashValue(entryPtr, (ClientData)stylePtr); return stylePtr; } return (Style*)Tcl_GetHashValue(entryPtr); }
/* + style map $style ? -resource statemap ... ? * * Note that resource names are unconstrained; the Style * doesn't know what resources individual elements may use. */ static int StyleMapCmd( ClientData clientData, /* Master StylePackageData pointer */ Tcl_Interp *interp, /* Current interpreter */ int objc, /* Number of arguments */ Tcl_Obj *const objv[]) /* Argument objects */ { StylePackageData *pkgPtr = clientData; Ttk_Theme theme = pkgPtr->currentTheme; const char *styleName; Style *stylePtr; int i; if (objc < 3) { usage: Tcl_WrongNumArgs(interp,2,objv,"style ?-option ?value...??"); return TCL_ERROR; } styleName = Tcl_GetString(objv[2]); stylePtr = Ttk_GetStyle(theme, styleName); /* NOTE: StateMaps are actually Tcl_Obj *s, so HashTableToDict works * for settingsTable. */ if (objc == 3) { /* style map $styleName */ Tcl_SetObjResult(interp, HashTableToDict(&stylePtr->settingsTable)); return TCL_OK; } else if (objc == 4) { /* style map $styleName -option */ const char *optionName = Tcl_GetString(objv[3]); Tcl_HashEntry *entryPtr = Tcl_FindHashEntry(&stylePtr->settingsTable, optionName); if (entryPtr) { Tcl_SetObjResult(interp, (Tcl_Obj*)Tcl_GetHashValue(entryPtr)); } return TCL_OK; } else if (objc % 2 != 1) { goto usage; } for (i = 3; i < objc; i += 2) { const char *optionName = Tcl_GetString(objv[i]); Tcl_Obj *stateMap = objv[i+1]; Tcl_HashEntry *entryPtr; int newEntry; /* Make sure 'stateMap' is legal: * (@@@ SHOULD: check for valid resource values as well, * but we don't know what types they should be at this level.) */ if (!Ttk_GetStateMapFromObj(interp, stateMap)) return TCL_ERROR; entryPtr = Tcl_CreateHashEntry( &stylePtr->settingsTable,optionName,&newEntry); Tcl_IncrRefCount(stateMap); if (!newEntry) { Tcl_DecrRefCount((Tcl_Obj*)Tcl_GetHashValue(entryPtr)); } Tcl_SetHashValue(entryPtr, stateMap); } ThemeChanged(pkgPtr); return TCL_OK; }