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:
Ingo Weinhold
2009-06-29 14:18:12 +00:00
parent 23eb9a9e82
commit a0747aad3b
5 changed files with 45 additions and 12 deletions
+27 -4
View File
@@ -6,7 +6,7 @@
* Adrian Oanca <[email protected]>
* Axel Dörfler, [email protected]
* Stephan Aßmus <[email protected]>
* Ingo Weinhold <[email protected].de>
* Ingo Weinhold <ingo_weinhold@gmx.de>
*/
#include <View.h>
@@ -323,7 +323,8 @@ struct BView::LayoutData {
fLayoutInvalidationDisabled(0),
fLayout(NULL),
fLayoutContext(NULL),
fLayoutValid(true), // <- TODO: Rethink this!
fLayoutValid(true), // TODO: Rethink these initial values!
fMinMaxValid(true), //
fLayoutInProgress(false),
fNeedsRelayout(true)
{
@@ -337,6 +338,7 @@ struct BView::LayoutData {
BLayout* fLayout;
BLayoutContext* fLayoutContext;
bool fLayoutValid;
bool fMinMaxValid;
bool fLayoutInProgress;
bool fNeedsRelayout;
};
@@ -4489,12 +4491,13 @@ BView::GetLayout() const
void
BView::InvalidateLayout(bool descendants)
{
if (fLayoutData->fLayoutValid && !fLayoutData->fLayoutInProgress
if (fLayoutData->fMinMaxValid && !fLayoutData->fLayoutInProgress
&& fLayoutData->fLayoutInvalidationDisabled == 0) {
if (fParent && fParent->fLayoutData->fLayoutValid)
if (fParent && fParent->fLayoutData->fMinMaxValid)
fParent->InvalidateLayout(false);
fLayoutData->fLayoutValid = false;
fLayoutData->fMinMaxValid = false;
if (fLayoutData->fLayout)
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*
BView::LayoutContext() const
{
@@ -4594,6 +4616,7 @@ BView::_Layout(bool force, BLayoutContext* context)
fLayoutData->fLayoutInProgress = false;
fLayoutData->fLayoutValid = true;
fLayoutData->fMinMaxValid = true;
fLayoutData->fNeedsRelayout = false;
// layout children