BALMLayout now takes the view min, max and pref values into account. Previously it managed its own values.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@38769 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Clemens Zeidler 2010-09-21 23:18:43 +00:00
parent 4243bc41f2
commit 8ec038986a
4 changed files with 122 additions and 143 deletions

View File

@ -54,12 +54,7 @@ public:
XTab* ContentRight() const;
YTab* ContentBottom() const;
BSize MinContentSize() const;
void SetMinContentSize(BSize min);
BSize MaxContentSize() const;
void SetMaxContentSize(BSize max);
BSize PreferredContentSize() const;
void SetPreferredContentSize(BSize preferred);
double ContentAspectRatio() const;
void SetContentAspectRatio(double ratio);
@ -94,6 +89,8 @@ public:
Constraint* HasSameHeightAs(Area* area);
BList* HasSameSizeAs(Area* area);
void InvalidateSizeConstraints();
protected:
Area(BALMLayout* layout, BLayoutItem* item);
@ -106,9 +103,13 @@ protected:
void DoLayout();
private:
void InitChildArea();
void UpdateHorizontal();
void UpdateVertical();
void _InitChildArea();
void _UpdateHorizontal();
void _UpdateVertical();
void _UpdateMinSizeConstraint(BSize min);
void _UpdateMaxSizeConstraint(BSize max);
void _UpdatePreferredConstraint(BSize preferred);
public:
static BSize kMaxSize;

View File

@ -79,6 +79,7 @@ public:
private:
Area* _AreaForItem(BLayoutItem* item) const;
void _UpdateAreaConstraints();
BSize CalculateMinSize();
BSize CalculateMaxSize();

View File

