diff options
author | treectrl <treectrl> | 2006-11-30 03:29:44 (GMT) |
---|---|---|
committer | treectrl <treectrl> | 2006-11-30 03:29:44 (GMT) |
commit | d06d46b9d793a14d301e135e6fd76a0c77bbb7b5 (patch) | |
tree | 4541a1618e4849901c37e986a011d8301e69c2f2 /generic | |
parent | 6137f8797b9b058e0cf9b93cf6b8708e42aeacde (diff) | |
download | tktreectrl-d06d46b9d793a14d301e135e6fd76a0c77bbb7b5.zip tktreectrl-d06d46b9d793a14d301e135e6fd76a0c77bbb7b5.tar.gz tktreectrl-d06d46b9d793a14d301e135e6fd76a0c77bbb7b5.tar.bz2 |
The item option -button may now be "auto" in which case a button is drawn only when the item has a child whose -visible option is true.
Diffstat (limited to 'generic')
-rw-r--r-- | generic/tkTreeCtrl.c | 7 | ||||
-rw-r--r-- | generic/tkTreeCtrl.h | 6 | ||||
-rw-r--r-- | generic/tkTreeItem.c | 87 | ||||
-rw-r--r-- | generic/tkTreeUtils.c | 146 |
4 files changed, 212 insertions, 34 deletions
diff --git a/generic/tkTreeCtrl.c b/generic/tkTreeCtrl.c index 4bd724f..a2ba9a7 100644 --- a/generic/tkTreeCtrl.c +++ b/generic/tkTreeCtrl.c @@ -7,7 +7,7 @@ * Copyright (c) 2002-2003 Christian Krone * Copyright (c) 2003-2005 ActiveState, a division of Sophos * - * RCS: @(#) $Id: tkTreeCtrl.c,v 1.89 2006/11/21 01:56:24 treectrl Exp $ + * RCS: @(#) $Id: tkTreeCtrl.c,v 1.90 2006/11/30 03:29:44 treectrl Exp $ */ #include "tkTreeCtrl.h" @@ -914,10 +914,9 @@ static int TreeWidgetCmd( (x < tree->columnTreeLeft + depth * tree->useIndent)) { int column = (x - tree->columnTreeLeft) / tree->useIndent + 1; if (column == depth) { - if (tree->showButtons && TreeItem_GetButton(tree, item)) + if (TreeItem_HasButton(tree, item)) sprintf(buf + strlen(buf), " button"); - } - else if (tree->showLines) { + } else if (tree->showLines) { TreeItem sibling; do { item = TreeItem_GetParent(tree, item); diff --git a/generic/tkTreeCtrl.h b/generic/tkTreeCtrl.h index 9df5446..b0fee04 100644 --- a/generic/tkTreeCtrl.h +++ b/generic/tkTreeCtrl.h @@ -7,7 +7,7 @@ * Copyright (c) 2002-2003 Christian Krone * Copyright (c) 2003 ActiveState Corporation * - * RCS: @(#) $Id: tkTreeCtrl.h,v 1.76 2006/11/27 02:04:40 treectrl Exp $ + * RCS: @(#) $Id: tkTreeCtrl.h,v 1.77 2006/11/30 03:29:44 treectrl Exp $ */ #include "tkPort.h" @@ -487,7 +487,7 @@ extern int TreeItem_ChangeState(TreeCtrl *tree, TreeItem item_, int stateOff, in extern void TreeItem_UndefineState(TreeCtrl *tree, TreeItem item_, int state); -extern int TreeItem_GetButton(TreeCtrl *tree, TreeItem item_); +extern int TreeItem_HasButton(TreeCtrl *tree, TreeItem item_); extern int TreeItem_GetDepth(TreeCtrl *tree, TreeItem item_); extern int TreeItem_GetID(TreeCtrl *tree, TreeItem item_); extern int TreeItem_SetID(TreeCtrl *tree, TreeItem item_, int id); @@ -1053,6 +1053,8 @@ extern int DynamicCO_Init(Tk_OptionSpec *optionTable, CONST char *optionName, extern int BooleanFlagCO_Init(Tk_OptionSpec *optionTable, CONST char *optionName, int theFlag); +extern int ItemButtonCO_Init(Tk_OptionSpec *optionTable, CONST char *optionName, + int flag1, int flag2); extern Tk_ObjCustomOption pixelsCO; extern Tk_ObjCustomOption stringCO; diff --git a/generic/tkTreeItem.c b/generic/tkTreeItem.c index 87debaf..caa368d 100644 --- a/generic/tkTreeItem.c +++ b/generic/tkTreeItem.c @@ -5,7 +5,7 @@ * * Copyright (c) 2002-2006 Tim Baker * - * RCS: @(#) $Id: tkTreeItem.c,v 1.94 2006/11/25 20:25:28 treectrl Exp $ + * RCS: @(#) $Id: tkTreeItem.c,v 1.95 2006/11/30 03:29:44 treectrl Exp $ */ #include "tkTreeCtrl.h" @@ -57,8 +57,9 @@ struct TreeItem_ { * need to redo them. Also indicates * we have an entry in * TreeCtrl.itemSpansHash. */ -#define ITEM_FLAG_BUTTON 0x0008 /* -button */ -#define ITEM_FLAG_VISIBLE 0x0010 /* -visible */ +#define ITEM_FLAG_BUTTON 0x0008 /* -button true */ +#define ITEM_FLAG_BUTTON_AUTO 0x0010 /* -button auto */ +#define ITEM_FLAG_VISIBLE 0x0020 /* -visible */ int flags; TagInfo *tagInfo; /* Tags. May be NULL. */ }; @@ -73,7 +74,6 @@ static CONST char *ItemUid = "Item", *ItemColumnUid = "ItemColumn"; #define IS_ALL(i) ((i) == ITEM_ALL) #define IS_DELETED(i) (((i)->flags & ITEM_FLAG_DELETED) != 0) -#define HAS_BUTTON(i) (((i)->flags & ITEM_FLAG_BUTTON) != 0) #define IS_VISIBLE(i) (((i)->flags & ITEM_FLAG_VISIBLE) != 0) /* @@ -817,8 +817,7 @@ TreeItem_ChangeState( } /* This item has a button */ - if (HAS_BUTTON(item) && tree->showButtons - && (!IS_ROOT(item) || tree->showRootButton)) { + if (TreeItem_HasButton(tree, item)) { Tk_Image image1, image2; Pixmap bitmap1, bitmap2; @@ -941,14 +940,15 @@ TreeItem_UndefineState( /* *---------------------------------------------------------------------- * - * TreeItem_GetButton -- + * TreeItem_HasButton -- * - * Return the value of the -button configuration option for an - * Item. + * Determine whether an item should have a button displayed next to + * it. This considers the value of the -button configuration option + * for an item as well as the treectrl options -showbuttons and + * -showrootbutton. * * Results: - * Boolean indicating whether the Item could have a button - * displayed next to it (-showbuttons must also be set). + * None. * * Side effects: * None. @@ -957,12 +957,24 @@ TreeItem_UndefineState( */ int -TreeItem_GetButton( +TreeItem_HasButton( TreeCtrl *tree, /* Widget info. */ TreeItem item /* Item token. */ ) { - return HAS_BUTTON(item); + if (!tree->showButtons || (IS_ROOT(item) && !tree->showRootButton)) + return 0; + if (item->flags & ITEM_FLAG_BUTTON) + return 1; + if (item->flags & ITEM_FLAG_BUTTON_AUTO) { + TreeItem child = item->firstChild; + while (child != NULL) { + if (IS_VISIBLE(child)) + return 1; + child = child->nextSibling; + } + } + return 0; } /* @@ -3300,8 +3312,7 @@ int TreeItem_Height( useHeight = Item_HeightOfStyles(tree, item); /* Can't have less height than our button */ - if (tree->showButtons && HAS_BUTTON(item) && - (!IS_ROOT(item) || tree->showRootButton)) { + if (TreeItem_HasButton(tree, item)) { buttonHeight = ButtonHeight(tree, item->state); } @@ -4282,9 +4293,7 @@ TreeItem_DrawButton( Tk_Image image; Pixmap bitmap; - if (!HAS_BUTTON(item)) - return; - if (IS_ROOT(item) && !tree->showRootButton) + if (!TreeItem_HasButton(tree, item)) return; #if defined(MAC_TCL) || defined(MAC_OSX_TK) @@ -4685,17 +4694,21 @@ static int Item_Configure( Tree_DInfoChanged(tree, DINFO_REDO_RANGES); } - if (mask & ITEM_CONF_BUTTON) + if (mask & ITEM_CONF_BUTTON) { if (tree->columnTree != NULL) Tree_InvalidateItemDInfo(tree, tree->columnTree, item, NULL); + } if ((mask & ITEM_CONF_VISIBLE) && (IS_VISIBLE(item) != lastVisible)) { - /* May change the width of any column */ + + /* Changing the visibility of an item can change the width of + * any column. This is due to column expansion (this item may + * be the widest item in the column) and spans > 1. */ Tree_InvalidateColumnWidth(tree, NULL); /* If this is the last child, redraw the lines of the previous * sibling and all of its descendants because the line from - * the previous sibling to us is appearing/disappearing */ + * the previous sibling to us is appearing/disappearing. */ if ((item->prevSibling != NULL) && (item->nextSibling == NULL) && tree->showLines && (tree->columnTree != NULL)) { @@ -4707,6 +4720,14 @@ static int Item_Configure( last); } + /* Redraw the parent if the parent has "-button auto". */ + if (item->parent != NULL && + (item->parent->flags & ITEM_FLAG_BUTTON_AUTO) != 0 && + tree->showButtons && tree->columnTree != NULL) { + Tree_InvalidateItemDInfo(tree, tree->columnTree, item->parent, + NULL); + } + tree->updateIndex = 1; Tree_DInfoChanged(tree, DINFO_REDO_RANGES | DINFO_REDO_SELECTION); } @@ -4768,11 +4789,22 @@ ItemCreateCmd( } switch (index) { case OPT_BUTTON: - if (Tcl_GetBooleanFromObj(interp, objv[i + 1], &button) - != TCL_OK) { - return TCL_ERROR; + { + int length; + char *s = Tcl_GetStringFromObj(objv[i + 1], &length); + if (s[0] == 'a' && strncmp(s, "auto", length) == 0) { + button = ITEM_FLAG_BUTTON_AUTO; + } else { + if (Tcl_GetBooleanFromObj(interp, objv[i + 1], &button) != TCL_OK) { + FormatResult(interp, "expected boolean or auto but got \"%s\"", s); + return TCL_ERROR; + } + if (button) { + button = ITEM_FLAG_BUTTON; + } } break; + } case OPT_COUNT: if (Tcl_GetIntFromObj(interp, objv[i + 1], &count) != TCL_OK) return TCL_ERROR; @@ -4852,8 +4884,8 @@ ItemCreateCmd( for (i = 0; i < count; i++) { item = Item_Alloc(tree); - if (button) item->flags |= ITEM_FLAG_BUTTON; - else item->flags &= ~ITEM_FLAG_BUTTON; + item->flags &= ~(ITEM_FLAG_BUTTON | ITEM_FLAG_BUTTON_AUTO); + item->flags |= button; if (visible) item->flags |= ITEM_FLAG_VISIBLE; else item->flags &= ~ITEM_FLAG_VISIBLE; if (open) item->state |= STATE_OPEN; @@ -8589,7 +8621,8 @@ TreeItem_Init( TreeCtrl *tree /* Widget info. */ ) { - BooleanFlagCO_Init(itemOptionSpecs, "-button", ITEM_FLAG_BUTTON); + ItemButtonCO_Init(itemOptionSpecs, "-button", ITEM_FLAG_BUTTON, + ITEM_FLAG_BUTTON_AUTO); BooleanFlagCO_Init(itemOptionSpecs, "-visible", ITEM_FLAG_VISIBLE); tree->itemOptionTable = Tk_CreateOptionTable(tree->interp, itemOptionSpecs); diff --git a/generic/tkTreeUtils.c b/generic/tkTreeUtils.c index 5df3261..4217ed7 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.54 2006/11/22 03:34:05 treectrl Exp $ + * RCS: @(#) $Id: tkTreeUtils.c,v 1.55 2006/11/30 03:29:44 treectrl Exp $ */ #include "tkTreeCtrl.h" @@ -5966,3 +5966,147 @@ BooleanFlagCO_Init( return TCL_OK; } +/* + *---------------------------------------------------------------------- + * + * ItemButtonCO_Set -- + * ItemButtonCO_Get -- + * ItemButtonCO_Restore -- + * + * These procedures implement a TK_OPTION_CUSTOM where the custom + * option is a boolean value or "auto"; the internal rep is two + * bits of an int: one bit for the boolean, and one for "auto". + * This is used for the item option -button. + * + * Results: + * None. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +struct ItemButtonCOClientData { + int flag1; /* Bit to set when object is "true". */ + int flag2; /* Bit to set when object is "auto". */ +}; + +static int +ItemButtonCO_Set( + ClientData clientData, + Tcl_Interp *interp, + Tk_Window tkwin, + Tcl_Obj **value, + char *recordPtr, + int internalOffset, + char *saveInternalPtr, + int flags + ) +{ + struct ItemButtonCOClientData *cd = clientData; + int new, *internalPtr, on, off; + char *s; + int length; + + if (internalOffset >= 0) + internalPtr = (int *) (recordPtr + internalOffset); + else + internalPtr = NULL; + + s = Tcl_GetStringFromObj((*value), &length); + if (s[0] == 'a' && strncmp(s, "auto", length) == 0) { + on = cd->flag2; + off = cd->flag1; + } else { + if (Tcl_GetBooleanFromObj(interp, (*value), &new) != TCL_OK) { + FormatResult(interp, "expected boolean or auto but got \"%s\"", s); + return TCL_ERROR; + } + if (new) { + on = cd->flag1; + off = cd->flag2; + } else { + on = 0; + off = cd->flag1 | cd->flag2; + } + } + + if (internalPtr != NULL) { + *((int *) saveInternalPtr) = *internalPtr; + *internalPtr |= on; + *internalPtr &= ~off; + } + + return TCL_OK; +} + +static Tcl_Obj * +ItemButtonCO_Get( + ClientData clientData, + Tk_Window tkwin, + char *recordPtr, + int internalOffset + ) +{ + struct ItemButtonCOClientData *cd = clientData; + int value = *(int *) (recordPtr + internalOffset); + + if (value & cd->flag2) + return Tcl_NewStringObj("auto", -1); + return Tcl_NewBooleanObj((value & cd->flag2) != 0); +} + +static void +ItemButtonCO_Restore( + ClientData clientData, + Tk_Window tkwin, + char *internalPtr, + char *saveInternalPtr + ) +{ + struct ItemButtonCOClientData *cd = clientData; + int value = *(int *) saveInternalPtr; + + *((int *) internalPtr) &= ~(cd->flag1 | cd->flag2); + *((int *) internalPtr) |= value & (cd->flag1 | cd->flag2); +} + +int +ItemButtonCO_Init( + Tk_OptionSpec *optionTable, + CONST char *optionName, + int flag1, + int flag2 + ) +{ + Tk_OptionSpec *specPtr; + Tk_ObjCustomOption *co; + struct ItemButtonCOClientData *cd; + + 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; + + /* ClientData for the Tk custom option record */ + cd = (struct ItemButtonCOClientData *)ckalloc( + sizeof(struct ItemButtonCOClientData)); + cd->flag1 = flag1; + cd->flag2 = flag2; + + /* The Tk custom option record */ + co = (Tk_ObjCustomOption *) ckalloc(sizeof(Tk_ObjCustomOption)); + co->name = "button option"; + co->setProc = ItemButtonCO_Set; + co->getProc = ItemButtonCO_Get; + co->restoreProc = ItemButtonCO_Restore; + co->freeProc = NULL; + co->clientData = cd; + + specPtr->clientData = co; + + return TCL_OK; +} + |