Thanks to anevilyak, the previous approach was not thread safe. You can specify a friend layout now if you want to connect tabs of different BALMLayout's.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@39041 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Clemens Zeidler 2010-10-21 11:19:18 +00:00
parent 56187df6eb
commit b23e9af5b5
2 changed files with 40 additions and 39 deletions

View File

@ -27,7 +27,8 @@ namespace BALM {
*/ */
class BALMLayout : public BAbstractLayout { class BALMLayout : public BAbstractLayout {
public: public:
BALMLayout(float spacing = 0.0f); BALMLayout(float spacing = 0.0f,
BALMLayout* friendLayout = NULL);
virtual ~BALMLayout(); virtual ~BALMLayout();
XTab* AddXTab(); XTab* AddXTab();
@ -134,7 +135,8 @@ private:
void _ParseGroupItem(GroupItem& item, XTab* left, void _ParseGroupItem(GroupItem& item, XTab* left,
YTab* top, XTab* right, YTab* bottom); YTab* top, XTab* right, YTab* bottom);
LinearSpec& fSolver; LinearSpec* fSolver;
LinearSpec fOwnSolver;
XTab* fLeft; XTab* fLeft;
XTab* fRight; XTab* fRight;

View File

@ -22,21 +22,20 @@ const BSize kMinSize(0, 0);
const BSize kMaxSize(B_SIZE_UNLIMITED, B_SIZE_UNLIMITED); const BSize kMaxSize(B_SIZE_UNLIMITED, B_SIZE_UNLIMITED);
static LinearSpec gLinearSolver; /*!
/**
* Constructor. * Constructor.
* Creates new layout engine. * Creates new layout engine.
*
* If friendLayout is not NULL the solver of the friend layout is used.
*/ */
BALMLayout::BALMLayout(float spacing) BALMLayout::BALMLayout(float spacing, BALMLayout* friendLayout)
: :
fSolver(gLinearSolver),
fInset(0.0f), fInset(0.0f),
fSpacing(spacing), fSpacing(spacing),
fCurrentArea(NULL) fCurrentArea(NULL)
{ {
fSolver = friendLayout ? friendLayout->Solver() : &fOwnSolver;
fLeft = AddXTab(); fLeft = AddXTab();
fRight = AddXTab(); fRight = AddXTab();
fTop = AddYTab(); fTop = AddYTab();
@ -70,10 +69,10 @@ BALMLayout::~BALMLayout()
XTab* XTab*
BALMLayout::AddXTab() BALMLayout::AddXTab()
{ {
XTab* tab = new XTab(&fSolver); XTab* tab = new XTab(fSolver);
if (!tab) if (!tab)
return NULL; return NULL;
if (!fSolver.AddVariable(tab)) { if (!fSolver->AddVariable(tab)) {
delete tab; delete tab;
return NULL; return NULL;
} }
@ -90,10 +89,10 @@ BALMLayout::AddXTab()
YTab* YTab*
BALMLayout::AddYTab() BALMLayout::AddYTab()
{ {
YTab* tab = new YTab(&fSolver); YTab* tab = new YTab(fSolver);
if (!tab) if (!tab)
return NULL; return NULL;
if (!fSolver.AddVariable(tab)) { if (!fSolver->AddVariable(tab)) {
delete tab; delete tab;
return NULL; return NULL;
} }
@ -480,7 +479,7 @@ BALMLayout::AddItem(BLayoutItem* item, XTab* left, YTab* top, XTab* right,
return NULL; return NULL;
fCurrentArea = area; fCurrentArea = area;
area->_Init(&fSolver, left, top, right, bottom); area->_Init(fSolver, left, top, right, bottom);
return area; return area;
} }
@ -495,7 +494,7 @@ BALMLayout::AddItem(BLayoutItem* item, Row* row, Column* column)
return NULL; return NULL;
fCurrentArea = area; fCurrentArea = area;
area->_Init(&fSolver, row, column); area->_Init(fSolver, row, column);
return area; return area;
} }
@ -700,13 +699,13 @@ BALMLayout::DerivedLayoutItems()
_SolveLayout(); _SolveLayout();
// if new layout is infeasible, use previous layout // if new layout is infeasible, use previous layout
if (fSolver.Result() == INFEASIBLE) if (fSolver->Result() == INFEASIBLE)
return; return;
if (fSolver.Result() != OPTIMAL) { if (fSolver->Result() != OPTIMAL) {
fSolver.Save("failed-layout.txt"); fSolver->Save("failed-layout.txt");
printf("Could not solve the layout specification (%d). ", printf("Could not solve the layout specification (%d). ",
fSolver.Result()); fSolver->Result());
printf("Saved specification in file failed-layout.txt\n"); printf("Saved specification in file failed-layout.txt\n");
} }
@ -743,7 +742,7 @@ BALMLayout::SetPerformancePath(char* path)
LinearSpec* LinearSpec*
BALMLayout::Solver() const BALMLayout::Solver() const
{ {
return const_cast<LinearSpec*>(&fSolver); return const_cast<LinearSpec*>(fSolver);
} }
@ -797,13 +796,13 @@ BALMLayout::_SolveLayout()
ResultType result; ResultType result;
for (int32 tries = 0; tries < 15; tries++) { for (int32 tries = 0; tries < 15; tries++) {
result = fSolver.Solve(); result = fSolver->Solve();
if (fPerformancePath != NULL) { if (fPerformancePath != NULL) {
/*char buffer [100]; /*char buffer [100];
file->Write(buffer, sprintf(buffer, "%d\t%fms\t#vars=%ld\t" file->Write(buffer, sprintf(buffer, "%d\t%fms\t#vars=%ld\t"
"#constraints=%ld\n", result, fSolver.SolvingTime(), "#constraints=%ld\n", result, fSolver->SolvingTime(),
fSolver.Variables()->CountItems(), fSolver->Variables()->CountItems(),
fSolver.Constraints()->CountItems()));*/ fSolver->Constraints()->CountItems()));*/
} }
if (result == OPTIMAL || result == INFEASIBLE) if (result == OPTIMAL || result == INFEASIBLE)
break; break;
@ -823,17 +822,17 @@ BALMLayout::_CalculateMinSize()
SummandList* newObjFunction = new SummandList(2); SummandList* newObjFunction = new SummandList(2);
newObjFunction->AddItem(new Summand(1.0, fRight)); newObjFunction->AddItem(new Summand(1.0, fRight));
newObjFunction->AddItem(new Summand(1.0, fBottom)); newObjFunction->AddItem(new Summand(1.0, fBottom));
SummandList* oldObjFunction = fSolver.SwapObjectiveFunction( SummandList* oldObjFunction = fSolver->SwapObjectiveFunction(
newObjFunction); newObjFunction);
_SolveLayout(); _SolveLayout();
fSolver.SetObjectiveFunction(oldObjFunction); fSolver->SetObjectiveFunction(oldObjFunction);
if (fSolver.Result() == UNBOUNDED) if (fSolver->Result() == UNBOUNDED)
return kMinSize; return kMinSize;
if (fSolver.Result() != OPTIMAL) { if (fSolver->Result() != OPTIMAL) {
fSolver.Save("failed-layout.txt"); fSolver->Save("failed-layout.txt");
printf("Could not solve the layout specification (%d). " printf("Could not solve the layout specification (%d). "
"Saved specification in file failed-layout.txt", fSolver.Result()); "Saved specification in file failed-layout.txt", fSolver->Result());
} }
return BSize(Right()->Value() - Left()->Value(), return BSize(Right()->Value() - Left()->Value(),
@ -852,17 +851,17 @@ BALMLayout::_CalculateMaxSize()
SummandList* newObjFunction = new SummandList(2); SummandList* newObjFunction = new SummandList(2);
newObjFunction->AddItem(new Summand(-1.0, fRight)); newObjFunction->AddItem(new Summand(-1.0, fRight));
newObjFunction->AddItem(new Summand(-1.0, fBottom)); newObjFunction->AddItem(new Summand(-1.0, fBottom));
SummandList* oldObjFunction = fSolver.SwapObjectiveFunction( SummandList* oldObjFunction = fSolver->SwapObjectiveFunction(
newObjFunction); newObjFunction);
_SolveLayout(); _SolveLayout();
fSolver.SetObjectiveFunction(oldObjFunction); fSolver->SetObjectiveFunction(oldObjFunction);
if (fSolver.Result() == UNBOUNDED) if (fSolver->Result() == UNBOUNDED)
return kMaxSize; return kMaxSize;
if (fSolver.Result() != OPTIMAL) { if (fSolver->Result() != OPTIMAL) {
fSolver.Save("failed-layout.txt"); fSolver->Save("failed-layout.txt");
printf("Could not solve the layout specification (%d). " printf("Could not solve the layout specification (%d). "
"Saved specification in file failed-layout.txt", fSolver.Result()); "Saved specification in file failed-layout.txt", fSolver->Result());
} }
return BSize(Right()->Value() - Left()->Value(), return BSize(Right()->Value() - Left()->Value(),
@ -879,10 +878,10 @@ BALMLayout::_CalculatePreferredSize()
_UpdateAreaConstraints(); _UpdateAreaConstraints();
_SolveLayout(); _SolveLayout();
if (fSolver.Result() != OPTIMAL) { if (fSolver->Result() != OPTIMAL) {
fSolver.Save("failed-layout.txt"); fSolver->Save("failed-layout.txt");
printf("Could not solve the layout specification (%d). " printf("Could not solve the layout specification (%d). "
"Saved specification in file failed-layout.txt", fSolver.Result()); "Saved specification in file failed-layout.txt", fSolver->Result());
} }
return BSize(Right()->Value() - Left()->Value(), return BSize(Right()->Value() - Left()->Value(),