Introduce SharedSolver class to improve BALMLayout's friend feature.
This commit is contained in:
@@ -17,6 +17,10 @@
|
|||||||
class BView;
|
class BView;
|
||||||
class BLayoutItem;
|
class BLayoutItem;
|
||||||
|
|
||||||
|
namespace BPrivate {
|
||||||
|
class SharedSolver;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
namespace BALM {
|
namespace BALM {
|
||||||
|
|
||||||
@@ -157,6 +161,7 @@ private:
|
|||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
friend class TabAddTransaction;
|
friend class TabAddTransaction;
|
||||||
|
friend class BPrivate::SharedSolver;
|
||||||
|
|
||||||
friend class XTab;
|
friend class XTab;
|
||||||
friend class YTab;
|
friend class YTab;
|
||||||
@@ -165,6 +170,8 @@ private:
|
|||||||
float InsetForTab(XTab* tab) const;
|
float InsetForTab(XTab* tab) const;
|
||||||
float InsetForTab(YTab* tab) const;
|
float InsetForTab(YTab* tab) const;
|
||||||
|
|
||||||
|
void UpdateConstraints(BLayoutContext* context);
|
||||||
|
|
||||||
void _RemoveSelfFromTab(XTab* tab);
|
void _RemoveSelfFromTab(XTab* tab);
|
||||||
void _RemoveSelfFromTab(YTab* tab);
|
void _RemoveSelfFromTab(YTab* tab);
|
||||||
bool _HasTabInLayout(XTab* tab);
|
bool _HasTabInLayout(XTab* tab);
|
||||||
@@ -174,15 +181,7 @@ private:
|
|||||||
|
|
||||||
BLayoutItem* _LayoutItemToAdd(BView* view);
|
BLayoutItem* _LayoutItemToAdd(BView* view);
|
||||||
|
|
||||||
void _UpdateAreaConstraints();
|
BPrivate::SharedSolver* fSolver;
|
||||||
|
|
||||||
BSize _CalculateMinSize();
|
|
||||||
BSize _CalculateMaxSize();
|
|
||||||
BSize _CalculatePreferredSize();
|
|
||||||
|
|
||||||
bool _TrySolve();
|
|
||||||
|
|
||||||
LinearProgramming::LinearSpec* fSolver;
|
|
||||||
|
|
||||||
BReference<XTab> fLeft;
|
BReference<XTab> fLeft;
|
||||||
BReference<XTab> fRight;
|
BReference<XTab> fRight;
|
||||||
|
|||||||
@@ -55,6 +55,9 @@ public:
|
|||||||
virtual BSize MinSize(Variable* width, Variable* height) = 0;
|
virtual BSize MinSize(Variable* width, Variable* height) = 0;
|
||||||
virtual BSize MaxSize(Variable* width, Variable* height) = 0;
|
virtual BSize MaxSize(Variable* width, Variable* height) = 0;
|
||||||
|
|
||||||
|
virtual ResultType FindMins(const VariableList* variables) = 0;
|
||||||
|
virtual ResultType FindMaxs(const VariableList* variables) = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
LinearSpec* fLinearSpec;
|
LinearSpec* fLinearSpec;
|
||||||
};
|
};
|
||||||
@@ -122,6 +125,9 @@ public:
|
|||||||
BSize MinSize(Variable* width, Variable* height);
|
BSize MinSize(Variable* width, Variable* height);
|
||||||
BSize MaxSize(Variable* width, Variable* height);
|
BSize MaxSize(Variable* width, Variable* height);
|
||||||
|
|
||||||
|
ResultType FindMins(const VariableList* variables);
|
||||||
|
ResultType FindMaxs(const VariableList* variables);
|
||||||
|
|
||||||
ResultType Solve();
|
ResultType Solve();
|
||||||
bool Save(const char* fileName);
|
bool Save(const char* fileName);
|
||||||
|
|
||||||
|
|||||||
+36
-103
@@ -15,6 +15,7 @@
|
|||||||
#include <ControlLook.h>
|
#include <ControlLook.h>
|
||||||
|
|
||||||
#include "RowColumnManager.h"
|
#include "RowColumnManager.h"
|
||||||
|
#include "SharedSolver.h"
|
||||||
#include "ViewLayoutItem.h"
|
#include "ViewLayoutItem.h"
|
||||||
|
|
||||||
|
|
||||||
@@ -133,9 +134,10 @@ BALMLayout::BALMLayout(float hSpacing, float vSpacing, BALMLayout* friendLayout)
|
|||||||
fVSpacing(BControlLook::ComposeSpacing(vSpacing)),
|
fVSpacing(BControlLook::ComposeSpacing(vSpacing)),
|
||||||
fBadLayoutPolicy(new DefaultPolicy())
|
fBadLayoutPolicy(new DefaultPolicy())
|
||||||
{
|
{
|
||||||
fSolver = friendLayout ? friendLayout->Solver() : new LinearSpec();
|
fSolver = friendLayout ? friendLayout->fSolver : new SharedSolver();
|
||||||
fSolver->AcquireReference();
|
fSolver->AcquireReference();
|
||||||
fRowColumnManager = new RowColumnManager(fSolver);
|
fSolver->RegisterLayout(this);
|
||||||
|
fRowColumnManager = new RowColumnManager(Solver());
|
||||||
|
|
||||||
fLeft = AddXTab();
|
fLeft = AddXTab();
|
||||||
fRight = AddXTab();
|
fRight = AddXTab();
|
||||||
@@ -159,6 +161,8 @@ BALMLayout::~BALMLayout()
|
|||||||
{
|
{
|
||||||
delete fRowColumnManager;
|
delete fRowColumnManager;
|
||||||
delete fBadLayoutPolicy;
|
delete fBadLayoutPolicy;
|
||||||
|
|
||||||
|
fSolver->LayoutLeaving(this);
|
||||||
fSolver->ReleaseReference();
|
fSolver->ReleaseReference();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,7 +178,7 @@ BALMLayout::AddXTab()
|
|||||||
BReference<XTab> tab(new(std::nothrow) XTab(this), true);
|
BReference<XTab> tab(new(std::nothrow) XTab(this), true);
|
||||||
if (!tab)
|
if (!tab)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (!fSolver->AddVariable(tab))
|
if (!Solver()->AddVariable(tab))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
fXTabList.AddItem(tab);
|
fXTabList.AddItem(tab);
|
||||||
@@ -213,7 +217,7 @@ BALMLayout::AddYTab()
|
|||||||
BReference<YTab> tab(new(std::nothrow) YTab(this), true);
|
BReference<YTab> tab(new(std::nothrow) YTab(this), true);
|
||||||
if (tab.Get() == NULL)
|
if (tab.Get() == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (!fSolver->AddVariable(tab))
|
if (!Solver()->AddVariable(tab))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
fYTabList.AddItem(tab);
|
fYTabList.AddItem(tab);
|
||||||
@@ -307,7 +311,7 @@ BALMLayout::AddRow(YTab* _top, YTab* _bottom)
|
|||||||
top = AddYTab();
|
top = AddYTab();
|
||||||
if (_bottom == NULL)
|
if (_bottom == NULL)
|
||||||
bottom = AddYTab();
|
bottom = AddYTab();
|
||||||
return new(std::nothrow) Row(fSolver, top, bottom);
|
return new(std::nothrow) Row(Solver(), top, bottom);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -327,7 +331,7 @@ BALMLayout::AddColumn(XTab* _left, XTab* _right)
|
|||||||
left = AddXTab();
|
left = AddXTab();
|
||||||
if (_right == NULL)
|
if (_right == NULL)
|
||||||
right = AddXTab();
|
right = AddXTab();
|
||||||
return new(std::nothrow) Column(fSolver, left, right);
|
return new(std::nothrow) Column(Solver(), left, right);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -598,7 +602,7 @@ BALMLayout::AddItem(BLayoutItem* item, XTab* left, YTab* top, XTab* _right,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
area->_Init(fSolver, left, top, right, bottom, fRowColumnManager);
|
area->_Init(Solver(), left, top, right, bottom, fRowColumnManager);
|
||||||
fRowColumnManager->AddArea(area);
|
fRowColumnManager->AddArea(area);
|
||||||
|
|
||||||
leftTabAdd.Commit();
|
leftTabAdd.Commit();
|
||||||
@@ -618,7 +622,7 @@ BALMLayout::AddItem(BLayoutItem* item, Row* row, Column* column)
|
|||||||
if (!area)
|
if (!area)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
area->_Init(fSolver, row, column, fRowColumnManager);
|
area->_Init(Solver(), row, column, fRowColumnManager);
|
||||||
|
|
||||||
fRowColumnManager->AddArea(area);
|
fRowColumnManager->AddArea(area);
|
||||||
return area;
|
return area;
|
||||||
@@ -817,8 +821,7 @@ BALMLayout::GetBadLayoutPolicy() const
|
|||||||
BSize
|
BSize
|
||||||
BALMLayout::BaseMinSize()
|
BALMLayout::BaseMinSize()
|
||||||
{
|
{
|
||||||
if (fMinSize == kUnsetSize)
|
fSolver->ValidateMinSize();
|
||||||
fMinSize = _CalculateMinSize();
|
|
||||||
return fMinSize;
|
return fMinSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -829,8 +832,7 @@ BALMLayout::BaseMinSize()
|
|||||||
BSize
|
BSize
|
||||||
BALMLayout::BaseMaxSize()
|
BALMLayout::BaseMaxSize()
|
||||||
{
|
{
|
||||||
if (fMaxSize == kUnsetSize)
|
fSolver->ValidateMaxSize();
|
||||||
fMaxSize = _CalculateMaxSize();
|
|
||||||
return fMaxSize;
|
return fMaxSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -841,9 +843,8 @@ BALMLayout::BaseMaxSize()
|
|||||||
BSize
|
BSize
|
||||||
BALMLayout::BasePreferredSize()
|
BALMLayout::BasePreferredSize()
|
||||||
{
|
{
|
||||||
if (fPreferredSize == kUnsetSize)
|
fSolver->ValidateMinSize();
|
||||||
fPreferredSize = _CalculatePreferredSize();
|
return fMinSize;
|
||||||
return fPreferredSize;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -870,6 +871,8 @@ BALMLayout::LayoutInvalidated(bool children)
|
|||||||
fMinSize = kUnsetSize;
|
fMinSize = kUnsetSize;
|
||||||
fMaxSize = kUnsetSize;
|
fMaxSize = kUnsetSize;
|
||||||
fPreferredSize = kUnsetSize;
|
fPreferredSize = kUnsetSize;
|
||||||
|
|
||||||
|
fSolver->Invalidate(children);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -899,26 +902,18 @@ BALMLayout::ItemRemoved(BLayoutItem* item, int32 fromIndex)
|
|||||||
void
|
void
|
||||||
BALMLayout::DoLayout()
|
BALMLayout::DoLayout()
|
||||||
{
|
{
|
||||||
_UpdateAreaConstraints();
|
fSolver->ValidateLayout(LayoutContext());
|
||||||
|
|
||||||
// Enforced absolute positions of Right and Bottom
|
|
||||||
BRect area(LayoutArea());
|
|
||||||
BSize size(area.Size());
|
|
||||||
Right()->SetRange(size.width, size.width);
|
|
||||||
Bottom()->SetRange(size.height, size.height);
|
|
||||||
|
|
||||||
_TrySolve();
|
|
||||||
|
|
||||||
// set the calculated positions and sizes for every area
|
// set the calculated positions and sizes for every area
|
||||||
for (int32 i = 0; i < CountItems(); i++)
|
for (int32 i = 0; i < CountItems(); i++)
|
||||||
AreaFor(ItemAt(i))->_DoLayout(area.LeftTop());
|
AreaFor(ItemAt(i))->_DoLayout(LayoutArea().LeftTop());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
LinearSpec*
|
LinearSpec*
|
||||||
BALMLayout::Solver() const
|
BALMLayout::Solver() const
|
||||||
{
|
{
|
||||||
return const_cast<LinearSpec*>(fSolver);
|
return fSolver->Solver();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1015,6 +1010,21 @@ BALMLayout::InsetForTab(YTab* tab) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BALMLayout::UpdateConstraints(BLayoutContext* context)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < CountItems(); i++)
|
||||||
|
AreaFor(ItemAt(i))->InvalidateSizeConstraints();
|
||||||
|
fRowColumnManager->UpdateConstraints();
|
||||||
|
|
||||||
|
if (context) {
|
||||||
|
BSize size(LayoutArea().Size());
|
||||||
|
Right()->SetRange(size.width, size.width);
|
||||||
|
Bottom()->SetRange(size.height, size.height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void BALMLayout::_RemoveSelfFromTab(XTab* tab) { tab->LayoutLeaving(this); }
|
void BALMLayout::_RemoveSelfFromTab(XTab* tab) { tab->LayoutLeaving(this); }
|
||||||
void BALMLayout::_RemoveSelfFromTab(YTab* tab) { tab->LayoutLeaving(this); }
|
void BALMLayout::_RemoveSelfFromTab(YTab* tab) { tab->LayoutLeaving(this); }
|
||||||
|
|
||||||
@@ -1034,83 +1044,6 @@ BALMLayout::_LayoutItemToAdd(BView* view)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Caculates the miminum size.
|
|
||||||
*/
|
|
||||||
BSize
|
|
||||||
BALMLayout::_CalculateMinSize()
|
|
||||||
{
|
|
||||||
_UpdateAreaConstraints();
|
|
||||||
|
|
||||||
Right()->SetRange(0, 20000);
|
|
||||||
Bottom()->SetRange(0, 20000);
|
|
||||||
|
|
||||||
BSize min(fSolver->MinSize(Right(), Bottom()));
|
|
||||||
ResultType result = fSolver->Result();
|
|
||||||
if (result != kUnbounded && result != kOptimal)
|
|
||||||
fBadLayoutPolicy->OnBadLayout(this);
|
|
||||||
return min;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Caculates the maximum size.
|
|
||||||
*/
|
|
||||||
BSize
|
|
||||||
BALMLayout::_CalculateMaxSize()
|
|
||||||
{
|
|
||||||
_UpdateAreaConstraints();
|
|
||||||
|
|
||||||
Right()->SetRange(0, 20000);
|
|
||||||
Bottom()->SetRange(0, 20000);
|
|
||||||
|
|
||||||
BSize max(fSolver->MaxSize(Right(), Bottom()));
|
|
||||||
ResultType result = fSolver->Result();
|
|
||||||
if (result != kUnbounded && result != kOptimal)
|
|
||||||
fBadLayoutPolicy->OnBadLayout(this);
|
|
||||||
return max;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Caculates the preferred size.
|
|
||||||
*/
|
|
||||||
BSize
|
|
||||||
BALMLayout::_CalculatePreferredSize()
|
|
||||||
{
|
|
||||||
_UpdateAreaConstraints();
|
|
||||||
|
|
||||||
Right()->SetRange(0, 20000);
|
|
||||||
Bottom()->SetRange(0, 20000);
|
|
||||||
|
|
||||||
_TrySolve();
|
|
||||||
|
|
||||||
return BSize(Right()->Value() - Left()->Value(),
|
|
||||||
Bottom()->Value() - Top()->Value());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool
|
|
||||||
BALMLayout::_TrySolve()
|
|
||||||
{
|
|
||||||
fSolver->Solve();
|
|
||||||
|
|
||||||
if (fSolver->Result() != kOptimal) {
|
|
||||||
return fBadLayoutPolicy->OnBadLayout(this);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
BALMLayout::_UpdateAreaConstraints()
|
|
||||||
{
|
|
||||||
for (int i = 0; i < CountItems(); i++)
|
|
||||||
AreaFor(ItemAt(i))->InvalidateSizeConstraints();
|
|
||||||
fRowColumnManager->UpdateConstraints();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
BALMLayout::Perform(perform_code d, void* arg)
|
BALMLayout::Perform(perform_code d, void* arg)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ SharedLibrary libalm.so :
|
|||||||
Column.cpp
|
Column.cpp
|
||||||
Row.cpp
|
Row.cpp
|
||||||
RowColumnManager.cpp
|
RowColumnManager.cpp
|
||||||
|
SharedSolver.cpp
|
||||||
Tab.cpp
|
Tab.cpp
|
||||||
:
|
:
|
||||||
liblinprog.a be $(TARGET_LIBSTDC++)
|
liblinprog.a be $(TARGET_LIBSTDC++)
|
||||||
|
|||||||
@@ -0,0 +1,247 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012, Haiku, Inc. All rights reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "SharedSolver.h"
|
||||||
|
|
||||||
|
#include <ALMLayout.h>
|
||||||
|
#include <ObjectList.h>
|
||||||
|
|
||||||
|
|
||||||
|
using LinearProgramming::LinearSpec;
|
||||||
|
|
||||||
|
|
||||||
|
struct LayoutOperation {
|
||||||
|
LayoutOperation(BObjectList<BALMLayout>* layouts)
|
||||||
|
:
|
||||||
|
fLayouts(layouts),
|
||||||
|
fVariables(layouts->CountItems() * 2)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~LayoutOperation()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Validate(SharedSolver* solver)
|
||||||
|
{
|
||||||
|
for (int32 i = fLayouts->CountItems() - 1; i >= 0; i--) {
|
||||||
|
BALMLayout* layout = fLayouts->ItemAt(i);
|
||||||
|
layout->Right()->SetRange(0, 20000);
|
||||||
|
layout->Bottom()->SetRange(0, 20000);
|
||||||
|
|
||||||
|
fVariables.AddItem(layout->Right());
|
||||||
|
fVariables.AddItem(layout->Bottom());
|
||||||
|
}
|
||||||
|
|
||||||
|
CallSolverMethod(solver->Solver(), &fVariables);
|
||||||
|
|
||||||
|
for (int32 i = fLayouts->CountItems() - 1; i >= 0; i--)
|
||||||
|
Finalize(fLayouts->ItemAt(i), solver);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void CallSolverMethod(LinearSpec* spec, VariableList* vars) = 0;
|
||||||
|
virtual void Finalize(BALMLayout* layout, SharedSolver* solver) = 0;
|
||||||
|
|
||||||
|
private:
|
||||||
|
BObjectList<BALMLayout>* fLayouts;
|
||||||
|
VariableList fVariables;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct SharedSolver::MinSizeValidator : LayoutOperation {
|
||||||
|
MinSizeValidator(BObjectList<BALMLayout>* layouts)
|
||||||
|
:
|
||||||
|
LayoutOperation(layouts)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CallSolverMethod(LinearSpec* spec, VariableList* vars)
|
||||||
|
{
|
||||||
|
spec->FindMins(vars);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Finalize(BALMLayout* layout, SharedSolver* solver)
|
||||||
|
{
|
||||||
|
solver->SetMinSize(layout, BSize(layout->Right()->Value(),
|
||||||
|
layout->Bottom()->Value()));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct SharedSolver::MaxSizeValidator : LayoutOperation {
|
||||||
|
MaxSizeValidator(BObjectList<BALMLayout>* layouts)
|
||||||
|
:
|
||||||
|
LayoutOperation(layouts)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CallSolverMethod(LinearSpec* spec, VariableList* vars)
|
||||||
|
{
|
||||||
|
spec->FindMaxs(vars);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Finalize(BALMLayout* layout, SharedSolver* solver)
|
||||||
|
{
|
||||||
|
solver->SetMaxSize(layout, BSize(layout->Right()->Value(),
|
||||||
|
layout->Bottom()->Value()));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
SharedSolver::SharedSolver()
|
||||||
|
:
|
||||||
|
fConstraintsValid(false),
|
||||||
|
fMinValid(false),
|
||||||
|
fMaxValid(false),
|
||||||
|
fLayoutValid(false),
|
||||||
|
fLayoutContext(NULL)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SharedSolver::~SharedSolver()
|
||||||
|
{
|
||||||
|
if (fLayouts.CountItems() > 0)
|
||||||
|
debugger("SharedSolver deleted while still in use!");
|
||||||
|
|
||||||
|
_SetContext(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LinearSpec*
|
||||||
|
SharedSolver::Solver() const
|
||||||
|
{
|
||||||
|
return const_cast<LinearSpec*>(&fLinearSpec);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
SharedSolver::Invalidate(bool children)
|
||||||
|
{
|
||||||
|
if (!fConstraintsValid && !fMaxValid && !fMinValid && !fLayoutValid)
|
||||||
|
return;
|
||||||
|
|
||||||
|
fConstraintsValid = false;
|
||||||
|
fMinValid = false;
|
||||||
|
fMaxValid = false;
|
||||||
|
fLayoutValid = false;
|
||||||
|
|
||||||
|
_SetContext(NULL);
|
||||||
|
|
||||||
|
for (int32 i = fLayouts.CountItems() - 1; i >= 0; i--)
|
||||||
|
fLayouts.ItemAt(i)->InvalidateLayout(children);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
SharedSolver::RegisterLayout(BALMLayout* layout)
|
||||||
|
{
|
||||||
|
fLayouts.AddItem(layout);
|
||||||
|
Invalidate(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
SharedSolver::LayoutLeaving(BALMLayout* layout)
|
||||||
|
{
|
||||||
|
fLayouts.RemoveItem(layout);
|
||||||
|
Invalidate(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
SharedSolver::ValidateMinSize()
|
||||||
|
{
|
||||||
|
if (fMinValid)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_ValidateConstraints();
|
||||||
|
|
||||||
|
MinSizeValidator validator(&fLayouts);
|
||||||
|
validator.Validate(this);
|
||||||
|
|
||||||
|
fMinResult = fLinearSpec.Result();
|
||||||
|
|
||||||
|
fMinValid = true;
|
||||||
|
fLayoutValid = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
SharedSolver::ValidateMaxSize()
|
||||||
|
{
|
||||||
|
if (fMaxValid)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_ValidateConstraints();
|
||||||
|
|
||||||
|
MaxSizeValidator validator(&fLayouts);
|
||||||
|
validator.Validate(this);
|
||||||
|
|
||||||
|
fMaxResult = fLinearSpec.Result();
|
||||||
|
|
||||||
|
fMaxValid = true;
|
||||||
|
fLayoutValid = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
SharedSolver::ValidateLayout(BLayoutContext* context)
|
||||||
|
{
|
||||||
|
if (fLayoutValid && fLayoutContext == context)
|
||||||
|
return;
|
||||||
|
|
||||||
|
fConstraintsValid = false;
|
||||||
|
_SetContext(context);
|
||||||
|
_ValidateConstraints();
|
||||||
|
fLayoutResult = fLinearSpec.Solve();
|
||||||
|
|
||||||
|
fLayoutValid = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
SharedSolver::SetMaxSize(BALMLayout* layout, const BSize& max)
|
||||||
|
{
|
||||||
|
layout->fMaxSize = max;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
SharedSolver::SetMinSize(BALMLayout* layout, const BSize& min)
|
||||||
|
{
|
||||||
|
layout->fMinSize = min;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
SharedSolver::LayoutContextLeft(BLayoutContext* context)
|
||||||
|
{
|
||||||
|
_SetContext(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
SharedSolver::_SetContext(BLayoutContext* context)
|
||||||
|
{
|
||||||
|
if (fLayoutContext)
|
||||||
|
fLayoutContext->RemoveListener(this);
|
||||||
|
fLayoutContext = context;
|
||||||
|
if (fLayoutContext)
|
||||||
|
fLayoutContext->AddListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
SharedSolver::_ValidateConstraints()
|
||||||
|
{
|
||||||
|
if (!fConstraintsValid) {
|
||||||
|
for (int32 i = fLayouts.CountItems() - 1; i >= 0; i--) {
|
||||||
|
fLayouts.ItemAt(i)->UpdateConstraints(fLayoutContext);
|
||||||
|
}
|
||||||
|
fConstraintsValid = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012, Haiku, Inc. All rights reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
#ifndef _SHARED_SOLVER_H
|
||||||
|
#define _SHARED_SOLVER_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <LayoutContext.h>
|
||||||
|
#include <ObjectList.h>
|
||||||
|
#include <Referenceable.h>
|
||||||
|
|
||||||
|
#include "LinearSpec.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace BALM {
|
||||||
|
class BALMLayout;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace BPrivate {
|
||||||
|
|
||||||
|
|
||||||
|
class SharedSolver : BLayoutContextListener, public BReferenceable {
|
||||||
|
public:
|
||||||
|
SharedSolver();
|
||||||
|
~SharedSolver();
|
||||||
|
|
||||||
|
void Invalidate(bool children);
|
||||||
|
|
||||||
|
LinearSpec* Solver() const;
|
||||||
|
ResultType Result();
|
||||||
|
|
||||||
|
void RegisterLayout(BALM::BALMLayout* layout);
|
||||||
|
void LayoutLeaving(BALM::BALMLayout* layout);
|
||||||
|
|
||||||
|
void ValidateMinSize();
|
||||||
|
void ValidateMaxSize();
|
||||||
|
void ValidateLayout(BLayoutContext* context);
|
||||||
|
private:
|
||||||
|
struct MinSizeValidator;
|
||||||
|
struct MaxSizeValidator;
|
||||||
|
|
||||||
|
friend struct MinSizeValidator;
|
||||||
|
friend struct MaxSizeValidator;
|
||||||
|
|
||||||
|
void SetMaxSize(BALM::BALMLayout* layout,
|
||||||
|
const BSize& max);
|
||||||
|
void SetMinSize(BALM::BALMLayout* layout,
|
||||||
|
const BSize& min);
|
||||||
|
|
||||||
|
virtual void LayoutContextLeft(BLayoutContext* context);
|
||||||
|
|
||||||
|
void _UpdateConstraints();
|
||||||
|
void _SetContext(BLayoutContext* context);
|
||||||
|
bool _IsMinSet();
|
||||||
|
bool _IsMaxSet();
|
||||||
|
void _ValidateConstraints();
|
||||||
|
|
||||||
|
bool fConstraintsValid;
|
||||||
|
bool fMinValid;
|
||||||
|
bool fMaxValid;
|
||||||
|
bool fLayoutValid;
|
||||||
|
|
||||||
|
BLayoutContext* fLayoutContext;
|
||||||
|
BObjectList<BALM::BALMLayout> fLayouts;
|
||||||
|
LinearSpec fLinearSpec;
|
||||||
|
|
||||||
|
ResultType fMinResult;
|
||||||
|
ResultType fMaxResult;
|
||||||
|
ResultType fLayoutResult;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
using BPrivate::SharedSolver;
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
#include "LayoutOptimizer.h"
|
#include "LayoutOptimizer.h"
|
||||||
|
|
||||||
|
|
||||||
//#define DEBUG_ACTIVE_SOLVER
|
// #define DEBUG_ACTIVE_SOLVER
|
||||||
|
|
||||||
#ifdef DEBUG_ACTIVE_SOLVER
|
#ifdef DEBUG_ACTIVE_SOLVER
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -579,6 +579,59 @@ ActiveSetSolver::MaxSize(Variable* width, Variable* height)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ResultType
|
||||||
|
ActiveSetSolver::FindMaxs(const VariableList* variables)
|
||||||
|
{
|
||||||
|
ConstraintList softConstraints;
|
||||||
|
_RemoveSoftConstraint(softConstraints);
|
||||||
|
|
||||||
|
const double kHugeValue = 32000;
|
||||||
|
ConstraintList maxConstraints;
|
||||||
|
for (int32 i = variables->CountItems() - 1; i >= 0; i--) {
|
||||||
|
maxConstraints.AddItem(fLinearSpec->AddConstraint(1,
|
||||||
|
variables->ItemAt(i), kEQ, kHugeValue, 5, 5));
|
||||||
|
}
|
||||||
|
|
||||||
|
ResultType result = Solve();
|
||||||
|
|
||||||
|
for (int32 i = maxConstraints.CountItems() - 1; i >= 0; i--)
|
||||||
|
fLinearSpec->RemoveConstraint(maxConstraints.ItemAt(i));
|
||||||
|
|
||||||
|
_AddSoftConstraint(softConstraints);
|
||||||
|
|
||||||
|
if (result != kOptimal)
|
||||||
|
TRACE("Could not solve the layout specification (%d). ", result);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ResultType
|
||||||
|
ActiveSetSolver::FindMins(const VariableList* variables)
|
||||||
|
{
|
||||||
|
ConstraintList softConstraints;
|
||||||
|
_RemoveSoftConstraint(softConstraints);
|
||||||
|
|
||||||
|
ConstraintList minConstraints;
|
||||||
|
for (int32 i = variables->CountItems() - 1; i >= 0; i--) {
|
||||||
|
minConstraints.AddItem(fLinearSpec->AddConstraint(1,
|
||||||
|
variables->ItemAt(i), kEQ, 0, 5, 5));
|
||||||
|
}
|
||||||
|
|
||||||
|
ResultType result = Solve();
|
||||||
|
|
||||||
|
for (int32 i = minConstraints.CountItems() - 1; i >= 0; i--)
|
||||||
|
fLinearSpec->RemoveConstraint(minConstraints.ItemAt(i));
|
||||||
|
|
||||||
|
_AddSoftConstraint(softConstraints);
|
||||||
|
|
||||||
|
if (result != kOptimal)
|
||||||
|
TRACE("Could not solve the layout specification (%d). ", result);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ActiveSetSolver::_RemoveSoftConstraint(ConstraintList& list)
|
ActiveSetSolver::_RemoveSoftConstraint(ConstraintList& list)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -74,6 +74,9 @@ public:
|
|||||||
BSize MinSize(Variable* width, Variable* height);
|
BSize MinSize(Variable* width, Variable* height);
|
||||||
BSize MaxSize(Variable* width, Variable* height);
|
BSize MaxSize(Variable* width, Variable* height);
|
||||||
|
|
||||||
|
ResultType FindMaxs(const VariableList* variables);
|
||||||
|
ResultType FindMins(const VariableList* variables);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void _RemoveSoftConstraint(ConstraintList& list);
|
void _RemoveSoftConstraint(ConstraintList& list);
|
||||||
void _AddSoftConstraint(const ConstraintList& list);
|
void _AddSoftConstraint(const ConstraintList& list);
|
||||||
|
|||||||
@@ -496,6 +496,21 @@ LinearSpec::MaxSize(Variable* width, Variable* height)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ResultType
|
||||||
|
LinearSpec::FindMins(const VariableList* variables)
|
||||||
|
{
|
||||||
|
return fSolver->FindMins(variables);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ResultType
|
||||||
|
LinearSpec::FindMaxs(const VariableList* variables)
|
||||||
|
{
|
||||||
|
return fSolver->FindMaxs(variables);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
LinearSpec::_CheckSummandList(SummandList* list)
|
LinearSpec::_CheckSummandList(SummandList* list)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user