Add a list of constraints which can be associated with a BALMLayout.
- Add Get{X,Y}Tabs methods. - Remove SaveLayout and RestoreLayout. These can be implemented outside of BALMLayout.
This commit is contained in:
parent
6cf32e83ad
commit
6c4a44e36b
@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
class BView;
|
class BView;
|
||||||
class BLayoutItem;
|
class BLayoutItem;
|
||||||
|
class Constraint;
|
||||||
|
|
||||||
|
|
||||||
namespace BPrivate {
|
namespace BPrivate {
|
||||||
class SharedSolver;
|
class SharedSolver;
|
||||||
@ -53,10 +55,41 @@ public:
|
|||||||
XTab* XTabAt(int32 index) const;
|
XTab* XTabAt(int32 index) const;
|
||||||
YTab* YTabAt(int32 index, bool ordered = false);
|
YTab* YTabAt(int32 index, bool ordered = false);
|
||||||
YTab* YTabAt(int32 index) const;
|
YTab* YTabAt(int32 index) const;
|
||||||
|
const XTabList GetXTabs() const;
|
||||||
|
const YTabList GetYTabs() const;
|
||||||
|
|
||||||
int32 IndexOf(XTab* tab, bool ordered = false);
|
int32 IndexOf(XTab* tab, bool ordered = false);
|
||||||
int32 IndexOf(YTab* tab, bool ordered = false);
|
int32 IndexOf(YTab* tab, bool ordered = false);
|
||||||
|
|
||||||
|
int32 CountConstraints() const;
|
||||||
|
Constraint* ConstraintAt(int32 index) const;
|
||||||
|
bool AddConstraint(Constraint* constraint);
|
||||||
|
bool RemoveConstraint(Constraint* constraint,
|
||||||
|
bool deleteConstraint = true);
|
||||||
|
|
||||||
|
Constraint* AddConstraint(double coeff1, Variable* var1,
|
||||||
|
OperatorType op, double rightSide,
|
||||||
|
double penaltyNeg = -1,
|
||||||
|
double penaltyPos = -1);
|
||||||
|
Constraint* AddConstraint(double coeff1, Variable* var1,
|
||||||
|
double coeff2, Variable* var2,
|
||||||
|
OperatorType op, double rightSide,
|
||||||
|
double penaltyNeg = -1,
|
||||||
|
double penaltyPos = -1);
|
||||||
|
Constraint* AddConstraint(double coeff1, Variable* var1,
|
||||||
|
double coeff2, Variable* var2,
|
||||||
|
double coeff3, Variable* var3,
|
||||||
|
OperatorType op, double rightSide,
|
||||||
|
double penaltyNeg = -1,
|
||||||
|
double penaltyPos = -1);
|
||||||
|
Constraint* AddConstraint(double coeff1, Variable* var1,
|
||||||
|
double coeff2, Variable* var2,
|
||||||
|
double coeff3, Variable* var3,
|
||||||
|
double coeff4, Variable* var4,
|
||||||
|
OperatorType op, double rightSide,
|
||||||
|
double penaltyNeg = -1,
|
||||||
|
double penaltyPos = -1);
|
||||||
|
|
||||||
Row* AddRow(YTab* top, YTab* bottom);
|
Row* AddRow(YTab* top, YTab* bottom);
|
||||||
Column* AddColumn(XTab* left, XTab* right);
|
Column* AddColumn(XTab* left, XTab* right);
|
||||||
|
|
||||||
@ -66,6 +99,7 @@ public:
|
|||||||
YTab* Bottom() const;
|
YTab* Bottom() const;
|
||||||
|
|
||||||
LinearProgramming::LinearSpec* Solver() const;
|
LinearProgramming::LinearSpec* Solver() const;
|
||||||
|
LinearProgramming::ResultType ValidateLayout();
|
||||||
|
|
||||||
void SetInsets(float insets);
|
void SetInsets(float insets);
|
||||||
void SetInsets(float x, float y);
|
void SetInsets(float x, float y);
|
||||||
@ -107,8 +141,6 @@ public:
|
|||||||
virtual Area* AddItem(BLayoutItem* item, Row* row,
|
virtual Area* AddItem(BLayoutItem* item, Row* row,
|
||||||
Column* column);
|
Column* column);
|
||||||
|
|
||||||
bool SaveLayout(BMessage* archive) const;
|
|
||||||
bool RestoreLayout(const BMessage* archive);
|
|
||||||
struct BadLayoutPolicy;
|
struct BadLayoutPolicy;
|
||||||
|
|
||||||
void SetBadLayoutPolicy(BadLayoutPolicy* policy);
|
void SetBadLayoutPolicy(BadLayoutPolicy* policy);
|
||||||
@ -192,6 +224,9 @@ private:
|
|||||||
friend class YTab;
|
friend class YTab;
|
||||||
friend class Area;
|
friend class Area;
|
||||||
|
|
||||||
|
class BALMLayoutSpecListener;
|
||||||
|
friend class BALMLayoutSpecListener;
|
||||||
|
|
||||||
float InsetForTab(XTab* tab) const;
|
float InsetForTab(XTab* tab) const;
|
||||||
float InsetForTab(YTab* tab) const;
|
float InsetForTab(YTab* tab) const;
|
||||||
|
|
||||||
@ -208,6 +243,7 @@ private:
|
|||||||
void _SetSolver(BPrivate::SharedSolver* solver);
|
void _SetSolver(BPrivate::SharedSolver* solver);
|
||||||
|
|
||||||
BPrivate::SharedSolver* fSolver;
|
BPrivate::SharedSolver* fSolver;
|
||||||
|
BALMLayoutSpecListener* fSpecListener;
|
||||||
|
|
||||||
BReference<XTab> fLeft;
|
BReference<XTab> fLeft;
|
||||||
BReference<XTab> fRight;
|
BReference<XTab> fRight;
|
||||||
@ -231,9 +267,12 @@ private:
|
|||||||
YTabList fYTabList;
|
YTabList fYTabList;
|
||||||
bool fYTabsSorted;
|
bool fYTabsSorted;
|
||||||
|
|
||||||
|
BObjectList<Constraint> fConstraints;
|
||||||
|
|
||||||
RowColumnManager* fRowColumnManager;
|
RowColumnManager* fRowColumnManager;
|
||||||
|
|
||||||
BadLayoutPolicy* fBadLayoutPolicy;
|
BadLayoutPolicy* fBadLayoutPolicy;
|
||||||
|
|
||||||
uint32 _reserved[5];
|
uint32 _reserved[5];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -184,6 +184,25 @@ BALM::BALMLayout::DefaultPolicy::Instantiate(BMessage* archive)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class BALMLayout::BALMLayoutSpecListener
|
||||||
|
: public LinearProgramming::SpecificationListener {
|
||||||
|
public:
|
||||||
|
BALMLayoutSpecListener(BALMLayout* layout)
|
||||||
|
:
|
||||||
|
fLayout(layout)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConstraintRemoved(Constraint* constraint)
|
||||||
|
{
|
||||||
|
fLayout->fConstraints.RemoveItem(constraint);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
BALMLayout* fLayout;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Constructor.
|
* Constructor.
|
||||||
* Creates new layout engine.
|
* Creates new layout engine.
|
||||||
@ -204,6 +223,9 @@ BALMLayout::BALMLayout(float hSpacing, float vSpacing, BALMLayout* friendLayout)
|
|||||||
{
|
{
|
||||||
_SetSolver(friendLayout ? friendLayout->fSolver : new SharedSolver());
|
_SetSolver(friendLayout ? friendLayout->fSolver : new SharedSolver());
|
||||||
|
|
||||||
|
fSpecListener = new BALMLayoutSpecListener(this);
|
||||||
|
Solver()->AddListener(fSpecListener);
|
||||||
|
|
||||||
fLeft = AddXTab();
|
fLeft = AddXTab();
|
||||||
fRight = AddXTab();
|
fRight = AddXTab();
|
||||||
fTop = AddYTab();
|
fTop = AddYTab();
|
||||||
@ -278,14 +300,23 @@ BALMLayout::BALMLayout(BMessage* archive)
|
|||||||
err = unarchiver.EnsureUnarchived(kSolverField);
|
err = unarchiver.EnsureUnarchived(kSolverField);
|
||||||
|
|
||||||
unarchiver.Finish(err);
|
unarchiver.Finish(err);
|
||||||
|
|
||||||
|
fSpecListener = new BALMLayoutSpecListener(this);
|
||||||
|
Solver()->AddListener(fSpecListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BALMLayout::~BALMLayout()
|
BALMLayout::~BALMLayout()
|
||||||
{
|
{
|
||||||
|
Solver()->RemoveListener(fSpecListener);
|
||||||
|
delete fSpecListener;
|
||||||
|
|
||||||
delete fRowColumnManager;
|
delete fRowColumnManager;
|
||||||
delete fBadLayoutPolicy;
|
delete fBadLayoutPolicy;
|
||||||
|
|
||||||
|
for (int32 i = 0; i < fConstraints.CountItems(); i++)
|
||||||
|
Solver()->RemoveConstraint(fConstraints.ItemAt(i), true);
|
||||||
|
|
||||||
if (fSolver) {
|
if (fSolver) {
|
||||||
fSolver->LayoutLeaving(this);
|
fSolver->LayoutLeaving(this);
|
||||||
fSolver->ReleaseReference();
|
fSolver->ReleaseReference();
|
||||||
@ -409,6 +440,20 @@ BALMLayout::YTabAt(int32 index) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const XTabList
|
||||||
|
BALMLayout::GetXTabs() const
|
||||||
|
{
|
||||||
|
return fXTabList;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const YTabList
|
||||||
|
BALMLayout::GetYTabs() const
|
||||||
|
{
|
||||||
|
return fYTabList;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int32
|
int32
|
||||||
BALMLayout::IndexOf(XTab* tab, bool ordered)
|
BALMLayout::IndexOf(XTab* tab, bool ordered)
|
||||||
{
|
{
|
||||||
@ -433,6 +478,85 @@ BALMLayout::IndexOf(YTab* tab, bool ordered)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32
|
||||||
|
BALMLayout::CountConstraints() const
|
||||||
|
{
|
||||||
|
return fConstraints.CountItems();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Constraint*
|
||||||
|
BALMLayout::ConstraintAt(int32 index) const
|
||||||
|
{
|
||||||
|
return fConstraints.ItemAt(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
BALMLayout::AddConstraint(Constraint* constraint)
|
||||||
|
{
|
||||||
|
fConstraints.AddItem(constraint);
|
||||||
|
return Solver()->AddConstraint(constraint);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
BALMLayout::RemoveConstraint(Constraint* constraint,
|
||||||
|
bool deleteConstraint)
|
||||||
|
{
|
||||||
|
if (!fConstraints.RemoveItem(constraint))
|
||||||
|
return false;
|
||||||
|
return Solver()->RemoveConstraint(constraint, deleteConstraint);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Constraint*
|
||||||
|
BALMLayout::AddConstraint(double coeff1, Variable* var1, OperatorType op,
|
||||||
|
double rightSide, double penaltyNeg, double penaltyPos)
|
||||||
|
{
|
||||||
|
Constraint* constraint = Solver()->AddConstraint(coeff1, var1, op,
|
||||||
|
rightSide, penaltyNeg, penaltyPos);
|
||||||
|
fConstraints.AddItem(constraint);
|
||||||
|
return constraint;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Constraint*
|
||||||
|
BALMLayout::AddConstraint(double coeff1, Variable* var1, double coeff2,
|
||||||
|
Variable* var2, OperatorType op, double rightSide, double penaltyNeg,
|
||||||
|
double penaltyPos)
|
||||||
|
{
|
||||||
|
Constraint* constraint = Solver()->AddConstraint(coeff1, var1, coeff2, var2,
|
||||||
|
op, rightSide, penaltyNeg, penaltyPos);
|
||||||
|
fConstraints.AddItem(constraint);
|
||||||
|
return constraint;
|
||||||
|
}
|
||||||
|
|
||||||
|
Constraint*
|
||||||
|
BALMLayout::AddConstraint(double coeff1, Variable* var1, double coeff2,
|
||||||
|
Variable* var2, double coeff3, Variable* var3, OperatorType op,
|
||||||
|
double rightSide, double penaltyNeg, double penaltyPos)
|
||||||
|
{
|
||||||
|
Constraint* constraint = Solver()->AddConstraint(coeff1, var1, coeff2, var2,
|
||||||
|
coeff3, var3, op, rightSide, penaltyNeg, penaltyPos);
|
||||||
|
fConstraints.AddItem(constraint);
|
||||||
|
return constraint;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Constraint*
|
||||||
|
BALMLayout::AddConstraint(double coeff1, Variable* var1, double coeff2,
|
||||||
|
Variable* var2, double coeff3, Variable* var3, double coeff4,
|
||||||
|
Variable* var4, OperatorType op, double rightSide, double penaltyNeg,
|
||||||
|
double penaltyPos)
|
||||||
|
{
|
||||||
|
Constraint* constraint = Solver()->AddConstraint(coeff1, var1, coeff2, var2,
|
||||||
|
coeff3, var3, coeff4, var4, op, rightSide, penaltyNeg, penaltyPos);
|
||||||
|
fConstraints.AddItem(constraint);
|
||||||
|
return constraint;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
|
||||||
@ -775,6 +899,7 @@ BALMLayout::AddItem(BLayoutItem* item, XTab* _left, YTab* _top, XTab* _right,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fSolver->Invalidate(true);
|
||||||
area->_Init(Solver(), left, top, right, bottom, fRowColumnManager);
|
area->_Init(Solver(), left, top, right, bottom, fRowColumnManager);
|
||||||
fRowColumnManager->AddArea(area);
|
fRowColumnManager->AddArea(area);
|
||||||
|
|
||||||
@ -795,6 +920,7 @@ BALMLayout::AddItem(BLayoutItem* item, Row* row, Column* column)
|
|||||||
if (!area)
|
if (!area)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
fSolver->Invalidate(true);
|
||||||
area->_Init(Solver(), row, column, fRowColumnManager);
|
area->_Init(Solver(), row, column, fRowColumnManager);
|
||||||
|
|
||||||
fRowColumnManager->AddArea(area);
|
fRowColumnManager->AddArea(area);
|
||||||
@ -802,134 +928,6 @@ BALMLayout::AddItem(BLayoutItem* item, Row* row, Column* column)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
enum {
|
|
||||||
kLeftBorderIndex = -2,
|
|
||||||
kTopBorderIndex = -3,
|
|
||||||
kRightBorderIndex = -4,
|
|
||||||
kBottomBorderIndex = -5,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
bool
|
|
||||||
BALMLayout::SaveLayout(BMessage* archive) const
|
|
||||||
{
|
|
||||||
archive->MakeEmpty();
|
|
||||||
|
|
||||||
archive->AddInt32("nXTabs", CountXTabs());
|
|
||||||
archive->AddInt32("nYTabs", CountYTabs());
|
|
||||||
|
|
||||||
XTabList xTabs = fXTabList;
|
|
||||||
xTabs.RemoveItem(fLeft);
|
|
||||||
xTabs.RemoveItem(fRight);
|
|
||||||
YTabList yTabs = fYTabList;
|
|
||||||
yTabs.RemoveItem(fTop);
|
|
||||||
yTabs.RemoveItem(fBottom);
|
|
||||||
|
|
||||||
int32 nAreas = CountAreas();
|
|
||||||
for (int32 i = 0; i < nAreas; i++) {
|
|
||||||
Area* area = AreaAt(i);
|
|
||||||
if (area->Left() == fLeft)
|
|
||||||
archive->AddInt32("left", kLeftBorderIndex);
|
|
||||||
else
|
|
||||||
archive->AddInt32("left", xTabs.IndexOf(area->Left()));
|
|
||||||
if (area->Top() == fTop)
|
|
||||||
archive->AddInt32("top", kTopBorderIndex);
|
|
||||||
else
|
|
||||||
archive->AddInt32("top", yTabs.IndexOf(area->Top()));
|
|
||||||
if (area->Right() == fRight)
|
|
||||||
archive->AddInt32("right", kRightBorderIndex);
|
|
||||||
else
|
|
||||||
archive->AddInt32("right", xTabs.IndexOf(area->Right()));
|
|
||||||
if (area->Bottom() == fBottom)
|
|
||||||
archive->AddInt32("bottom", kBottomBorderIndex);
|
|
||||||
else
|
|
||||||
archive->AddInt32("bottom", yTabs.IndexOf(area->Bottom()));
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool
|
|
||||||
BALMLayout::RestoreLayout(const BMessage* archive)
|
|
||||||
{
|
|
||||||
int32 neededXTabs;
|
|
||||||
int32 neededYTabs;
|
|
||||||
if (archive->FindInt32("nXTabs", &neededXTabs) != B_OK)
|
|
||||||
return false;
|
|
||||||
if (archive->FindInt32("nYTabs", &neededYTabs) != B_OK)
|
|
||||||
return false;
|
|
||||||
// First store a reference to all needed tabs otherwise they might get lost
|
|
||||||
// while editing the layout
|
|
||||||
std::vector<BReference<XTab> > newXTabs;
|
|
||||||
std::vector<BReference<YTab> > newYTabs;
|
|
||||||
int32 existingXTabs = fXTabList.CountItems();
|
|
||||||
for (int32 i = 0; i < neededXTabs; i++) {
|
|
||||||
if (i < existingXTabs)
|
|
||||||
newXTabs.push_back(BReference<XTab>(fXTabList.ItemAt(i)));
|
|
||||||
else
|
|
||||||
newXTabs.push_back(AddXTab());
|
|
||||||
}
|
|
||||||
int32 existingYTabs = fYTabList.CountItems();
|
|
||||||
for (int32 i = 0; i < neededYTabs; i++) {
|
|
||||||
if (i < existingYTabs)
|
|
||||||
newYTabs.push_back(BReference<YTab>(fYTabList.ItemAt(i)));
|
|
||||||
else
|
|
||||||
newYTabs.push_back(AddYTab());
|
|
||||||
}
|
|
||||||
|
|
||||||
XTabList xTabs = fXTabList;
|
|
||||||
xTabs.RemoveItem(fLeft);
|
|
||||||
xTabs.RemoveItem(fRight);
|
|
||||||
YTabList yTabs = fYTabList;
|
|
||||||
yTabs.RemoveItem(fTop);
|
|
||||||
yTabs.RemoveItem(fBottom);
|
|
||||||
|
|
||||||
int32 nAreas = CountAreas();
|
|
||||||
for (int32 i = 0; i < nAreas; i++) {
|
|
||||||
Area* area = AreaAt(i);
|
|
||||||
if (area == NULL)
|
|
||||||
return false;
|
|
||||||
int32 left = -1;
|
|
||||||
if (archive->FindInt32("left", i, &left) != B_OK)
|
|
||||||
break;
|
|
||||||
int32 top = archive->FindInt32("top", i);
|
|
||||||
int32 right = archive->FindInt32("right", i);
|
|
||||||
int32 bottom = archive->FindInt32("bottom", i);
|
|
||||||
|
|
||||||
XTab* leftTab = NULL;
|
|
||||||
YTab* topTab = NULL;
|
|
||||||
XTab* rightTab = NULL;
|
|
||||||
YTab* bottomTab = NULL;
|
|
||||||
|
|
||||||
if (left == kLeftBorderIndex)
|
|
||||||
leftTab = fLeft;
|
|
||||||
else
|
|
||||||
leftTab = xTabs.ItemAt(left);
|
|
||||||
if (top == kTopBorderIndex)
|
|
||||||
topTab = fTop;
|
|
||||||
else
|
|
||||||
topTab = yTabs.ItemAt(top);
|
|
||||||
if (right == kRightBorderIndex)
|
|
||||||
rightTab = fRight;
|
|
||||||
else
|
|
||||||
rightTab = xTabs.ItemAt(right);
|
|
||||||
if (bottom == kBottomBorderIndex)
|
|
||||||
bottomTab = fBottom;
|
|
||||||
else
|
|
||||||
bottomTab = yTabs.ItemAt(bottom);
|
|
||||||
if (leftTab == NULL || topTab == NULL || rightTab == NULL
|
|
||||||
|| bottomTab == NULL)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
area->SetLeft(leftTab);
|
|
||||||
area->SetTop(topTab);
|
|
||||||
area->SetRight(rightTab);
|
|
||||||
area->SetBottom(bottomTab);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the left variable.
|
* Gets the left variable.
|
||||||
*/
|
*/
|
||||||
@ -1337,6 +1335,17 @@ BALMLayout::Solver() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ResultType
|
||||||
|
BALMLayout::ValidateLayout()
|
||||||
|
{
|
||||||
|
// we explicitly recaluclate the layout so set the invalidate flag first
|
||||||
|
fSolver->Invalidate(true);
|
||||||
|
|
||||||
|
BLayoutContext* context = LayoutContext();
|
||||||
|
return fSolver->ValidateLayout(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BALMLayout::SetInsets(float left, float top, float right,
|
BALMLayout::SetInsets(float left, float top, float right,
|
||||||
float bottom)
|
float bottom)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user