After the first call to BView::InvalidateLayout() further invocations don't
invoke the layout's InvalidateLayout() anymore. This could cause problems when the layout caches layout related information and also updates those on calls other than LayoutView(). A call to such a method after an InvalidateLayout() would mark the cached info valid and the layout would use the cached info until the first InvalidateLayout() after the next LayoutView(), even if BView::InvalidateLayout() had been called again in the meantime. * Introduced a new method BView::ResetLayoutInvalidation(), which must be called by layout implementations whenever they have updated their cached information and need further InvalidateLayout() notifications. * Adjusted the existing layout implementations to use the method. Fixes bug #4047. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@31316 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2001-2006, Haiku.
|
* Copyright 2001-2009, Haiku.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
@@ -532,6 +532,7 @@ public:
|
|||||||
void EnableLayoutInvalidation();
|
void EnableLayoutInvalidation();
|
||||||
void DisableLayoutInvalidation();
|
void DisableLayoutInvalidation();
|
||||||
bool IsLayoutValid() const;
|
bool IsLayoutValid() const;
|
||||||
|
void ResetLayoutInvalidation();
|
||||||
|
|
||||||
BLayoutContext* LayoutContext() const;
|
BLayoutContext* LayoutContext() const;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2006, Ingo Weinhold <[email protected].de>.
|
* Copyright 2006-2009, Ingo Weinhold <ingo_weinhold@gmx.de>.
|
||||||
* All rights reserved. Distributed under the terms of the MIT License.
|
* All rights reserved. Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -54,7 +54,7 @@ BCardLayout::SetVisibleItem(BLayoutItem* item)
|
|||||||
|
|
||||||
if (item != NULL && IndexOfItem(item) < 0)
|
if (item != NULL && IndexOfItem(item) < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (fVisibleItem != NULL)
|
if (fVisibleItem != NULL)
|
||||||
fVisibleItem->SetVisible(false);
|
fVisibleItem->SetVisible(false);
|
||||||
|
|
||||||
@@ -107,7 +107,7 @@ BCardLayout::HasHeightForWidth()
|
|||||||
if (ItemAt(i)->HasHeightForWidth())
|
if (ItemAt(i)->HasHeightForWidth())
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -157,7 +157,7 @@ void
|
|||||||
BCardLayout::InvalidateLayout()
|
BCardLayout::InvalidateLayout()
|
||||||
{
|
{
|
||||||
BLayout::InvalidateLayout();
|
BLayout::InvalidateLayout();
|
||||||
|
|
||||||
fMinMaxValid = false;
|
fMinMaxValid = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -231,6 +231,9 @@ BCardLayout::_ValidateMinMax()
|
|||||||
fPreferred.height = max_c(fPreferred.height, fMin.height);
|
fPreferred.height = max_c(fPreferred.height, fMin.height);
|
||||||
fPreferred.width = min_c(fPreferred.width, fMax.width);
|
fPreferred.width = min_c(fPreferred.width, fMax.width);
|
||||||
fPreferred.height = min_c(fPreferred.height, fMax.height);
|
fPreferred.height = min_c(fPreferred.height, fMax.height);
|
||||||
|
|
||||||
fMinMaxValid = true;
|
fMinMaxValid = true;
|
||||||
|
|
||||||
|
if (BView* view = View())
|
||||||
|
view->ResetLayoutInvalidation();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2006, Ingo Weinhold <[email protected].de>.
|
* Copyright 2006-2009, Ingo Weinhold <ingo_weinhold@gmx.de>.
|
||||||
* All rights reserved. Distributed under the terms of the MIT License.
|
* All rights reserved. Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -1147,6 +1147,9 @@ BSplitLayout::_ValidateMinMax()
|
|||||||
fHorizontalLayoutInfo = fHorizontalLayouter->CreateLayoutInfo();
|
fHorizontalLayoutInfo = fHorizontalLayouter->CreateLayoutInfo();
|
||||||
if (fHeightForWidthItems.IsEmpty())
|
if (fHeightForWidthItems.IsEmpty())
|
||||||
fVerticalLayoutInfo = fVerticalLayouter->CreateLayoutInfo();
|
fVerticalLayoutInfo = fVerticalLayouter->CreateLayoutInfo();
|
||||||
|
|
||||||
|
if (BView* view = View())
|
||||||
|
view->ResetLayoutInvalidation();
|
||||||
}
|
}
|
||||||
|
|
||||||
// _InternalGetHeightForWidth
|
// _InternalGetHeightForWidth
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2006, Ingo Weinhold <[email protected].de>.
|
* Copyright 2006-2009, Ingo Weinhold <ingo_weinhold@gmx.de>.
|
||||||
* All rights reserved. Distributed under the terms of the MIT License.
|
* All rights reserved. Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -448,6 +448,9 @@ void
|
|||||||
BTwoDimensionalLayout::_ValidateMinMax()
|
BTwoDimensionalLayout::_ValidateMinMax()
|
||||||
{
|
{
|
||||||
fLocalLayouter->ValidateMinMax();
|
fLocalLayouter->ValidateMinMax();
|
||||||
|
|
||||||
|
if (BView* view = View())
|
||||||
|
view->ResetLayoutInvalidation();
|
||||||
}
|
}
|
||||||
|
|
||||||
// _CurrentLayoutContext
|
// _CurrentLayoutContext
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
* Adrian Oanca <[email protected]>
|
* Adrian Oanca <[email protected]>
|
||||||
* Axel Dörfler, [email protected]
|
* Axel Dörfler, [email protected]
|
||||||
* Stephan Aßmus <[email protected]>
|
* Stephan Aßmus <[email protected]>
|
||||||
* Ingo Weinhold <[email protected].de>
|
* Ingo Weinhold <ingo_weinhold@gmx.de>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <View.h>
|
#include <View.h>
|
||||||
@@ -323,7 +323,8 @@ struct BView::LayoutData {
|
|||||||
fLayoutInvalidationDisabled(0),
|
fLayoutInvalidationDisabled(0),
|
||||||
fLayout(NULL),
|
fLayout(NULL),
|
||||||
fLayoutContext(NULL),
|
fLayoutContext(NULL),
|
||||||
fLayoutValid(true), // <- TODO: Rethink this!
|
fLayoutValid(true), // TODO: Rethink these initial values!
|
||||||
|
fMinMaxValid(true), //
|
||||||
fLayoutInProgress(false),
|
fLayoutInProgress(false),
|
||||||
fNeedsRelayout(true)
|
fNeedsRelayout(true)
|
||||||
{
|
{
|
||||||
@@ -337,6 +338,7 @@ struct BView::LayoutData {
|
|||||||
BLayout* fLayout;
|
BLayout* fLayout;
|
||||||
BLayoutContext* fLayoutContext;
|
BLayoutContext* fLayoutContext;
|
||||||
bool fLayoutValid;
|
bool fLayoutValid;
|
||||||
|
bool fMinMaxValid;
|
||||||
bool fLayoutInProgress;
|
bool fLayoutInProgress;
|
||||||
bool fNeedsRelayout;
|
bool fNeedsRelayout;
|
||||||
};
|
};
|
||||||
@@ -4489,12 +4491,13 @@ BView::GetLayout() const
|
|||||||
void
|
void
|
||||||
BView::InvalidateLayout(bool descendants)
|
BView::InvalidateLayout(bool descendants)
|
||||||
{
|
{
|
||||||
if (fLayoutData->fLayoutValid && !fLayoutData->fLayoutInProgress
|
if (fLayoutData->fMinMaxValid && !fLayoutData->fLayoutInProgress
|
||||||
&& fLayoutData->fLayoutInvalidationDisabled == 0) {
|
&& fLayoutData->fLayoutInvalidationDisabled == 0) {
|
||||||
if (fParent && fParent->fLayoutData->fLayoutValid)
|
if (fParent && fParent->fLayoutData->fMinMaxValid)
|
||||||
fParent->InvalidateLayout(false);
|
fParent->InvalidateLayout(false);
|
||||||
|
|
||||||
fLayoutData->fLayoutValid = false;
|
fLayoutData->fLayoutValid = false;
|
||||||
|
fLayoutData->fMinMaxValid = false;
|
||||||
|
|
||||||
if (fLayoutData->fLayout)
|
if (fLayoutData->fLayout)
|
||||||
fLayoutData->fLayout->InvalidateLayout();
|
fLayoutData->fLayout->InvalidateLayout();
|
||||||
@@ -4536,6 +4539,25 @@ BView::IsLayoutValid() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*! \brief Service call for BLayout derived classes reenabling
|
||||||
|
InvalidateLayout() notifications.
|
||||||
|
BView::InvalidateLayout() invokes InvalidateLayout() on its layout the first
|
||||||
|
time, but suppresses further calls until Layout()/Relayout() has been
|
||||||
|
invoked. This method will reenable the notification for the next call of
|
||||||
|
BView::InvalidateLayout().
|
||||||
|
|
||||||
|
If the layout caches internal layout information and updates those
|
||||||
|
information also in methods other than LayoutView(), it has to invoke this
|
||||||
|
method, when it has done so, since otherwise the information might become
|
||||||
|
obsolete without the layout noticing.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
BView::ResetLayoutInvalidation()
|
||||||
|
{
|
||||||
|
fLayoutData->fMinMaxValid = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
BLayoutContext*
|
BLayoutContext*
|
||||||
BView::LayoutContext() const
|
BView::LayoutContext() const
|
||||||
{
|
{
|
||||||
@@ -4594,6 +4616,7 @@ BView::_Layout(bool force, BLayoutContext* context)
|
|||||||
fLayoutData->fLayoutInProgress = false;
|
fLayoutData->fLayoutInProgress = false;
|
||||||
|
|
||||||
fLayoutData->fLayoutValid = true;
|
fLayoutData->fLayoutValid = true;
|
||||||
|
fLayoutData->fMinMaxValid = true;
|
||||||
fLayoutData->fNeedsRelayout = false;
|
fLayoutData->fNeedsRelayout = false;
|
||||||
|
|
||||||
// layout children
|
// layout children
|
||||||
|
|||||||
Reference in New Issue
Block a user