/* + style layout name ?spec? */ static int StyleLayoutCmd( ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { StylePackageData *pkgPtr = clientData; Ttk_Theme theme = pkgPtr->currentTheme; const char *layoutName; Ttk_LayoutTemplate layoutTemplate; if (objc < 3 || objc > 4) { Tcl_WrongNumArgs(interp, 2, objv, "name ?spec?"); return TCL_ERROR; } layoutName = Tcl_GetString(objv[2]); if (objc == 3) { layoutTemplate = Ttk_FindLayoutTemplate(theme, layoutName); if (!layoutTemplate) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "Layout %s not found", layoutName)); Tcl_SetErrorCode(interp, "TTK", "LOOKUP", "LAYOUT", layoutName, NULL); return TCL_ERROR; } Tcl_SetObjResult(interp, Ttk_UnparseLayoutTemplate(layoutTemplate)); } else { layoutTemplate = Ttk_ParseLayoutTemplate(interp, objv[3]); if (!layoutTemplate) { return TCL_ERROR; } Ttk_RegisterLayoutTemplate(theme, layoutName, layoutTemplate); ThemeChanged(pkgPtr); } return TCL_OK; }
Ttk_LayoutTemplate Ttk_ParseLayoutTemplate(Tcl_Interp *interp, Tcl_Obj *objPtr) { enum { OP_SIDE, OP_STICKY, OP_EXPAND, OP_BORDER, OP_UNIT, OP_CHILDREN }; static const char *optStrings[] = { "-side", "-sticky", "-expand", "-border", "-unit", "-children", 0 }; int i = 0, objc; Tcl_Obj **objv; Ttk_TemplateNode *head = 0, *tail = 0; if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) return 0; while (i < objc) { char *elementName = Tcl_GetString(objv[i]); unsigned flags = 0x0, sticky = TTK_FILL_BOTH; Tcl_Obj *childSpec = 0; /* * Parse options: */ ++i; while (i < objc) { const char *optName = Tcl_GetString(objv[i]); int option, value; if (optName[0] != '-') break; if (Tcl_GetIndexFromObj( interp, objv[i], optStrings, "option", 0, &option) != TCL_OK) { goto error; } if (++i >= objc) { Tcl_ResetResult(interp); Tcl_AppendResult(interp, "Missing value for option ",Tcl_GetString(objv[i-1]), NULL); goto error; } switch (option) { case OP_SIDE: /* <<NOTE-PACKSIDE>> */ if (Tcl_GetIndexFromObj(interp, objv[i], packSideStrings, "side", 0, &value) != TCL_OK) { goto error; } flags |= (TTK_PACK_LEFT << value); break; case OP_STICKY: if (Ttk_GetStickyFromObj(interp,objv[i],&sticky) != TCL_OK) goto error; break; case OP_EXPAND: if (Tcl_GetBooleanFromObj(interp,objv[i],&value) != TCL_OK) goto error; if (value) flags |= TTK_EXPAND; break; case OP_BORDER: if (Tcl_GetBooleanFromObj(interp,objv[i],&value) != TCL_OK) goto error; if (value) flags |= TTK_BORDER; break; case OP_UNIT: if (Tcl_GetBooleanFromObj(interp,objv[i],&value) != TCL_OK) goto error; if (value) flags |= TTK_UNIT; break; case OP_CHILDREN: childSpec = objv[i]; break; } ++i; } /* * Build new node: */ if (tail) { tail->next = Ttk_NewTemplateNode(elementName, flags | sticky); tail = tail->next; } else { head = tail = Ttk_NewTemplateNode(elementName, flags | sticky); } if (childSpec) { tail->child = Ttk_ParseLayoutTemplate(interp, childSpec); if (!tail->child) { goto error; } } } return head; error: Ttk_FreeLayoutTemplate(head); return 0; }