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
+3 -1
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. * Distributed under the terms of the MIT License.
*/ */
#ifndef _VIEW_H #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_TOP_BOTTOM _rule_(_VIEW_TOP_, 0, _VIEW_BOTTOM_, 0)
#define B_FOLLOW_V_CENTER _rule_(_VIEW_CENTER_, 0, _VIEW_CENTER_, 0) #define B_FOLLOW_V_CENTER _rule_(_VIEW_CENTER_, 0, _VIEW_CENTER_, 0)
class BBitmap; class BBitmap;
class BCursor; class BCursor;
class BLayout; class BLayout;
@@ -693,6 +694,7 @@ private:
bool _AddChild(BView *child, BView *before); bool _AddChild(BView *child, BView *before);
bool _RemoveSelf(); bool _RemoveSelf();
void _RemoveLayoutItemsFromLayout(bool deleteItems);
// Debugging methods // Debugging methods
void _PrintToStream(); void _PrintToStream();
+22 -14
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. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
@@ -699,12 +699,13 @@ BView::~BView()
{ {
STRACE(("BView(%s)::~BView()\n", this->Name())); STRACE(("BView(%s)::~BView()\n", this->Name()));
if (fOwner) { if (fOwner != NULL) {
debugger("Trying to delete a view that belongs to a window. " debugger("Trying to delete a view that belongs to a window. "
"Call RemoveSelf first."); "Call RemoveSelf first.");
} }
RemoveSelf(); _RemoveLayoutItemsFromLayout(true);
_RemoveSelf();
if (fToolTip != NULL) if (fToolTip != NULL)
fToolTip->ReleaseReference(); fToolTip->ReleaseReference();
@@ -4152,17 +4153,7 @@ BView::PreviousSibling() const
bool bool
BView::RemoveSelf() BView::RemoveSelf()
{ {
if (fParent && fParent->fLayoutData->fLayout) { _RemoveLayoutItemsFromLayout(false);
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;
}
}
return _RemoveSelf(); 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*
BView::Parent() const BView::Parent() const
{ {