@ -91,7 +91,7 @@ Area::SetLeft(XTab* left)
if (fMaxContentWidth != NULL)
fMaxContentWidth->SetLeftSide(-1.0, fLeft, 1.0, fRight);
} else
UpdateHorizontal();
_UpdateHorizontal();
fALMLayout->InvalidateLayout();
}
@ -126,7 +126,7 @@ Area::SetRight(XTab* right)
if (fMaxContentWidth != NULL)
fMaxContentWidth->SetLeftSide(-1.0, fLeft, 1.0, fRight);
} else
UpdateHorizontal();
_UpdateHorizontal();
fALMLayout->InvalidateLayout();
}
@ -157,7 +157,7 @@ Area::SetTop(YTab* top)
if (fMaxContentHeight != NULL)
fMaxContentHeight->SetLeftSide(-1.0, fTop, 1.0, fBottom);
} else
UpdateVertical();
_UpdateVertical();
fALMLayout->InvalidateLayout();
}
@ -188,7 +188,7 @@ Area::SetBottom(YTab* bottom)
if (fMaxContentHeight != NULL)
fMaxContentHeight->SetLeftSide(-1.0, fTop, 1.0, fBottom);
} else
UpdateVertical();
_UpdateVertical();
fALMLayout->InvalidateLayout();
}
@ -281,112 +281,6 @@ Area::ContentBottom() const
}
/**
* Gets minimum size of the area's content.
*/
BSize
Area::MinContentSize() const
{
return (fChildArea == NULL) ? fMinContentSize : fChildArea->fMinContentSize;
}
/**
* Sets minimum size of the area's content.
* May be different from the minimum size of the area.
*/
void
Area::SetMinContentSize(BSize min)
{
if (fChildArea == NULL) {
fMinContentSize = min;
fMinContentWidth->SetRightSide(fMinContentSize.Width());
fMinContentHeight->SetRightSide(fMinContentSize.Height());
} else
fChildArea->SetMinContentSize(min);
fALMLayout->InvalidateLayout();
}
/**
* Gets maximum size of the area's content.
*/
BSize Area::MaxContentSize() const {
return (fChildArea == NULL) ? fMaxContentSize : fChildArea->fMaxContentSize;
}
/**
* Sets maximum size of the area's content.
* May be different from the maximum size of the area.
*/
void
Area::SetMaxContentSize(BSize max)
{
if (fChildArea == NULL) {
fMaxContentSize = max;
if (fMaxContentWidth == NULL) {
fMaxContentWidth = fLS->AddConstraint(-1.0, fLeft, 1.0, fRight, OperatorType(LE),
fMaxContentSize.Width());
fConstraints->AddItem(fMaxContentWidth);
fMaxContentHeight = fLS->AddConstraint(-1.0, fTop, 1.0, fBottom, OperatorType(LE),
fMaxContentSize.Height());
fConstraints->AddItem(fMaxContentHeight);
} else {
fMaxContentWidth->SetRightSide(fMaxContentSize.Width());
fMaxContentHeight->SetRightSide(fMaxContentSize.Height());
}
} else
fChildArea->SetMaxContentSize(max);
fALMLayout->InvalidateLayout();
}
/**
* Gets Preferred size of the area's content.
*/
BSize
Area::PreferredContentSize() const
{
return (fChildArea == NULL) ? fPreferredContentSize
: fChildArea->fPreferredContentSize;
}
/**
* Sets Preferred size of the area's content.
* May be different from the preferred size of the area.
* Manual changes of PreferredContentSize are ignored unless
* autoPreferredContentSize is set to false.
*/
void
Area::SetPreferredContentSize(BSize preferred)
{
if (fChildArea == NULL) {
fPreferredContentSize = preferred;
if (fPreferredContentWidth == NULL) {
fPreferredContentWidth = fLS->AddConstraint(
-1.0, fLeft, 1.0, fRight, OperatorType(EQ),
fPreferredContentSize.Width(), fShrinkPenalties.Width(),
fGrowPenalties.Width());
fConstraints->AddItem(fPreferredContentWidth);
fPreferredContentHeight = fLS->AddConstraint(
-1.0, fTop, 1.0, fBottom, OperatorType(EQ),
fPreferredContentSize.Height(), fShrinkPenalties.Height(),
fGrowPenalties.Height());
fConstraints->AddItem(fPreferredContentHeight);
} else {
fPreferredContentWidth->SetRightSide(preferred.Width());
fPreferredContentHeight->SetRightSide(preferred.Height());
}
} else
fChildArea->SetPreferredContentSize(preferred);
fALMLayout->InvalidateLayout();
}
/**
* The reluctance with which the area's content shrinks below its preferred size.
* The bigger the less likely is such shrinking.
@ -479,8 +373,8 @@ void
Area::SetExplicitAlignment(BAlignment alignment)
{
fAlignment = alignment;
UpdateHorizontal();
UpdateVertical();
_UpdateHorizontal();
_UpdateVertical();
fALMLayout->InvalidateLayout();
}
@ -491,7 +385,7 @@ Area::SetExplicitAlignment(BAlignment alignment)
*/
void Area::SetHorizontalAlignment(alignment horizontal) {
fAlignment.SetHorizontal(horizontal);
UpdateHorizontal();
_UpdateHorizontal();
fALMLayout->InvalidateLayout();
}
@ -503,7 +397,7 @@ void
Area::SetVerticalAlignment(vertical_alignment vertical)
{
fAlignment.SetVertical(vertical);
UpdateVertical();
_UpdateVertical();
fALMLayout->InvalidateLayout();
}
@ -525,7 +419,7 @@ void
Area::SetLeftInset(int32 left)
{
fLeftInset = left;
UpdateHorizontal();
_UpdateHorizontal();
fALMLayout->InvalidateLayout();
}
@ -547,7 +441,7 @@ void
Area::SetTopInset(int32 top)
{
fTopInset = top;
UpdateVertical();
_UpdateVertical();
fALMLayout->InvalidateLayout();
}
@ -569,7 +463,7 @@ void
Area::SetRightInset(int32 right)
{
fRightInset = right;
UpdateHorizontal();
_UpdateHorizontal();
}
@ -590,7 +484,7 @@ void
Area::SetBottomInset(int32 bottom)
{
fBottomInset = bottom;
UpdateVertical();
_UpdateVertical();
}
@ -602,17 +496,11 @@ void
Area::SetDefaultBehavior()
{
if (View() == NULL) {
SetPreferredContentSize(BSize(0, 0));
SetShrinkPenalties(BSize(0, 0));
SetGrowPenalties(BSize(0, 0));
return;
}
if (PreferredContentSize() != View()->PreferredSize()){
SetPreferredContentSize(View()->PreferredSize());
fALMLayout->InvalidateLayout();
}
if (dynamic_cast<BButton*>(View()) != NULL
|| dynamic_cast<BRadioButton*>(View()) != NULL
|| dynamic_cast<BCheckBox*>(View()) != NULL
@ -697,14 +585,26 @@ Area::HasSameSizeAs(Area* area)
}
void
Area::InvalidateSizeConstraints()
{
BSize minSize = fLayoutItem->MinSize();
BSize maxSize = fLayoutItem->MaxSize();
BSize prefSize = fLayoutItem->PreferredSize();
_UpdateMinSizeConstraint(minSize);
_UpdateMaxSizeConstraint(maxSize);
_UpdatePreferredConstraint(prefSize);
}
/**
* Destructor.
* Removes the area from its specification.
*/
Area::~Area()
{
if (fChildArea != NULL)
delete fChildArea;
delete fChildArea;
for (int32 i = 0; i < fConstraints->CountItems(); i++)
delete (Constraint*)fConstraints->ItemAt(i);
}
@ -816,7 +716,7 @@ void Area::DoLayout()
* i.e. when the user requests insets or special alignment.
*/
void
Area::InitChildArea()
Area::_InitChildArea()
{
// add a child area with new tabs,
// and add constraints that set its tabs to be equal to the
@ -842,7 +742,6 @@ Area::InitChildArea()
fConstraints->RemoveItem(fMinContentHeight);
delete fMinContentHeight;
fMinContentHeight = fChildArea->fMinContentHeight;
fChildArea->SetMinContentSize(fMinContentSize);
// if there are maximum content size constraints on this area,
// change them so that they refer to the tabs of the childArea
@ -882,11 +781,11 @@ Area::InitChildArea()
* Update the constraints for horizontal insets and alignment.
*/
void
Area::UpdateHorizontal()
Area::_UpdateHorizontal()
{
// if the area does not have a childAdrea yet, this is the time to add it
if (fChildArea == NULL)
InitChildArea();
_InitChildArea();
// change the constraints leftConstraint and rightConstraint so that the horizontal
// alignment and insets of the childArea within this area are as specified by the user
@ -937,10 +836,10 @@ Area::UpdateHorizontal()
/**
* Update the constraints for vertical insets and alignment.
*/
void Area::UpdateVertical() {
void Area::_UpdateVertical() {
// if the area does not have a childAdrea yet, this is the time to add it
if (fChildArea == NULL)
InitChildArea();
_InitChildArea();
// change the constraints topConstraint and bottomConstraint so that the vertical
// alignment and insets of the childArea within this area are as specified by the user
@ -987,3 +886,68 @@ void Area::UpdateVertical() {
}
}
void
Area::_UpdateMinSizeConstraint(BSize min)
{
if (fChildArea == NULL) {
fMinContentSize = min;
fMinContentWidth->SetRightSide(fMinContentSize.Width());
fMinContentHeight->SetRightSide(fMinContentSize.Height());
} else
fChildArea->_UpdateMinSizeConstraint(min);
}
void
Area::_UpdateMaxSizeConstraint(BSize max)
{
if (fChildArea == NULL) {
fMaxContentSize = max;
if (fMaxContentWidth == NULL) {
fMaxContentWidth = fLS->AddConstraint(-1.0, fLeft, 1.0, fRight,
OperatorType(LE), fMaxContentSize.Width());
fConstraints->AddItem(fMaxContentWidth);
fMaxContentHeight = fLS->AddConstraint(-1.0, fTop, 1.0, fBottom,
OperatorType(LE), fMaxContentSize.Height());
fConstraints->AddItem(fMaxContentHeight);
} else {
fMaxContentWidth->SetRightSide(fMaxContentSize.Width());
fMaxContentHeight->SetRightSide(fMaxContentSize.Height());
}
} else
fChildArea->_UpdateMaxSizeConstraint(max);
}
/**
* Sets Preferred size of the area's content.
* May be different from the preferred size of the area.
* Manual changes of PreferredContentSize are ignored unless
* autoPreferredContentSize is set to false.
*/
void
Area::_UpdatePreferredConstraint(BSize preferred)
{
if (fChildArea == NULL) {
fPreferredContentSize = preferred;
if (fPreferredContentWidth == NULL) {
fPreferredContentWidth = fLS->AddConstraint(
-1.0, fLeft, 1.0, fRight, OperatorType(EQ),
fPreferredContentSize.Width(), fShrinkPenalties.Width(),
fGrowPenalties.Width());
fConstraints->AddItem(fPreferredContentWidth);
fPreferredContentHeight = fLS->AddConstraint(
-1.0, fTop, 1.0, fBottom, OperatorType(EQ),
fPreferredContentSize.Height(), fShrinkPenalties.Height(),
fGrowPenalties.Height());
fConstraints->AddItem(fPreferredContentHeight);
} else {
fPreferredContentWidth->SetRightSide(preferred.Width());
fPreferredContentHeight->SetRightSide(preferred.Height());
}
} else
fChildArea->_UpdatePreferredConstraint(preferred);
}

View File

@ -457,8 +457,7 @@ BALMLayout::DerivedLayoutItems()
if (Owner() == NULL)
return;
//TODO
// _UpdateConstraints();
_UpdateAreaConstraints();
// reverse engineer a layout specification if none was given
//~ if (this == NULL) RecoverLayout(View());
@ -539,6 +538,8 @@ BALMLayout::Solver()
BSize
BALMLayout::CalculateMinSize()
{
_UpdateAreaConstraints();
SummandList* oldObjFunction = fSolver.ObjFunction();
SummandList* newObjFunction = new SummandList(2);
newObjFunction->AddItem(new Summand(1.0, fRight));
@ -570,6 +571,8 @@ BALMLayout::CalculateMinSize()
BSize
BALMLayout::CalculateMaxSize()
{
_UpdateAreaConstraints();
SummandList* oldObjFunction = fSolver.ObjFunction();
SummandList* newObjFunction = new SummandList(2);
newObjFunction->AddItem(new Summand(-1.0, fRight));
@ -601,6 +604,8 @@ BALMLayout::CalculateMaxSize()
BSize
BALMLayout::CalculatePreferredSize()
{
_UpdateAreaConstraints();
SolveLayout();
if (fSolver.Result() != OPTIMAL) {
fSolver.Save("failed-layout.txt");
@ -620,3 +625,11 @@ BALMLayout::_AreaForItem(BLayoutItem* item) const
return NULL;
return static_cast<Area*>(item->LayoutData());
}
void
BALMLayout::_UpdateAreaConstraints()
{
for (int i = 0; i < CountItems(); i++)
_AreaForItem(ItemAt(i))->InvalidateSizeConstraints();
}