Add a method to BView::Private that calls BView::_RemoveSelf().

Add a struct to kits/interface/Layout.cpp that uses BView::Private to
provide RAII mechanics for the removal of views (calling
BView::Private::RemoveSelf()).
Use the new struct to simplify BLayout::AddItem().
This commit is contained in:
Alex Wilson
2011-10-28 14:16:03 -06:00
parent 0926395334
commit edb4c8244c
2 changed files with 46 additions and 16 deletions
+5
View File
@@ -66,6 +66,11 @@ public:
bool WillLayout();
bool MinMaxValid();
bool RemoveSelf()
{
return fView->_RemoveSelf();
}
BView* fView;
};
+41 -16
View File
@@ -40,6 +40,31 @@ namespace {
= B_LAYOUT_INVALID | B_LAYOUT_IN_PROGRESS;
const char* const kLayoutItemField = "BLayout:items";
struct ViewRemover {
ViewRemover(BView* view) : fView(view) {};
~ViewRemover()
{
if (fView)
BView::Private(fView).RemoveSelf();
}
void SetTo(BView* view)
{
if (fView)
BView::Private(fView).RemoveSelf();
fView = view;
}
void Detach()
{
fView = NULL;
}
BView* fView;
};
}
@@ -148,31 +173,31 @@ BLayout::AddItem(int32 index, BLayoutItem* item)
// if the item refers to a BView, we make sure it is added to the parent
// view
bool addedView = false;
BView* view = item->View();
if (view && view->fParent != fTarget
&& !(addedView = fTarget->_AddChild(view, NULL)))
ViewRemover remover(view);
if (view && view->fParent != fTarget && !fTarget->_AddChild(view, NULL)) {
remover.Detach(); // view wasn't added
return false;
}
// validate the index
if (index < 0 || index > fItems.CountItems())
index = fItems.CountItems();
if (fItems.AddItem(item, index) && ItemAdded(item, index)) {
item->SetLayout(this);
if (!fAncestorsVisible)
item->AncestorVisibilityChanged(fAncestorsVisible);
InvalidateLayout();
return true;
} else {
// this check is necessary so that if an addition somewhere other
// than the end of the list fails, we don't remove the wrong item
if (fItems.ItemAt(index) == item)
fItems.RemoveItem(index);
if (addedView)
view->_RemoveSelf();
if (!fItems.AddItem(item, index))
return false;
if (!ItemAdded(item, index)) {
fItems.RemoveItem(index);
return false;
}
item->SetLayout(this);
if (!fAncestorsVisible)
item->AncestorVisibilityChanged(fAncestorsVisible);
InvalidateLayout();
remover.Detach();
return true;
}