diff options
author | jenglish <jenglish@flightlab.com> | 2010-03-28 21:43:25 (GMT) |
---|---|---|
committer | jenglish <jenglish@flightlab.com> | 2010-03-28 21:43:25 (GMT) |
commit | d57497b08ca7f6e28de6e670b3319f92e8fc18b7 (patch) | |
tree | 8e34ad5c3d74ee021a6a5c88057db3fa60b18ae8 /generic/ttk | |
parent | 32b447840477bfd7ee73349a241155bef7d841b7 (diff) | |
download | tk-d57497b08ca7f6e28de6e670b3319f92e8fc18b7.zip tk-d57497b08ca7f6e28de6e670b3319f92e8fc18b7.tar.gz tk-d57497b08ca7f6e28de6e670b3319f92e8fc18b7.tar.bz2 |
ttk::treeview widget: add 'tag names', 'tag add', and 'tag remove' methods.
Diffstat (limited to 'generic/ttk')
-rw-r--r-- | generic/ttk/ttkTagSet.c | 73 | ||||
-rw-r--r-- | generic/ttk/ttkTheme.c | 14 | ||||
-rw-r--r-- | generic/ttk/ttkTheme.h | 4 | ||||
-rw-r--r-- | generic/ttk/ttkTreeview.c | 104 | ||||
-rw-r--r-- | generic/ttk/ttkWidget.h | 9 |
5 files changed, 188 insertions, 16 deletions
diff --git a/generic/ttk/ttkTagSet.c b/generic/ttk/ttkTagSet.c index d925a78..dbf6a5c 100644 --- a/generic/ttk/ttkTagSet.c +++ b/generic/ttk/ttkTagSet.c @@ -1,4 +1,4 @@ -/* $Id: ttkTagSet.c,v 1.4 2008/05/23 20:20:05 jenglish Exp $ +/* $Id: ttkTagSet.c,v 1.5 2010/03/28 21:43:25 jenglish Exp $ * * Tag tables. 3/4-baked, work in progress. * @@ -17,7 +17,8 @@ */ struct TtkTag { int priority; /* 1=>highest */ - void *tagRecord; + const char *tagName; /* Back-pointer to hash table entry */ + void *tagRecord; /* User data */ }; struct TtkTagTable { @@ -32,13 +33,14 @@ struct TtkTagTable { /*------------------------------------------------------------------------ * +++ Tags. */ -static Ttk_Tag NewTag(Ttk_TagTable tagTable) +static Ttk_Tag NewTag(Ttk_TagTable tagTable, const char *tagName) { Ttk_Tag tag = (Ttk_Tag)ckalloc(sizeof(*tag)); tag->tagRecord = ckalloc(tagTable->recordSize); memset(tag->tagRecord, 0, tagTable->recordSize); /* Don't need Tk_InitOptions() here, all defaults should be NULL. */ tag->priority = ++tagTable->nTags; + tag->tagName = tagName; return tag; } @@ -89,7 +91,8 @@ Ttk_Tag Ttk_GetTag(Ttk_TagTable tagTable, const char *tagName) &tagTable->tags, tagName, &isNew); if (isNew) { - Tcl_SetHashValue(entryPtr, NewTag(tagTable)); + tagName = Tcl_GetHashKey(&tagTable->tags, entryPtr); + Tcl_SetHashValue(entryPtr, NewTag(tagTable,tagName)); } return Tcl_GetHashValue(entryPtr); } @@ -139,6 +142,21 @@ Ttk_TagSet Ttk_GetTagSetFromObj( return tagset; } +/* Ttk_NewTagSetObj -- + * Construct a fresh Tcl_Obj * from a tag set. + */ +Tcl_Obj *Ttk_NewTagSetObj(Ttk_TagSet tagset) +{ + Tcl_Obj *result = Tcl_NewListObj(0,0); + int i; + + for (i = 0; i < tagset->nTags; ++i) { + Tcl_ListObjAppendElement( + NULL, result, Tcl_NewStringObj(tagset->tags[i]->tagName, -1)); + } + return result; +} + void Ttk_FreeTagSet(Ttk_TagSet tagset) { ckfree((ClientData)tagset->tags); @@ -158,10 +176,55 @@ int Ttk_TagSetContains(Ttk_TagSet tagset, Ttk_Tag tag) return 0; } +/* Ttk_TagSetAdd -- add a tag to a tag set. + * + * Returns: 0 if tagset already contained tag, + * 1 if tagset was modified. + */ +int Ttk_TagSetAdd(Ttk_TagSet tagset, Ttk_Tag tag) +{ + int i; + for (i = 0; i < tagset->nTags; ++i) { + if (tagset->tags[i] == tag) { + return 0; + } + } + tagset->tags = (void*)ckrealloc((void*)tagset->tags, + (tagset->nTags+1)*sizeof(tagset->tags[0])); + tagset->tags[tagset->nTags++] = tag; + return 1; +} + +/* Ttk_TagSetRemove -- remove a tag from a tag set. + * + * Returns: 0 if tagset did not contain tag, + * 1 if tagset was modified. + */ +int Ttk_TagSetRemove(Ttk_TagSet tagset, Ttk_Tag tag) +{ + int i = 0, j = 0; + while (i < tagset->nTags) { + if ((tagset->tags[j] = tagset->tags[i]) != tag) { + ++j; + } + ++i; + } + tagset->nTags = j; + return j != i; +} + /*------------------------------------------------------------------------ * +++ Utilities for widget commands. */ +/* Ttk_EnumerateTags -- implements [$w tag names] + */ +int Ttk_EnumerateTags( + Tcl_Interp *interp, Ttk_TagTable tagTable) +{ + return TtkEnumerateHashTable(interp, &tagTable->tags); +} + /* Ttk_EnumerateTagOptions -- implements [$w tag configure $tag] */ int Ttk_EnumerateTagOptions( @@ -171,6 +234,8 @@ int Ttk_EnumerateTagOptions( tagTable->optionSpecs, tagTable->optionTable, tagTable->tkwin); } +/* Ttk_TagOptionValue -- implements [$w tag configure $tag -option] + */ Tcl_Obj *Ttk_TagOptionValue( Tcl_Interp *interp, Ttk_TagTable tagTable, diff --git a/generic/ttk/ttkTheme.c b/generic/ttk/ttkTheme.c index 5bf362d..59df20d 100644 --- a/generic/ttk/ttkTheme.c +++ b/generic/ttk/ttkTheme.c @@ -9,7 +9,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * $Id: ttkTheme.c,v 1.22 2010/02/05 21:33:14 jenglish Exp $ + * $Id: ttkTheme.c,v 1.23 2010/03/28 21:43:25 jenglish Exp $ */ #include <stdlib.h> @@ -1118,7 +1118,7 @@ Ttk_DrawElement( */ /* - * EnumerateHashTable -- + * TtkEnumerateHashTable -- * Helper routine. Sets interp's result to the list of all keys * in the hash table. * @@ -1126,7 +1126,8 @@ Ttk_DrawElement( * Side effects: Sets interp's result. */ -static int EnumerateHashTable(Tcl_Interp *interp, Tcl_HashTable *ht) +MODULE_SCOPE +int TtkEnumerateHashTable(Tcl_Interp *interp, Tcl_HashTable *ht) { Tcl_HashSearch search; Tcl_Obj *result = Tcl_NewListObj(0, NULL); @@ -1436,7 +1437,7 @@ static int StyleThemeNamesCmd( ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { StylePackageData *pkgPtr = clientData; - return EnumerateHashTable(interp, &pkgPtr->themeTable); + return TtkEnumerateHashTable(interp, &pkgPtr->themeTable); } /* + style theme settings $theme $script @@ -1516,7 +1517,7 @@ static int StyleElementNamesCmd( Tcl_WrongNumArgs(interp, 3, objv, NULL); return TCL_ERROR; } - return EnumerateHashTable(interp, &theme->elementTable); + return TtkEnumerateHashTable(interp, &theme->elementTable); } /* + style element options $element -- @@ -1661,7 +1662,8 @@ StyleObjCmd( return Ttk_InvokeEnsemble(StyleEnsemble, 1, clientData,interp,objc,objv); } -MODULE_SCOPE int Ttk_InvokeEnsemble( /* Run an ensemble command */ +MODULE_SCOPE +int Ttk_InvokeEnsemble( /* Run an ensemble command */ const Ttk_Ensemble *ensemble, int cmdIndex, void *clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { diff --git a/generic/ttk/ttkTheme.h b/generic/ttk/ttkTheme.h index a123db5..0b7c935 100644 --- a/generic/ttk/ttkTheme.h +++ b/generic/ttk/ttkTheme.h @@ -1,4 +1,4 @@ -/* $Id: ttkTheme.h,v 1.18 2010/01/31 22:50:56 jenglish Exp $ +/* $Id: ttkTheme.h,v 1.19 2010/03/28 21:43:25 jenglish Exp $ * Copyright (c) 2003 Joe English. Freely redistributable. * * Declarations for Tk theme engine. @@ -421,6 +421,8 @@ MODULE_SCOPE int Ttk_InvokeEnsemble( /* Run an ensemble command */ const Ttk_Ensemble *commands, int cmdIndex, void *clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); +MODULE_SCOPE int TtkEnumerateHashTable(Tcl_Interp *, Tcl_HashTable *); + /*------------------------------------------------------------------------ * +++ Stub table declarations. */ diff --git a/generic/ttk/ttkTreeview.c b/generic/ttk/ttkTreeview.c index a1380ba..a023eaf 100644 --- a/generic/ttk/ttkTreeview.c +++ b/generic/ttk/ttkTreeview.c @@ -1,4 +1,4 @@ -/* $Id: ttkTreeview.c,v 1.37 2010/02/20 21:30:37 jenglish Exp $ +/* $Id: ttkTreeview.c,v 1.38 2010/03/28 21:43:25 jenglish Exp $ * Copyright (c) 2004, Joe English * * ttk::treeview widget implementation. @@ -3114,10 +3114,110 @@ static int TreeviewTagHasCommand( } } +/* + $tv tag names $tag + */ +static int TreeviewTagNamesCommand( + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) +{ + Treeview *tv = recordPtr; + + if (objc != 3) { + Tcl_WrongNumArgs(interp, 3, objv, ""); + return TCL_ERROR; + } + + return Ttk_EnumerateTags(interp, tv->tree.tagTable); +} + +/* + $tv tag add $tag $items + */ +static void AddTag(TreeItem *item, Ttk_Tag tag) +{ + if (Ttk_TagSetAdd(item->tagset, tag)) { + Tcl_DecrRefCount(item->tagsObj); + item->tagsObj = Ttk_NewTagSetObj(item->tagset); + Tcl_IncrRefCount(item->tagsObj); + } +} + +static int TreeviewTagAddCommand( + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) +{ + Treeview *tv = recordPtr; + Ttk_Tag tag; + TreeItem **items; + int i; + + if (objc != 5) { + Tcl_WrongNumArgs(interp, 3, objv, "tagName items"); + return TCL_ERROR; + } + + tag = Ttk_GetTagFromObj(tv->tree.tagTable, objv[3]); + items = GetItemListFromObj(interp, tv, objv[4]); + + if (!items) { + return TCL_ERROR; + } + + for (i=0; items[i]; ++i) { + AddTag(items[i], tag); + } + + return TCL_OK; +} + +/* + $tv tag remove $tag $items + */ +static void RemoveTag(TreeItem *item, Ttk_Tag tag) +{ + if (Ttk_TagSetRemove(item->tagset, tag)) { + Tcl_DecrRefCount(item->tagsObj); + item->tagsObj = Ttk_NewTagSetObj(item->tagset); + Tcl_IncrRefCount(item->tagsObj); + } +} + +static int TreeviewTagRemoveCommand( + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) +{ + Treeview *tv = recordPtr; + Ttk_Tag tag; + + if (objc < 4) { + Tcl_WrongNumArgs(interp, 3, objv, "tagName items"); + return TCL_ERROR; + } + + tag = Ttk_GetTagFromObj(tv->tree.tagTable, objv[3]); + + if (objc == 5) { + TreeItem **items = GetItemListFromObj(interp, tv, objv[4]); + int i; + + if (!items) { + return TCL_ERROR; + } + for (i=0; items[i]; ++i) { + RemoveTag(items[i], tag); + } + } else if (objc == 4) { + TreeItem *item = tv->tree.root; + while (item) { + RemoveTag(item, tag); + item=NextPreorder(item); + } + } + return TCL_OK; +} + static const Ttk_Ensemble TreeviewTagCommands[] = { + { "add", TreeviewTagAddCommand,0 }, { "bind", TreeviewTagBindCommand,0 }, { "configure", TreeviewTagConfigureCommand,0 }, - { "has", TreeviewTagHasCommand,0 }, + { "has", TreeviewTagHasCommand,0 }, + { "names", TreeviewTagNamesCommand,0 }, + { "remove", TreeviewTagRemoveCommand,0 }, { 0,0,0 } }; diff --git a/generic/ttk/ttkWidget.h b/generic/ttk/ttkWidget.h index a5694be..99df0fb 100644 --- a/generic/ttk/ttkWidget.h +++ b/generic/ttk/ttkWidget.h @@ -1,4 +1,4 @@ -/* $Id: ttkWidget.h,v 1.14 2010/02/05 21:33:14 jenglish Exp $ +/* $Id: ttkWidget.h,v 1.15 2010/03/28 21:43:25 jenglish Exp $ * Copyright (c) 2003, Joe English * Helper routines for widget implementations. */ @@ -215,18 +215,21 @@ MODULE_SCOPE Tcl_Obj *Ttk_TagOptionValue( MODULE_SCOPE int Ttk_EnumerateTagOptions( Tcl_Interp *, Ttk_TagTable, Ttk_Tag); +MODULE_SCOPE int Ttk_EnumerateTags(Tcl_Interp *, Ttk_TagTable); + MODULE_SCOPE int Ttk_ConfigureTag( Tcl_Interp *interp, Ttk_TagTable tagTable, Ttk_Tag tag, int objc, Tcl_Obj *const objv[]); MODULE_SCOPE Ttk_TagSet Ttk_GetTagSetFromObj( Tcl_Interp *interp, Ttk_TagTable, Tcl_Obj *objPtr); +MODULE_SCOPE Tcl_Obj *Ttk_NewTagSetObj(Ttk_TagSet); MODULE_SCOPE void Ttk_FreeTagSet(Ttk_TagSet); MODULE_SCOPE int Ttk_TagSetContains(Ttk_TagSet, Ttk_Tag tag); -MODULE_SCOPE void Ttk_TagSetAdd(Ttk_TagSet, Ttk_Tag tag); -MODULE_SCOPE void Ttk_TagSetRemove(Ttk_TagSet, Ttk_Tag tag); +MODULE_SCOPE int Ttk_TagSetAdd(Ttk_TagSet, Ttk_Tag tag); +MODULE_SCOPE int Ttk_TagSetRemove(Ttk_TagSet, Ttk_Tag tag); MODULE_SCOPE void Ttk_TagSetValues(Ttk_TagTable, Ttk_TagSet, void *record); MODULE_SCOPE void Ttk_TagSetApplyStyle(Ttk_TagTable,Ttk_Style,Ttk_State,void*); |