diff options
author | treectrl <treectrl> | 2006-10-16 01:16:30 (GMT) |
---|---|---|
committer | treectrl <treectrl> | 2006-10-16 01:16:30 (GMT) |
commit | 803725a37fbf9a19b325947c85e1ebb8e6037d81 (patch) | |
tree | 71de45fb8534834a5a5fa283e67cc22020ca076b /generic/tkTreeDisplay.c | |
parent | b3397722a2f81f202020aabf01206bd96a99948f (diff) | |
download | tktreectrl-803725a37fbf9a19b325947c85e1ebb8e6037d81.zip tktreectrl-803725a37fbf9a19b325947c85e1ebb8e6037d81.tar.gz tktreectrl-803725a37fbf9a19b325947c85e1ebb8e6037d81.tar.bz2 |
Track which item-columns are onscreen so that window elements are unmapped when columns are moved, hidden or obscurred.
Diffstat (limited to 'generic/tkTreeDisplay.c')
-rw-r--r-- | generic/tkTreeDisplay.c | 323 |
1 files changed, 288 insertions, 35 deletions
diff --git a/generic/tkTreeDisplay.c b/generic/tkTreeDisplay.c index 9cc8e9a..c08c65a 100644 --- a/generic/tkTreeDisplay.c +++ b/generic/tkTreeDisplay.c @@ -5,7 +5,7 @@ * * Copyright (c) 2002-2006 Tim Baker * - * RCS: @(#) $Id: tkTreeDisplay.c,v 1.44 2006/10/14 21:19:53 treectrl Exp $ + * RCS: @(#) $Id: tkTreeDisplay.c,v 1.45 2006/10/16 01:16:30 treectrl Exp $ */ #include "tkTreeCtrl.h" @@ -2632,44 +2632,210 @@ UpdateSpansForItem( } #endif -#define DCOLUMNxxx +#define DCOLUMN #ifdef DCOLUMN + +/* + *-------------------------------------------------------------- + * + * GetOnScreenColumnsForItemAux -- + * + * Determine which columns of an item are onscreen. + * + * Results: + * Sets the column list. + * + * Side effects: + * Memory may be allocated. + * + *-------------------------------------------------------------- + */ + static void -UpdateDColumnsForItem( +GetOnScreenColumnsForItemAux( TreeCtrl *tree, /* Widget info. */ - DItem *dItem /* Display info for an item. */ + DItem *dItem, /* Display info for an item. */ + DItemArea *area, /* Layout info. */ + int bounds[4], /* Window bounds of what's visible. */ +#ifdef COLUMN_LOCK + int lock, /* Set of columns we care about. */ +#endif + TreeColumnList *columns /* Initialized list to append to. */ ) { DInfo *dInfo = (DInfo *) tree->dInfo; - int minX, maxX, columnIndex, x = 0; - TreeColumn column, first = NULL, last = NULL; - - minX = MAX(dItem->x, Tree_ContentLeft(tree)); - maxX = MIN(dItem->x + dItem->width, Tree_ContentRight(tree)); - - minX -= dItem->x; - maxX -= dItem->x; - - for (column = tree->columns, columnIndex = 0; - column != NULL; - column = TreeColumn_Next(column), columnIndex++) { - if (TreeColumn_Visible(column) && TreeColumn_Lock(column) == COLUMN_LOCK_NONE) { - if (x < maxX && x + dInfo->columns[columnIndex].width > minX) { - if (first == NULL) - first = column; - last = column; + int minX, maxX, columnIndex, x = 0, i, width; + TreeColumn column; + + minX = MAX(area->x, bounds[0]); + maxX = MIN(area->x + area->width, bounds[2]); + + minX -= area->x; + maxX -= area->x; + + for (columnIndex = 0; columnIndex < tree->columnCount; columnIndex++) { + column = dInfo->columns[columnIndex].column; + if (!TreeColumn_Visible(column)) + continue; + if (TreeColumn_Lock(column) != lock) + continue; + width = dInfo->columns[columnIndex].width; +#ifdef COLUMN_SPAN + if (dItem->spans[columnIndex] != columnIndex) + goto next; + /* Start of a span */ + for (i = columnIndex + 1; columnIndex < tree->columnCount && + dItem->spans[i] == columnIndex; i++) + width += dInfo->columns[i].width; +#endif + if (x < maxX && x + width > minX) { + TreeColumnList_Append(columns, column); + } +#ifdef COLUMN_SPAN + columnIndex = i - 1; +#endif +next: + x += width; + if (x >= maxX) + break; + } +} + +/* + *-------------------------------------------------------------- + * + * GetOnScreenColumnsForItem -- + * + * Determine which columns of an item are onscreen. + * + * Results: + * Sets the column list. + * + * Side effects: + * Memory may be allocated. + * + *-------------------------------------------------------------- + */ + +static int +GetOnScreenColumnsForItem( + TreeCtrl *tree, /* Widget info. */ + DItem *dItem, /* Display info for an item. */ + TreeColumnList *columns /* Initialized list to append to. */ + ) +{ + DInfo *dInfo = (DInfo *) tree->dInfo; + + if (!dInfo->empty) { + GetOnScreenColumnsForItemAux(tree, dItem, &dItem->area, + dInfo->bounds, +#ifdef COLUMN_LOCK + COLUMN_LOCK_NONE, +#endif + columns); + } +#ifdef COLUMN_LOCK + if (!dInfo->emptyL) { + GetOnScreenColumnsForItemAux(tree, dItem, + &dItem->left, dInfo->boundsL, COLUMN_LOCK_LEFT, + columns); + } + if (!dInfo->emptyR) { + GetOnScreenColumnsForItemAux(tree, dItem, + &dItem->right, dInfo->boundsR, COLUMN_LOCK_RIGHT, + columns); + } +#endif /* COLUMN_LOCK */ + return TreeColumnList_Count(columns); +} + +/* + *-------------------------------------------------------------- + * + * TrackOnScreenColumnsForItem -- + * + * Compares the list of onscreen columns for an item to the + * list of previously-onscreen columns for the item. + * + * Results: + * Hides window elements for columns that are no longer + * onscreen. + * + * Side effects: + * Memory may be allocated. + * + *-------------------------------------------------------------- + */ + +static void +TrackOnScreenColumnsForItem( + TreeCtrl *tree, /* Widget info. */ + DItem *dItem, /* Item display info. */ + Tcl_HashEntry *hPtr /* DInfo.itemVisHash entry. */ + ) +{ + TreeColumnList columns; + TreeColumn column, *value; + int i, j, count = 0, n = 0; + char buf[256]; + + TreeColumnList_Init(tree, &columns, 0); + count = GetOnScreenColumnsForItem(tree, dItem, &columns); + + if (tree->debug.enable && tree->debug.display) + sprintf(buf, "item %d:", TreeItem_GetID(tree, dItem->item)); + + value = (TreeColumn *) Tcl_GetHashValue(hPtr); + + /* Track newly-visible columns */ + for (i = 0; i < count; i++) { + column = TreeColumnList_Nth(&columns, i); + for (j = 0; value[j] != NULL; j++) { + if (column == value[j]) + break; + } + if (value[j] == NULL) { + if (tree->debug.enable && tree->debug.display) + sprintf(buf + strlen(buf), " +%d", TreeColumn_GetID(column)); + n++; + } + } + + /* Track newly-hidden columns */ + for (j = 0; value[j] != NULL; j++) { + column = value[j]; + for (i = 0; i < count; i++) { + if (TreeColumnList_Nth(&columns, i) == column) + break; + } + if (i == count) { + TreeItemColumn itemColumn = TreeItem_FindColumn(tree, dItem->item, + TreeColumn_Index(column)); + if (itemColumn != NULL) { + TreeStyle style = TreeItemColumn_GetStyle(tree, itemColumn); + if (style != NULL) + TreeStyle_OnScreen(tree, style, FALSE); } - x += dInfo->columns[columnIndex].width; + if (tree->debug.enable && tree->debug.display) + sprintf(buf + strlen(buf), " -%d", TreeColumn_GetID(column)); + n++; } } - if (first != NULL && tree->debug.enable && tree->debug.display) - dbwin("UpdateDColumnsForItem %d %d-%d\n", - TreeItem_GetID(tree, dItem->item), - TreeColumn_GetID(first), - TreeColumn_GetID(last)); + if (n && tree->debug.enable && tree->debug.display) + dbwin("%s", buf); + + if (n > 0) { + ckfree((char *) value); + value = (TreeColumn *) ckalloc(sizeof(TreeColumn) * (count + 1)); + memcpy(value, (TreeColumn *) columns.pointers, sizeof(TreeColumn) * count); + value[count] = NULL; + Tcl_SetHashValue(hPtr, (ClientData) value); + } + TreeColumnList_Free(&columns); } -#endif + +#endif /* DCOLUMN */ /* *-------------------------------------------------------------- @@ -2797,9 +2963,6 @@ UpdateDInfoForRange( #ifdef COLUMN_SPAN UpdateSpansForItem(tree, dItem); #endif -#ifdef DCOLUMN - UpdateDColumnsForItem(tree, dItem); -#endif /* Keep track of the maximum item size */ if (area->width > dInfo->itemWidth) @@ -2909,9 +3072,6 @@ UpdateDInfoForRange( #ifdef COLUMN_SPAN UpdateSpansForItem(tree, dItem); #endif -#ifdef DCOLUMN - UpdateDColumnsForItem(tree, dItem); -#endif /* Keep track of the maximum item size */ if (area->width > dInfo->itemWidth) @@ -4673,6 +4833,13 @@ displayRetry: TreeItemList_Append(&newV, dItem->item); TreeItem_OnScreen(tree, dItem->item, TRUE); } +#ifdef DCOLUMN + /* The item was onscreen and still is. Figure out which + * item-columns have become visible or hidden. */ + else { + TrackOnScreenColumnsForItem(tree, dItem, hPtr); + } +#endif /* DCOLUMN */ } hPtr = Tcl_FirstHashEntry(&dInfo->itemVisHash, &search); @@ -4691,6 +4858,9 @@ displayRetry: for (i = 0; i < count; i++) { item = TreeItemList_Nth(&newH, i); hPtr = Tcl_FindHashEntry(&dInfo->itemVisHash, (char *) item); +#ifdef DCOLUMN + ckfree((char *) Tcl_GetHashValue(hPtr)); +#endif Tcl_DeleteHashEntry(hPtr); } @@ -4699,6 +4869,34 @@ displayRetry: for (i = 0; i < count; i++) { item = TreeItemList_Nth(&newV, i); hPtr = Tcl_CreateHashEntry(&dInfo->itemVisHash, (char *) item, &isNew); +#ifdef DCOLUMN + { + TreeColumnList columns; + TreeColumn *value; + int i, count = 0; + + dItem = (DItem *) TreeItem_GetDInfo(tree, item); + + TreeColumnList_Init(tree, &columns, 0); + count = GetOnScreenColumnsForItem(tree, dItem, &columns); + + value = (TreeColumn *) ckalloc(sizeof(TreeColumn) * (count + 1)); + memcpy(value, (TreeColumn *) columns.pointers, sizeof(TreeColumn) * count); + value[count] = NULL; + Tcl_SetHashValue(hPtr, (ClientData) value); + + TreeColumnList_Free(&columns); + + if (tree->debug.enable && tree->debug.display) { + char buf[256]; + sprintf(buf, "item %d:", TreeItem_GetID(tree, dItem->item)); + for (i = 0; i < count; i++) + sprintf(buf + strlen(buf), " +%d", + TreeColumn_GetID(value[i])); + dbwin("%s", buf); + } + } +#endif /* DCOLUMN */ } requests = dInfo->requests; @@ -5969,8 +6167,63 @@ TreeDisplay_ItemDeleted( Tcl_HashEntry *hPtr; hPtr = Tcl_FindHashEntry(&dInfo->itemVisHash, (char *) item); - if (hPtr != NULL) + if (hPtr != NULL) { +#ifdef DCOLUMN + ckfree((char *) Tcl_GetHashValue(hPtr)); +#endif Tcl_DeleteHashEntry(hPtr); + } +} + +/* + *-------------------------------------------------------------- + * + * TreeDisplay_ColumnDeleted -- + * + * Removes a column from the list of on-screen columns for + * all on-screen items. + * + * Results: + * None. + * + * Side effects: + * None. + * + *-------------------------------------------------------------- + */ + +void +TreeDisplay_ColumnDeleted( + TreeCtrl *tree, /* Widget info. */ + TreeColumn column /* Column to remove. */ + ) +{ +#ifdef DCOLUMN + DInfo *dInfo = (DInfo *) tree->dInfo; + Tcl_HashSearch search; + Tcl_HashEntry *hPtr; + TreeColumn *value; + int i; + + hPtr = Tcl_FirstHashEntry(&dInfo->itemVisHash, &search); + while (hPtr != NULL) { + value = (TreeColumn *) Tcl_GetHashValue(hPtr); + for (i = 0; value[i] != NULL; i++) { + if (value[i] == column) { + while (value[i] != NULL) { + value[i] = value[i + 1]; + ++i; + } +if (tree->debug.enable && tree->debug.display) + dbwin("TreeDisplay_ColumnDeleted item %d column %d", + TreeItem_GetID(tree, Tcl_GetHashKey(&dInfo->itemVisHash, hPtr)), + TreeColumn_GetID(column)); + break; + } + } + hPtr = Tcl_NextHashEntry(&search); + } +#endif } /* |