/* Ttk_CloneElement -- element factory procedure. * (style element create $name) "from" $theme ?$element? */ static int Ttk_CloneElement( Tcl_Interp *interp, void *clientData, Ttk_Theme theme, const char *elementName, int objc, Tcl_Obj *const objv[]) { Ttk_Theme fromTheme; Ttk_ElementClass *fromElement; if (objc <= 0 || objc > 2) { Tcl_WrongNumArgs(interp, 0, objv, "theme ?element?"); return TCL_ERROR; } fromTheme = Ttk_GetTheme(interp, Tcl_GetString(objv[0])); if (!fromTheme) { return TCL_ERROR; } if (objc == 2) { fromElement = Ttk_GetElement(fromTheme, Tcl_GetString(objv[1])); } else { fromElement = Ttk_GetElement(fromTheme, elementName); } if (!fromElement) { return TCL_ERROR; } if (Ttk_RegisterElement(interp, theme, elementName, fromElement->specPtr, fromElement->clientData) == NULL) { return TCL_ERROR; } return TCL_OK; }
/* + style element options $element -- * Return list of element options for specified element */ static int StyleElementOptionsCmd( ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { StylePackageData *pkgPtr = clientData; Ttk_Theme theme = pkgPtr->currentTheme; const char *elementName; Ttk_ElementClass *elementClass; if (objc != 4) { Tcl_WrongNumArgs(interp, 3, objv, "element"); return TCL_ERROR; } elementName = Tcl_GetString(objv[3]); elementClass = Ttk_GetElement(theme, elementName); if (elementClass) { Ttk_ElementSpec *specPtr = elementClass->specPtr; Ttk_ElementOptionSpec *option = specPtr->options; Tcl_Obj *result = Tcl_NewListObj(0,0); while (option->optionName) { Tcl_ListObjAppendElement( interp, result, Tcl_NewStringObj(option->optionName,-1)); ++option; } Tcl_SetObjResult(interp, result); return TCL_OK; } Tcl_SetObjResult(interp, Tcl_ObjPrintf( "element %s not found", elementName)); Tcl_SetErrorCode(interp, "TTK", "LOOKUP", "ELEMENT", elementName, NULL); return TCL_ERROR; }
/* InstantiateLayout -- * Create a layout tree from a template. */ static Ttk_LayoutNode * Ttk_InstantiateLayout(Ttk_Theme theme, Ttk_TemplateNode *op) { Ttk_ElementImpl elementImpl = Ttk_GetElement(theme, op->name); Ttk_LayoutNode *node = Ttk_NewLayoutNode(op->flags, elementImpl); if (op->next) { node->next = Ttk_InstantiateLayout(theme,op->next); } if (op->child) { node->child = Ttk_InstantiateLayout(theme,op->child); } return node; }
/* * Ttk_GetElement -- * Look up an element implementation by name in a given theme. * If not found, try generic element names in this theme, then * repeat the lookups in the parent theme. * If not found, return the null element. */ Ttk_ElementImpl Ttk_GetElement(Ttk_Theme themePtr, const char *elementName) { Tcl_HashEntry *entryPtr; const char *dot = elementName; /* * Check if element has already been registered: */ entryPtr = Tcl_FindHashEntry(&themePtr->elementTable, elementName); if (entryPtr) { return (Ttk_ElementImpl)Tcl_GetHashValue(entryPtr); } /* * Check generic names: */ while (!entryPtr && ((dot = strchr(dot, '.')) != NULL)) { dot++; entryPtr = Tcl_FindHashEntry(&themePtr->elementTable, dot); } if (entryPtr) { return (ElementImpl *)Tcl_GetHashValue(entryPtr); } /* * Check parent theme: */ if (themePtr->parentPtr) { return Ttk_GetElement(themePtr->parentPtr, elementName); } /* * Not found, and this is the root theme; return null element, "". * (@@@ SHOULD: signal a background error) */ entryPtr = Tcl_FindHashEntry(&themePtr->elementTable, ""); /* ASSERT: entryPtr != 0 */ return (Ttk_ElementImpl)Tcl_GetHashValue(entryPtr); }