* Simplified and optimized a lot the "ToString()" debugging facilities.

* *::Index() is now const, thanks to the BList improvements.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@34521 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus
2009-12-06 13:14:45 +00:00
parent b0850e9ba1
commit b8ec67f491
9 changed files with 404 additions and 423 deletions
+12 -12
View File
@@ -29,7 +29,7 @@ class BALMLayout;
* Rectangular area in the GUI, defined by a tab on each side. * Rectangular area in the GUI, defined by a tab on each side.
*/ */
class Area { class Area {
public: public:
XTab* Left() const; XTab* Left() const;
void SetLeft(XTab* left); void SetLeft(XTab* left);
@@ -83,32 +83,32 @@ public:
bool AutoPreferredContentSize() const; bool AutoPreferredContentSize() const;
void SetAutoPreferredContentSize(bool value); void SetAutoPreferredContentSize(bool value);
BString* ToBString(); operator BString() const;
const char* ToString(); void GetString(BString& string) const;
Constraint* HasSameWidthAs(Area* area); Constraint* HasSameWidthAs(Area* area);
Constraint* HasSameHeightAs(Area* area); Constraint* HasSameHeightAs(Area* area);
BList* HasSameSizeAs(Area* area); BList* HasSameSizeAs(Area* area);
~Area(); ~Area();
protected: protected:
Area(BALMLayout* ls, XTab* left, YTab* top, Area(BALMLayout* ls, XTab* left, YTab* top,
XTab* right, YTab* bottom, XTab* right, YTab* bottom,
BView* content, BView* content,
BSize minContentSize); BSize minContentSize);
Area(BALMLayout* ls, Row* row, Column* column, Area(BALMLayout* ls, Row* row, Column* column,
BView* content, BView* content,
BSize minContentSize); BSize minContentSize);
void DoLayout(); void DoLayout();
private: private:
void InitChildArea(); void InitChildArea();
void UpdateHorizontal(); void UpdateHorizontal();
void UpdateVertical(); void UpdateVertical();
void Init(BALMLayout* ls, XTab* left, YTab* top, void Init(BALMLayout* ls, XTab* left, YTab* top,
XTab* right, YTab* bottom, XTab* right, YTab* bottom,
BView* content, BView* content,
BSize minContentSize); BSize minContentSize);
public: public:
@@ -152,7 +152,7 @@ private:
Constraint* fTopConstraint; Constraint* fTopConstraint;
Constraint* fRightConstraint; Constraint* fRightConstraint;
Constraint* fBottomConstraint; Constraint* fBottomConstraint;
public: public:
friend class BALMLayout; friend class BALMLayout;
+9 -9
View File
@@ -19,28 +19,28 @@
namespace LinearProgramming { namespace LinearProgramming {
class LinearSpec; class LinearSpec;
/** /**
* Hard linear constraint, i.e. one that must be satisfied. * Hard linear constraint, i.e. one that must be satisfied.
* May render a specification infeasible. * May render a specification infeasible.
*/ */
class Constraint { class Constraint {
public: public:
int32 Index(); int32 Index() const;
BList* LeftSide(); BList* LeftSide();
void SetLeftSide(BList* summands); void SetLeftSide(BList* summands);
void UpdateLeftSide(); void UpdateLeftSide();
void SetLeftSide(double coeff1, Variable* var1); void SetLeftSide(double coeff1, Variable* var1);
void SetLeftSide(double coeff1, Variable* var1, void SetLeftSide(double coeff1, Variable* var1,
double coeff2, Variable* var2); double coeff2, Variable* var2);
void SetLeftSide(double coeff1, Variable* var1, void SetLeftSide(double coeff1, Variable* var1,
double coeff2, Variable* var2, double coeff2, Variable* var2,
double coeff3, Variable* var3); double coeff3, Variable* var3);
void SetLeftSide(double coeff1, Variable* var1, void SetLeftSide(double coeff1, Variable* var1,
double coeff2, Variable* var2, double coeff2, Variable* var2,
double coeff3, Variable* var3, double coeff3, Variable* var3,
double coeff4, Variable* var4); double coeff4, Variable* var4);
@@ -68,8 +68,8 @@ public:
bool IsValid(); bool IsValid();
void Invalidate(); void Invalidate();
BString* ToBString(); operator BString() const;
const char* ToString(); void GetString(BString& string) const;
~Constraint(); ~Constraint();
+29 -29
View File
@@ -25,7 +25,7 @@
namespace LinearProgramming { namespace LinearProgramming {
class Constraint; class Constraint;
class ObjFunctionSummand; class ObjFunctionSummand;
class PenaltyFunction; class PenaltyFunction;
@@ -35,52 +35,52 @@ class Variable;
* Specification of a linear programming problem. * Specification of a linear programming problem.
*/ */
class LinearSpec { class LinearSpec {
public: public:
LinearSpec(); LinearSpec();
virtual ~LinearSpec(); virtual ~LinearSpec();
Variable* AddVariable(); Variable* AddVariable();
Constraint* AddConstraint(BList* summands, Constraint* AddConstraint(BList* summands,
OperatorType op, double rightSide);
Constraint* AddConstraint(double coeff1, Variable* var1,
OperatorType op, double rightSide);
Constraint* AddConstraint(double coeff1, Variable* var1,
double coeff2, Variable* var2,
OperatorType op, double rightSide); OperatorType op, double rightSide);
Constraint* AddConstraint(double coeff1, Variable* var1, Constraint* AddConstraint(double coeff1, Variable* var1,
double coeff2, Variable* var2,
double coeff3, Variable* var3,
OperatorType op, double rightSide); OperatorType op, double rightSide);
Constraint* AddConstraint(double coeff1, Variable* var1, Constraint* AddConstraint(double coeff1, Variable* var1,
double coeff2, Variable* var2, double coeff2, Variable* var2,
double coeff3, Variable* var3, OperatorType op, double rightSide);
double coeff4, Variable* var4, Constraint* AddConstraint(double coeff1, Variable* var1,
double coeff2, Variable* var2,
double coeff3, Variable* var3,
OperatorType op, double rightSide);
Constraint* AddConstraint(double coeff1, Variable* var1,
double coeff2, Variable* var2,
double coeff3, Variable* var3,
double coeff4, Variable* var4,
OperatorType op, double rightSide); OperatorType op, double rightSide);
Constraint* AddConstraint(BList* summands, Constraint* AddConstraint(BList* summands,
OperatorType op, double rightSide, OperatorType op, double rightSide,
double penaltyNeg, double penaltyPos); double penaltyNeg, double penaltyPos);
Constraint* AddConstraint(double coeff1, Variable* var1, Constraint* AddConstraint(double coeff1, Variable* var1,
OperatorType op, double rightSide, OperatorType op, double rightSide,
double penaltyNeg, double penaltyPos); double penaltyNeg, double penaltyPos);
Constraint* AddConstraint(double coeff1, Variable* var1, Constraint* AddConstraint(double coeff1, Variable* var1,
double coeff2, Variable* var2, double coeff2, Variable* var2,
OperatorType op, double rightSide, OperatorType op, double rightSide,
double penaltyNeg, double penaltyPos); double penaltyNeg, double penaltyPos);
Constraint* AddConstraint(double coeff1, Variable* var1, Constraint* AddConstraint(double coeff1, Variable* var1,
double coeff2, Variable* var2, double coeff2, Variable* var2,
double coeff3, Variable* var3, double coeff3, Variable* var3,
OperatorType op, double rightSide, OperatorType op, double rightSide,
double penaltyNeg, double penaltyPos); double penaltyNeg, double penaltyPos);
Constraint* AddConstraint(double coeff1, Variable* var1, Constraint* AddConstraint(double coeff1, Variable* var1,
double coeff2, Variable* var2, double coeff2, Variable* var2,
double coeff3, Variable* var3, double coeff3, Variable* var3,
double coeff4, Variable* var4, double coeff4, Variable* var4,
OperatorType op, double rightSide, OperatorType op, double rightSide,
double penaltyNeg, double penaltyPos); double penaltyNeg, double penaltyPos);
PenaltyFunction* AddPenaltyFunction(Variable* var, BList* xs, BList* gs); PenaltyFunction* AddPenaltyFunction(Variable* var, BList* xs, BList* gs);
BList* ObjFunction(); BList* ObjFunction();
@@ -90,7 +90,7 @@ public:
ResultType Presolve(); ResultType Presolve();
void RemovePresolved(); void RemovePresolved();
ResultType Solve(); ResultType Solve();
void Save(char* fname); void Save(const char* fileName);
int32 CountColumns() const; int32 CountColumns() const;
OptimizationType Optimization() const; OptimizationType Optimization() const;
@@ -101,8 +101,8 @@ public:
double ObjectiveValue() const; double ObjectiveValue() const;
double SolvingTime() const; double SolvingTime() const;
BString* ToBString(); operator BString() const;
const char* ToString(); void GetString(BString& string) const;
protected: protected:
int32 fCountColumns; int32 fCountColumns;
+4 -4
View File
@@ -24,7 +24,7 @@ class Summand;
class Variable { class Variable {
public: public:
int32 Index(); int32 Index() const;
LinearSpec* LS() const; LinearSpec* LS() const;
double Value() const; double Value() const;
void SetValue(double value); void SetValue(double value);
@@ -36,9 +36,9 @@ public:
const char* Label(); const char* Label();
void SetLabel(const char* label); void SetLabel(const char* label);
BString* ToBString(); operator BString() const;
const char* ToString(); void GetString(BString& string) const;
Constraint* IsEqual(Variable* var); Constraint* IsEqual(Variable* var);
Constraint* IsSmallerOrEqual(Variable* var); Constraint* IsSmallerOrEqual(Variable* var);
+94 -102
View File
@@ -73,12 +73,12 @@ void
Area::SetLeft(XTab* left) Area::SetLeft(XTab* left)
{ {
fLeft = left; fLeft = left;
fColumn = NULL; fColumn = NULL;
if (fChildArea == NULL) { if (fChildArea == NULL) {
fMinContentWidth->SetLeftSide(-1.0, fLeft, 1.0, fRight); fMinContentWidth->SetLeftSide(-1.0, fLeft, 1.0, fRight);
if (fMaxContentWidth != NULL) if (fMaxContentWidth != NULL)
fMaxContentWidth->SetLeftSide(-1.0, fLeft, 1.0, fRight); fMaxContentWidth->SetLeftSide(-1.0, fLeft, 1.0, fRight);
} else } else
@@ -108,12 +108,12 @@ void
Area::SetRight(XTab* right) Area::SetRight(XTab* right)
{ {
fRight = right; fRight = right;
fColumn = NULL; fColumn = NULL;
if (fChildArea == NULL) { if (fChildArea == NULL) {
fMinContentWidth->SetLeftSide(-1.0, fLeft, 1.0, fRight); fMinContentWidth->SetLeftSide(-1.0, fLeft, 1.0, fRight);
if (fMaxContentWidth != NULL) if (fMaxContentWidth != NULL)
fMaxContentWidth->SetLeftSide(-1.0, fLeft, 1.0, fRight); fMaxContentWidth->SetLeftSide(-1.0, fLeft, 1.0, fRight);
} else } else
@@ -139,12 +139,12 @@ void
Area::SetTop(YTab* top) Area::SetTop(YTab* top)
{ {
fTop = top; fTop = top;
fRow = NULL; fRow = NULL;
if (fChildArea == NULL) { if (fChildArea == NULL) {
fMinContentHeight->SetLeftSide(-1.0, fTop, 1.0, fBottom); fMinContentHeight->SetLeftSide(-1.0, fTop, 1.0, fBottom);
if (fMaxContentHeight != NULL) if (fMaxContentHeight != NULL)
fMaxContentHeight->SetLeftSide(-1.0, fTop, 1.0, fBottom); fMaxContentHeight->SetLeftSide(-1.0, fTop, 1.0, fBottom);
} else } else
@@ -170,12 +170,12 @@ void
Area::SetBottom(YTab* bottom) Area::SetBottom(YTab* bottom)
{ {
fBottom = bottom; fBottom = bottom;
fRow = NULL; fRow = NULL;
if (fChildArea == NULL) { if (fChildArea == NULL) {
fMinContentHeight->SetLeftSide(-1.0, fTop, 1.0, fBottom); fMinContentHeight->SetLeftSide(-1.0, fTop, 1.0, fBottom);
if (fMaxContentHeight != NULL) if (fMaxContentHeight != NULL)
fMaxContentHeight->SetLeftSide(-1.0, fTop, 1.0, fBottom); fMaxContentHeight->SetLeftSide(-1.0, fTop, 1.0, fBottom);
} else } else
@@ -315,7 +315,7 @@ Area::SetMinContentSize(BSize min)
fMinContentSize = min; fMinContentSize = min;
fMinContentWidth->SetRightSide(fMinContentSize.Width()); fMinContentWidth->SetRightSide(fMinContentSize.Width());
fMinContentHeight->SetRightSide(fMinContentSize.Height()); fMinContentHeight->SetRightSide(fMinContentSize.Height());
} else } else
fChildArea->SetMinContentSize(min); fChildArea->SetMinContentSize(min);
fLS->InvalidateLayout(); fLS->InvalidateLayout();
} }
@@ -342,7 +342,7 @@ Area::SetMaxContentSize(BSize max)
fMaxContentWidth = fLS->AddConstraint(-1.0, fLeft, 1.0, fRight, OperatorType(LE), fMaxContentWidth = fLS->AddConstraint(-1.0, fLeft, 1.0, fRight, OperatorType(LE),
fMaxContentSize.Width()); fMaxContentSize.Width());
fConstraints->AddItem(fMaxContentWidth); fConstraints->AddItem(fMaxContentWidth);
fMaxContentHeight = fLS->AddConstraint(-1.0, fTop, 1.0, fBottom, OperatorType(LE), fMaxContentHeight = fLS->AddConstraint(-1.0, fTop, 1.0, fBottom, OperatorType(LE),
fMaxContentSize.Height()); fMaxContentSize.Height());
fConstraints->AddItem(fMaxContentHeight); fConstraints->AddItem(fMaxContentHeight);
@@ -370,7 +370,7 @@ Area::PreferredContentSize() const
/** /**
* Sets Preferred size of the area's content. * Sets Preferred size of the area's content.
* May be different from the preferred size of the area. * May be different from the preferred size of the area.
* Manual changes of PreferredContentSize are ignored unless * Manual changes of PreferredContentSize are ignored unless
* autoPreferredContentSize is set to false. * autoPreferredContentSize is set to false.
*/ */
void void
@@ -384,7 +384,7 @@ Area::SetPreferredContentSize(BSize preferred)
fPreferredContentSize.Width(), fShrinkPenalties.Width(), fPreferredContentSize.Width(), fShrinkPenalties.Width(),
fGrowPenalties.Width()); fGrowPenalties.Width());
fConstraints->AddItem(fPreferredContentWidth); fConstraints->AddItem(fPreferredContentWidth);
fPreferredContentHeight = fLS->AddConstraint( fPreferredContentHeight = fLS->AddConstraint(
-1.0, fTop, 1.0, fBottom, OperatorType(EQ), -1.0, fTop, 1.0, fBottom, OperatorType(EQ),
fPreferredContentSize.Height(), fShrinkPenalties.Height(), fPreferredContentSize.Height(), fShrinkPenalties.Height(),
@@ -418,7 +418,7 @@ void Area::SetShrinkPenalties(BSize shrink) {
fPreferredContentWidth->SetPenaltyNeg(shrink.Width()); fPreferredContentWidth->SetPenaltyNeg(shrink.Width());
fPreferredContentHeight->SetPenaltyNeg(shrink.Height()); fPreferredContentHeight->SetPenaltyNeg(shrink.Height());
} }
} else } else
fChildArea->SetShrinkPenalties(shrink); fChildArea->SetShrinkPenalties(shrink);
fLS->InvalidateLayout(); fLS->InvalidateLayout();
} }
@@ -444,7 +444,7 @@ Area::SetGrowPenalties(BSize grow)
fPreferredContentWidth->SetPenaltyPos(grow.Width()); fPreferredContentWidth->SetPenaltyPos(grow.Width());
fPreferredContentHeight->SetPenaltyPos(grow.Height()); fPreferredContentHeight->SetPenaltyPos(grow.Height());
} }
} else } else
fChildArea->SetGrowPenalties(grow); fChildArea->SetGrowPenalties(grow);
fLS->InvalidateLayout(); fLS->InvalidateLayout();
} }
@@ -616,7 +616,7 @@ Area::SetBottomInset(int32 bottom)
/** /**
* Sets the preferred size according to the content's PreferredSize method, * Sets the preferred size according to the content's PreferredSize method,
* and the penalties according to heuristics. * and the penalties according to heuristics.
*/ */
void void
@@ -628,12 +628,12 @@ Area::SetDefaultBehavior()
SetGrowPenalties(BSize(0, 0)); SetGrowPenalties(BSize(0, 0));
return; return;
} }
if (PreferredContentSize() != Content()->PreferredSize()){ if (PreferredContentSize() != Content()->PreferredSize()){
SetPreferredContentSize(Content()->PreferredSize()); SetPreferredContentSize(Content()->PreferredSize());
fLS->InvalidateLayout(); fLS->InvalidateLayout();
} }
if (dynamic_cast<BButton*>(Content()) != NULL if (dynamic_cast<BButton*>(Content()) != NULL
|| dynamic_cast<BRadioButton*>(Content()) != NULL || dynamic_cast<BRadioButton*>(Content()) != NULL
|| dynamic_cast<BCheckBox*>(Content()) != NULL || dynamic_cast<BCheckBox*>(Content()) != NULL
@@ -649,40 +649,32 @@ Area::SetDefaultBehavior()
} }
BString* Area::operator BString() const
Area::ToBString() {
{ BString string;
BString* str = new BString(); GetString(string);
BString* leftStr = fLeft->ToBString(); return string;
BString* topStr = fTop->ToBString(); }
BString* rightStr = fRight->ToBString();
BString* bottomStr = fBottom->ToBString();
*str << "Area(" << *leftStr << ", " void
<< *topStr << ", " Area::GetString(BString& string) const
<< *rightStr << ", " {
<< *bottomStr << ")"; string << "Area(";
delete leftStr; fLeft->GetString(string);
delete topStr; string << ", ";
delete rightStr; fTop->GetString(string);
delete bottomStr; string << ", ";
return str; fRight->GetString(string);
} string << ", ";
fBottom->GetString(string);
string << ")";
const char*
Area::ToString()
{
BString* str = new BString();
char* result = (char*) malloc(str->Length() + 1);
str->CopyInto(result, 0, str->Length());
delete str;
return result;
} }
/** /**
* Sets the width of the area to be the same as the width of the given area. * Sets the width of the area to be the same as the width of the given area.
* *
* @param area the area that should have the same width * @param area the area that should have the same width
* @return the same-width constraint * @return the same-width constraint
*/ */
@@ -690,14 +682,14 @@ Constraint*
Area::HasSameWidthAs(Area* area) Area::HasSameWidthAs(Area* area)
{ {
return fLS->AddConstraint( return fLS->AddConstraint(
-1.0, fLeft, 1.0, fRight, 1.0, area->fLeft, -1.0, area->fRight, -1.0, fLeft, 1.0, fRight, 1.0, area->fLeft, -1.0, area->fRight,
OperatorType(EQ), 0.0); OperatorType(EQ), 0.0);
} }
/** /**
* Sets the height of the area to be the same as the height of the given area. * Sets the height of the area to be the same as the height of the given area.
* *
* @param area the area that should have the same height * @param area the area that should have the same height
* @return the same-height constraint * @return the same-height constraint
*/ */
@@ -705,14 +697,14 @@ Constraint*
Area::HasSameHeightAs(Area* area) Area::HasSameHeightAs(Area* area)
{ {
return fLS->AddConstraint( return fLS->AddConstraint(
-1.0, fTop, 1.0, fBottom, 1.0, area->fTop, -1.0, area->fBottom, -1.0, fTop, 1.0, fBottom, 1.0, area->fTop, -1.0, area->fBottom,
OperatorType(EQ), 0.0); OperatorType(EQ), 0.0);
} }
/** /**
* Sets the size of the area to be the same as the size of the given area. * Sets the size of the area to be the same as the size of the given area.
* *
* @param area the area that should have the same size * @param area the area that should have the same size
* @return a list containing a same-width and same-height constraint * @return a list containing a same-width and same-height constraint
*/ */
@@ -743,9 +735,9 @@ Area::~Area()
* Constructor. * Constructor.
* Uses XTabs and YTabs. * Uses XTabs and YTabs.
*/ */
Area::Area(BALMLayout* ls, XTab* left, YTab* top, XTab* right, YTab* bottom, Area::Area(BALMLayout* ls, XTab* left, YTab* top, XTab* right, YTab* bottom,
BView* content, BSize minContentSize) BView* content, BSize minContentSize)
{ {
Init(ls, left, top, right, bottom, content, minContentSize); Init(ls, left, top, right, bottom, content, minContentSize);
} }
@@ -757,8 +749,8 @@ Area::Area(BALMLayout* ls, XTab* left, YTab* top, XTab* right, YTab* bottom,
Area::Area(BALMLayout* ls, Row* row, Column* column, BView* content, Area::Area(BALMLayout* ls, Row* row, Column* column, BView* content,
BSize minContentSize) BSize minContentSize)
{ {
Init(ls, column->Left(), row->Top(), column->Right(), row->Bottom(), Init(ls, column->Left(), row->Top(), column->Right(), row->Bottom(),
content, minContentSize); content, minContentSize);
fRow = row; fRow = row;
fColumn = column; fColumn = column;
@@ -769,40 +761,40 @@ Area::Area(BALMLayout* ls, Row* row, Column* column, BView* content,
* Initialize variables. * Initialize variables.
*/ */
void void
Area::Init(BALMLayout* ls, XTab* left, YTab* top, XTab* right, YTab* bottom, Area::Init(BALMLayout* ls, XTab* left, YTab* top, XTab* right, YTab* bottom,
BView* content, BSize minContentSize) BView* content, BSize minContentSize)
{ {
fConstraints = new BList(2); fConstraints = new BList(2);
fMaxContentSize = kMaxSize; fMaxContentSize = kMaxSize;
fMaxContentWidth = NULL; fMaxContentWidth = NULL;
fMaxContentHeight = NULL; fMaxContentHeight = NULL;
fPreferredContentSize = kUndefinedSize; fPreferredContentSize = kUndefinedSize;
fShrinkPenalties = BSize(2, 2); fShrinkPenalties = BSize(2, 2);
fGrowPenalties = BSize(1, 1); fGrowPenalties = BSize(1, 1);
fContentAspectRatio = 0; fContentAspectRatio = 0;
fContentAspectRatioC = NULL; fContentAspectRatioC = NULL;
fAutoPreferredContentSize = false; fAutoPreferredContentSize = false;
fPreferredContentWidth = NULL; fPreferredContentWidth = NULL;
fPreferredContentHeight = NULL; fPreferredContentHeight = NULL;
fChildArea = NULL; fChildArea = NULL;
fAlignment = BAlignment(B_ALIGN_USE_FULL_WIDTH, B_ALIGN_USE_FULL_HEIGHT); fAlignment = BAlignment(B_ALIGN_USE_FULL_WIDTH, B_ALIGN_USE_FULL_HEIGHT);
fLeftInset = 0; fLeftInset = 0;
fTopInset = 0; fTopInset = 0;
fRightInset = 0; fRightInset = 0;
fBottomInset = 0; fBottomInset = 0;
fLeftConstraint = NULL; fLeftConstraint = NULL;
fTopConstraint = NULL; fTopConstraint = NULL;
fRightConstraint = NULL; fRightConstraint = NULL;
fBottomConstraint = NULL; fBottomConstraint = NULL;
fLS = ls; fLS = ls;
fLeft = left; fLeft = left;
fRight = right; fRight = right;
@@ -810,13 +802,13 @@ Area::Init(BALMLayout* ls, XTab* left, YTab* top, XTab* right, YTab* bottom,
fBottom = bottom; fBottom = bottom;
SetContent(content); SetContent(content);
fMinContentSize = minContentSize; fMinContentSize = minContentSize;
// adds the two essential constraints of the area that make sure that the left x-tab is // 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 // really to the left of the right x-tab, and the top y-tab really above the bottom y-tab
fMinContentWidth = ls->AddConstraint(-1.0, left, 1.0, right, OperatorType(GE), fMinContentWidth = ls->AddConstraint(-1.0, left, 1.0, right, OperatorType(GE),
minContentSize.Width()); minContentSize.Width());
fConstraints->AddItem(fMinContentWidth); fConstraints->AddItem(fMinContentWidth);
fMinContentHeight = ls->AddConstraint(-1.0, top, 1.0, bottom, OperatorType(GE), fMinContentHeight = ls->AddConstraint(-1.0, top, 1.0, bottom, OperatorType(GE),
minContentSize.Height()); minContentSize.Height());
fConstraints->AddItem(fMinContentHeight); fConstraints->AddItem(fMinContentHeight);
@@ -828,14 +820,14 @@ Area::Init(BALMLayout* ls, XTab* left, YTab* top, XTab* right, YTab* bottom,
*/ */
void Area::DoLayout() void Area::DoLayout()
{ {
if (Content() == NULL) if (Content() == NULL)
return; // empty areas need no layout return; // empty areas need no layout
// if there is a childArea, then it is the childArea that actually contains the content // if there is a childArea, then it is the childArea that actually contains the content
Area* area = (fChildArea != NULL) ? fChildArea : this; Area* area = (fChildArea != NULL) ? fChildArea : this;
// set content location and size // set content location and size
area->Content()->MoveTo(floor(area->Left()->Value() + 0.5), area->Content()->MoveTo(floor(area->Left()->Value() + 0.5),
floor(area->Top()->Value() + 0.5)); floor(area->Top()->Value() + 0.5));
int32 width = (int32)floor(area->Right()->Value() - area->Left()->Value() + 0.5); int32 width = (int32)floor(area->Right()->Value() - area->Left()->Value() + 0.5);
int32 height = (int32)floor(area->Bottom()->Value() - area->Top()->Value() + 0.5); int32 height = (int32)floor(area->Bottom()->Value() - area->Top()->Value() + 0.5);
@@ -844,15 +836,15 @@ void Area::DoLayout()
/** /**
* Adds a childArea to this area, together with constraints that specify the relative location * Adds a childArea to this area, together with constraints that specify the relative location
* of the childArea within this area. It is called when such a childArea becomes necessary, * of the childArea within this area. It is called when such a childArea becomes necessary,
* i.e. when the user requests insets or special alignment. * i.e. when the user requests insets or special alignment.
*/ */
void void
Area::InitChildArea() Area::InitChildArea()
{ {
// add a child area with new tabs, // add a child area with new tabs,
// and add constraints that set its tabs to be equal to the // and add constraints that set its tabs to be equal to the
// coresponding tabs of this area (for a start) // coresponding tabs of this area (for a start)
fChildArea = new Area(fLS, new XTab(fLS), new YTab(fLS), new XTab(fLS), fChildArea = new Area(fLS, new XTab(fLS), new YTab(fLS), new XTab(fLS),
new YTab(fLS), fContent, BSize(0, 0)); new YTab(fLS), fContent, BSize(0, 0));
@@ -864,7 +856,7 @@ Area::InitChildArea()
fConstraints->AddItem(fRightConstraint); fConstraints->AddItem(fRightConstraint);
fBottomConstraint = fBottom->IsEqual(fChildArea->Bottom()); fBottomConstraint = fBottom->IsEqual(fChildArea->Bottom());
fConstraints->AddItem(fBottomConstraint); fConstraints->AddItem(fBottomConstraint);
// remove the minimum content size constraints from this area // remove the minimum content size constraints from this area
// and copy the minimum content size setting to the childArea // and copy the minimum content size setting to the childArea
fConstraints->RemoveItem(fMinContentWidth); fConstraints->RemoveItem(fMinContentWidth);
@@ -875,33 +867,33 @@ Area::InitChildArea()
fMinContentHeight = fChildArea->fMinContentHeight; fMinContentHeight = fChildArea->fMinContentHeight;
fChildArea->SetMinContentSize(fMinContentSize); fChildArea->SetMinContentSize(fMinContentSize);
// if there are maximum content size constraints on this area, // if there are maximum content size constraints on this area,
// change them so that they refer to the tabs of the childArea // change them so that they refer to the tabs of the childArea
// and copy the minimum content size settings to the childArea // and copy the minimum content size settings to the childArea
if (fMaxContentWidth != NULL) { if (fMaxContentWidth != NULL) {
fChildArea->fMaxContentSize = fMaxContentSize; fChildArea->fMaxContentSize = fMaxContentSize;
fChildArea->fMaxContentWidth = fMaxContentWidth; fChildArea->fMaxContentWidth = fMaxContentWidth;
fMaxContentWidth->SetLeftSide( fMaxContentWidth->SetLeftSide(
-1.0, fChildArea->Left(), 1.0, fChildArea->Right()); -1.0, fChildArea->Left(), 1.0, fChildArea->Right());
fChildArea->fMaxContentHeight = fMaxContentHeight; fChildArea->fMaxContentHeight = fMaxContentHeight;
fMaxContentHeight->SetLeftSide( fMaxContentHeight->SetLeftSide(
-1.0, fChildArea->Top(), 1.0, fChildArea->Bottom()); -1.0, fChildArea->Top(), 1.0, fChildArea->Bottom());
} }
// if there are preferred content size constraints on this area, // if there are preferred content size constraints on this area,
// change them so that they refer to the tabs of the childArea // change them so that they refer to the tabs of the childArea
// and copy the preferred content size settings to the childArea // and copy the preferred content size settings to the childArea
if (fPreferredContentHeight != NULL) { if (fPreferredContentHeight != NULL) {
fChildArea->fPreferredContentSize = fPreferredContentSize; fChildArea->fPreferredContentSize = fPreferredContentSize;
fChildArea->fShrinkPenalties = fShrinkPenalties; fChildArea->fShrinkPenalties = fShrinkPenalties;
fChildArea->fGrowPenalties = fGrowPenalties; fChildArea->fGrowPenalties = fGrowPenalties;
fChildArea->fPreferredContentWidth = fPreferredContentWidth; fChildArea->fPreferredContentWidth = fPreferredContentWidth;
fPreferredContentWidth->SetLeftSide( fPreferredContentWidth->SetLeftSide(
-1.0, fChildArea->Left(), 1.0, fChildArea->Right()); -1.0, fChildArea->Left(), 1.0, fChildArea->Right());
fChildArea->fPreferredContentHeight = fPreferredContentHeight; fChildArea->fPreferredContentHeight = fPreferredContentHeight;
fPreferredContentHeight->SetLeftSide( fPreferredContentHeight->SetLeftSide(
-1.0, fChildArea->Top(), 1.0, fChildArea->Bottom()); -1.0, fChildArea->Top(), 1.0, fChildArea->Bottom());
@@ -919,13 +911,13 @@ Area::UpdateHorizontal()
if (fChildArea == NULL) if (fChildArea == NULL)
InitChildArea(); InitChildArea();
// change the constraints leftConstraint and rightConstraint so that the horizontal // 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 // alignment and insets of the childArea within this area are as specified by the user
if (fAlignment.Horizontal() == B_ALIGN_LEFT) { if (fAlignment.Horizontal() == B_ALIGN_LEFT) {
fLeftConstraint->SetLeftSide(-1.0, fLeft, 1.0, fChildArea->Left()); fLeftConstraint->SetLeftSide(-1.0, fLeft, 1.0, fChildArea->Left());
fLeftConstraint->SetOp(OperatorType(EQ)); fLeftConstraint->SetOp(OperatorType(EQ));
fLeftConstraint->SetRightSide(fLeftInset); fLeftConstraint->SetRightSide(fLeftInset);
fRightConstraint->SetLeftSide(-1.0, fChildArea->Right(), 1.0, fRight); fRightConstraint->SetLeftSide(-1.0, fChildArea->Right(), 1.0, fRight);
fRightConstraint->SetOp(OperatorType(GE)); fRightConstraint->SetOp(OperatorType(GE));
fRightConstraint->SetRightSide(fRightInset); fRightConstraint->SetRightSide(fRightInset);
@@ -933,7 +925,7 @@ Area::UpdateHorizontal()
fLeftConstraint->SetLeftSide(-1.0, fLeft, 1.0, fChildArea->Left()); fLeftConstraint->SetLeftSide(-1.0, fLeft, 1.0, fChildArea->Left());
fLeftConstraint->SetOp(OperatorType(GE)); fLeftConstraint->SetOp(OperatorType(GE));
fLeftConstraint->SetRightSide(fLeftInset); fLeftConstraint->SetRightSide(fLeftInset);
fRightConstraint->SetLeftSide(-1.0, fChildArea->Right(), 1.0, fRight); fRightConstraint->SetLeftSide(-1.0, fChildArea->Right(), 1.0, fRight);
fRightConstraint->SetOp(OperatorType(EQ)); fRightConstraint->SetOp(OperatorType(EQ));
fRightConstraint->SetRightSide(fRightInset); fRightConstraint->SetRightSide(fRightInset);
@@ -941,7 +933,7 @@ Area::UpdateHorizontal()
fLeftConstraint->SetLeftSide(-1.0, fLeft, 1.0, fChildArea->Left()); fLeftConstraint->SetLeftSide(-1.0, fLeft, 1.0, fChildArea->Left());
fLeftConstraint->SetOp(OperatorType(GE)); fLeftConstraint->SetOp(OperatorType(GE));
fLeftConstraint->SetRightSide(max(fLeftInset, fRightInset)); fLeftConstraint->SetRightSide(max(fLeftInset, fRightInset));
fRightConstraint->SetLeftSide(-1.0, fLeft, 1.0, fChildArea->Left(), 1.0, fChildArea->Right(), -1.0, fRight); fRightConstraint->SetLeftSide(-1.0, fLeft, 1.0, fChildArea->Left(), 1.0, fChildArea->Right(), -1.0, fRight);
fRightConstraint->SetOp(OperatorType(EQ)); fRightConstraint->SetOp(OperatorType(EQ));
fRightConstraint->SetRightSide(0); fRightConstraint->SetRightSide(0);
@@ -949,7 +941,7 @@ Area::UpdateHorizontal()
fLeftConstraint->SetLeftSide(-1.0, fLeft, 1.0, fChildArea->Left()); fLeftConstraint->SetLeftSide(-1.0, fLeft, 1.0, fChildArea->Left());
fLeftConstraint->SetOp(OperatorType(EQ)); fLeftConstraint->SetOp(OperatorType(EQ));
fLeftConstraint->SetRightSide(fLeftInset); fLeftConstraint->SetRightSide(fLeftInset);
fRightConstraint->SetLeftSide(-1.0, fChildArea->Right(), 1.0, fRight); fRightConstraint->SetLeftSide(-1.0, fChildArea->Right(), 1.0, fRight);
fRightConstraint->SetOp(OperatorType(EQ)); fRightConstraint->SetOp(OperatorType(EQ));
fRightConstraint->SetRightSide(fRightInset); fRightConstraint->SetRightSide(fRightInset);
@@ -957,7 +949,7 @@ Area::UpdateHorizontal()
fLeftConstraint->SetLeftSide(-1.0, fLeft, 1.0, fChildArea->Left()); fLeftConstraint->SetLeftSide(-1.0, fLeft, 1.0, fChildArea->Left());
fLeftConstraint->SetOp(OperatorType(GE)); fLeftConstraint->SetOp(OperatorType(GE));
fLeftConstraint->SetRightSide(fLeftInset); fLeftConstraint->SetRightSide(fLeftInset);
fRightConstraint->SetLeftSide(-1.0, fChildArea->Right(), 1.0, fRight); fRightConstraint->SetLeftSide(-1.0, fChildArea->Right(), 1.0, fRight);
fRightConstraint->SetOp(OperatorType(GE)); fRightConstraint->SetOp(OperatorType(GE));
fRightConstraint->SetRightSide(fRightInset); fRightConstraint->SetRightSide(fRightInset);
@@ -970,16 +962,16 @@ Area::UpdateHorizontal()
*/ */
void Area::UpdateVertical() { void Area::UpdateVertical() {
// if the area does not have a childAdrea yet, this is the time to add it // if the area does not have a childAdrea yet, this is the time to add it
if (fChildArea == NULL) if (fChildArea == NULL)
InitChildArea(); InitChildArea();
// change the constraints topConstraint and bottomConstraint so that the vertical // 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 // alignment and insets of the childArea within this area are as specified by the user
if (fAlignment.Vertical() == B_ALIGN_TOP) { if (fAlignment.Vertical() == B_ALIGN_TOP) {
fTopConstraint->SetLeftSide(-1.0, fTop, 1.0, fChildArea->Top()); fTopConstraint->SetLeftSide(-1.0, fTop, 1.0, fChildArea->Top());
fTopConstraint->SetOp(OperatorType(EQ)); fTopConstraint->SetOp(OperatorType(EQ));
fTopConstraint->SetRightSide(fTopInset); fTopConstraint->SetRightSide(fTopInset);
fBottomConstraint->SetLeftSide(-1.0, fChildArea->Bottom(), 1.0, fBottom); fBottomConstraint->SetLeftSide(-1.0, fChildArea->Bottom(), 1.0, fBottom);
fBottomConstraint->SetOp(OperatorType(GE)); fBottomConstraint->SetOp(OperatorType(GE));
fBottomConstraint->SetRightSide(fBottomInset); fBottomConstraint->SetRightSide(fBottomInset);
@@ -987,7 +979,7 @@ void Area::UpdateVertical() {
fTopConstraint->SetLeftSide(-1.0, fTop, 1.0, fChildArea->Top()); fTopConstraint->SetLeftSide(-1.0, fTop, 1.0, fChildArea->Top());
fTopConstraint->SetOp(OperatorType(GE)); fTopConstraint->SetOp(OperatorType(GE));
fTopConstraint->SetRightSide(fTopInset); fTopConstraint->SetRightSide(fTopInset);
fBottomConstraint->SetLeftSide(-1.0, fChildArea->Bottom(), 1.0, fBottom); fBottomConstraint->SetLeftSide(-1.0, fChildArea->Bottom(), 1.0, fBottom);
fBottomConstraint->SetOp(OperatorType(EQ)); fBottomConstraint->SetOp(OperatorType(EQ));
fBottomConstraint->SetRightSide(fBottomInset); fBottomConstraint->SetRightSide(fBottomInset);
@@ -995,7 +987,7 @@ void Area::UpdateVertical() {
fTopConstraint->SetLeftSide(-1.0, fTop, 1.0, fChildArea->Top()); fTopConstraint->SetLeftSide(-1.0, fTop, 1.0, fChildArea->Top());
fTopConstraint->SetOp(OperatorType(GE)); fTopConstraint->SetOp(OperatorType(GE));
fTopConstraint->SetRightSide(max(fTopInset, fBottomInset)); fTopConstraint->SetRightSide(max(fTopInset, fBottomInset));
fBottomConstraint->SetLeftSide(-1.0, fTop, 1.0, fChildArea->Top(), 1.0, fChildArea->Bottom(), -1.0, fBottom); fBottomConstraint->SetLeftSide(-1.0, fTop, 1.0, fChildArea->Top(), 1.0, fChildArea->Bottom(), -1.0, fBottom);
fBottomConstraint->SetOp(OperatorType(EQ)); fBottomConstraint->SetOp(OperatorType(EQ));
fBottomConstraint->SetRightSide(0); fBottomConstraint->SetRightSide(0);
@@ -1003,7 +995,7 @@ void Area::UpdateVertical() {
fTopConstraint->SetLeftSide(-1.0, fTop, 1.0, fChildArea->Top()); fTopConstraint->SetLeftSide(-1.0, fTop, 1.0, fChildArea->Top());
fTopConstraint->SetOp(OperatorType(EQ)); fTopConstraint->SetOp(OperatorType(EQ));
fTopConstraint->SetRightSide(fTopInset); fTopConstraint->SetRightSide(fTopInset);
fBottomConstraint->SetLeftSide(-1.0, fChildArea->Bottom(), 1.0, fBottom); fBottomConstraint->SetLeftSide(-1.0, fChildArea->Bottom(), 1.0, fBottom);
fBottomConstraint->SetOp(OperatorType(EQ)); fBottomConstraint->SetOp(OperatorType(EQ));
fBottomConstraint->SetRightSide(fBottomInset); fBottomConstraint->SetRightSide(fBottomInset);
@@ -1011,7 +1003,7 @@ void Area::UpdateVertical() {
fTopConstraint->SetLeftSide(-1.0, fTop, 1.0, fChildArea->Top()); fTopConstraint->SetLeftSide(-1.0, fTop, 1.0, fChildArea->Top());
fTopConstraint->SetOp(OperatorType(GE)); fTopConstraint->SetOp(OperatorType(GE));
fTopConstraint->SetRightSide(fTopInset); fTopConstraint->SetRightSide(fTopInset);
fBottomConstraint->SetLeftSide(-1.0, fChildArea->Bottom(), 1.0, fBottom); fBottomConstraint->SetLeftSide(-1.0, fChildArea->Bottom(), 1.0, fBottom);
fBottomConstraint->SetOp(OperatorType(GE)); fBottomConstraint->SetOp(OperatorType(GE));
fBottomConstraint->SetRightSide(fBottomInset); fBottomConstraint->SetRightSide(fBottomInset);
+57 -50
View File
@@ -19,29 +19,29 @@
* Constructor. * Constructor.
* Creates new layout engine. * Creates new layout engine.
*/ */
BALMLayout::BALMLayout() BALMLayout::BALMLayout()
: BLayout(), : BLayout(),
LinearSpec() LinearSpec()
{ {
fLayoutStyle = FIT_TO_SIZE; fLayoutStyle = FIT_TO_SIZE;
fActivated = true; fActivated = true;
fAreas = new BList(1); fAreas = new BList(1);
fLeft = new XTab(this); fLeft = new XTab(this);
fRight = new XTab(this); fRight = new XTab(this);
fTop = new YTab(this); fTop = new YTab(this);
fBottom = new YTab(this); fBottom = new YTab(this);
// the Left tab is always at x-position 0, and the Top tab is always at y-position 0 // the Left tab is always at x-position 0, and the Top tab is always at y-position 0
fLeft->SetRange(0, 0); fLeft->SetRange(0, 0);
fTop->SetRange(0, 0); fTop->SetRange(0, 0);
// cached layout values // cached layout values
// need to be invalidated whenever the layout specification is changed // need to be invalidated whenever the layout specification is changed
fMinSize = Area::kUndefinedSize; fMinSize = Area::kUndefinedSize;
fMaxSize = Area::kUndefinedSize; fMaxSize = Area::kUndefinedSize;
fPreferredSize = Area::kUndefinedSize; fPreferredSize = Area::kUndefinedSize;
fPerformancePath = NULL; fPerformancePath = NULL;
} }
@@ -61,23 +61,28 @@ BALMLayout::SolveLayout()
if (currentArea->AutoPreferredContentSize()) if (currentArea->AutoPreferredContentSize())
currentArea->SetDefaultBehavior(); currentArea->SetDefaultBehavior();
} }
// try to solve the layout until the result is OPTIMAL or INFEASIBLE, maximally // Try to solve the layout until the result is OPTIMAL or INFEASIBLE,
// 15 tries sometimes the solving algorithm encounters numerical problems // maximally 15 tries sometimes the solving algorithm encounters numerical
// (NUMFAILURE), and repeating the solving often helps to overcome them // problems (NUMFAILURE), and repeating the solving often helps to overcome
BFile* file = new BFile(fPerformancePath, // them.
B_READ_WRITE | B_CREATE_FILE | B_OPEN_AT_END); BFile* file = NULL;
if (fPerformancePath != NULL) {
file = new BFile(fPerformancePath,
B_READ_WRITE | B_CREATE_FILE | B_OPEN_AT_END);
}
ResultType result; ResultType result;
for (int32 tries = 0; tries < 15; tries++) { for (int32 tries = 0; tries < 15; tries++) {
result = Solve(); result = 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#constraints=%ld\n", file->Write(buffer, sprintf(buffer, "%d\t%fms\t#vars=%ld\t"
result, SolvingTime(), Variables()->CountItems(), "#constraints=%ld\n", result, SolvingTime(),
Constraints()->CountItems())); Variables()->CountItems(), Constraints()->CountItems()));
} }
if (result == OPTIMAL || result == INFEASIBLE) break; if (result == OPTIMAL || result == INFEASIBLE)
break;
} }
delete file; delete file;
} }
@@ -85,7 +90,7 @@ BALMLayout::SolveLayout()
/** /**
* Adds a new x-tab to the specification. * Adds a new x-tab to the specification.
* *
* @return the new x-tab * @return the new x-tab
*/ */
XTab* XTab*
@@ -93,11 +98,11 @@ BALMLayout::AddXTab()
{ {
return new XTab(this); return new XTab(this);
} }
/** /**
* Adds a new y-tab to the specification. * Adds a new y-tab to the specification.
* *
* @return the new y-tab * @return the new y-tab
*/ */
YTab* YTab*
@@ -109,7 +114,7 @@ BALMLayout::AddYTab()
/** /**
* Adds a new row to the specification. * Adds a new row to the specification.
* *
* @return the new row * @return the new row
*/ */
Row* Row*
@@ -121,7 +126,7 @@ BALMLayout::AddRow()
/** /**
* Adds a new row to the specification that is glued to the given y-tabs. * Adds a new row to the specification that is glued to the given y-tabs.
* *
* @param top * @param top
* @param bottom * @param bottom
* @return the new row * @return the new row
@@ -130,15 +135,17 @@ Row*
BALMLayout::AddRow(YTab* top, YTab* bottom) BALMLayout::AddRow(YTab* top, YTab* bottom)
{ {
Row* row = new Row(this); Row* row = new Row(this);
if (top != NULL) row->Constraints()->AddItem(row->Top()->IsEqual(top)); if (top != NULL)
if (bottom != NULL) row->Constraints()->AddItem(row->Bottom()->IsEqual(bottom)); row->Constraints()->AddItem(row->Top()->IsEqual(top));
if (bottom != NULL)
row->Constraints()->AddItem(row->Bottom()->IsEqual(bottom));
return row; return row;
} }
/** /**
* Adds a new column to the specification. * Adds a new column to the specification.
* *
* @return the new column * @return the new column
*/ */
Column* Column*
@@ -150,7 +157,7 @@ BALMLayout::AddColumn()
/** /**
* Adds a new column to the specification that is glued to the given x-tabs. * Adds a new column to the specification that is glued to the given x-tabs.
* *
* @param left * @param left
* @param right * @param right
* @return the new column * @return the new column
@@ -167,7 +174,7 @@ BALMLayout::AddColumn(XTab* left, XTab* right)
/** /**
* Adds a new area to the specification, setting only the necessary minimum size constraints. * Adds a new area to the specification, setting only the necessary minimum size constraints.
* *
* @param left left border * @param left left border
* @param top top border * @param top top border
* @param right right border * @param right right border
@@ -179,7 +186,7 @@ BALMLayout::AddColumn(XTab* left, XTab* right)
Area* Area*
BALMLayout::AddArea(XTab* left, YTab* top, XTab* right, YTab* bottom, BALMLayout::AddArea(XTab* left, YTab* top, XTab* right, YTab* bottom,
BView* content, BSize minContentSize) BView* content, BSize minContentSize)
{ {
InvalidateLayout(); InvalidateLayout();
if (content != NULL) if (content != NULL)
View()->AddChild(content); View()->AddChild(content);
@@ -191,7 +198,7 @@ BALMLayout::AddArea(XTab* left, YTab* top, XTab* right, YTab* bottom,
/** /**
* Adds a new area to the specification, setting only the necessary minimum size constraints. * Adds a new area to the specification, setting only the necessary minimum size constraints.
* *
* @param row the row that defines the top and bottom border * @param row the row that defines the top and bottom border
* @param column the column that defines the left and right border * @param column the column that defines the left and right border
* @param content the control which is the area content * @param content the control which is the area content
@@ -201,7 +208,7 @@ BALMLayout::AddArea(XTab* left, YTab* top, XTab* right, YTab* bottom,
Area* Area*
BALMLayout::AddArea(Row* row, Column* column, BView* content, BALMLayout::AddArea(Row* row, Column* column, BView* content,
BSize minContentSize) BSize minContentSize)
{ {
InvalidateLayout(); InvalidateLayout();
if (content != NULL) if (content != NULL)
View()->AddChild(content); View()->AddChild(content);
@@ -213,7 +220,7 @@ BALMLayout::AddArea(Row* row, Column* column, BView* content,
/** /**
* Adds a new area to the specification, automatically setting preferred size constraints. * Adds a new area to the specification, automatically setting preferred size constraints.
* *
* @param left left border * @param left left border
* @param top top border * @param top top border
* @param right right border * @param right right border
@@ -224,7 +231,7 @@ BALMLayout::AddArea(Row* row, Column* column, BView* content,
Area* Area*
BALMLayout::AddArea(XTab* left, YTab* top, XTab* right, YTab* bottom, BALMLayout::AddArea(XTab* left, YTab* top, XTab* right, YTab* bottom,
BView* content) BView* content)
{ {
InvalidateLayout(); InvalidateLayout();
if (content != NULL) if (content != NULL)
View()->AddChild(content); View()->AddChild(content);
@@ -238,11 +245,11 @@ BALMLayout::AddArea(XTab* left, YTab* top, XTab* right, YTab* bottom,
/** /**
* Adds a new area to the specification, automatically setting preferred size constraints. * Adds a new area to the specification, automatically setting preferred size constraints.
* *
* @param row the row that defines the top and bottom border * @param row the row that defines the top and bottom border
* @param column the column that defines the left and right border * @param column the column that defines the left and right border
* @param content the control which is the area content * @param content the control which is the area content
* @return the new area * @return the new area
*/ */
Area* Area*
BALMLayout::AddArea(Row* row, Column* column, BView* content) BALMLayout::AddArea(Row* row, Column* column, BView* content)
@@ -260,7 +267,7 @@ BALMLayout::AddArea(Row* row, Column* column, BView* content)
/** /**
* Finds the area that contains the given control. * Finds the area that contains the given control.
* *
* @param control the control to look for * @param control the control to look for
* @return the area that contains the control * @return the area that contains the control
*/ */
@@ -270,7 +277,7 @@ BALMLayout::AreaOf(BView* control)
Area* area; Area* area;
for (int32 i = 0; i < fAreas->CountItems(); i++) { for (int32 i = 0; i < fAreas->CountItems(); i++) {
area = (Area*)fAreas->ItemAt(i); area = (Area*)fAreas->ItemAt(i);
if (area->Content() == control) if (area->Content() == control)
return area; return area;
} }
return NULL; return NULL;
@@ -516,45 +523,45 @@ BALMLayout::LayoutView()
if (!fActivated) if (!fActivated)
return; return;
fActivated = false; fActivated = false;
if (View() == NULL) if (View() == NULL)
return; return;
// reverse engineer a layout specification if none was given // reverse engineer a layout specification if none was given
//~ if (this == NULL) RecoverLayout(View()); //~ if (this == NULL) RecoverLayout(View());
// if the layout engine is set to fit the GUI to the given size, // if the layout engine is set to fit the GUI to the given size,
// then the given size is enforced by setting absolute positions for Right and Bottom // then the given size is enforced by setting absolute positions for Right and Bottom
if (fLayoutStyle == FIT_TO_SIZE) { if (fLayoutStyle == FIT_TO_SIZE) {
Right()->SetRange(View()->Bounds().Width(), View()->Bounds().Width()); Right()->SetRange(View()->Bounds().Width(), View()->Bounds().Width());
Bottom()->SetRange(View()->Bounds().Height(), View()->Bounds().Height()); Bottom()->SetRange(View()->Bounds().Height(), View()->Bounds().Height());
} }
SolveLayout(); SolveLayout();
// if new layout is infasible, use previous layout // if new layout is infasible, use previous layout
if (Result() == INFEASIBLE) { if (Result() == INFEASIBLE) {
fActivated = true; // now layout calculation is allowed to run again fActivated = true; // now layout calculation is allowed to run again
return; return;
} }
if (Result() != OPTIMAL) { if (Result() != OPTIMAL) {
Save("failed-layout.txt"); Save("failed-layout.txt");
printf("Could not solve the layout specification (%d). ", Result()); printf("Could not solve the layout specification (%d). ", Result());
printf("Saved specification in file failed-layout.txt\n"); printf("Saved specification in file failed-layout.txt\n");
} }
// change the size of the GUI according to the calculated size // change the size of the GUI according to the calculated size
// if the layout engine was configured to do so // if the layout engine was configured to do so
if (fLayoutStyle == ADJUST_SIZE) { if (fLayoutStyle == ADJUST_SIZE) {
View()->ResizeTo(floor(Right()->Value() - Left()->Value() + 0.5), View()->ResizeTo(floor(Right()->Value() - Left()->Value() + 0.5),
floor(Bottom()->Value() - Top()->Value() + 0.5)); floor(Bottom()->Value() - Top()->Value() + 0.5));
} }
// set the calculated positions and sizes for every area // set the calculated positions and sizes for every area
for (int32 i = 0; i < Areas()->CountItems(); i++) for (int32 i = 0; i < Areas()->CountItems(); i++)
((Area*)Areas()->ItemAt(i))->DoLayout(); ((Area*)Areas()->ItemAt(i))->DoLayout();
fActivated = true; fActivated = true;
} }
@@ -600,14 +607,14 @@ BALMLayout::CalculateMinSize()
delete (Summand*)newObjFunction->ItemAt(0); delete (Summand*)newObjFunction->ItemAt(0);
delete (Summand*)newObjFunction->ItemAt(1); delete (Summand*)newObjFunction->ItemAt(1);
delete newObjFunction; delete newObjFunction;
if (Result() == UNBOUNDED) if (Result() == UNBOUNDED)
return Area::kMinSize; return Area::kMinSize;
if (Result() != OPTIMAL) { if (Result() != OPTIMAL) {
Save("failed-layout.txt"); Save("failed-layout.txt");
printf("Could not solve the layout specification (%d). Saved specification in file failed-layout.txt", Result()); printf("Could not solve the layout specification (%d). Saved specification in file failed-layout.txt", Result());
} }
return BSize(Right()->Value() - Left()->Value(), Bottom()->Value() - Top()->Value()); return BSize(Right()->Value() - Left()->Value(), Bottom()->Value() - Top()->Value());
} }
@@ -629,14 +636,14 @@ BALMLayout::CalculateMaxSize()
delete (Summand*)newObjFunction->ItemAt(0); delete (Summand*)newObjFunction->ItemAt(0);
delete (Summand*)newObjFunction->ItemAt(1); delete (Summand*)newObjFunction->ItemAt(1);
delete newObjFunction; delete newObjFunction;
if (Result() == UNBOUNDED) if (Result() == UNBOUNDED)
return Area::kMaxSize; return Area::kMaxSize;
if (Result() != OPTIMAL) { if (Result() != OPTIMAL) {
Save("failed-layout.txt"); Save("failed-layout.txt");
printf("Could not solve the layout specification (%d). Saved specification in file failed-layout.txt", Result()); printf("Could not solve the layout specification (%d). Saved specification in file failed-layout.txt", Result());
} }
return BSize(Right()->Value() - Left()->Value(), Bottom()->Value() - Top()->Value()); return BSize(Right()->Value() - Left()->Value(), Bottom()->Value() - Top()->Value());
} }
@@ -652,7 +659,7 @@ BALMLayout::CalculatePreferredSize()
Save("failed-layout.txt"); Save("failed-layout.txt");
printf("Could not solve the layout specification (%d). Saved specification in file failed-layout.txt", Result()); printf("Could not solve the layout specification (%d). Saved specification in file failed-layout.txt", Result());
} }
return BSize(Right()->Value() - Left()->Value(), Bottom()->Value() - Top()->Value()); return BSize(Right()->Value() - Left()->Value(), Bottom()->Value() - Top()->Value());
} }
+61 -68
View File
@@ -23,11 +23,11 @@
/** /**
* Gets the index of the constraint. * Gets the index of the constraint.
* *
* @return the index of the constraint * @return the index of the constraint
*/ */
int32 int32
Constraint::Index() Constraint::Index() const
{ {
int32 i = fLS->Constraints()->IndexOf(this); int32 i = fLS->Constraints()->IndexOf(this);
if (i == -1) { if (i == -1) {
@@ -40,7 +40,7 @@ Constraint::Index()
/** /**
* Gets the left side of the constraint. * Gets the left side of the constraint.
* *
* @return pointer to a BList containing the summands on the left side of the constraint * @return pointer to a BList containing the summands on the left side of the constraint
*/ */
BList* BList*
@@ -53,7 +53,7 @@ Constraint::LeftSide()
/** /**
* Sets the summands on the left side of the constraint. * Sets the summands on the left side of the constraint.
* The old summands are NOT deleted. * The old summands are NOT deleted.
* *
* @param summands a BList containing the Summand objects that make up the new left side * @param summands a BList containing the Summand objects that make up the new left side
*/ */
void void
@@ -81,22 +81,22 @@ Constraint::UpdateLeftSide()
coeffs[i] = s->Coeff(); coeffs[i] = s->Coeff();
varIndexes[i] = s->Var()->Index(); varIndexes[i] = s->Var()->Index();
} }
if (fDNegObjSummand != NULL && fOp != OperatorType(LE)) { if (fDNegObjSummand != NULL && fOp != OperatorType(LE)) {
varIndexes[i] = fDNegObjSummand->Var()->Index(); varIndexes[i] = fDNegObjSummand->Var()->Index();
coeffs[i] = 1.0; coeffs[i] = 1.0;
i++; i++;
} }
if (fDPosObjSummand != NULL && fOp != OperatorType(GE)) { if (fDPosObjSummand != NULL && fOp != OperatorType(GE)) {
varIndexes[i] = fDPosObjSummand->Var()->Index(); varIndexes[i] = fDPosObjSummand->Var()->Index();
coeffs[i] = -1.0; coeffs[i] = -1.0;
i++; i++;
} }
if (!set_rowex(fLS->fLP, this->Index(), i, &coeffs[0], &varIndexes[0])) if (!set_rowex(fLS->fLP, this->Index(), i, &coeffs[0], &varIndexes[0]))
STRACE(("Error in set_rowex.")); STRACE(("Error in set_rowex."));
fLS->UpdateObjFunction(); fLS->UpdateObjFunction();
fLS->RemovePresolved(); fLS->RemovePresolved();
} }
@@ -117,7 +117,7 @@ Constraint::SetLeftSide(double coeff1, Variable* var1)
void void
Constraint::SetLeftSide(double coeff1, Variable* var1, Constraint::SetLeftSide(double coeff1, Variable* var1,
double coeff2, Variable* var2) double coeff2, Variable* var2)
{ {
if (!fIsValid) if (!fIsValid)
@@ -131,9 +131,9 @@ Constraint::SetLeftSide(double coeff1, Variable* var1,
UpdateLeftSide(); UpdateLeftSide();
} }
void void
Constraint::SetLeftSide(double coeff1, Variable* var1, Constraint::SetLeftSide(double coeff1, Variable* var1,
double coeff2, Variable* var2, double coeff2, Variable* var2,
double coeff3, Variable* var3) double coeff3, Variable* var3)
{ {
@@ -172,7 +172,7 @@ Constraint::SetLeftSide(double coeff1, Variable* var1,
/** /**
* Gets the operator used for this constraint. * Gets the operator used for this constraint.
* *
* @return the operator used for this constraint * @return the operator used for this constraint
*/ */
OperatorType OperatorType
@@ -184,7 +184,7 @@ Constraint::Op()
/** /**
* Sets the operator used for this constraint. * Sets the operator used for this constraint.
* *
* @param value operator * @param value operator
*/ */
void void
@@ -199,14 +199,14 @@ Constraint::SetOp(OperatorType value)
: (fOp == OperatorType(GE)) ? GE : (fOp == OperatorType(GE)) ? GE
: LE))) : LE)))
STRACE(("Error in set_constr_type.")); STRACE(("Error in set_constr_type."));
fLS->RemovePresolved(); fLS->RemovePresolved();
} }
/** /**
* Gets the constant value that is on the right side of the operator. * Gets the constant value that is on the right side of the operator.
* *
* @return the constant value that is on the right side of the operator * @return the constant value that is on the right side of the operator
*/ */
double double
@@ -215,10 +215,10 @@ Constraint::RightSide() const
return fRightSide; return fRightSide;
} }
/** /**
* Sets the constant value that is on the right side of the operator. * Sets the constant value that is on the right side of the operator.
* *
* @param value constant value that is on the right side of the operator * @param value constant value that is on the right side of the operator
*/ */
void void
@@ -230,14 +230,14 @@ Constraint::SetRightSide(double value)
fRightSide = value; fRightSide = value;
if (!set_rh(fLS->fLP, Index(), fRightSide)) if (!set_rh(fLS->fLP, Index(), fRightSide))
STRACE(("Error in set_rh.")); STRACE(("Error in set_rh."));
fLS->RemovePresolved(); fLS->RemovePresolved();
} }
/** /**
* Gets the penalty coefficient for negative deviations. * Gets the penalty coefficient for negative deviations.
* *
* @return the penalty coefficient * @return the penalty coefficient
*/ */
double double
@@ -252,7 +252,7 @@ Constraint::PenaltyNeg() const
/** /**
* The penalty coefficient for negative deviations from the soft constraint's exact solution,&nbsp; * The penalty coefficient for negative deviations from the soft constraint's exact solution,&nbsp;
* i.e. if the left side is too large. * i.e. if the left side is too large.
* *
* @param value coefficient of negative penalty <code>double</code> * @param value coefficient of negative penalty <code>double</code>
*/ */
void void
@@ -268,7 +268,7 @@ Constraint::SetPenaltyNeg(double value)
fLS->UpdateObjFunction(); fLS->UpdateObjFunction();
return; return;
} }
if (value == fDNegObjSummand->Coeff()) if (value == fDNegObjSummand->Coeff())
return; return;
@@ -279,7 +279,7 @@ Constraint::SetPenaltyNeg(double value)
/** /**
* Gets the penalty coefficient for positive deviations. * Gets the penalty coefficient for positive deviations.
* *
* @return the penalty coefficient * @return the penalty coefficient
*/ */
double double
@@ -294,7 +294,7 @@ Constraint::PenaltyPos() const
/** /**
* The penalty coefficient for negative deviations from the soft constraint's exact solution, * The penalty coefficient for negative deviations from the soft constraint's exact solution,
* i.e. if the left side is too small. * i.e. if the left side is too small.
* *
* @param value coefficient of positive penalty <code>double</code> * @param value coefficient of positive penalty <code>double</code>
*/ */
void void
@@ -339,33 +339,32 @@ Constraint::WriteXML(BFile* file)
{ {
if (file->IsWritable() && fOwner == NULL) { if (file->IsWritable() && fOwner == NULL) {
char buffer[200]; char buffer[200];
file->Write(buffer, sprintf(buffer, "\t<constraint>\n")); file->Write(buffer, sprintf(buffer, "\t<constraint>\n"));
file->Write(buffer, sprintf(buffer, "\t\t<leftside>\n")); file->Write(buffer, sprintf(buffer, "\t\t<leftside>\n"));
Summand* summand; Summand* summand;
for (int32 i = 0; i < fLeftSide->CountItems(); i++) { for (int32 i = 0; i < fLeftSide->CountItems(); i++) {
summand = (Summand*)fLeftSide->ItemAt(i); summand = (Summand*)fLeftSide->ItemAt(i);
file->Write(buffer, sprintf(buffer, "\t\t\t<summand>\n")); file->Write(buffer, sprintf(buffer, "\t\t\t<summand>\n"));
file->Write(buffer, sprintf(buffer, "\t\t\t\t<coeff>%f</coeff>\n", file->Write(buffer, sprintf(buffer, "\t\t\t\t<coeff>%f</coeff>\n",
summand->Coeff())); summand->Coeff()));
BString* varStr = summand->Var()->ToBString(); BString varStr = *(summand->Var());
file->Write(buffer, sprintf(buffer, "\t\t\t\t<var>%s</var>\n", file->Write(buffer, sprintf(buffer, "\t\t\t\t<var>%s</var>\n",
varStr->String())); varStr.String()));
delete varStr;
file->Write(buffer, sprintf(buffer, "\t\t\t</summand>\n")); file->Write(buffer, sprintf(buffer, "\t\t\t</summand>\n"));
} }
file->Write(buffer, sprintf(buffer, "\t\t</leftside>\n")); file->Write(buffer, sprintf(buffer, "\t\t</leftside>\n"));
char* op; const char* op = "??";
if (fOp == OperatorType(EQ)) if (fOp == OperatorType(EQ))
op = "EQ"; op = "EQ";
else if (fOp == OperatorType(LE)) else if (fOp == OperatorType(LE))
op = "LE"; op = "LE";
else if (fOp == OperatorType(GE)) else if (fOp == OperatorType(GE))
op = "GE"; op = "GE";
file->Write(buffer, sprintf(buffer, "\t\t<op>%s</op>\n", op)); file->Write(buffer, sprintf(buffer, "\t\t<op>%s</op>\n", op));
file->Write(buffer, sprintf(buffer, "\t\t<rightside>%f</rightside>\n", fRightSide)); file->Write(buffer, sprintf(buffer, "\t\t<rightside>%f</rightside>\n", fRightSide));
//~ file->Write(buffer, sprintf(buffer, "\t\t<penaltyneg>%s</penaltyneg>\n", PenaltyNeg())); //~ file->Write(buffer, sprintf(buffer, "\t\t<penaltyneg>%s</penaltyneg>\n", PenaltyNeg()));
@@ -377,7 +376,7 @@ Constraint::WriteXML(BFile* file)
/** /**
* Gets the slack variable for the negative variations. * Gets the slack variable for the negative variations.
* *
* @return the slack variable for the negative variations * @return the slack variable for the negative variations
*/ */
Variable* Variable*
@@ -391,7 +390,7 @@ Constraint::DNeg() const
/** /**
* Gets the slack variable for the positive variations. * Gets the slack variable for the positive variations.
* *
* @return the slack variable for the positive variations * @return the slack variable for the positive variations
*/ */
Variable* Variable*
@@ -452,56 +451,50 @@ Constraint::Invalidate()
fDPosObjSummand = NULL; fDPosObjSummand = NULL;
} }
del_constraint(fLS->fLP, this->Index()); del_constraint(fLS->fLP, this->Index());
fLS->Constraints()->RemoveItem(this); fLS->Constraints()->RemoveItem(this);
} }
BString* Constraint::operator BString() const
Constraint::ToBString()
{ {
BString* str = new BString(); BString string;
*str << "Constraint "; GetString(string);
return string;
}
void
Constraint::GetString(BString& string) const
{
string << "Constraint ";
if (fLabel) if (fLabel)
*str << fLabel; string << fLabel;
*str << "(" << (int32)this << "): "; string << "(" << (int32)this << "): ";
if (fIsValid) { if (fIsValid) {
for (int i = 0; i < fLeftSide->CountItems(); i++) { for (int i = 0; i < fLeftSide->CountItems(); i++) {
Summand* s = static_cast<Summand*>(fLeftSide->ItemAt(i)); Summand* s = static_cast<Summand*>(fLeftSide->ItemAt(i));
*str << (float)s->Coeff() << "*"; string << (float)s->Coeff() << "*";
BString* varString = s->Var()->ToBString(); s->Var()->GetString(string);
*str << *varString << " "; string << " ";
delete varString;
} }
*str << ((fOp == OperatorType(EQ)) ? "== " string << ((fOp == OperatorType(EQ)) ? "== "
: (fOp == OperatorType(GE)) ? ">= " : (fOp == OperatorType(GE)) ? ">= "
: (fOp == OperatorType(LE)) ? "<= " : (fOp == OperatorType(LE)) ? "<= "
: "?? "); : "?? ");
*str << (float)fRightSide; string << (float)fRightSide;
*str << " PenaltyPos=" << (float)PenaltyPos(); string << " PenaltyPos=" << (float)PenaltyPos();
*str << " PenaltyNeg=" << (float)PenaltyNeg(); string << " PenaltyNeg=" << (float)PenaltyNeg();
} else } else
*str << "invalid"; string << "invalid";
return str;
}
const char*
Constraint::ToString()
{
BString* str = ToBString();
char* result = (char*) malloc(str->Length() + 1);
str->CopyInto(result, 0, str->Length());
delete str;
return result;
} }
/** /**
* Constructor. * Constructor.
*/ */
Constraint::Constraint(LinearSpec* ls, BList* summands, OperatorType op, Constraint::Constraint(LinearSpec* ls, BList* summands, OperatorType op,
double rightSide, double penaltyNeg, double penaltyPos) double rightSide, double penaltyNeg, double penaltyPos)
: fLS(ls), : fLS(ls),
fLeftSide(summands), fLeftSide(summands),
@@ -519,7 +512,7 @@ Constraint::Constraint(LinearSpec* ls, BList* summands, OperatorType op,
coeffs[i] = s->Coeff(); coeffs[i] = s->Coeff();
varIndexes[i] = s->Var()->Index(); varIndexes[i] = s->Var()->Index();
} }
if (penaltyNeg != INFINITY if (penaltyNeg != INFINITY
&& fOp != OperatorType(LE)) { && fOp != OperatorType(LE)) {
fDNegObjSummand = new Summand(penaltyNeg, new Variable(fLS)); fDNegObjSummand = new Summand(penaltyNeg, new Variable(fLS));
@@ -530,7 +523,7 @@ Constraint::Constraint(LinearSpec* ls, BList* summands, OperatorType op,
} }
else else
fDNegObjSummand = NULL; fDNegObjSummand = NULL;
if (penaltyPos != INFINITY if (penaltyPos != INFINITY
&& fOp != OperatorType(GE)) { && fOp != OperatorType(GE)) {
fDPosObjSummand = new Summand(penaltyPos, new Variable(fLS)); fDPosObjSummand = new Summand(penaltyPos, new Variable(fLS));
+101 -107
View File
@@ -31,7 +31,7 @@ LinearSpec::LinearSpec()
/** /**
* Destructor. * Destructor.
* Removes the specification and deletes all constraints, * Removes the specification and deletes all constraints,
* objective function summands and variables. * objective function summands and variables.
*/ */
LinearSpec::~LinearSpec() LinearSpec::~LinearSpec()
@@ -49,7 +49,7 @@ LinearSpec::~LinearSpec()
/** /**
* Adds a new variable to the specification. * Adds a new variable to the specification.
* *
* @return the new variable * @return the new variable
*/ */
Variable* Variable*
@@ -61,7 +61,7 @@ LinearSpec::AddVariable()
/** /**
* Adds a new hard linear constraint to the specification. * Adds a new hard linear constraint to the specification.
* *
* @param coeffs the constraint's coefficients * @param coeffs the constraint's coefficients
* @param vars the constraint's variables * @param vars the constraint's variables
* @param op the constraint's operand * @param op the constraint's operand
@@ -70,7 +70,7 @@ LinearSpec::AddVariable()
*/ */
Constraint* Constraint*
LinearSpec::AddConstraint(BList* summands, OperatorType op, double rightSide) LinearSpec::AddConstraint(BList* summands, OperatorType op, double rightSide)
{ {
Constraint* c = new Constraint(this, summands, op, rightSide, Constraint* c = new Constraint(this, summands, op, rightSide,
INFINITY, INFINITY); INFINITY, INFINITY);
RemovePresolved(); RemovePresolved();
@@ -80,7 +80,7 @@ LinearSpec::AddConstraint(BList* summands, OperatorType op, double rightSide)
/** /**
* Adds a new hard linear constraint to the specification with a single summand. * Adds a new hard linear constraint to the specification with a single summand.
* *
* @param coeff1 the constraint's first coefficient * @param coeff1 the constraint's first coefficient
* @param var1 the constraint's first variable * @param var1 the constraint's first variable
* @param op the constraint's operand * @param op the constraint's operand
@@ -88,9 +88,9 @@ LinearSpec::AddConstraint(BList* summands, OperatorType op, double rightSide)
* @return the new constraint * @return the new constraint
*/ */
Constraint* Constraint*
LinearSpec::AddConstraint(double coeff1, Variable* var1, LinearSpec::AddConstraint(double coeff1, Variable* var1,
OperatorType op, double rightSide) OperatorType op, double rightSide)
{ {
BList* summands = new BList(1); BList* summands = new BList(1);
summands->AddItem(new Summand(coeff1, var1)); summands->AddItem(new Summand(coeff1, var1));
Constraint* c = new Constraint(this, summands, op, rightSide, Constraint* c = new Constraint(this, summands, op, rightSide,
@@ -102,7 +102,7 @@ LinearSpec::AddConstraint(double coeff1, Variable* var1,
/** /**
* Adds a new hard linear constraint to the specification with two summands. * Adds a new hard linear constraint to the specification with two summands.
* *
* @param coeff1 the constraint's first coefficient * @param coeff1 the constraint's first coefficient
* @param var1 the constraint's first variable * @param var1 the constraint's first variable
* @param coeff2 the constraint's second coefficient * @param coeff2 the constraint's second coefficient
@@ -112,22 +112,22 @@ LinearSpec::AddConstraint(double coeff1, Variable* var1,
* @return the new constraint * @return the new constraint
*/ */
Constraint* Constraint*
LinearSpec::AddConstraint(double coeff1, Variable* var1, LinearSpec::AddConstraint(double coeff1, Variable* var1,
double coeff2, Variable* var2, OperatorType op, double rightSide) double coeff2, Variable* var2, OperatorType op, double rightSide)
{ {
BList* summands = new BList(2); BList* summands = new BList(2);
summands->AddItem(new Summand(coeff1, var1)); summands->AddItem(new Summand(coeff1, var1));
summands->AddItem(new Summand(coeff2, var2)); summands->AddItem(new Summand(coeff2, var2));
Constraint* c = new Constraint(this, summands, op, rightSide, Constraint* c = new Constraint(this, summands, op, rightSide,
INFINITY, INFINITY); INFINITY, INFINITY);
RemovePresolved(); RemovePresolved();
return c; return c;
} }
/** /**
* Adds a new hard linear constraint to the specification with three summands. * Adds a new hard linear constraint to the specification with three summands.
* *
* @param coeff1 the constraint's first coefficient * @param coeff1 the constraint's first coefficient
* @param var1 the constraint's first variable * @param var1 the constraint's first variable
* @param coeff2 the constraint's second coefficient * @param coeff2 the constraint's second coefficient
@@ -139,10 +139,10 @@ LinearSpec::AddConstraint(double coeff1, Variable* var1,
* @return the new constraint * @return the new constraint
*/ */
Constraint* Constraint*
LinearSpec::AddConstraint(double coeff1, Variable* var1, LinearSpec::AddConstraint(double coeff1, Variable* var1,
double coeff2, Variable* var2, double coeff3, Variable* var3, double coeff2, Variable* var2, double coeff3, Variable* var3,
OperatorType op, double rightSide) OperatorType op, double rightSide)
{ {
BList* summands = new BList(3); BList* summands = new BList(3);
summands->AddItem(new Summand(coeff1, var1)); summands->AddItem(new Summand(coeff1, var1));
summands->AddItem(new Summand(coeff2, var2)); summands->AddItem(new Summand(coeff2, var2));
@@ -150,13 +150,13 @@ LinearSpec::AddConstraint(double coeff1, Variable* var1,
Constraint* c = new Constraint(this, summands, op, rightSide, Constraint* c = new Constraint(this, summands, op, rightSide,
INFINITY, INFINITY); INFINITY, INFINITY);
RemovePresolved(); RemovePresolved();
return c; return c;
} }
/** /**
* Adds a new hard linear constraint to the specification with four summands. * Adds a new hard linear constraint to the specification with four summands.
* *
* @param coeff1 the constraint's first coefficient * @param coeff1 the constraint's first coefficient
* @param var1 the constraint's first variable * @param var1 the constraint's first variable
* @param coeff2 the constraint's second coefficient * @param coeff2 the constraint's second coefficient
@@ -170,10 +170,10 @@ LinearSpec::AddConstraint(double coeff1, Variable* var1,
* @return the new constraint * @return the new constraint
*/ */
Constraint* Constraint*
LinearSpec::AddConstraint(double coeff1, Variable* var1, LinearSpec::AddConstraint(double coeff1, Variable* var1,
double coeff2, Variable* var2, double coeff3, Variable* var3, double coeff2, Variable* var2, double coeff3, Variable* var3,
double coeff4, Variable* var4, OperatorType op, double rightSide) double coeff4, Variable* var4, OperatorType op, double rightSide)
{ {
BList* summands = new BList(3); BList* summands = new BList(3);
summands->AddItem(new Summand(coeff1, var1)); summands->AddItem(new Summand(coeff1, var1));
summands->AddItem(new Summand(coeff2, var2)); summands->AddItem(new Summand(coeff2, var2));
@@ -182,14 +182,14 @@ LinearSpec::AddConstraint(double coeff1, Variable* var1,
Constraint* c = new Constraint(this, summands, op, rightSide, Constraint* c = new Constraint(this, summands, op, rightSide,
INFINITY, INFINITY); INFINITY, INFINITY);
RemovePresolved(); RemovePresolved();
return c; return c;
} }
/** /**
* Adds a new soft linear constraint to the specification. * Adds a new soft linear constraint to the specification.
* i.e. a constraint that does not always have to be satisfied. * i.e. a constraint that does not always have to be satisfied.
* *
* @param coeffs the constraint's coefficients * @param coeffs the constraint's coefficients
* @param vars the constraint's variables * @param vars the constraint's variables
* @param op the constraint's operand * @param op the constraint's operand
@@ -198,10 +198,10 @@ LinearSpec::AddConstraint(double coeff1, Variable* var1,
* @param penaltyPos the coefficient penalizing positive deviations from the exact solution * @param penaltyPos the coefficient penalizing positive deviations from the exact solution
*/ */
Constraint* Constraint*
LinearSpec::AddConstraint(BList* summands, OperatorType op, LinearSpec::AddConstraint(BList* summands, OperatorType op,
double rightSide, double penaltyNeg, double penaltyPos) double rightSide, double penaltyNeg, double penaltyPos)
{ {
Constraint* c = new Constraint(this, summands, op, rightSide, Constraint* c = new Constraint(this, summands, op, rightSide,
penaltyNeg, penaltyPos); penaltyNeg, penaltyPos);
RemovePresolved(); RemovePresolved();
return c; return c;
@@ -210,7 +210,7 @@ LinearSpec::AddConstraint(BList* summands, OperatorType op,
/** /**
* Adds a new soft linear constraint to the specification with a single summand. * Adds a new soft linear constraint to the specification with a single summand.
* *
* @param coeff1 the constraint's first coefficient * @param coeff1 the constraint's first coefficient
* @param var1 the constraint's first variable * @param var1 the constraint's first variable
* @param op the constraint's operand * @param op the constraint's operand
@@ -219,9 +219,9 @@ LinearSpec::AddConstraint(BList* summands, OperatorType op,
* @param penaltyPos the coefficient penalizing positive deviations from the exact solution * @param penaltyPos the coefficient penalizing positive deviations from the exact solution
*/ */
Constraint* Constraint*
LinearSpec::AddConstraint(double coeff1, Variable* var1, LinearSpec::AddConstraint(double coeff1, Variable* var1,
OperatorType op, double rightSide, double penaltyNeg, double penaltyPos) OperatorType op, double rightSide, double penaltyNeg, double penaltyPos)
{ {
BList* summands = new BList(1); BList* summands = new BList(1);
summands->AddItem(new Summand(coeff1, var1)); summands->AddItem(new Summand(coeff1, var1));
Constraint* c = new Constraint(this, summands, op, rightSide, Constraint* c = new Constraint(this, summands, op, rightSide,
@@ -233,7 +233,7 @@ LinearSpec::AddConstraint(double coeff1, Variable* var1,
/** /**
* Adds a new soft linear constraint to the specification with two summands. * Adds a new soft linear constraint to the specification with two summands.
* *
* @param coeff1 the constraint's first coefficient * @param coeff1 the constraint's first coefficient
* @param var1 the constraint's first variable * @param var1 the constraint's first variable
* @param coeff2 the constraint's second coefficient * @param coeff2 the constraint's second coefficient
@@ -244,10 +244,10 @@ LinearSpec::AddConstraint(double coeff1, Variable* var1,
* @param penaltyPos the coefficient penalizing positive deviations from the exact solution * @param penaltyPos the coefficient penalizing positive deviations from the exact solution
*/ */
Constraint* Constraint*
LinearSpec::AddConstraint(double coeff1, Variable* var1, LinearSpec::AddConstraint(double coeff1, Variable* var1,
double coeff2, Variable* var2, OperatorType op, double rightSide, double coeff2, Variable* var2, OperatorType op, double rightSide,
double penaltyNeg, double penaltyPos) double penaltyNeg, double penaltyPos)
{ {
BList* summands = new BList(2); BList* summands = new BList(2);
summands->AddItem(new Summand(coeff1, var1)); summands->AddItem(new Summand(coeff1, var1));
summands->AddItem(new Summand(coeff2, var2)); summands->AddItem(new Summand(coeff2, var2));
@@ -260,7 +260,7 @@ LinearSpec::AddConstraint(double coeff1, Variable* var1,
/** /**
* Adds a new soft linear constraint to the specification with three summands. * Adds a new soft linear constraint to the specification with three summands.
* *
* @param coeff1 the constraint's first coefficient * @param coeff1 the constraint's first coefficient
* @param var1 the constraint's first variable * @param var1 the constraint's first variable
* @param coeff2 the constraint's second coefficient * @param coeff2 the constraint's second coefficient
@@ -273,8 +273,8 @@ LinearSpec::AddConstraint(double coeff1, Variable* var1,
* @param penaltyPos the coefficient penalizing positive deviations from the exact solution * @param penaltyPos the coefficient penalizing positive deviations from the exact solution
*/ */
Constraint* Constraint*
LinearSpec::AddConstraint(double coeff1, Variable* var1, LinearSpec::AddConstraint(double coeff1, Variable* var1,
double coeff2, Variable* var2, double coeff3, Variable* var3, double coeff2, Variable* var2, double coeff3, Variable* var3,
OperatorType op, double rightSide, double penaltyNeg, double penaltyPos) OperatorType op, double rightSide, double penaltyNeg, double penaltyPos)
{ {
BList* summands = new BList(2); BList* summands = new BList(2);
@@ -290,7 +290,7 @@ LinearSpec::AddConstraint(double coeff1, Variable* var1,
/** /**
* Adds a new soft linear constraint to the specification with four summands. * Adds a new soft linear constraint to the specification with four summands.
* *
* @param coeff1 the constraint's first coefficient * @param coeff1 the constraint's first coefficient
* @param var1 the constraint's first variable * @param var1 the constraint's first variable
* @param coeff2 the constraint's second coefficient * @param coeff2 the constraint's second coefficient
@@ -305,11 +305,11 @@ LinearSpec::AddConstraint(double coeff1, Variable* var1,
* @param penaltyPos the coefficient penalizing positive deviations from the exact solution * @param penaltyPos the coefficient penalizing positive deviations from the exact solution
*/ */
Constraint* Constraint*
LinearSpec::AddConstraint(double coeff1, Variable* var1, LinearSpec::AddConstraint(double coeff1, Variable* var1,
double coeff2, Variable* var2, double coeff3, Variable* var3, double coeff2, Variable* var2, double coeff3, Variable* var3,
double coeff4, Variable* var4, OperatorType op, double rightSide, double coeff4, Variable* var4, OperatorType op, double rightSide,
double penaltyNeg, double penaltyPos) double penaltyNeg, double penaltyPos)
{ {
BList* summands = new BList(2); BList* summands = new BList(2);
summands->AddItem(new Summand(coeff1, var1)); summands->AddItem(new Summand(coeff1, var1));
summands->AddItem(new Summand(coeff2, var2)); summands->AddItem(new Summand(coeff2, var2));
@@ -324,7 +324,7 @@ LinearSpec::AddConstraint(double coeff1, Variable* var1,
/** /**
* Adds a new penalty function to the specification. * Adds a new penalty function to the specification.
* *
* @param var the penalty function's variable * @param var the penalty function's variable
* @param xs the penalty function's sampling points * @param xs the penalty function's sampling points
* @param gs the penalty function's gradients * @param gs the penalty function's gradients
@@ -339,7 +339,7 @@ LinearSpec::AddPenaltyFunction(Variable* var, BList* xs, BList* gs)
/** /**
* Gets the objective function. * Gets the objective function.
* *
* @return BList containing the objective function's summands * @return BList containing the objective function's summands
*/ */
BList* BList*
@@ -352,7 +352,7 @@ LinearSpec::ObjFunction()
/** /**
* Sets a new objective function. * Sets a new objective function.
* The old objective function summands are NOT deleted. * The old objective function summands are NOT deleted.
* *
* @param summands BList containing the objective function's summands * @param summands BList containing the objective function's summands
*/ */
void void
@@ -379,17 +379,17 @@ LinearSpec::UpdateObjFunction()
coeffs[i] = current->Coeff(); coeffs[i] = current->Coeff();
varIndexes[i] = current->Var()->Index(); varIndexes[i] = current->Var()->Index();
} }
if (!set_obj_fnex(fLP, size, &coeffs[0], &varIndexes[0])) if (!set_obj_fnex(fLP, size, &coeffs[0], &varIndexes[0]))
printf("Error in set_obj_fnex."); printf("Error in set_obj_fnex.");
RemovePresolved(); RemovePresolved();
} }
/** /**
* Remove a cached presolved model, if existent. * Remove a cached presolved model, if existent.
* This is automatically done each time after the model has been changed, * This is automatically done each time after the model has been changed,
* to avoid an old cached presolved model getting out of sync. * to avoid an old cached presolved model getting out of sync.
*/ */
void void
@@ -403,11 +403,11 @@ LinearSpec::RemovePresolved()
/** /**
* Creates and caches a simplified version of the linear programming problem, * Creates and caches a simplified version of the linear programming problem,
* where redundant rows, columns and constraints are removed, * where redundant rows, columns and constraints are removed,
* if it has not been created before. * if it has not been created before.
* Then, the simplified problem is solved. * Then, the simplified problem is solved.
* *
* @return the result of the solving attempt * @return the result of the solving attempt
*/ */
ResultType ResultType
@@ -415,28 +415,28 @@ LinearSpec::Presolve()
{ {
bigtime_t start, end; bigtime_t start, end;
start = system_time(); start = system_time();
if (fLpPresolved == NULL) { if (fLpPresolved == NULL) {
fLpPresolved = copy_lp(fLP); fLpPresolved = copy_lp(fLP);
set_presolve(fLpPresolved, PRESOLVE_ROWS | PRESOLVE_COLS | PRESOLVE_LINDEP, set_presolve(fLpPresolved, PRESOLVE_ROWS | PRESOLVE_COLS | PRESOLVE_LINDEP,
get_presolveloops(fLpPresolved)); get_presolveloops(fLpPresolved));
} }
fResult = (ResultType)solve(fLpPresolved); fResult = (ResultType)solve(fLpPresolved);
fObjectiveValue = get_objective(fLpPresolved); fObjectiveValue = get_objective(fLpPresolved);
if (fResult == OPTIMAL) { if (fResult == OPTIMAL) {
int32 size = fVariables->CountItems(); int32 size = fVariables->CountItems();
for (int32 i = 0; i < size; i++) { for (int32 i = 0; i < size; i++) {
Variable* current = (Variable*)fVariables->ItemAt(i); Variable* current = (Variable*)fVariables->ItemAt(i);
current->SetValue(get_var_primalresult(fLpPresolved, current->SetValue(get_var_primalresult(fLpPresolved,
get_Norig_rows(fLpPresolved) + current->Index())); get_Norig_rows(fLpPresolved) + current->Index()));
} }
} }
end = system_time(); end = system_time();
fSolvingTime = (end - start) / 1000.0; fSolvingTime = (end - start) / 1000.0;
return fResult; return fResult;
} }
@@ -444,7 +444,7 @@ LinearSpec::Presolve()
/** /**
* Tries to solve the linear programming problem. * Tries to solve the linear programming problem.
* If a cached simplified version of the problem exists, it is used instead. * If a cached simplified version of the problem exists, it is used instead.
* *
* @return the result of the solving attempt * @return the result of the solving attempt
*/ */
ResultType ResultType
@@ -452,29 +452,29 @@ LinearSpec::Solve()
{ {
if (fLpPresolved != NULL) if (fLpPresolved != NULL)
return Presolve(); return Presolve();
bigtime_t start, end; bigtime_t start, end;
start = system_time(); start = system_time();
fResult = (ResultType)solve(fLP); fResult = (ResultType)solve(fLP);
fObjectiveValue = get_objective(fLP); fObjectiveValue = get_objective(fLP);
if (fResult == OPTIMAL) { if (fResult == OPTIMAL) {
int32 size = fVariables->CountItems(); int32 size = fVariables->CountItems();
double x[size]; double x[size];
if (!get_variables(fLP, &x[0])) if (!get_variables(fLP, &x[0]))
printf("Error in get_variables."); printf("Error in get_variables.");
int32 i = 0; int32 i = 0;
while (i < size) { while (i < size) {
((Variable*)fVariables->ItemAt(i))->SetValue(x[i]); ((Variable*)fVariables->ItemAt(i))->SetValue(x[i]);
i++; i++;
} }
} }
end = system_time(); end = system_time();
fSolvingTime = (end - start) / 1000.0; fSolvingTime = (end - start) / 1000.0;
return fResult; return fResult;
} }
@@ -482,13 +482,14 @@ LinearSpec::Solve()
/** /**
* Writes the specification into a text file. * Writes the specification into a text file.
* The file will be overwritten if it exists. * The file will be overwritten if it exists.
* *
* @param fname the file name * @param fname the file name
*/ */
void void
LinearSpec::Save(char* fname) LinearSpec::Save(const char* fileName)
{ {
write_lp(fLP, fname); // TODO: Constness should be fixed in liblpsolve API.
write_lp(fLP, const_cast<char*>(fileName));
} }
@@ -507,7 +508,7 @@ LinearSpec::CountColumns() const
/** /**
* Gets the current optimization. * Gets the current optimization.
* The default is minimization. * The default is minimization.
* *
* @return the current optimization * @return the current optimization
*/ */
OptimizationType OptimizationType
@@ -520,7 +521,7 @@ LinearSpec::Optimization() const
/** /**
* Sets whether the solver should minimize or maximize the objective function. * Sets whether the solver should minimize or maximize the objective function.
* The default is minimization. * The default is minimization.
* *
* @param optimization the optimization type * @param optimization the optimization type
*/ */
void void
@@ -536,7 +537,7 @@ LinearSpec::SetOptimization(OptimizationType value)
/** /**
* Gets the the variables. * Gets the the variables.
* *
* @return the variables * @return the variables
*/ */
BList* BList*
@@ -548,7 +549,7 @@ LinearSpec::Variables() const
/** /**
* Gets the constraints. * Gets the constraints.
* *
* @return the constraints * @return the constraints
*/ */
BList* BList*
@@ -560,7 +561,7 @@ LinearSpec::Constraints() const
/** /**
* Gets the result type. * Gets the result type.
* *
* @return the result type * @return the result type
*/ */
ResultType ResultType
@@ -572,7 +573,7 @@ LinearSpec::Result() const
/** /**
* Gets the objective value. * Gets the objective value.
* *
* @return the objective value * @return the objective value
*/ */
double double
@@ -584,7 +585,7 @@ LinearSpec::ObjectiveValue() const
/** /**
* Gets the solving time. * Gets the solving time.
* *
* @return the solving time * @return the solving time
*/ */
double double
@@ -594,54 +595,47 @@ LinearSpec::SolvingTime() const
} }
BString* LinearSpec::operator BString() const
LinearSpec::ToBString()
{ {
BString* str = new BString(); BString string;
*str << "LinearSpec " << (int32)this << ":\n"; GetString(string);
return string;
}
void
LinearSpec::GetString(BString& string) const
{
string << "LinearSpec " << (int32)this << ":\n";
for (int i = 0; i < fVariables->CountItems(); i++) { for (int i = 0; i < fVariables->CountItems(); i++) {
Variable* variable = static_cast<Variable*>(fVariables->ItemAt(i)); Variable* variable = static_cast<Variable*>(fVariables->ItemAt(i));
BString* vStr = variable->ToBString(); variable->GetString(string);
*str << *vStr << "=" << (float)variable->Value() << " "; string << "=" << (float)variable->Value() << " ";
delete vStr;
} }
*str << "\n"; string << "\n";
for (int i = 0; i < fConstraints->CountItems(); i++) { for (int i = 0; i < fConstraints->CountItems(); i++) {
Constraint* c = static_cast<Constraint*>(fConstraints->ItemAt(i)); Constraint* c = static_cast<Constraint*>(fConstraints->ItemAt(i));
BString* cStr = c->ToBString(); string << i << ": ";
*str << i << ": " << *cStr; c->GetString(string);
delete cStr; string << "\n";
*str << "\n";
} }
*str << "Result="; string << "Result=";
if (fResult==-1) if (fResult==-1)
*str << "ERROR"; string << "ERROR";
else if (fResult==0) else if (fResult==0)
*str << "OPTIMAL"; string << "OPTIMAL";
else if (fResult==1) else if (fResult==1)
*str << "SUBOPTIMAL"; string << "SUBOPTIMAL";
else if (fResult==2) else if (fResult==2)
*str << "INFEASIBLE"; string << "INFEASIBLE";
else if (fResult==3) else if (fResult==3)
*str << "UNBOUNDED"; string << "UNBOUNDED";
else if (fResult==4) else if (fResult==4)
*str << "DEGENERATE"; string << "DEGENERATE";
else if (fResult==5) else if (fResult==5)
*str << "NUMFAILURE"; string << "NUMFAILURE";
else else
*str << fResult; string << fResult;
*str << " SolvingTime=" << (float)fSolvingTime << "ms"; string << " SolvingTime=" << (float)fSolvingTime << "ms";
return str;
}
const char*
LinearSpec::ToString()
{
BString* str = ToBString();
char* result = (char*) malloc(str->Length() + 1);
str->CopyInto(result, 0, str->Length());
delete str;
return result;
} }
+37 -42
View File
@@ -26,11 +26,11 @@
/** /**
* Gets index of the variable. * Gets index of the variable.
* *
* @return the index of the variable * @return the index of the variable
*/ */
int32 int32
Variable::Index() Variable::Index() const
{ {
int32 i = fLS->Variables()->IndexOf(this); int32 i = fLS->Variables()->IndexOf(this);
if (i == -1) { if (i == -1) {
@@ -43,7 +43,7 @@ Variable::Index()
/** /**
* Gets the current linear specification. * Gets the current linear specification.
* *
* @return the current linear specification * @return the current linear specification
*/ */
LinearSpec* LinearSpec*
@@ -55,7 +55,7 @@ Variable::LS() const
/** /**
* Gets the value. * Gets the value.
* *
* @return the value * @return the value
*/ */
double double
@@ -67,7 +67,7 @@ Variable::Value() const
/** /**
* Sets the value. * Sets the value.
* *
* @param value the value * @param value the value
*/ */
void void
@@ -79,7 +79,7 @@ Variable::SetValue(double value)
/** /**
* Gets the minimum value of the variable. * Gets the minimum value of the variable.
* *
* @return the minimum value of variable * @return the minimum value of variable
*/ */
double double
@@ -91,7 +91,7 @@ Variable::Min() const
/** /**
* Sets the minimum value of the variable. * Sets the minimum value of the variable.
* *
* @param min minimum value * @param min minimum value
*/ */
void void
@@ -107,7 +107,7 @@ Variable::SetMin(double min)
/** /**
* Gets the maximum value of the variable. * Gets the maximum value of the variable.
* *
* @return the maximum value of variable * @return the maximum value of variable
*/ */
double double
@@ -119,7 +119,7 @@ Variable::Max() const
/** /**
* Sets the maximum value of the variable. * Sets the maximum value of the variable.
* *
* @param max maximum value * @param max maximum value
*/ */
void void
@@ -135,7 +135,7 @@ Variable::SetMax(double max)
/** /**
* Sets the minimum and maximum values of the variable. * Sets the minimum and maximum values of the variable.
* *
* @param min minimum value * @param min minimum value
* @param max maximum value * @param max maximum value
*/ */
@@ -166,45 +166,40 @@ Variable::SetLabel(const char* label)
} }
/** Variable::operator BString() const
* Returns index of the variable as String.
* E.g. "Var2"
*
* @return the <code>String</code> index of the variable
*/
BString*
Variable::ToBString()
{ {
BString* str = new BString(); BString string;
if (fLabel) { GetString(string);
*str << fLabel; return string;
if (!fIsValid)
*str << "(invalid)";
} else {
*str << "Var";
if (!fIsValid)
*str << "(invalid," << (int32)this << ")";
else
*str << Index();
}
return str;
} }
const char* /**
Variable::ToString() * 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* str = ToBString(); if (fLabel) {
char* result = (char*) malloc(str->Length() + 1); string << fLabel;
str->CopyInto(result, 0, str->Length()); if (!fIsValid)
delete str; string << "(invalid)";
return result; } else {
string << "Var";
if (!fIsValid)
string << "(invalid," << (int32)this << ")";
else
string << Index();
}
} }
/** /**
* Adds a constraint that sets this variable equal to the given one. * Adds a constraint that sets this variable equal to the given one.
* *
* @param var variable that should have the same value * @param var variable that should have the same value
* @return the new equality constraint * @return the new equality constraint
*/ */
@@ -220,7 +215,7 @@ Variable::IsEqual(Variable* var)
/** /**
* Adds a constraint that sets this variable smaller or equal to the given one. * Adds a constraint that sets this variable smaller or equal to the given one.
* *
* @param var variable that should have a larger or equal value * @param var variable that should have a larger or equal value
* @return the new constraint * @return the new constraint
*/ */
@@ -236,7 +231,7 @@ Variable::IsSmallerOrEqual(Variable* var)
/** /**
* Adds a constraint that sets this variable greater or equal to the given one. * Adds a constraint that sets this variable greater or equal to the given one.
* *
* @param var variable that should have a smaller or equal value * @param var variable that should have a smaller or equal value
* @return the new constraint * @return the new constraint
*/ */
@@ -341,7 +336,7 @@ Variable::Variable(LinearSpec* ls)
fIsValid(true) fIsValid(true)
{ {
fLS->Variables()->AddItem(this); fLS->Variables()->AddItem(this);
if (fLS->Variables()->CountItems() > fLS->CountColumns()) { if (fLS->Variables()->CountItems() > fLS->CountColumns()) {
double d = 0; double d = 0;
int i = 0; int i = 0;