BView: fixed RemoveSelf() layout item handling.

* When RemoveSelf() is called, we do not own our own layout items, so
  we must not delete them.
* However, we do own them when we still have layout items left when
  we get deleted ourselves.
* This fixes removing/adding a child view to a view without deleting
  it inbetween (like the new Network preferences will do).
* Optimized item removal -- not a good idea to always remove item 0.
This commit is contained in:
Axel Dörfler 2015-02-13 22:34:34 +01:00
parent b617d006f9
commit 794c227e83
2 changed files with 25 additions and 15 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2001-2013 Haiku, Inc. All rights reserved.
* Copyright 2001-2015 Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef _VIEW_H
@ -107,6 +107,7 @@ inline uint32 _rule_(uint32 r1, uint32 r2, uint32 r3, uint32 r4)
#define B_FOLLOW_TOP_BOTTOM _rule_(_VIEW_TOP_, 0, _VIEW_BOTTOM_, 0)
#define B_FOLLOW_V_CENTER _rule_(_VIEW_CENTER_, 0, _VIEW_CENTER_, 0)
class BBitmap;
class BCursor;
class BLayout;
@ -693,6 +694,7 @@ private:
bool _AddChild(BView *child, BView *before);
bool _RemoveSelf();
void _RemoveLayoutItemsFromLayout(bool deleteItems);
// Debugging methods
void _PrintToStream();

View File

@ -1,5 +1,5 @@
/*
* Copyright 2001-2014 Haiku, Inc. All rights reserved.
* Copyright 2001-2015 Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
@ -699,12 +699,13 @@ BView::~BView()
{
STRACE(("BView(%s)::~BView()\n", this->Name()));
if (fOwner) {
if (fOwner != NULL) {
debugger("Trying to delete a view that belongs to a window. "
"Call RemoveSelf first.");
}
RemoveSelf();
_RemoveLayoutItemsFromLayout(true);
_RemoveSelf();
if (fToolTip != NULL)
fToolTip->ReleaseReference();
@ -4152,17 +4153,7 @@ BView::PreviousSibling() const
bool
BView::RemoveSelf()
{
if (fParent && fParent->fLayoutData->fLayout) {
int32 itemsRemaining = fLayoutData->fLayoutItems.CountItems();
while (itemsRemaining-- > 0) {
BLayoutItem* item = fLayoutData->fLayoutItems.ItemAt(0);
// always remove item at index 0, since items are shuffled
// downwards by BObjectList
item->Layout()->RemoveItem(item);
// removes item from fLayoutItems list
delete item;
}
}
_RemoveLayoutItemsFromLayout(false);
return _RemoveSelf();
}
@ -4201,6 +4192,23 @@ BView::_RemoveSelf()
}
void
BView::_RemoveLayoutItemsFromLayout(bool deleteItems)
{
if (fParent == NULL || fParent->fLayoutData->fLayout == NULL)
return;
int32 index = fLayoutData->fLayoutItems.CountItems();
while (index-- > 0) {
BLayoutItem* item = fLayoutData->fLayoutItems.ItemAt(index);
item->Layout()->RemoveItem(item);
// Removes item from fLayoutItems list
if (deleteItems)
delete item;
}
}
BView*
BView::Parent() const
{