Skip to content

Commit

Permalink
Fix [8e9d65d2d4]: Unexpected behavior of ttk::treeview with detached …
Browse files Browse the repository at this point in the history
…items.
  • Loading branch information
fvogelnew1 committed Sep 17, 2024
2 parents 024063e + affa231 commit 5f2f4da
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 8 deletions.
36 changes: 29 additions & 7 deletions generic/ttk/ttkTreeview.c
Original file line number Diff line number Diff line change
Expand Up @@ -1741,6 +1741,26 @@ static int DisplayRow(int row, Treeview *tv)
return row - tv->tree.yscroll.first + tv->tree.titleRows;
}

/* Is an item detached? The root is never detached. */
static int IsDetached(Treeview* tv, TreeItem* item)
{
return item->next == NULL && item->prev == NULL &&
item->parent == NULL && item != tv->tree.root;
}

/* Is an item or one of its ancestors detached? */
static int IsItemOrAncestorDetached(Treeview* tv, TreeItem* item)
{
TreeItem *parent;

for (parent = item; parent; parent = parent->parent) {
if (IsDetached(tv, parent)) {
return 1;
}
}
return 0;
}

/* + BoundingBox --
* Compute the parcel of the specified column of the specified item,
* (or the entire item if column is NULL)
Expand All @@ -1767,6 +1787,9 @@ static int BoundingBox(
/* not viewable, or off-screen */
return 0;
}
if (IsItemOrAncestorDetached(tv, item)) {
return 0;
}

bbox.y += dispRow * tv->tree.rowHeight;
bbox.height = tv->tree.rowHeight * item->height;
Expand Down Expand Up @@ -3347,13 +3370,6 @@ static int TreeviewDetachCommand(
return TCL_OK;
}

/* Is an item detached? The root is never detached. */
static int IsDetached(Treeview *tv, TreeItem *item)
{
return item->next == NULL && item->prev == NULL &&
item->parent == NULL && item != tv->tree.root;
}

/* + $tv detached ?$item? --
* List detached items (in arbitrary order) or query the detached state of
* $item.
Expand Down Expand Up @@ -3567,6 +3583,12 @@ static int TreeviewSeeCommand(
return TCL_ERROR;
}

/* The item cannot be moved into view if any ancestor (or itself) is detached.
*/
if (IsItemOrAncestorDetached(tv, item)) {
return TCL_OK;
}

/* Make sure all ancestors are open:
*/
for (parent = item->parent; parent; parent = parent->parent) {
Expand Down
31 changes: 30 additions & 1 deletion tests/ttk/treeview.test
Original file line number Diff line number Diff line change
Expand Up @@ -688,10 +688,39 @@ test treeview-9.3 {scrolling on see command, requested item is closed} -setup {
.top.tree see e
update idletasks
set after [lindex [.top.vs get] 1]
expr $after < $before
expr ($after < $before)
} -cleanup {
destroy .top
} -result 1
test treeview-9.4 {no scrolling on see command on an item below a detached item; bbox on such item is empty} -setup {
toplevel .top
ttk::treeview .top.tree -show tree -height 10 -columns {label} \
-yscrollcommand [list .top.vs set]
ttk::scrollbar .top.vs -command {.top.tree yview}
grid .top.tree -row 0 -column 0 -sticky ns
grid .top.vs -row 0 -column 1 -sticky ns

foreach dir {A B C D E F G H} {
set id [string cat dir $dir]
.top.tree insert {} end -id $id -text "dir $dir" -open 1
for {set i 1} {$i <= 10} {incr i} {
.top.tree insert $id end -id $id-$i -text "dir $dir item $i"
}
}
update
.top.tree detach dirD
.top.tree item dirC -open 0
update
} -body {
set before [lindex [.top.vs get] 1]
.top.tree see dirD-4
update
set after [lindex [.top.vs get] 1]
set res [expr ($after == $before)]
lappend res [.top.tree bbox dirD-4]
} -cleanup {
destroy .top
} -result {1 {}}

test treeview-10.0 "See command" -setup {
# Setup common for all 10.* tests
Expand Down

0 comments on commit 5f2f4da

Please sign in to comment.