diff --git a/headers/os/interface/View.h b/headers/os/interface/View.h index ec327d4166..9b3e98ca3d 100644 --- a/headers/os/interface/View.h +++ b/headers/os/interface/View.h @@ -1,5 +1,5 @@ /* - * Copyright 2001-2006, Haiku. + * Copyright 2001-2009, Haiku. * Distributed under the terms of the MIT License. * * Authors: @@ -532,6 +532,7 @@ public: void EnableLayoutInvalidation(); void DisableLayoutInvalidation(); bool IsLayoutValid() const; + void ResetLayoutInvalidation(); BLayoutContext* LayoutContext() const; diff --git a/src/kits/interface/CardLayout.cpp b/src/kits/interface/CardLayout.cpp index 778db59ef7..face9ebae9 100644 --- a/src/kits/interface/CardLayout.cpp +++ b/src/kits/interface/CardLayout.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2006, Ingo Weinhold . + * Copyright 2006-2009, Ingo Weinhold . * 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) return; - + if (fVisibleItem != NULL) fVisibleItem->SetVisible(false); @@ -107,7 +107,7 @@ BCardLayout::HasHeightForWidth() if (ItemAt(i)->HasHeightForWidth()) return true; } - + return false; } @@ -157,7 +157,7 @@ void BCardLayout::InvalidateLayout() { BLayout::InvalidateLayout(); - + fMinMaxValid = false; } @@ -231,6 +231,9 @@ BCardLayout::_ValidateMinMax() fPreferred.height = max_c(fPreferred.height, fMin.height); fPreferred.width = min_c(fPreferred.width, fMax.width); fPreferred.height = min_c(fPreferred.height, fMax.height); - + fMinMaxValid = true; + + if (BView* view = View()) + view->ResetLayoutInvalidation(); } diff --git a/src/kits/interface/SplitLayout.cpp b/src/kits/interface/SplitLayout.cpp index fd5066f0c8..dca0a61068 100644 --- a/src/kits/interface/SplitLayout.cpp +++ b/src/kits/interface/SplitLayout.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2006, Ingo Weinhold . + * Copyright 2006-2009, Ingo Weinhold . * All rights reserved. Distributed under the terms of the MIT License. */ @@ -1147,6 +1147,9 @@ BSplitLayout::_ValidateMinMax() fHorizontalLayoutInfo = fHorizontalLayouter->CreateLayoutInfo(); if (fHeightForWidthItems.IsEmpty()) fVerticalLayoutInfo = fVerticalLayouter->CreateLayoutInfo(); + + if (BView* view = View()) + view->ResetLayoutInvalidation(); } // _InternalGetHeightForWidth diff --git a/src/kits/interface/TwoDimensionalLayout.cpp b/src/kits/interface/TwoDimensionalLayout.cpp index 522cb001fd..15ca7a0d78 100644 --- a/src/kits/interface/TwoDimensionalLayout.cpp +++ b/src/kits/interface/TwoDimensionalLayout.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2006, Ingo Weinhold . + * Copyright 2006-2009, Ingo Weinhold . * All rights reserved. Distributed under the terms of the MIT License. */ @@ -448,6 +448,9 @@ void BTwoDimensionalLayout::_ValidateMinMax() { fLocalLayouter->ValidateMinMax(); + + if (BView* view = View()) + view->ResetLayoutInvalidation(); } // _CurrentLayoutContext diff --git a/src/kits/interface/View.cpp b/src/kits/interface/View.cpp index 58ad2a1846..9d2284993c 100644 --- a/src/kits/interface/View.cpp +++ b/src/kits/interface/View.cpp @@ -6,7 +6,7 @@ * Adrian Oanca * Axel Dörfler, axeld@pinc-software.de * Stephan Aßmus - * Ingo Weinhold + * Ingo Weinhold */ #include @@ -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