- Areas with same tabs are put in a column/row automtically. Move preferred size constraint from Area to the column/row. This avoids a "spring" effect of the

quadratic solver if multiple Areas are in the same column/row.
- Replace GetString by ToString.
- some clean up



git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@40941 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Clemens Zeidler
2011-03-14 00:24:12 +00:00
parent 66c782cdc0
commit ef93b55df4
18 changed files with 540 additions and 662 deletions
+17 -9
View File
@@ -22,6 +22,10 @@
namespace BALM {
class RowColumnManager;
/*!
* A GUI layout engine using the Auckland Layout Model (ALM).
*/
@@ -33,9 +37,12 @@ public:
XTab* AddXTab();
YTab* AddYTab();
Row* AddRow();
int32 CountXTabs() const;
int32 CountYTabs() const;
XTab* XTabAt(int32 index) const;
YTab* YTabAt(int32 index) const;
Row* AddRow(YTab* top, YTab* bottom);
Column* AddColumn();
Column* AddColumn(XTab* left, XTab* right);
XTab* Left() const;
@@ -56,10 +63,11 @@ public:
Area* AreaFor(const BView* view) const;
Area* AreaFor(const BLayoutItem* item) const;
Area* AreaAt(int32 index) const;
Area* CurrentArea() const;
void SetCurrentArea(const Area* area);
void SetCurrentArea(const BView* view);
void SetCurrentArea(const BLayoutItem* item);
bool SetCurrentArea(const Area* area);
bool SetCurrentArea(const BView* view);
bool SetCurrentArea(const BLayoutItem* item);
XTab* LeftOf(const BView* view) const;
XTab* LeftOf(const BLayoutItem* item) const;
@@ -150,10 +158,10 @@ private:
Area* fCurrentArea;
#if USE_SCALE_VARIABLE
Variable* fScaleWidth;
Variable* fScaleHeight;
#endif
XTabList fXTabList;
YTabList fYTabList;
RowColumnManager* fRowColumnManager;
};
} // namespace BALM
+14 -31
View File
@@ -20,9 +20,6 @@
#include "Tab.h"
#define USE_SCALE_VARIABLE 0
class Constraint;
@@ -58,6 +55,9 @@ private:
};
class RowColumnManager;
/**
* Rectangular area in the GUI, defined by a tab on each side.
*/
@@ -65,7 +65,7 @@ class Area {
public:
~Area();
BView* View();
BLayoutItem* Item();
XTab* Left() const;
XTab* Right() const;
@@ -78,8 +78,6 @@ public:
Row* GetRow() const;
Column* GetColumn() const;
void SetRow(Row* row);
void SetColumn(Column* column);
double ContentAspectRatio() const;
void SetContentAspectRatio(double ratio);
@@ -98,40 +96,29 @@ public:
void SetRightInset(float right);
void SetBottomInset(float bottom);
operator BString() const;
void GetString(BString& string) const;
BString ToString() const;
Constraint* SetWidthAs(Area* area, float factor = 1.0f);
Constraint* SetHeightAs(Area* area, float factor = 1.0f);
void InvalidateSizeConstraints();
BRect Frame();
BRect ItemFrame();
private:
Area(BLayoutItem* item);
#if USE_SCALE_VARIABLE
void _Init(LinearSpec* ls, XTab* left, YTab* top,
XTab* right, YTab* bottom,
Variable* scaleWidth,
Variable* scaleHeight);
RowColumnManager* manager);
void _Init(LinearSpec* ls, Row* row, Column* column,
Variable* scaleWidth,
Variable* scaleHeight);
#else
void _Init(LinearSpec* ls, XTab* left, YTab* top,
XTab* right, YTab* bottom);
void _Init(LinearSpec* ls, Row* row, Column* column);
#endif
RowColumnManager* manager);
void _DoLayout();
void _UpdateMinSizeConstraint(BSize min);
void _UpdateMaxSizeConstraint(BSize max);
void _UpdatePreferredWidthConstraint(
BSize& preferred);
void _UpdatePreferredHeightConstraint(
BSize& preferred);
void _SetupPreferredConstraints();
private:
BLayoutItem* fLayoutItem;
@@ -151,22 +138,18 @@ private:
BSize fTopLeftInset;
BSize fRightBottomInset;
BList fConstraints;
BObjectList<Constraint> fConstraints;
Constraint* fMinContentWidth;
Constraint* fMaxContentWidth;
Constraint* fMinContentHeight;
Constraint* fMaxContentHeight;
Constraint* fPreferredContentWidth;
Constraint* fPreferredContentHeight;
double fContentAspectRatio;
Constraint* fContentAspectRatioC;
#if USE_SCALE_VARIABLE
Variable* fScaleWidth;
Variable* fScaleHeight;
#endif
RowColumnManager* fRowColumnManager;
public:
friend class BALMLayout;
friend class BALMLayout;
friend class RowColumnManager;
};
+11 -20
View File
@@ -13,7 +13,11 @@
namespace BALM {
class Area;
class BALMLayout;
class RowColumnManager;
/**
* Represents a column defined by two x-tabs.
@@ -24,34 +28,21 @@ public:
XTab* Left() const;
XTab* Right() const;
Column* Previous() const;
void SetPrevious(Column* value);
Column* Next() const;
void SetNext(Column* value);
void InsertBefore(Column* column);
void InsertAfter(Column* column);
Constraint* HasSameWidthAs(Column* column);
private:
Column(LinearSpec* ls, XTab* left, XTab* right);
ConstraintList* Constraints() const;
protected:
Column(BALMLayout* layout);
protected:
LinearSpec* fLS;
XTab* fLeft;
XTab* fRight;
private:
Column* fPrevious;
Column* fNext;
Constraint* fPreviousGlue;
Constraint* fNextGlue;
ConstraintList fConstraints;
//! managed by RowColumnManager
Constraint* fPrefSizeConstraint;
BObjectList<Area> fAreas;
public:
friend class BALMLayout;
friend class BALMLayout;
friend class BALM::RowColumnManager;
};
+11 -18
View File
@@ -13,7 +13,11 @@
namespace BALM {
class Area;
class BALMLayout;
class RowColumnManager;
/**
* Represents a row defined by two y-tabs.
@@ -24,32 +28,21 @@ public:
YTab* Top() const;
YTab* Bottom() const;
Row* Previous() const;
void SetPrevious(Row* value);
Row* Next() const;
void SetNext(Row* value);
void InsertBefore(Row* row);
void InsertAfter(Row* row);
Constraint* HasSameHeightAs(Row* row);
ConstraintList* Constraints() const;
protected:
Row(BALMLayout* layout);
private:
Row(LinearSpec* ls, YTab* top, YTab* bottom);
protected:
LinearSpec* fLS;
YTab* fTop;
YTab* fBottom;
private:
Row* fPrevious;
Row* fNext;
Constraint* fPreviousGlue;
Constraint* fNextGlue;
ConstraintList fConstraints;
//! managed by RowColumnManager
Constraint* fPrefSizeConstraint;
BObjectList<Area> fAreas;
public:
friend class BALMLayout;
friend class BALMLayout;
friend class BALM::RowColumnManager;
};
+5
View File
@@ -46,7 +46,12 @@ public:
} // namespace BALM
using BALM::XTab;
using BALM::YTab;
typedef BObjectList<XTab> XTabList;
typedef BObjectList<YTab> YTabList;
#endif // X_TAB_H
+1 -2
View File
@@ -64,8 +64,7 @@ public:
bool IsValid();
void Invalidate();
operator BString() const;
void GetString(BString& string) const;
BString ToString() const;
void PrintToStream();
~Constraint();
+1 -2
View File
@@ -129,8 +129,7 @@ public:
ResultType Result() const;
bigtime_t SolvingTime() const;
operator BString() const;
void GetString(BString& string) const;
BString ToString() const;
const ConstraintList& Constraints() const;
const VariableList& UsedVariables() const;
+2 -3
View File
@@ -35,8 +35,7 @@ public:
const char* Label();
void SetLabel(const char* label);
operator BString() const;
void GetString(BString& string) const;
BString ToString() const;
Constraint* IsEqual(Variable* var);
Constraint* IsSmallerOrEqual(Variable* var);
@@ -54,7 +53,7 @@ public:
//! delete it yourself!
void Invalidate();
~Variable();
virtual ~Variable();
protected:
Variable(LinearSpec* ls);
+116 -67
View File
@@ -12,6 +12,7 @@
#include <new>
#include <iostream>
#include "RowColumnManager.h"
#include "ViewLayoutItem.h"
@@ -30,10 +31,11 @@ const BSize kUnsetSize(B_SIZE_UNSET, B_SIZE_UNSET);
BALMLayout::BALMLayout(float spacing, BALMLayout* friendLayout)
:
fInset(0.0f),
fSpacing(spacing),
fSpacing(spacing / 2),
fCurrentArea(NULL)
{
fSolver = friendLayout ? friendLayout->Solver() : &fOwnSolver;
fRowColumnManager = new RowColumnManager(fSolver);
fLeft = AddXTab();
fRight = AddXTab();
@@ -52,20 +54,12 @@ BALMLayout::BALMLayout(float spacing, BALMLayout* friendLayout)
fPreferredSize = kUnsetSize;
fPerformancePath = NULL;
#if USE_SCALE_VARIABLE
fScaleWidth = fSolver->AddVariable();
fScaleHeight = fSolver->AddVariable();
#endif
}
BALMLayout::~BALMLayout()
{
#if USE_SCALE_VARIABLE
delete fScaleWidth;
delete fScaleHeight;
#endif
delete fRowColumnManager;
}
@@ -85,6 +79,7 @@ BALMLayout::AddXTab()
return NULL;
}
fXTabList.AddItem(tab);
return tab;
}
@@ -105,19 +100,36 @@ BALMLayout::AddYTab()
return NULL;
}
fYTabList.AddItem(tab);
return tab;
}
/**
* Adds a new row to the specification.
*
* @return the new row
*/
Row*
BALMLayout::AddRow()
int32
BALMLayout::CountXTabs() const
{
return new(std::nothrow) Row(this);
return fXTabList.CountItems();
}
int32
BALMLayout::CountYTabs() const
{
return fYTabList.CountItems();
}
XTab*
BALMLayout::XTabAt(int32 index) const
{
return fXTabList.ItemAt(index);
}
YTab*
BALMLayout::YTabAt(int32 index) const
{
return fYTabList.ItemAt(index);
}
@@ -131,24 +143,11 @@ BALMLayout::AddRow()
Row*
BALMLayout::AddRow(YTab* top, YTab* bottom)
{
Row* row = new(std::nothrow) Row(this);
if (top != NULL)
row->Constraints()->AddItem(row->Top()->IsEqual(top));
if (bottom != NULL)
row->Constraints()->AddItem(row->Bottom()->IsEqual(bottom));
return row;
}
/**
* Adds a new column to the specification.
*
* @return the new column
*/
Column*
BALMLayout::AddColumn()
{
return new(std::nothrow) Column(this);
if (top == NULL)
top = AddYTab();
if (bottom == NULL)
bottom = AddYTab();
return new(std::nothrow) Row(fSolver, top, bottom);
}
@@ -162,12 +161,11 @@ BALMLayout::AddColumn()
Column*
BALMLayout::AddColumn(XTab* left, XTab* right)
{
Column* column = new(std::nothrow) Column(this);
if (left != NULL)
column->Constraints()->AddItem(column->Left()->IsEqual(left));
if (right != NULL)
column->Constraints()->AddItem(column->Right()->IsEqual(right));
return column;
if (left == NULL)
left = AddXTab();
if (right == NULL)
right = AddXTab();
return new(std::nothrow) Column(fSolver, left, right);
}
@@ -193,6 +191,13 @@ BALMLayout::AreaFor(const BLayoutItem* item) const
}
Area*
BALMLayout::AreaAt(int32 index) const
{
return AreaFor(ItemAt(index));
}
Area*
BALMLayout::CurrentArea() const
{
@@ -200,80 +205,113 @@ BALMLayout::CurrentArea() const
}
void
bool
BALMLayout::SetCurrentArea(const Area* area)
{
fCurrentArea = const_cast<Area*>(area);
return true;
}
void
bool
BALMLayout::SetCurrentArea(const BView* view)
{
fCurrentArea = AreaFor(view);
Area* area = AreaFor(view);
if (!area)
return false;
fCurrentArea = area;
return true;
}
void
bool
BALMLayout::SetCurrentArea(const BLayoutItem* item)
{
fCurrentArea = AreaFor(item);
Area* area = AreaFor(item);
if (!area)
return false;
fCurrentArea = area;
return true;
}
XTab*
BALMLayout::LeftOf(const BView* view) const
{
return AreaFor(view)->Left();
Area* area = AreaFor(view);
if (!area)
return NULL;
return area->Left();
}
XTab*
BALMLayout::LeftOf(const BLayoutItem* item) const
{
return AreaFor(item)->Left();
Area* area = AreaFor(item);
if (!area)
return NULL;
return area->Left();
}
XTab*
BALMLayout::RightOf(const BView* view) const
{
return AreaFor(view)->Right();
Area* area = AreaFor(view);
if (!area)
return NULL;
return area->Right();
}
XTab*
BALMLayout::RightOf(const BLayoutItem* item) const
{
return AreaFor(item)->Right();
Area* area = AreaFor(item);
if (!area)
return NULL;
return area->Right();
}
YTab*
BALMLayout::TopOf(const BView* view) const
{
return AreaFor(view)->Top();
Area* area = AreaFor(view);
if (!area)
return NULL;
return area->Top();
}
YTab*
BALMLayout::TopOf(const BLayoutItem* item) const
{
return AreaFor(item)->Top();
Area* area = AreaFor(item);
if (!area)
return NULL;
return area->Top();
}
YTab*
BALMLayout::BottomOf(const BView* view) const
{
return AreaFor(view)->Bottom();
Area* area = AreaFor(view);
if (!area)
return NULL;
return area->Bottom();
}
YTab*
BALMLayout::BottomOf(const BLayoutItem* item) const
{
return AreaFor(item)->Bottom();
Area* area = AreaFor(item);
if (!area)
return NULL;
return area->Bottom();
}
@@ -480,6 +518,7 @@ BALMLayout::AddItem(BLayoutItem* item, XTab* left, YTab* top, XTab* right,
if (!bottom)
bottom = AddYTab();
// Area is added int ItemAdded
if (!BAbstractLayout::AddItem(-1, item))
return NULL;
Area* area = AreaFor(item);
@@ -487,11 +526,9 @@ BALMLayout::AddItem(BLayoutItem* item, XTab* left, YTab* top, XTab* right,
return NULL;
fCurrentArea = area;
#if USE_SCALE_VARIABLE
area->_Init(fSolver, left, top, right, bottom, fScaleWidth, fScaleHeight);
#else
area->_Init(fSolver, left, top, right, bottom);
#endif
area->_Init(fSolver, left, top, right, bottom, fRowColumnManager);
fRowColumnManager->AddArea(area);
return area;
}
@@ -506,11 +543,9 @@ BALMLayout::AddItem(BLayoutItem* item, Row* row, Column* column)
return NULL;
fCurrentArea = area;
#if USE_SCALE_VARIABLE
area->_Init(fSolver, row, column, fScaleWidth, fScaleHeight);
#else
area->_Init(fSolver, row, column);
#endif
area->_Init(fSolver, row, column, fRowColumnManager);
fRowColumnManager->AddArea(area);
return area;
}
@@ -519,6 +554,9 @@ Area*
BALMLayout::AddItemToRight(BLayoutItem* item, XTab* right, YTab* top,
YTab* bottom)
{
if (fCurrentArea == NULL)
return NULL;
XTab* left = fCurrentArea->Right();
if (!right)
right = AddXTab();
@@ -535,6 +573,9 @@ Area*
BALMLayout::AddItemToLeft(BLayoutItem* item, XTab* left, YTab* top,
YTab* bottom)
{
if (fCurrentArea == NULL)
return NULL;
if (!left)
left = AddXTab();
XTab* right = fCurrentArea->Left();
@@ -550,6 +591,9 @@ BALMLayout::AddItemToLeft(BLayoutItem* item, XTab* left, YTab* top,
Area*
BALMLayout::AddItemToTop(BLayoutItem* item, YTab* top, XTab* left, XTab* right)
{
if (fCurrentArea == NULL)
return NULL;
if (!left)
left = fCurrentArea->Left();
if (!right)
@@ -566,6 +610,9 @@ Area*
BALMLayout::AddItemToBottom(BLayoutItem* item, YTab* bottom, XTab* left,
XTab* right)
{
if (fCurrentArea == NULL)
return NULL;
if (!left)
left = fCurrentArea->Left();
if (!right)
@@ -692,6 +739,7 @@ void
BALMLayout::ItemRemoved(BLayoutItem* item, int32 fromIndex)
{
if (Area* area = AreaFor(item)) {
fRowColumnManager->RemoveArea(area);
item->SetLayoutData(NULL);
delete area;
}
@@ -779,14 +827,14 @@ BALMLayout::Inset() const
void
BALMLayout::SetSpacing(float spacing)
{
fSpacing = spacing;
fSpacing = spacing / 2;
}
float
BALMLayout::Spacing() const
{
return fSpacing;
return fSpacing * 2;
}
@@ -846,4 +894,5 @@ BALMLayout::_UpdateAreaConstraints()
{
for (int i = 0; i < CountItems(); i++)
AreaFor(ItemAt(i))->InvalidateSizeConstraints();
fRowColumnManager->UpdateConstraints();
}
+42 -173
View File
@@ -18,6 +18,7 @@
#include <StringView.h>
#include "ALMLayout.h"
#include "RowColumnManager.h"
using namespace LinearProgramming;
@@ -111,10 +112,10 @@ GroupItem::_AddItem(const GroupItem& item, enum orientation orien)
}
BView*
Area::View()
BLayoutItem*
Area::Item()
{
return fLayoutItem->View();
return fLayoutItem;
}
@@ -175,11 +176,9 @@ Area::SetLeft(XTab* left)
fColumn = NULL;
fMinContentWidth->SetLeftSide(-1.0, fLeft, 1.0, fRight);
BSize preferredSize = fLayoutItem->PreferredSize();
_UpdatePreferredWidthConstraint(preferredSize);
if (fMaxContentWidth != NULL)
fMaxContentWidth->SetLeftSide(-1.0, fLeft, 1.0, fRight);
fRowColumnManager->TabsChanged(this);
fLayoutItem->Layout()->InvalidateLayout();
}
@@ -198,10 +197,9 @@ Area::SetRight(XTab* right)
fColumn = NULL;
fMinContentWidth->SetLeftSide(-1.0, fLeft, 1.0, fRight);
BSize preferredSize = fLayoutItem->PreferredSize();
_UpdatePreferredWidthConstraint(preferredSize);
if (fMaxContentWidth != NULL)
fMaxContentWidth->SetLeftSide(-1.0, fLeft, 1.0, fRight);
fRowColumnManager->TabsChanged(this);
fLayoutItem->Layout()->InvalidateLayout();
}
@@ -218,10 +216,9 @@ Area::SetTop(YTab* top)
fRow = NULL;
fMinContentHeight->SetLeftSide(-1.0, fTop, 1.0, fBottom);
BSize preferredSize = fLayoutItem->PreferredSize();
_UpdatePreferredHeightConstraint(preferredSize);
if (fMaxContentHeight != NULL)
fMaxContentHeight->SetLeftSide(-1.0, fTop, 1.0, fBottom);
fRowColumnManager->TabsChanged(this);
fLayoutItem->Layout()->InvalidateLayout();
}
@@ -238,10 +235,9 @@ Area::SetBottom(YTab* bottom)
fRow = NULL;
fMinContentHeight->SetLeftSide(-1.0, fTop, 1.0, fBottom);
BSize preferredSize = fLayoutItem->PreferredSize();
_UpdatePreferredHeightConstraint(preferredSize);
if (fMaxContentHeight != NULL)
fMaxContentHeight->SetLeftSide(-1.0, fTop, 1.0, fBottom);
fRowColumnManager->TabsChanged(this);
fLayoutItem->Layout()->InvalidateLayout();
}
@@ -267,34 +263,6 @@ Area::GetColumn() const
}
/**
* Sets the row that defines the top and bottom tabs.
* May be null.
*/
void
Area::SetRow(Row* row)
{
SetTop(row->Top());
SetBottom(row->Bottom());
fRow = row;
fLayoutItem->Layout()->InvalidateLayout();
}
/**
* Sets the column that defines the left and right tabs.
* May be null.
*/
void
Area::SetColumn(Column* column)
{
SetLeft(column->Left());
SetRight(column->Right());
fColumn = column;
fLayoutItem->Layout()->InvalidateLayout();
}
/**
* The reluctance with which the area's content shrinks below its preferred size.
* The bigger the less likely is such shrinking.
@@ -317,12 +285,10 @@ Area::GrowPenalties() const
}
void Area::SetShrinkPenalties(BSize shrink) {
void
Area::SetShrinkPenalties(BSize shrink) {
fShrinkPenalties = shrink;
if (fPreferredContentWidth != NULL) {
fPreferredContentWidth->SetPenaltyNeg(shrink.Width());
fPreferredContentHeight->SetPenaltyNeg(shrink.Height());
}
fLayoutItem->Layout()->InvalidateLayout();
}
@@ -331,10 +297,7 @@ void
Area::SetGrowPenalties(BSize grow)
{
fGrowPenalties = grow;
if (fPreferredContentWidth != NULL) {
fPreferredContentWidth->SetPenaltyPos(grow.Width());
fPreferredContentHeight->SetPenaltyPos(grow.Height());
}
fLayoutItem->Layout()->InvalidateLayout();
}
@@ -480,26 +443,19 @@ Area::SetBottomInset(float bottom)
}
Area::operator BString() const
BString
Area::ToString() const
{
BString string;
GetString(string);
return string;
}
void
Area::GetString(BString& string) const
{
string << "Area(";
fLeft->GetString(string);
BString string = "Area(";
string += fLeft->ToString();
string << ", ";
fTop->GetString(string);
string += fTop->ToString();
string << ", ";
fRight->GetString(string);
string += fRight->ToString();
string << ", ";
fBottom->GetString(string);
string += fBottom->ToString();
string << ")";
return string;
}
@@ -542,12 +498,24 @@ Area::InvalidateSizeConstraints()
BSize minSize = fLayoutItem->MinSize();
BSize maxSize = fLayoutItem->MaxSize();
BSize prefSize = fLayoutItem->PreferredSize();
_UpdateMinSizeConstraint(minSize);
_UpdateMaxSizeConstraint(maxSize);
_UpdatePreferredWidthConstraint(prefSize);
_UpdatePreferredHeightConstraint(prefSize);
}
BRect
Area::Frame()
{
return BRect(fLeft->Value(), fTop->Value(), fRight->Value(),
fBottom->Value());
}
BRect
Area::ItemFrame()
{
return fLayoutItem->Frame();
}
@@ -558,7 +526,7 @@ Area::InvalidateSizeConstraints()
Area::~Area()
{
for (int32 i = 0; i < fConstraints.CountItems(); i++)
delete (Constraint*)fConstraints.ItemAt(i);
delete fConstraints.ItemAt(i);
}
@@ -586,8 +554,6 @@ Area::Area(BLayoutItem* item)
fMaxContentWidth(NULL),
fMinContentHeight(NULL),
fMaxContentHeight(NULL),
fPreferredContentWidth(NULL),
fPreferredContentHeight(NULL),
fContentAspectRatio(-1),
fContentAspectRatioC(NULL)
@@ -599,24 +565,18 @@ Area::Area(BLayoutItem* item)
/**
* Initialize variables.
*/
#if USE_SCALE_VARIABLE
void
Area::_Init(LinearSpec* ls, XTab* left, YTab* top, XTab* right, YTab* bottom,
Variable* scaleWidth, Variable* scaleHeight)
RowColumnManager* manager)
{
fScaleWidth = scaleWidth;
fScaleHeight = scaleHeight;
#else
void
Area::_Init(LinearSpec* ls, XTab* left, YTab* top, XTab* right, YTab* bottom)
{
#endif
fLS = ls;
fLeft = left;
fRight = right;
fTop = top;
fBottom = bottom;
fRowColumnManager = manager;
// adds the two essential constraints of the area that make sure that the
// left x-tab is really to the left of the right x-tab, and the top y-tab
// really above the bottom y-tab
@@ -625,31 +585,14 @@ Area::_Init(LinearSpec* ls, XTab* left, YTab* top, XTab* right, YTab* bottom)
fConstraints.AddItem(fMinContentWidth);
fConstraints.AddItem(fMinContentHeight);
_SetupPreferredConstraints();
BSize preferredSize = fLayoutItem->PreferredSize();
_UpdatePreferredWidthConstraint(preferredSize);
_UpdatePreferredHeightConstraint(preferredSize);
fConstraints.AddItem(fPreferredContentWidth);
fConstraints.AddItem(fPreferredContentHeight);
}
#if USE_SCALE_VARIABLE
void
Area::_Init(LinearSpec* ls, Row* row, Column* column, Variable* scaleWidth,
Variable* scaleHeight)
Area::_Init(LinearSpec* ls, Row* row, Column* column, RowColumnManager* manager)
{
_Init(ls, column->Left(), row->Top(), column->Right(), row->Bottom(),
scaleWidth, scaleHeight);
#else
void
Area::_Init(LinearSpec* ls, Row* row, Column* column)
{
_Init(ls, column->Left(), row->Top(), column->Right(), row->Bottom());
#endif
_Init(ls, column->Left(), row->Top(), column->Right(), row->Bottom(), manager);
fRow = row;
fColumn = column;
}
@@ -728,77 +671,3 @@ Area::_UpdateMaxSizeConstraint(BSize max)
fMaxContentWidth = NULL;
}
}
void
Area::_UpdatePreferredWidthConstraint(BSize& preferred)
{
if (preferred.width == -1) {
delete fPreferredContentWidth;
fPreferredContentWidth = NULL;
return;
}
float width = 0;
if (preferred.width > 0)
width = preferred.width + LeftInset() + RightInset();
_SetupPreferredConstraints();
#if USE_SCALE_VARIABLE
fPreferredContentWidth->SetLeftSide(-1.0, fLeft, 1.0, fRight, -width,
fScaleWidth);
#else
fPreferredContentWidth->SetRightSide(width);
#endif
}
void
Area::_UpdatePreferredHeightConstraint(BSize& preferred)
{
if (preferred.height == -1) {
delete fPreferredContentHeight;
fPreferredContentHeight = NULL;
return;
}
float height = 0;
if (preferred.height > 0)
height = preferred.height + TopInset() + BottomInset();
_SetupPreferredConstraints();
#if USE_SCALE_VARIABLE
fPreferredContentHeight->SetLeftSide(-1.0, fTop, 1.0, fBottom, -height,
fScaleHeight);
#else
fPreferredContentHeight->SetRightSide(height);
#endif
}
void
Area::_SetupPreferredConstraints()
{
#if USE_SCALE_VARIABLE
if (!fPreferredContentWidth) {
fPreferredContentWidth = fLS->AddConstraint(-1.0, fLeft, 1.0, fRight,
-1.0, fScaleWidth, kEQ, 0, fShrinkPenalties.Width(),
fGrowPenalties.Width());
}
if (!fPreferredContentHeight) {
fPreferredContentHeight = fLS->AddConstraint(-1.0, fTop, 1.0, fBottom,
-1.0, fScaleHeight, kEQ, 0, fShrinkPenalties.Height(),
fGrowPenalties.Height());
}
#else
if (!fPreferredContentWidth) {
fPreferredContentWidth = fLS->AddConstraint(-1.0, fLeft, 1.0, fRight,
kEQ, 0, fShrinkPenalties.Width(), fGrowPenalties.Width());
}
if (!fPreferredContentHeight) {
fPreferredContentHeight = fLS->AddConstraint(-1.0, fTop, 1.0, fBottom,
kEQ, 0, fShrinkPenalties.Height(), fGrowPenalties.Height());
}
#endif
}
+9 -147
View File
@@ -1,4 +1,5 @@
/*
* Copyright 2007-2011, Haiku, Inc. All rights reserved.
* Copyright 2007-2008, Christof Lutteroth, lutteroth@cs.auckland.ac.nz
* Copyright 2007-2008, James Kim, jkim202@ec.auckland.ac.nz
* Copyright 2010, Clemens Zeidler <haiku@clemens-zeidler.de>
@@ -35,164 +36,25 @@ Column::Right() const
}
/**
* Gets the column directly to the left of this column.
*/
Column*
Column::Previous() const
{
return fPrevious;
}
/**
* Sets the column directly to the left of this column.
* May be null.
*/
void
Column::SetPrevious(Column* value)
{
// if there should be no column directly left of this column, then we have to
// separate any such column and can remove any constraint that was used
// to glue this column to it
if (value == NULL) {
if (fPrevious == NULL) return;
fPrevious->fNext = NULL;
fPrevious->fNextGlue = NULL;
fPrevious = NULL;
delete fPreviousGlue;
fPreviousGlue = NULL;
return;
}
// otherwise we have to set up the pointers and the glue constraint accordingly
if (value->fNext != NULL)
value->SetNext(NULL);
if (fPrevious != NULL)
SetPrevious(NULL);
fPrevious = value;
fPrevious->fNext = this;
value->fNextGlue = value->Right()->IsEqual(Left());
fPreviousGlue = value->fNextGlue;
}
/**
* Gets the column directly to the right of this column.
*/
Column*
Column::Next() const
{
return fNext;
}
/**
* Sets the column directly to the right of this column.
* May be null.
*/
void
Column::SetNext(Column* value)
{
// if there should be no column directly right of this column, then we have to
// separate any such column and can remove any constraint that was used
// to glue this column to it
if (value == NULL) {
if (fNext == NULL) return;
fNext->fPrevious = NULL;
fNext->fPreviousGlue = NULL;
fNext = NULL;
delete fNextGlue;
fNextGlue = NULL;
return;
}
// otherwise we have to set up the pointers and the glue constraint accordingly
if (value->fPrevious != NULL)
value->SetPrevious(NULL);
if (fNext != NULL)
SetNext(NULL);
fNext = value;
fNext->fPrevious = this;
value->fPreviousGlue = Right()->IsEqual(value->Left());
fNextGlue = value->fPreviousGlue;
}
/**
* Inserts the given column directly to the left of this column.
*
* @param column the column to insert
*/
void
Column::InsertBefore(Column* column)
{
SetPrevious(column->fPrevious);
SetNext(column);
}
/**
* Inserts the given column directly to the right of this column.
*
* @param column the column to insert
*/
void
Column::InsertAfter(Column* column)
{
SetNext(column->fNext);
SetPrevious(column);
}
/**
* Constrains this column to have the same width as the given column.
*
* @param column the column that should have the same width
* @return the resulting same-width constraint
*/
Constraint*
Column::HasSameWidthAs(Column* column)
{
Constraint* constraint = fLS->AddConstraint(
-1.0, Left(), 1.0, Right(), 1.0, column->Left(), -1.0, column->Right(),
kEQ, 0.0);
fConstraints.AddItem(constraint);
return constraint;
}
ConstraintList*
Column::Constraints() const
{
return const_cast<ConstraintList*>(&fConstraints);
}
/**
* Destructor.
* Removes the column from the specification.
*/
Column::~Column()
{
if (fPrevious != NULL)
fPrevious->SetNext(fNext);
for (int32 i = 0; i < fConstraints.CountItems(); i++)
delete fConstraints.ItemAt(i);
delete fLeft;
delete fRight;
delete fPrefSizeConstraint;
}
/**
* Constructor.
*/
Column::Column(BALMLayout* layout)
Column::Column(LinearSpec* ls, XTab* left, XTab* right)
:
fLS(ls),
fLeft(left),
fRight(right),
fPrefSizeConstraint(NULL)
{
fLS = layout->Solver();
fLeft = layout->AddXTab();
fRight = layout->AddXTab();
}
}
+5 -4
View File
@@ -1,17 +1,18 @@
SubDir HAIKU_TOP src libs alm ;
SetSubDirSupportedPlatformsBeOSCompatible ;
UseLibraryHeaders lp_solve linprog alm ;
UsePrivateHeaders shared ;
UseHeaders [ FDirName $(SUBDIR) $(DOTDOT) $(DOTDOT) kits interface ] ;
SharedLibrary libalm.so :
SharedLibrary libalm.so :
ALMLayout.cpp
Area.cpp
Column.cpp
ALMLayout.cpp
Row.cpp
RowColumnManager.cpp
:
liblpsolve55.so liblinprog.a be $(TARGET_LIBSTDC++)
liblpsolve55.so liblinprog.a
be $(TARGET_LIBSTDC++)
;
+9 -151
View File
@@ -1,4 +1,5 @@
/*
* Copyright 2007-2011, Haiku, Inc. All rights reserved.
* Copyright 2007-2008, Christof Lutteroth, lutteroth@cs.auckland.ac.nz
* Copyright 2007-2008, James Kim, jkim202@ec.auckland.ac.nz
* Copyright 2010, Clemens Zeidler <haiku@clemens-zeidler.de>
@@ -37,169 +38,26 @@ Row::Bottom() const
}
/**
* Gets the row directly above this row.
*/
Row*
Row::Previous() const
{
return fPrevious;
}
/**
* Sets the row directly above this row.
* May be null.
*/
void
Row::SetPrevious(Row* value)
{
// if there should be no row directly above this row, then we have to
// separate any such row and can remove any constraint that was used
// to glue this row to it
if (value == NULL) {
if (fPrevious == NULL)
return;
fPrevious->fNext = NULL;
fPrevious->fNextGlue = NULL;
fPrevious = NULL;
delete fPreviousGlue;
fPreviousGlue = NULL;
return;
}
// otherwise we have to set up the pointers and the glue constraint accordingly
if (value->fNext != NULL)
value->SetNext(NULL);
if (fPrevious != NULL)
SetPrevious(NULL);
fPrevious = value;
fPrevious->fNext = this;
value->fNextGlue = value->Bottom()->IsEqual(Top());
fPreviousGlue = value->fNextGlue;
}
/**
* Gets the row directly below this row.
*/
Row*
Row::Next() const
{
return fNext;
}
/**
* Sets the row directly below this row.
* May be null.
*/
void
Row::SetNext(Row* value)
{
// if there should be no row directly below this row, then we have to
// separate any such row and can remove any constraint that was used
// to glue this row to it
if (value == NULL) {
if (fNext == NULL)
return;
fNext->fPrevious = NULL;
fNext->fPreviousGlue = NULL;
fNext = NULL;
delete fNextGlue;
fNextGlue = NULL;
return;
}
// otherwise we have to set up the pointers and the glue constraint accordingly
if (value->fPrevious != NULL)
value->SetPrevious(NULL);
if (fNext != NULL)
SetNext(NULL);
fNext = value;
fNext->fPrevious = this;
value->fPreviousGlue = Bottom()->IsEqual(value->Top());
fNextGlue = value->fPreviousGlue;
}
/**
* Inserts the given row directly above this row.
*
* @param row the row to insert
*/
void
Row::InsertBefore(Row* row)
{
SetPrevious(row->fPrevious);
SetNext(row);
}
/**
* Inserts the given row directly below this row.
*
* @param row the row to insert
*/
void
Row::InsertAfter(Row* row)
{
SetNext(row->fNext);
SetPrevious(row);
}
/**
* Constrains this row to have the same height as the given row.
*
* @param row the row that should have the same height
* @return the resulting same-height constraint
*/
Constraint*
Row::HasSameHeightAs(Row* row)
{
Constraint* constraint = fLS->AddConstraint(
-1.0, Top(), 1.0, Bottom(), 1.0, row->Top(), -1.0, row->Bottom(), kEQ,
0.0);
fConstraints.AddItem(constraint);
return constraint;
}
/**
* Gets the constraints.
*/
ConstraintList*
Row::Constraints() const
{
return const_cast<ConstraintList*>(&fConstraints);
}
/**
* Destructor.
* Removes the row from the specification.
*/
Row::~Row()
{
if (fPrevious != NULL)
fPrevious->SetNext(fNext);
for (int32 i = 0; i < fConstraints.CountItems(); i++)
delete (Constraint*)fConstraints.ItemAt(i);
delete fTop;
delete fBottom;
delete fPrefSizeConstraint;
}
/**
* Constructor.
*/
Row::Row(BALMLayout* layout)
Row::Row(LinearSpec* ls, YTab* top, YTab* bottom)
:
fLS(ls),
fTop(top),
fBottom(bottom),
fPrefSizeConstraint(NULL)
{
fLS = layout->Solver();
fTop = layout->AddYTab();
fBottom = layout->AddYTab();
}
+226
View File
@@ -0,0 +1,226 @@
/*
* Copyright 2011, Haiku, Inc. All rights reserved.
* Copyright 2011, Clemens Zeidler <haiku@clemens-zeidler.de>
* Distributed under the terms of the MIT License.
*/
#include "RowColumnManager.h"
#include <LayoutItem.h>
using namespace LinearProgramming;
namespace BALM {
RowColumnManager::RowColumnManager(LinearSpec* spec)
:
fLinearSpec(spec)
{
}
RowColumnManager::~RowColumnManager()
{
for (int32 i = 0; i < fRows.CountItems(); i++)
delete fRows.ItemAt(i)->fPrefSizeConstraint;
for (int32 i = 0; i < fColumns.CountItems(); i++)
delete fColumns.ItemAt(i)->fPrefSizeConstraint;
}
void
RowColumnManager::AddArea(Area* area)
{
Row* row = _FindRowFor(area);
if (row == NULL) {
row = new Row(fLinearSpec, area->Top(), area->Bottom());
fRows.AddItem(row);
area->fRow = row;
}
row->fAreas.AddItem(area);
Column* column = _FindColumnFor(area);
if (column == NULL) {
column = new Column(fLinearSpec, area->Left(), area->Right());
fColumns.AddItem(column);
area->fColumn = column;
}
column->fAreas.AddItem(area);
_UpdateConstraints(row);
_UpdateConstraints(column);
}
void
RowColumnManager::RemoveArea(Area* area)
{
Row* row = _FindRowFor(area);
if (row) {
row->fAreas.RemoveItem(area);
if (row->fAreas.CountItems() == 0) {
fRows.RemoveItem(row);
delete row;
} else
_UpdateConstraints(row);
}
Column* column = _FindColumnFor(area);
if (column) {
column->fAreas.RemoveItem(area);
if (column->fAreas.CountItems() == 0) {
fColumns.RemoveItem(column);
delete column;
} else
_UpdateConstraints(column);
}
}
void
RowColumnManager::UpdateConstraints()
{
for (int32 i = 0; i < fRows.CountItems(); i++)
_UpdateConstraints(fRows.ItemAt(i));
for (int32 i = 0; i < fColumns.CountItems(); i++)
_UpdateConstraints(fColumns.ItemAt(i));
}
void
RowColumnManager::TabsChanged(Area* area)
{
RemoveArea(area);
AddArea(area);
}
Row*
RowColumnManager::_FindRowFor(Area* area)
{
for (int32 i = 0; i < fRows.CountItems(); i++) {
Row* row = fRows.ItemAt(i);
if (row->fTop == area->Top() && row->fBottom == area->Bottom())
return row;
}
return NULL;
}
Column*
RowColumnManager::_FindColumnFor(Area* area)
{
for (int32 i = 0; i < fColumns.CountItems(); i++) {
Column* column = fColumns.ItemAt(i);
if (column->fLeft == area->Left() && column->fRight == area->Right())
return column;
}
return NULL;
}
double
RowColumnManager::_PreferredHeight(Row* row, double& weight)
{
weight = 0;
int nAreas = 0;
double pref = 0;
for (int32 i = 0; i < row->fAreas.CountItems(); i++) {
BSize prefSize = row->fAreas.ItemAt(i)->Item()->PreferredSize();
if (prefSize.height > 0) {
nAreas++;
pref += prefSize.height;
}
double negPen = row->fAreas.ItemAt(i)->ShrinkPenalties().height;
if (negPen > 0)
weight += negPen;
}
if (nAreas == 0) {
pref = 0;
weight = 1;
} else {
pref /= nAreas;
weight /= nAreas;
}
return pref;
}
double
RowColumnManager::_PreferredWidth(Column* column, double& weight)
{
weight = 0;
int nAreas = 0;
double pref = 0;
for (int32 i = 0; i < column->fAreas.CountItems(); i++) {
BSize prefSize = column->fAreas.ItemAt(i)->Item()->PreferredSize();
if (prefSize.width > 0) {
nAreas++;
pref += prefSize.width;
}
double negPen = column->fAreas.ItemAt(i)->ShrinkPenalties().height;
if (negPen > 0)
weight += negPen;
}
if (nAreas == 0) {
pref = 0;
weight = 1;
} else {
pref /= nAreas;
weight /= nAreas;
}
return pref;
}
void
RowColumnManager::_UpdateConstraints(Row* row)
{
double weight;
double prefSize = _PreferredHeight(row, weight);
if (prefSize >= 0) {
if (row->fPrefSizeConstraint == NULL) {
row->fPrefSizeConstraint = fLinearSpec->AddConstraint(1,
row->fBottom, -1, row->fTop, kEQ, prefSize, weight, weight);
} else {
row->fPrefSizeConstraint->SetRightSide(prefSize);
row->fPrefSizeConstraint->SetPenaltyNeg(weight);
row->fPrefSizeConstraint->SetPenaltyPos(weight);
}
} else {
delete row->fPrefSizeConstraint;
row->fPrefSizeConstraint = NULL;
}
}
void
RowColumnManager::_UpdateConstraints(Column* column)
{
double weight;
double prefSize = _PreferredWidth(column, weight);
if (prefSize >= 0) {
if (column->fPrefSizeConstraint == NULL) {
column->fPrefSizeConstraint = fLinearSpec->AddConstraint(1,
column->fRight, -1, column->fLeft, kEQ, prefSize, weight,
weight);
} else {
column->fPrefSizeConstraint->SetRightSide(prefSize);
column->fPrefSizeConstraint->SetPenaltyNeg(weight);
column->fPrefSizeConstraint->SetPenaltyPos(weight);
}
} else {
delete column->fPrefSizeConstraint;
column->fPrefSizeConstraint = NULL;
}
}
} // end BALM namespace
+55
View File
@@ -0,0 +1,55 @@
/*
* Copyright 2011, Haiku, Inc. All rights reserved.
* Copyright 2011, Clemens Zeidler <haiku@clemens-zeidler.de>
* Distributed under the terms of the MIT License.
*/
#ifndef ROW_COLUMN_MANAGER_H
#define ROW_COLUMN_MANAGER_H
#include "Area.h"
#include "Column.h"
#include "LinearSpec.h"
#include "Row.h"
#include "Tab.h"
namespace BALM {
class RowColumnManager {
public:
RowColumnManager(LinearSpec* spec);
~RowColumnManager();
void AddArea(Area* area);
void RemoveArea(Area* area);
void UpdateConstraints();
void TabsChanged(Area* area);
Row* CreateRow(YTab* top, YTab* bottom);
Column* CreateColumn(XTab* left, XTab* right);
private:
Row* _FindRowFor(Area* area);
Column* _FindColumnFor(Area* area);
double _PreferredHeight(Row* row,
double& weight);
double _PreferredWidth(Column* column,
double& weight);
void _UpdateConstraints(Row* row);
void _UpdateConstraints(Column* column);
BObjectList<Row> fRows;
BObjectList<Column> fColumns;
LinearSpec* fLinearSpec;
};
} // namespace BALM
#endif // ROW_COLUMN_MANAGER_H
+4 -11
View File
@@ -325,17 +325,10 @@ Constraint::Invalidate()
}
Constraint::operator BString() const
BString
Constraint::ToString() const
{
BString string;
GetString(string);
return string;
}
void
Constraint::GetString(BString& string) const
{
string << "Constraint ";
string << fLabel;
string << "(" << (int32)this << "): ";
@@ -357,14 +350,14 @@ Constraint::GetString(BString& string) const
string << " PenaltyNeg=" << (float)PenaltyNeg();
} else
string << "invalid";
return string;
}
void
Constraint::PrintToStream()
{
BString string;
GetString(string);
BString string = ToString();
printf("%s\n", string.String());
}
+7 -13
View File
@@ -618,28 +618,21 @@ LinearSpec::SolvingTime() const
}
LinearSpec::operator BString() const
BString
LinearSpec::ToString() const
{
BString string;
GetString(string);
return string;
}
void
LinearSpec::GetString(BString& string) const
{
string << "LinearSpec " << (int32)this << ":\n";
for (int i = 0; i < fVariables.CountItems(); i++) {
Variable* variable = static_cast<Variable*>(fVariables.ItemAt(i));
variable->GetString(string);
Variable* variable = fVariables.ItemAt(i);
string += variable->ToString();
string << "=" << (float)variable->Value() << " ";
}
string << "\n";
for (int i = 0; i < fConstraints.CountItems(); i++) {
Constraint* c = static_cast<Constraint*>(fConstraints.ItemAt(i));
Constraint* c = fConstraints.ItemAt(i);
string << i << ": ";
c->GetString(string);
string += c->ToString();
string << "\n";
}
string << "Result=";
@@ -660,5 +653,6 @@ LinearSpec::GetString(BString& string) const
else
string << fResult;
string << " SolvingTime=" << fSolvingTime << "micro s";
return string;
}
+5 -11
View File
@@ -160,34 +160,28 @@ Variable::SetLabel(const char* label)
}
Variable::operator BString() const
{
BString string;
GetString(string);
return string;
}
/**
* Returns index of the variable as String.
* E.g. "Var2"
*
* @return the <code>String</code> index of the variable
*/
void
Variable::GetString(BString& string) const
BString
Variable::ToString() const
{
BString string;
if (fLabel) {
string << fLabel;
if (!fIsValid)
string << "(invalid)";
} else {
string << "Var";
string << "Variable ";
if (!fIsValid)
string << "(invalid," << (int32)this << ")";
else
string << Index();
}
return string;
}