diff options
-rw-r--r-- | generic/tkTreeUtils.c | 234 |
1 files changed, 182 insertions, 52 deletions
diff --git a/generic/tkTreeUtils.c b/generic/tkTreeUtils.c index 8120b1b..9b79ffd 100644 --- a/generic/tkTreeUtils.c +++ b/generic/tkTreeUtils.c @@ -5,7 +5,7 @@ * * Copyright (c) 2002-2006 Tim Baker * - * RCS: @(#) $Id: tkTreeUtils.c,v 1.52 2006/11/10 22:33:41 treectrl Exp $ + * RCS: @(#) $Id: tkTreeUtils.c,v 1.53 2006/11/19 23:43:58 treectrl Exp $ */ #include "tkTreeCtrl.h" @@ -4693,6 +4693,37 @@ OptionHax_Forget( /* *---------------------------------------------------------------------- * + * OptionSpec_Find -- + * + * Return a pointer to a name Tk_OptionSpec in a table. + * + * Results: + * Returns a pointer or panics. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +Tk_OptionSpec * +OptionSpec_Find( + Tk_OptionSpec *optionTable, + CONST char *optionName + ) +{ + while (optionTable->type != TK_OPTION_END) { + if (strcmp(optionTable->optionName, optionName) == 0) + return optionTable; + optionTable++; + } + panic("OptionSpec_Find: can't find %s", optionName); + return NULL; +} + +/* + *---------------------------------------------------------------------- + * * PerStateCO_Set -- * PerStateCO_Get -- * PerStateCO_Restore -- @@ -4911,27 +4942,17 @@ PerStateCO_Init( StateFromObjProc proc ) { - Tk_ObjCustomOption *co; - int i; - - for (i = 0; optionTable[i].type != TK_OPTION_END; i++) { - if (strcmp(optionTable[i].optionName, optionName)) - continue; + Tk_OptionSpec *specPtr; - if (optionTable[i].clientData != NULL) - return TCL_OK; + specPtr = OptionSpec_Find(optionTable, optionName); + if (specPtr->type != TK_OPTION_CUSTOM) + panic("PerStateCO_Init: %s is not TK_OPTION_CUSTOM", optionName); + if (specPtr->clientData != NULL) + return TCL_OK; - if (optionTable[i].objOffset < 0) - panic("PerStateCO_Init %s objOffset < 0", optionName); + specPtr->clientData = PerStateCO_Alloc(optionName, typePtr, proc); - /* The Tk custom option record */ - co = PerStateCO_Alloc(optionName, typePtr, proc); - - /* Update the option table */ - optionTable[i].clientData = (ClientData) co; - return TCL_OK; - } - return TCL_ERROR; + return TCL_OK; } #define DEBUG_DYNAMICxxx @@ -5340,50 +5361,44 @@ DynamicCO_Init( * NULL. */ ) { + Tk_OptionSpec *specPtr; DynamicCOClientData *cd; Tk_ObjCustomOption *co; - int i; if (size <= 0) panic("DynamicCO_Init: option %s size=%d", optionName, size); - for (i = 0; optionTable[i].type != TK_OPTION_END; i++) { - if (strcmp(optionTable[i].optionName, optionName)) - continue; + specPtr = OptionSpec_Find(optionTable, optionName); + if (specPtr->type != TK_OPTION_CUSTOM) + panic("DynamicCO_Init: %s is not TK_OPTION_CUSTOM", optionName); + if (specPtr->clientData != NULL) + return TCL_OK; + + /* ClientData for the Tk custom option record */ + cd = (DynamicCOClientData *) ckalloc(sizeof(DynamicCOClientData)); + cd->id = id; + cd->size = size; + cd->objOffset = objOffset; + cd->internalOffset = internalOffset; + cd->custom = custom; + cd->init = init; + + /* The Tk custom option record */ + co = (Tk_ObjCustomOption *) ckalloc(sizeof(Tk_ObjCustomOption)); + co->name = (char *) optionName + 1; + co->setProc = DynamicCO_Set; + co->getProc = DynamicCO_Get; + co->restoreProc = DynamicCO_Restore; + co->freeProc = DynamicCO_Free; + co->clientData = (ClientData) cd; - if (optionTable[i].clientData != NULL) - return TCL_OK; - - if (optionTable[i].type != TK_OPTION_CUSTOM) - panic("DynamicCO_Init: %s is not TK_OPTION_CUSTOM", optionName); - - /* ClientData for the Tk custom option record */ - cd = (DynamicCOClientData *) ckalloc(sizeof(DynamicCOClientData)); - cd->id = id; - cd->size = size; - cd->objOffset = objOffset; - cd->internalOffset = internalOffset; - cd->custom = custom; - cd->init = init; - - /* The Tk custom option record */ - co = (Tk_ObjCustomOption *) ckalloc(sizeof(Tk_ObjCustomOption)); - co->name = (char *) optionName + 1; - co->setProc = DynamicCO_Set; - co->getProc = DynamicCO_Get; - co->restoreProc = DynamicCO_Restore; - co->freeProc = DynamicCO_Free; - co->clientData = (ClientData) cd; - - /* Update the option table */ - optionTable[i].clientData = (ClientData) co; + /* Update the option table */ + specPtr->clientData = co; #ifdef DEBUG_DYNAMIC dbwin("DynamicCO_Init id=%d size=%d objOffset=%d internalOffset=%d custom->name=%s\n", id, size, objOffset, internalOffset, custom->name); #endif - return TCL_OK; - } - return TCL_ERROR; + return TCL_OK; } /* @@ -5784,3 +5799,118 @@ Tk_ObjCustomOption styleCO = (ClientData) NULL }; +/* + *---------------------------------------------------------------------- + * + * BooleanFlagCO_Set -- + * BooleanFlagCO_Get -- + * BooleanFlagCO_Restore -- + * + * These procedures implement a TK_OPTION_CUSTOM where the custom + * option is a boolean value whose internal rep is a single bit of + * an int rather than the entire int. + * + * Results: + * None. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +static int +BooleanFlagCO_Set( + ClientData clientData, + Tcl_Interp *interp, + Tk_Window tkwin, + Tcl_Obj **value, + char *recordPtr, + int internalOffset, + char *saveInternalPtr, + int flags + ) +{ + int theFlag = (int) clientData; + int new, *internalPtr; + + if (internalOffset >= 0) + internalPtr = (int *) (recordPtr + internalOffset); + else + internalPtr = NULL; + + if (Tcl_GetBooleanFromObj(interp, (*value), &new) != TCL_OK) + return TCL_ERROR; + + if (internalPtr != NULL) { + *((int *) saveInternalPtr) = *internalPtr; + if (new) + *internalPtr |= theFlag; + else + *internalPtr &= ~theFlag; + } + + return TCL_OK; +} + +static Tcl_Obj * +BooleanFlagCO_Get( + ClientData clientData, + Tk_Window tkwin, + char *recordPtr, + int internalOffset + ) +{ + int theFlag = (int) clientData; + int value = *(int *) (recordPtr + internalOffset); + + return Tcl_NewBooleanObj(value & theFlag); +} + +static void +BooleanFlagCO_Restore( + ClientData clientData, + Tk_Window tkwin, + char *internalPtr, + char *saveInternalPtr + ) +{ + int theFlag = (int) clientData; + int value = *(int *) saveInternalPtr; + + if (value & theFlag) + *((int *) internalPtr) |= theFlag; + else + *((int *) internalPtr) &= ~theFlag; +} + +int +BooleanFlagCO_Init( + Tk_OptionSpec *optionTable, + CONST char *optionName, + int theFlag + ) +{ + Tk_OptionSpec *specPtr; + Tk_ObjCustomOption *co; + + specPtr = OptionSpec_Find(optionTable, optionName); + if (specPtr->type != TK_OPTION_CUSTOM) + panic("IntegerCO_Init: %s is not TK_OPTION_CUSTOM", optionName); + if (specPtr->clientData != NULL) + return TCL_OK; + + /* The Tk custom option record */ + co = (Tk_ObjCustomOption *) ckalloc(sizeof(Tk_ObjCustomOption)); + co->name = "boolean"; + co->setProc = BooleanFlagCO_Set; + co->getProc = BooleanFlagCO_Get; + co->restoreProc = BooleanFlagCO_Restore; + co->freeProc = NULL; + co->clientData = (ClientData) theFlag; + + specPtr->clientData = co; + + return TCL_OK; +} + |