diff --git a/headers/libs/linprog/LinearSpec.h b/headers/libs/linprog/LinearSpec.h index b6e0fac067..b0dc5adbb2 100644 --- a/headers/libs/linprog/LinearSpec.h +++ b/headers/libs/linprog/LinearSpec.h @@ -58,6 +58,10 @@ public: virtual ResultType FindMins(const VariableList* variables) = 0; virtual ResultType FindMaxs(const VariableList* variables) = 0; + virtual void GetRangeConstraints(const Variable* var, + const Constraint** _min, + const Constraint** _max) const = 0; + protected: LinearSpec* fLinearSpec; }; @@ -138,6 +142,9 @@ public: BString ToString() const; + void GetRangeConstraints(const Variable*, + const Constraint** _min, + const Constraint** _max) const; const ConstraintList& Constraints() const; const VariableList& UsedVariables() const; const VariableList& AllVariables() const; diff --git a/src/libs/alm/SharedSolver.cpp b/src/libs/alm/SharedSolver.cpp index 57529c5165..34f090abe4 100644 --- a/src/libs/alm/SharedSolver.cpp +++ b/src/libs/alm/SharedSolver.cpp @@ -217,12 +217,13 @@ SharedSolver::AllArchived(BMessage* archive) const for each archived layout: add it to our archive add constraints created by areas and column manager to a set + add range constraints on the left/top/right/bottom tabs to the same set for each constraint in the linear spec: if it is not in the set above: archive it */ BArchiver archiver(archive); - std::set autoConstraints; + std::set autoConstraints; for (int32 i = fLayouts.CountItems() - 1; i >= 0; i--) { BALMLayout* layout = fLayouts.ItemAt(i); if (!archiver.IsArchived(layout)) @@ -233,22 +234,35 @@ SharedSolver::AllArchived(BMessage* archive) const for (int32 j = layout->fRowColumnManager->fRows.CountItems() - 1; j >= 0; j--) { - Row* row = layout->fRowColumnManager->fRows.ItemAt(i); + Row* row = layout->fRowColumnManager->fRows.ItemAt(j); autoConstraints.insert(row->fPrefSizeConstraint); } for (int32 j = layout->fRowColumnManager->fColumns.CountItems() - 1; j >= 0; j--) { - Column* column = layout->fRowColumnManager->fColumns.ItemAt(i); + Column* column = layout->fRowColumnManager->fColumns.ItemAt(j); autoConstraints.insert(column->fPrefSizeConstraint); } + + Variable* corners[] = {layout->fLeft, layout->fTop, layout->fRight, + layout->fBottom}; + + for (int32 j = 0; j < 4; j++) { + const Constraint* min; + const Constraint* max; + fLinearSpec.GetRangeConstraints(corners[j], &min, &max); + if (min) + autoConstraints.insert(min); + if (max) + autoConstraints.insert(max); + } } status_t err = B_OK; const ConstraintList& constraints = fLinearSpec.Constraints(); for (int32 i = constraints.CountItems() - 1; i >= 0 && err == B_OK; i--) { Constraint* constraint = constraints.ItemAt(i); - if (autoConstraints.find(constraint) != autoConstraints.end()) + if (autoConstraints.find(constraint) == autoConstraints.end()) err = _AddConstraintToArchive(constraint, archive); } return err; @@ -279,7 +293,7 @@ SharedSolver::AllUnarchived(const BMessage* archive) void SharedSolver::_AddConstraintsToSet(Area* area, - std::set& constraints) + std::set& constraints) { if (area->fMinContentWidth) constraints.insert(area->fMinContentWidth); @@ -295,8 +309,20 @@ SharedSolver::_AddConstraintsToSet(Area* area, status_t -SharedSolver::_AddConstraintToArchive(Constraint* constraint, BMessage* archive) +SharedSolver::_AddConstraintToArchive(Constraint* constraint, + BMessage* archive) { + /* Format: + * int32: summandCount + * { int32 : token + * double: coefficient + * } [summandCount] + * int32: operator + * double: rightSide + * double: penaltyNeg + * double: penaltyPos + */ + // TODO: check Read/Write calls BArchiver archiver(archive); BMallocIO buffer; @@ -338,6 +364,17 @@ status_t SharedSolver::_InstantiateConstraint(const void* rawData, ssize_t numBytes, BUnarchiver& unarchiver) { + /* Format: + * int32: summandCount + * { int32 : token + * double: coefficient + * } [summandCount] + * int32: operator + * double: rightSide + * double: penaltyNeg + * double: penaltyPos + */ + // TODO: check Read/Write calls BMemoryIO buffer(rawData, numBytes); int32 summandCount; @@ -376,13 +413,16 @@ SharedSolver::_InstantiateConstraint(const void* rawData, ssize_t numBytes, double penaltyPos; buffer.Read(&penaltyPos, sizeof(penaltyPos)); - if (err == B_OK) { - fLinearSpec.AddConstraint(summandList, (OperatorType)op, rightSide, - penaltyNeg, penaltyPos); + if (err != B_OK) + return err; + + if (fLinearSpec.AddConstraint(summandList, (OperatorType)op, rightSide, + penaltyNeg, penaltyPos) != NULL) { deleter.Detach(); + return B_OK; } - return err; + return B_NO_MEMORY; } diff --git a/src/libs/alm/SharedSolver.h b/src/libs/alm/SharedSolver.h index 0e9c84d649..3d397fa427 100644 --- a/src/libs/alm/SharedSolver.h +++ b/src/libs/alm/SharedSolver.h @@ -70,7 +70,7 @@ private: static void _AddConstraintsToSet(Area* area, - std::set& constraints); + std::set& constraints); static status_t _AddConstraintToArchive(Constraint* constraint, BMessage* archive); status_t _InstantiateConstraint(const void* rawData, diff --git a/src/libs/alm/Tab.cpp b/src/libs/alm/Tab.cpp index 13646c4119..f9614b6789 100644 --- a/src/libs/alm/Tab.cpp +++ b/src/libs/alm/Tab.cpp @@ -60,7 +60,8 @@ TabBase::TabBase() TabBase::TabBase(BMessage* archive) : - BArchivable(BUnarchiver::PrepareArchive(archive)) + BArchivable(BUnarchiver::PrepareArchive(archive)), + fLayouts(NULL) { BUnarchiver(archive).Finish(B_OK); } diff --git a/src/libs/linprog/ActiveSetSolver.cpp b/src/libs/linprog/ActiveSetSolver.cpp index aa592a23d5..95c98281e4 100644 --- a/src/libs/linprog/ActiveSetSolver.cpp +++ b/src/libs/linprog/ActiveSetSolver.cpp @@ -613,6 +613,19 @@ ActiveSetSolver::FindMins(const VariableList* variables) } +void +ActiveSetSolver::GetRangeConstraints(const Variable* var, + const Constraint** _min, const Constraint** _max) const +{ + int32 variableIndex = var->GlobalIndex(); + + if (_min) + *_min = fVariableGEConstraints.ItemAt(variableIndex); + if (_max) + *_max = fVariableLEConstraints.ItemAt(variableIndex); +} + + void ActiveSetSolver::_RemoveSoftConstraint(ConstraintList& list) { diff --git a/src/libs/linprog/ActiveSetSolver.h b/src/libs/linprog/ActiveSetSolver.h index ec55b1c906..397afe5834 100644 --- a/src/libs/linprog/ActiveSetSolver.h +++ b/src/libs/linprog/ActiveSetSolver.h @@ -77,6 +77,9 @@ public: ResultType FindMaxs(const VariableList* variables); ResultType FindMins(const VariableList* variables); + void GetRangeConstraints(const Variable* var, + const Constraint** _min, + const Constraint** _max) const; private: void _RemoveSoftConstraint(ConstraintList& list); void _AddSoftConstraint(const ConstraintList& list); diff --git a/src/libs/linprog/LinearSpec.cpp b/src/libs/linprog/LinearSpec.cpp index fa3e8d5af5..a266f0485f 100644 --- a/src/libs/linprog/LinearSpec.cpp +++ b/src/libs/linprog/LinearSpec.cpp @@ -590,6 +590,18 @@ LinearSpec::Save(const char* fileName) } +/** + * Gets the constraints generated by calls to Variable::SetRange() + * + */ +void +LinearSpec::GetRangeConstraints(const Variable* var, const Constraint** _min, + const Constraint** _max) const +{ + fSolver->GetRangeConstraints(var, _min, _max); +} + + /** * Gets the constraints. * diff --git a/src/tests/libs/alm/FriendLayout.cpp b/src/tests/libs/alm/FriendLayout.cpp index 5006cc16a3..0d12305f24 100644 --- a/src/tests/libs/alm/FriendLayout.cpp +++ b/src/tests/libs/alm/FriendLayout.cpp @@ -69,8 +69,8 @@ public: fRight = xTabs[1]; layout1->AreaFor(button2)->SetContentAspectRatio(1.0f); - fLayout2->Solver()->AddConstraint(-1.0f, xTabs[0], 1.0f, xTabs[1], - LinearProgramming::kGE, 20.0f); + fLayout2->Solver()->AddConstraint(-1.0f, layout1->Left(), 1.0f, xTabs[0], + LinearProgramming::kLE, 90.0f); BButton* archiveButton = new BButton("clone", new BMessage('arcv')); archiveButton->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED,