summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--generic/tkTreeColumn.c220
-rw-r--r--generic/tkTreeCtrl.h6
2 files changed, 224 insertions, 2 deletions
diff --git a/generic/tkTreeColumn.c b/generic/tkTreeColumn.c
index ec67b36..a640df0 100644
--- a/generic/tkTreeColumn.c
+++ b/generic/tkTreeColumn.c
@@ -7,13 +7,21 @@
* Copyright (c) 2002-2003 Christian Krone
* Copyright (c) 2003 ActiveState Corporation
*
- * RCS: @(#) $Id: tkTreeColumn.c,v 1.47 2006/10/26 02:56:54 treectrl Exp $
+ * RCS: @(#) $Id: tkTreeColumn.c,v 1.48 2006/10/27 02:58:49 treectrl Exp $
*/
#include "tkTreeCtrl.h"
typedef struct Column Column;
+#ifdef UNIFORM_GROUP
+typedef struct UniformGroup {
+ Tcl_HashEntry *hPtr;
+ int refCount;
+ int minSize;
+} UniformGroup;
+#endif
+
/*
* The following structure holds information about a single
* column in a TreeCtrl.
@@ -28,9 +36,11 @@ struct Column
Tcl_Obj *minWidthObj; /* -minwidth */
int maxWidth; /* -maxwidth */
Tcl_Obj *maxWidthObj; /* -maxwidth */
+#ifdef DEPRECATED
int stepWidth; /* -stepwidth */
Tcl_Obj *stepWidthObj; /* -stepwidth */
int widthHack; /* -widthhack */
+#endif /* DEPRECATED */
Tk_Font tkfont; /* -font */
Tk_Justify justify; /* -justify */
PerStateInfo border; /* -background */
@@ -107,8 +117,147 @@ struct Column
#define TEXT_WRAP_WORD 1
int textWrap; /* -textwrap */
int textLines; /* -textlines */
+#ifdef UNIFORM_GROUP
+ UniformGroup *uniform; /* -uniform */
+ int weight; /* -weight */
+#endif
};
+#ifdef UNIFORM_GROUP
+/*
+ *----------------------------------------------------------------------
+ *
+ * UniformGroupCO_Set --
+ * UniformGroupCO_Get --
+ * UniformGroupCO_Restore --
+ * UniformGroupCO_Free --
+ *
+ * These procedures implement a TK_OPTION_CUSTOM where the custom
+ * option is a UniformGroup.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+UniformGroupCO_Set(
+ ClientData clientData,
+ Tcl_Interp *interp,
+ Tk_Window tkwin,
+ Tcl_Obj **valuePtr,
+ char *recordPtr,
+ int internalOffset,
+ char *saveInternalPtr,
+ int flags
+ )
+{
+ TreeCtrl *tree = (TreeCtrl *) ((TkWindow *) tkwin)->instanceData;
+ int objEmpty;
+ UniformGroup **internalPtr, *new;
+
+ if (internalOffset >= 0)
+ internalPtr = (UniformGroup **) (recordPtr + internalOffset);
+ else
+ internalPtr = NULL;
+
+ objEmpty = ObjectIsEmpty((*valuePtr));
+
+ if ((flags & TK_OPTION_NULL_OK) && objEmpty)
+ (*valuePtr) = NULL;
+
+ if (internalPtr != NULL) {
+ if (*valuePtr != NULL) {
+ int isNew;
+ Tcl_HashEntry *hPtr = Tcl_CreateHashEntry(&tree->uniformGroupHash,
+ Tcl_GetString(*valuePtr), &isNew);
+ if (isNew) {
+ new = (UniformGroup *) ckalloc(sizeof(UniformGroup));
+ new->refCount = 0;
+ new->hPtr = hPtr;
+ Tcl_SetHashValue(hPtr, (ClientData) new);
+ } else {
+ new = (UniformGroup *) Tcl_GetHashValue(hPtr);
+ }
+ new->refCount++;
+#ifdef TREECTRL_DEBUG
+ dbwin("UniformGroupCO_Set: %s refCount=%d\n", Tcl_GetString(*valuePtr), new->refCount);
+#endif
+ } else {
+ new = NULL;
+ }
+ *((UniformGroup **) saveInternalPtr) = *internalPtr;
+ *internalPtr = new;
+ }
+
+ return TCL_OK;
+}
+
+static Tcl_Obj *
+UniformGroupCO_Get(
+ ClientData clientData,
+ Tk_Window tkwin,
+ char *recordPtr,
+ int internalOffset
+ )
+{
+ TreeCtrl *tree = (TreeCtrl *) ((TkWindow *) tkwin)->instanceData;
+ UniformGroup *uniform = *(UniformGroup **) (recordPtr + internalOffset);
+
+ if (uniform == NULL)
+ return NULL;
+ return Tcl_NewStringObj(Tcl_GetHashKey(&tree->uniformGroupHash,
+ uniform->hPtr), -1);
+}
+
+static void
+UniformGroupCO_Restore(
+ ClientData clientData,
+ Tk_Window tkwin,
+ char *internalPtr,
+ char *saveInternalPtr
+ )
+{
+ *(UniformGroup **) internalPtr = *(UniformGroup **) saveInternalPtr;
+}
+
+static void
+UniformGroupCO_Free(
+ ClientData clientData,
+ Tk_Window tkwin,
+ char *internalPtr
+ )
+{
+ UniformGroup *uniform = *(UniformGroup **) internalPtr;
+
+#ifdef TREECTRL_DEBUG
+ if (uniform != NULL) {
+ TreeCtrl *tree = (TreeCtrl *) ((TkWindow *) tkwin)->instanceData;
+ dbwin("UniformGroupCO_Free: %s refCount=%d\n", Tcl_GetHashKey(&tree->uniformGroupHash, uniform->hPtr), uniform->refCount - 1);
+ }
+#endif
+ if ((uniform != NULL) && (--uniform->refCount <= 0)) {
+ Tcl_DeleteHashEntry(uniform->hPtr);
+ ckfree((char *) uniform);
+ *((UniformGroup **) internalPtr) = NULL;
+ }
+}
+
+Tk_ObjCustomOption uniformGroupCO =
+{
+ "uniform group",
+ UniformGroupCO_Set,
+ UniformGroupCO_Get,
+ UniformGroupCO_Restore,
+ UniformGroupCO_Free,
+ (ClientData) NULL
+};
+#endif /* UNIFORM_GROUP */
+
static char *arrowST[] = { "none", "up", "down", (char *) NULL };
static char *arrowSideST[] = { "left", "right", (char *) NULL };
static char *stateST[] = { "normal", "active", "pressed", (char *) NULL };
@@ -215,10 +364,12 @@ static Tk_OptionSpec columnSpecs[] = {
{TK_OPTION_STRING_TABLE, "-state", (char *) NULL, (char *) NULL,
"normal", -1, Tk_Offset(Column, state), 0, (ClientData) stateST,
COLU_CONF_NWIDTH | COLU_CONF_NHEIGHT | COLU_CONF_DISPLAY},
+#ifdef DEPRECATED
{TK_OPTION_PIXELS, "-stepwidth", (char *) NULL, (char *) NULL,
(char *) NULL, Tk_Offset(Column, stepWidthObj),
Tk_Offset(Column, stepWidth),
TK_OPTION_NULL_OK, (ClientData) NULL, COLU_CONF_RANGES},
+#endif /* DEPRECATED */
{TK_OPTION_CUSTOM, "-tags", (char *) NULL, (char *) NULL,
(char *) NULL, -1, Tk_Offset(Column, tagInfo),
TK_OPTION_NULL_OK, (ClientData) &TagInfoCO, COLU_CONF_TAGS},
@@ -241,15 +392,25 @@ static Tk_OptionSpec columnSpecs[] = {
"0", Tk_Offset(Column, textPadYObj),
Tk_Offset(Column, textPadY), 0, (ClientData) &PadAmountOption,
COLU_CONF_NHEIGHT | COLU_CONF_DISPLAY},
+#ifdef UNIFORM_GROUP
+ {TK_OPTION_CUSTOM, "-uniform", (char *) NULL, (char *) NULL,
+ (char *) NULL, -1, Tk_Offset(Column, uniform), TK_OPTION_NULL_OK,
+ (ClientData) &uniformGroupCO, COLU_CONF_TWIDTH},
+ {TK_OPTION_INT, "-weight", (char *) NULL, (char *) NULL,
+ "0", -1, Tk_Offset(Column, weight),
+ TK_OPTION_NULL_OK, (ClientData) NULL, COLU_CONF_TWIDTH},
+#endif
{TK_OPTION_PIXELS, "-width", (char *) NULL, (char *) NULL,
(char *) NULL, Tk_Offset(Column, widthObj), Tk_Offset(Column, width),
TK_OPTION_NULL_OK, (ClientData) NULL, COLU_CONF_TWIDTH},
{TK_OPTION_BOOLEAN, "-visible", (char *) NULL, (char *) NULL,
"1", -1, Tk_Offset(Column, visible),
0, (ClientData) NULL, COLU_CONF_TWIDTH | COLU_CONF_DISPLAY},
+#ifdef DEPRECATED
{TK_OPTION_BOOLEAN, "-widthhack", (char *) NULL, (char *) NULL,
"0", -1, Tk_Offset(Column, widthHack),
0, (ClientData) NULL, COLU_CONF_RANGES},
+#endif /* DEPRECATED */
{TK_OPTION_END, (char *) NULL, (char *) NULL, (char *) NULL,
(char *) NULL, 0, -1, 0, 0, 0}
};
@@ -2247,6 +2408,7 @@ TreeColumn_MaxWidth(
return column->maxWidthObj ? column->maxWidth : -1;
}
+#ifdef DEPRECATED
/*
*----------------------------------------------------------------------
*
@@ -2272,6 +2434,7 @@ TreeColumn_StepWidth(
Column *column = (Column *) column_;
return column->stepWidthObj ? column->stepWidth : -1;
}
+#endif /* DEPRECATED */
/*
*----------------------------------------------------------------------
@@ -3050,6 +3213,7 @@ TreeColumn_Justify(
return ((Column *) column_)->justify;
}
+#ifdef DEPRECATED
/*
*----------------------------------------------------------------------
*
@@ -3074,6 +3238,7 @@ TreeColumn_WidthHack(
{
return ((Column *) column_)->widthHack;
}
+#endif /* DEPRECATED */
/*
*----------------------------------------------------------------------
@@ -4776,6 +4941,18 @@ Tree_LayoutColumns(
Column *column = (Column *) tree->columns;
int width, visWidth, totalWidth = 0;
int numExpand = 0, numSqueeze = 0;
+#ifdef UNIFORM_GROUP
+ Tcl_HashEntry *hPtr;
+ Tcl_HashSearch search;
+ UniformGroup *uniform;
+
+ hPtr = Tcl_FirstHashEntry(&tree->uniformGroupHash, &search);
+ while (hPtr != NULL) {
+ uniform = (UniformGroup *) Tcl_GetHashValue(hPtr);
+ uniform->minSize = 0;
+ hPtr = Tcl_NextHashEntry(&search);
+ }
+#endif
#ifdef COLUMN_LOCK
column = (Column *) tree->columnLockNone;
@@ -4792,6 +4969,16 @@ Tree_LayoutColumns(
width = MAX(width, TreeColumn_MinWidth((TreeColumn) column));
if (TreeColumn_MaxWidth((TreeColumn) column) != -1)
width = MIN(width, TreeColumn_MaxWidth((TreeColumn) column));
+#ifdef UNIFORM_GROUP
+ /* Track the maximum requested width of every column in this
+ * column's uniform group considering -weight. */
+ if (column->uniform != NULL) {
+ int weight = MAX(column->weight, 1);
+ int minSize = (width + weight - 1) / weight;
+ if (minSize > column->uniform->minSize)
+ column->uniform->minSize = minSize;
+ }
+#endif
if (column->expand)
numExpand++;
if (column->squeeze)
@@ -4804,6 +4991,29 @@ Tree_LayoutColumns(
column = column->next;
}
+#ifdef UNIFORM_GROUP
+ /* Apply the -uniform and -weight options. */
+#ifdef COLUMN_LOCK
+ column = (Column *) tree->columnLockNone;
+ while (column != NULL && column->lock == COLUMN_LOCK_NONE) {
+#else
+ while (column != NULL) {
+#endif
+ if (column->visible &&
+ column->widthObj == NULL &&
+ column->uniform != NULL) {
+ int weight = MAX(column->weight, 1);
+ totalWidth -= column->useWidth;
+ width = column->uniform->minSize * weight;
+ if (column->maxWidthObj != NULL)
+ width = MIN(width, column->maxWidth);
+ column->useWidth = width;
+ totalWidth += width;
+ }
+ column = column->next;
+ }
+#endif
+
visWidth = Tree_ContentWidth(tree);
if (visWidth <= 0) return;
@@ -5423,6 +5633,10 @@ Tree_InitColumns(
tree->columnDrag.optionTable = Tk_CreateOptionTable(tree->interp, dragSpecs);
(void) Tk_InitOptions(tree->interp, (char *) tree,
tree->columnDrag.optionTable, tree->tkwin);
+
+#ifdef UNIFORM_GROUP
+ Tcl_InitHashTable(&tree->uniformGroupHash, TCL_STRING_KEYS);
+#endif
}
/*
@@ -5453,6 +5667,10 @@ void Tree_FreeColumns(
Column_Free((Column *) tree->columnTail);
tree->columnCount = 0;
+
+#ifdef UNIFORM_GROUP
+ Tcl_DeleteHashTable(&tree->uniformGroupHash);
+#endif
}
int
diff --git a/generic/tkTreeCtrl.h b/generic/tkTreeCtrl.h
index 4353774..5fc6c3e 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.58 2006/10/26 03:00:32 treectrl Exp $
+ * RCS: @(#) $Id: tkTreeCtrl.h,v 1.59 2006/10/27 02:58:49 treectrl Exp $
*/
#include "tkPort.h"
@@ -282,6 +282,10 @@ struct TreeCtrl
int columnCountVisLeft; /* Number of visible left-locked columns */
int columnCountVisRight; /* Number of visible right-locked columns */
#endif
+#define UNIFORM_GROUP
+#ifdef UNIFORM_GROUP
+ Tcl_HashTable uniformGroupHash; /* -uniform -> UniformGroup */
+#endif
TreeItem root;
TreeItem activeItem;