/* Ttk_GetStateMapFromObj -- * Returns a Ttk_StateMap from a Tcl_Obj*. * Since a Ttk_StateMap is just a specially-formatted Tcl_Obj, * this basically just checks for errors. */ Ttk_StateMap Ttk_GetStateMapFromObj( Tcl_Interp *interp, /* Where to leave error messages; may be NULL */ Tcl_Obj *mapObj) /* State map */ { Tcl_Obj **specs; int nSpecs; int j, status; status = Tcl_ListObjGetElements(interp, mapObj, &nSpecs, &specs); if (status != TCL_OK) return NULL; if (nSpecs % 2 != 0) { if (interp) Tcl_SetResult(interp, "State map must have an even number of elements", TCL_STATIC); return 0; } for (j = 0; j < nSpecs; j += 2) { Ttk_StateSpec spec; if (Ttk_GetStateSpecFromObj(interp, specs[j], &spec) != TCL_OK) return NULL; } return mapObj; }
/* * Tk_StateMapLookup -- * * A state map is a paired list of StateSpec / value pairs. * Returns the value corresponding to the first matching state * specification, or NULL if not found or an error occurs. */ Tcl_Obj *Ttk_StateMapLookup( Tcl_Interp *interp, /* Where to leave error messages; may be NULL */ Ttk_StateMap map, /* State map */ Ttk_State state) /* State to look up */ { Tcl_Obj **specs; int nSpecs; int j, status; status = Tcl_ListObjGetElements(interp, map, &nSpecs, &specs); if (status != TCL_OK) return NULL; for (j = 0; j < nSpecs; j += 2) { Ttk_StateSpec spec; status = Ttk_GetStateSpecFromObj(interp, specs[j], &spec); if (status != TCL_OK) return NULL; if (Ttk_StateMatches(state, &spec)) return specs[j+1]; } if (interp) { Tcl_ResetResult(interp); Tcl_AppendResult(interp, "No match in state map", NULL); } return NULL; }
/* Ttk_GetStateMapFromObj -- * Returns a Ttk_StateMap from a Tcl_Obj*. * Since a Ttk_StateMap is just a specially-formatted Tcl_Obj, * this basically just checks for errors. */ Ttk_StateMap Ttk_GetStateMapFromObj( Tcl_Interp *interp, /* Where to leave error messages; may be NULL */ Tcl_Obj *mapObj) /* State map */ { Tcl_Obj **specs; int nSpecs; int j, status; status = Tcl_ListObjGetElements(interp, mapObj, &nSpecs, &specs); if (status != TCL_OK) return NULL; if (nSpecs % 2 != 0) { if (interp) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "State map must have an even number of elements", -1)); Tcl_SetErrorCode(interp, "TTK", "VALUE", "STATEMAP", NULL); } return 0; } for (j = 0; j < nSpecs; j += 2) { Ttk_StateSpec spec; if (Ttk_GetStateSpecFromObj(interp, specs[j], &spec) != TCL_OK) return NULL; } return mapObj; }
/* * Tk_StateMapLookup -- * * A state map is a paired list of StateSpec / value pairs. * Returns the value corresponding to the first matching state * specification, or NULL if not found or an error occurs. */ Tcl_Obj *Ttk_StateMapLookup( Tcl_Interp *interp, /* Where to leave error messages; may be NULL */ Ttk_StateMap map, /* State map */ Ttk_State state) /* State to look up */ { Tcl_Obj **specs; int nSpecs; int j, status; status = Tcl_ListObjGetElements(interp, map, &nSpecs, &specs); if (status != TCL_OK) return NULL; for (j = 0; j < nSpecs; j += 2) { Ttk_StateSpec spec; status = Ttk_GetStateSpecFromObj(interp, specs[j], &spec); if (status != TCL_OK) return NULL; if (Ttk_StateMatches(state, &spec)) return specs[j+1]; } if (interp) { Tcl_SetObjResult(interp, Tcl_NewStringObj("No match in state map", -1)); Tcl_SetErrorCode(interp, "TTK", "STATE", "UNMATCHED", NULL); } 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; }
/* TtkGetImageSpec -- * Constructs a Ttk_ImageSpec * from a Tcl_Obj *. * Result must be released using TtkFreeImageSpec. * * TODO: Need a variant of this that takes a user-specified ImageChanged proc */ Ttk_ImageSpec * TtkGetImageSpec(Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr) { Ttk_ImageSpec *imageSpec = 0; int i = 0, n = 0, objc; Tcl_Obj **objv; imageSpec = (Ttk_ImageSpec *)ckalloc(sizeof(*imageSpec)); imageSpec->baseImage = 0; imageSpec->mapCount = 0; imageSpec->states = 0; imageSpec->images = 0; if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) { goto error; } if ((objc % 2) != 1) { if (interp) { Tcl_SetResult(interp, "image specification must contain an odd number of elements", TCL_STATIC); } goto error; } n = (objc - 1) / 2; imageSpec->states = (Ttk_StateSpec*)ckalloc(n * sizeof(Ttk_StateSpec)); imageSpec->images = (Tk_Image*)ckalloc(n * sizeof(Tk_Image *)); /* Get base image: */ imageSpec->baseImage = Tk_GetImage( interp, tkwin, Tcl_GetString(objv[0]), NullImageChanged, NULL); if (!imageSpec->baseImage) { goto error; } /* Extract state and image specifications: */ for (i = 0; i < n; ++i) { Tcl_Obj *stateSpec = objv[2*i + 1]; const char *imageName = Tcl_GetString(objv[2*i + 2]); Ttk_StateSpec state; if (Ttk_GetStateSpecFromObj(interp, stateSpec, &state) != TCL_OK) { goto error; } imageSpec->states[i] = state; imageSpec->images[i] = Tk_GetImage( interp, tkwin, imageName, NullImageChanged, NULL); if (imageSpec->images[i] == NULL) { goto error; } imageSpec->mapCount = i+1; } return imageSpec; error: TtkFreeImageSpec(imageSpec); return NULL; }