Fix a memory leak I introduced with my modification of BLayout::RemoveItem() and add comments so that it doesn't happen again. Also resolve some TODOs on the appropriate timing of calls to hook methods in BLayoutItem/BLayout.

This commit is contained in:
Alex Wilson 2011-09-09 14:34:23 -06:00
parent fa01d08496
commit cc1ca167a4
2 changed files with 17 additions and 18 deletions

View File

@ -226,19 +226,17 @@ BLayout::RemoveItem(int32 index)
return NULL;
BLayoutItem* item = (BLayoutItem*)fItems.RemoveItem(index);
// If this is the last item in use that refers to a certain BView,
// that BView now needs to be removed.
BView* view = item->View();
if (view && BView::Private(view).CountLayoutItems() == 0)
view->_RemoveSelf();
// TODO: Is this the right place/order to call these hooks?
// view->Parent() could be NULL, maybe that's not a problem..
ItemRemoved(item, index);
item->SetLayout(NULL);
InvalidateLayout();
// If this is the last item in use that refers to its BView,
// that BView now needs to be removed. UNLESS fTarget is NULL,
// in which case we leave the view as is. (See SetTarget() for more info)
BView* view = item->View();
if (fTarget && view && BView::Private(view).CountLayoutItems() == 0)
view->_RemoveSelf();
InvalidateLayout();
return item;
}
@ -624,8 +622,10 @@ void
BLayout::SetTarget(BView* target)
{
if (fTarget != target) {
/* With fTarget NULL, RemoveItem() will not remove the views from their
* parent. This ensures that the views are not lost to the void.
*/
fTarget = NULL;
// only remove items, not views
// remove and delete all items
for (int32 i = CountItems() - 1; i >= 0; i--)

View File

@ -164,17 +164,16 @@ BLayoutItem::SetLayout(BLayout* layout)
if (layout == fLayout)
return;
std::swap(fLayout, layout);
if (layout)
BLayout* oldLayout = fLayout;
fLayout = layout;
if (oldLayout)
DetachedFromLayout(layout);
// TODO: is this the right place to do this?
// at this point, this->Layout() will return not exactly truthful
// values... this could cause problems in DetachedFromLayout();
if (BView* view = View()) {
if (layout && !fLayout) {
if (oldLayout && !fLayout) {
BView::Private(view).DeregisterLayoutItem(this);
} else if (fLayout && !layout) {
} else if (fLayout && !oldLayout) {
BView::Private(view).RegisterLayoutItem(this);
}
}