summaryrefslogtreecommitdiffstats
path: root/generic/ttk
diff options
context:
space:
mode:
authorjenglish <jenglish@flightlab.com>2010-03-28 21:43:25 (GMT)
committerjenglish <jenglish@flightlab.com>2010-03-28 21:43:25 (GMT)
commitd57497b08ca7f6e28de6e670b3319f92e8fc18b7 (patch)
tree8e34ad5c3d74ee021a6a5c88057db3fa60b18ae8 /generic/ttk
parent32b447840477bfd7ee73349a241155bef7d841b7 (diff)
downloadtk-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.c73
-rw-r--r--generic/ttk/ttkTheme.c14
-rw-r--r--generic/ttk/ttkTheme.h4
-rw-r--r--generic/ttk/ttkTreeview.c104
-rw-r--r--generic/ttk/ttkWidget.h9
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*);