From 2f368a273ae9a5bd3ae6e84438d952bdc1f2e2e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Thu, 26 Aug 2010 13:10:27 +0000 Subject: [PATCH] Fixed the overly complicated computation of the height of the removed rows in OutlineView::RemoveRow(BRow* row). It also contained a bug (tracked down by Duggan in ticket #3897, thanks!) which caused it to skip the sub-tree height computation when FindParent() returns false, which it does for root items. Now the computation is simple: The subTreeHeight is the height of the row itself, if a) the row doesn't have a parent or b) the parent is visible and expanded. Then if the row being removed is expanded, we calculate the sub-tree height recursively. Removed a lot of duplicated or even trippled checks along the way and solved two easily solvable TODOs with regards to what is invalidated. Previously the entire list view was invalidated for each row being removed, even if they were scrolled out the view bounds. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@38372 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/kits/interface/ColumnListView.cpp | 65 +++++++++++++++------------ 1 file changed, 36 insertions(+), 29 deletions(-) diff --git a/src/kits/interface/ColumnListView.cpp b/src/kits/interface/ColumnListView.cpp index 071fcc984f..3ce6475d0e 100644 --- a/src/kits/interface/ColumnListView.cpp +++ b/src/kits/interface/ColumnListView.cpp @@ -4042,42 +4042,49 @@ OutlineView::RemoveRow(BRow* row) BRow* parentRow; bool parentIsVisible; - float subTreeHeight = row->Height(); - if (FindParent(row, &parentRow, &parentIsVisible)) { - // adjust height - if (parentIsVisible && (parentRow == 0 || parentRow->fIsExpanded)) { - if (row->fIsExpanded) { - for (RecursiveOutlineIterator iterator(row->fChildList); - iterator.CurrentRow(); iterator.GoToNext()) - subTreeHeight += iterator.CurrentRow()->Height(); - } + FindParent(row, &parentRow, &parentIsVisible); + // NOTE: This could be a root row without a parent, in which case + // it is always visible, though. + + // Adjust height for the visible sub-tree that is going to be removed. + float subTreeHeight = 0.0f; + if (parentIsVisible && (parentRow == NULL || parentRow->fIsExpanded)) { + // The row itself is visible at least. + subTreeHeight = row->Height() + 1; + if (row->fIsExpanded) { + // Adjust for the height of visible sub-items as well. + // (By default, the iterator follows open branches only.) + for (RecursiveOutlineIterator iterator(row->fChildList); + iterator.CurrentRow(); iterator.GoToNext()) + subTreeHeight += iterator.CurrentRow()->Height() + 1; + } + BRect invalid; + if (FindRect(row, &invalid)) { + invalid.bottom = Bounds().bottom; + if (invalid.IsValid()) + Invalidate(invalid); } } - if (parentRow != NULL) { - if (parentRow->fIsExpanded) - fItemsHeight -= subTreeHeight + 1; - } else { - fItemsHeight -= subTreeHeight + 1; - } + + fItemsHeight -= subTreeHeight; + FixScrollBar(false); - if (parentRow) + if (parentRow != NULL) { parentRow->fChildList->RemoveItem(row); - else + if (parentRow->fChildList->CountItems() == 0) { + delete parentRow->fChildList; + parentRow->fChildList = 0; + // It was the last child row of the parent, which also means the + // latch disappears. + BRect parentRowRect; + if (parentIsVisible && FindRect(parentRow, &parentRowRect)) + Invalidate(parentRowRect); + } + } else fRows.RemoveItem(row); - if (parentRow != 0 && parentRow->fChildList->CountItems() == 0) { - delete parentRow->fChildList; - parentRow->fChildList = 0; - if (parentIsVisible) - Invalidate(); // xxx crude way of redrawing latch - } - - if (parentIsVisible && (parentRow == 0 || parentRow->fIsExpanded)) - Invalidate(); // xxx make me smarter. - - // Adjust focus row if necessary. - if (fFocusRow && FindRect(fFocusRow, &fFocusRowRect) == false) { + if (fFocusRow && !FindRect(fFocusRow, &fFocusRowRect)) { // focus row is in a subtree that is gone, move it up to the parent. fFocusRow = parentRow; if (fFocusRow)