Fix BALMLayout archiving issues.
SharedSolver was archiving too many constraints, partly because of multiple typos, also because it archived some which were just artifacts of the layout process. These extra constraints are created when the layout calls SetRange() on the left/top/right/bottom tabs during layout. * LinearSpec/ActiveSetSolver had to be adjusted to get access to the constraints added by the SetRange() calls. * BALM::TabBase was adjusted to avoid a segfault during unarchiving, caused by an unitialized member. * ALMFriendLayoutTest was adjusted to include a more obvious custom constraint for testing.
This commit is contained in:
@@ -58,6 +58,10 @@ public:
|
|||||||
virtual ResultType FindMins(const VariableList* variables) = 0;
|
virtual ResultType FindMins(const VariableList* variables) = 0;
|
||||||
virtual ResultType FindMaxs(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:
|
protected:
|
||||||
LinearSpec* fLinearSpec;
|
LinearSpec* fLinearSpec;
|
||||||
};
|
};
|
||||||
@@ -138,6 +142,9 @@ public:
|
|||||||
|
|
||||||
BString ToString() const;
|
BString ToString() const;
|
||||||
|
|
||||||
|
void GetRangeConstraints(const Variable*,
|
||||||
|
const Constraint** _min,
|
||||||
|
const Constraint** _max) const;
|
||||||
const ConstraintList& Constraints() const;
|
const ConstraintList& Constraints() const;
|
||||||
const VariableList& UsedVariables() const;
|
const VariableList& UsedVariables() const;
|
||||||
const VariableList& AllVariables() const;
|
const VariableList& AllVariables() const;
|
||||||
|
|||||||
@@ -217,12 +217,13 @@ SharedSolver::AllArchived(BMessage* archive) const
|
|||||||
for each archived layout:
|
for each archived layout:
|
||||||
add it to our archive
|
add it to our archive
|
||||||
add constraints created by areas and column manager to a set
|
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:
|
for each constraint in the linear spec:
|
||||||
if it is not in the set above:
|
if it is not in the set above:
|
||||||
archive it
|
archive it
|
||||||
*/
|
*/
|
||||||
BArchiver archiver(archive);
|
BArchiver archiver(archive);
|
||||||
std::set<Constraint*> autoConstraints;
|
std::set<const Constraint*> autoConstraints;
|
||||||
for (int32 i = fLayouts.CountItems() - 1; i >= 0; i--) {
|
for (int32 i = fLayouts.CountItems() - 1; i >= 0; i--) {
|
||||||
BALMLayout* layout = fLayouts.ItemAt(i);
|
BALMLayout* layout = fLayouts.ItemAt(i);
|
||||||
if (!archiver.IsArchived(layout))
|
if (!archiver.IsArchived(layout))
|
||||||
@@ -233,22 +234,35 @@ SharedSolver::AllArchived(BMessage* archive) const
|
|||||||
|
|
||||||
for (int32 j = layout->fRowColumnManager->fRows.CountItems() - 1;
|
for (int32 j = layout->fRowColumnManager->fRows.CountItems() - 1;
|
||||||
j >= 0; j--) {
|
j >= 0; j--) {
|
||||||
Row* row = layout->fRowColumnManager->fRows.ItemAt(i);
|
Row* row = layout->fRowColumnManager->fRows.ItemAt(j);
|
||||||
autoConstraints.insert(row->fPrefSizeConstraint);
|
autoConstraints.insert(row->fPrefSizeConstraint);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int32 j = layout->fRowColumnManager->fColumns.CountItems() - 1;
|
for (int32 j = layout->fRowColumnManager->fColumns.CountItems() - 1;
|
||||||
j >= 0; j--) {
|
j >= 0; j--) {
|
||||||
Column* column = layout->fRowColumnManager->fColumns.ItemAt(i);
|
Column* column = layout->fRowColumnManager->fColumns.ItemAt(j);
|
||||||
autoConstraints.insert(column->fPrefSizeConstraint);
|
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;
|
status_t err = B_OK;
|
||||||
const ConstraintList& constraints = fLinearSpec.Constraints();
|
const ConstraintList& constraints = fLinearSpec.Constraints();
|
||||||
for (int32 i = constraints.CountItems() - 1; i >= 0 && err == B_OK; i--) {
|
for (int32 i = constraints.CountItems() - 1; i >= 0 && err == B_OK; i--) {
|
||||||
Constraint* constraint = constraints.ItemAt(i);
|
Constraint* constraint = constraints.ItemAt(i);
|
||||||
if (autoConstraints.find(constraint) != autoConstraints.end())
|
if (autoConstraints.find(constraint) == autoConstraints.end())
|
||||||
err = _AddConstraintToArchive(constraint, archive);
|
err = _AddConstraintToArchive(constraint, archive);
|
||||||
}
|
}
|
||||||
return err;
|
return err;
|
||||||
@@ -279,7 +293,7 @@ SharedSolver::AllUnarchived(const BMessage* archive)
|
|||||||
|
|
||||||
void
|
void
|
||||||
SharedSolver::_AddConstraintsToSet(Area* area,
|
SharedSolver::_AddConstraintsToSet(Area* area,
|
||||||
std::set<Constraint*>& constraints)
|
std::set<const Constraint*>& constraints)
|
||||||
{
|
{
|
||||||
if (area->fMinContentWidth)
|
if (area->fMinContentWidth)
|
||||||
constraints.insert(area->fMinContentWidth);
|
constraints.insert(area->fMinContentWidth);
|
||||||
@@ -295,8 +309,20 @@ SharedSolver::_AddConstraintsToSet(Area* area,
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
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
|
// TODO: check Read/Write calls
|
||||||
BArchiver archiver(archive);
|
BArchiver archiver(archive);
|
||||||
BMallocIO buffer;
|
BMallocIO buffer;
|
||||||
@@ -338,6 +364,17 @@ status_t
|
|||||||
SharedSolver::_InstantiateConstraint(const void* rawData, ssize_t numBytes,
|
SharedSolver::_InstantiateConstraint(const void* rawData, ssize_t numBytes,
|
||||||
BUnarchiver& unarchiver)
|
BUnarchiver& unarchiver)
|
||||||
{
|
{
|
||||||
|
/* Format:
|
||||||
|
* int32: summandCount
|
||||||
|
* { int32 : token
|
||||||
|
* double: coefficient
|
||||||
|
* } [summandCount]
|
||||||
|
* int32: operator
|
||||||
|
* double: rightSide
|
||||||
|
* double: penaltyNeg
|
||||||
|
* double: penaltyPos
|
||||||
|
*/
|
||||||
|
|
||||||
// TODO: check Read/Write calls
|
// TODO: check Read/Write calls
|
||||||
BMemoryIO buffer(rawData, numBytes);
|
BMemoryIO buffer(rawData, numBytes);
|
||||||
int32 summandCount;
|
int32 summandCount;
|
||||||
@@ -376,13 +413,16 @@ SharedSolver::_InstantiateConstraint(const void* rawData, ssize_t numBytes,
|
|||||||
double penaltyPos;
|
double penaltyPos;
|
||||||
buffer.Read(&penaltyPos, sizeof(penaltyPos));
|
buffer.Read(&penaltyPos, sizeof(penaltyPos));
|
||||||
|
|
||||||
if (err == B_OK) {
|
if (err != B_OK)
|
||||||
fLinearSpec.AddConstraint(summandList, (OperatorType)op, rightSide,
|
return err;
|
||||||
penaltyNeg, penaltyPos);
|
|
||||||
|
if (fLinearSpec.AddConstraint(summandList, (OperatorType)op, rightSide,
|
||||||
|
penaltyNeg, penaltyPos) != NULL) {
|
||||||
deleter.Detach();
|
deleter.Detach();
|
||||||
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
return err;
|
return B_NO_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ private:
|
|||||||
|
|
||||||
|
|
||||||
static void _AddConstraintsToSet(Area* area,
|
static void _AddConstraintsToSet(Area* area,
|
||||||
std::set<Constraint*>& constraints);
|
std::set<const Constraint*>& constraints);
|
||||||
static status_t _AddConstraintToArchive(Constraint* constraint,
|
static status_t _AddConstraintToArchive(Constraint* constraint,
|
||||||
BMessage* archive);
|
BMessage* archive);
|
||||||
status_t _InstantiateConstraint(const void* rawData,
|
status_t _InstantiateConstraint(const void* rawData,
|
||||||
|
|||||||
@@ -60,7 +60,8 @@ TabBase::TabBase()
|
|||||||
|
|
||||||
TabBase::TabBase(BMessage* archive)
|
TabBase::TabBase(BMessage* archive)
|
||||||
:
|
:
|
||||||
BArchivable(BUnarchiver::PrepareArchive(archive))
|
BArchivable(BUnarchiver::PrepareArchive(archive)),
|
||||||
|
fLayouts(NULL)
|
||||||
{
|
{
|
||||||
BUnarchiver(archive).Finish(B_OK);
|
BUnarchiver(archive).Finish(B_OK);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
void
|
||||||
ActiveSetSolver::_RemoveSoftConstraint(ConstraintList& list)
|
ActiveSetSolver::_RemoveSoftConstraint(ConstraintList& list)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -77,6 +77,9 @@ public:
|
|||||||
ResultType FindMaxs(const VariableList* variables);
|
ResultType FindMaxs(const VariableList* variables);
|
||||||
ResultType FindMins(const VariableList* variables);
|
ResultType FindMins(const VariableList* variables);
|
||||||
|
|
||||||
|
void GetRangeConstraints(const Variable* var,
|
||||||
|
const Constraint** _min,
|
||||||
|
const Constraint** _max) const;
|
||||||
private:
|
private:
|
||||||
void _RemoveSoftConstraint(ConstraintList& list);
|
void _RemoveSoftConstraint(ConstraintList& list);
|
||||||
void _AddSoftConstraint(const ConstraintList& list);
|
void _AddSoftConstraint(const ConstraintList& list);
|
||||||
|
|||||||
@@ -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.
|
* Gets the constraints.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -69,8 +69,8 @@ public:
|
|||||||
fRight = xTabs[1];
|
fRight = xTabs[1];
|
||||||
|
|
||||||
layout1->AreaFor(button2)->SetContentAspectRatio(1.0f);
|
layout1->AreaFor(button2)->SetContentAspectRatio(1.0f);
|
||||||
fLayout2->Solver()->AddConstraint(-1.0f, xTabs[0], 1.0f, xTabs[1],
|
fLayout2->Solver()->AddConstraint(-1.0f, layout1->Left(), 1.0f, xTabs[0],
|
||||||
LinearProgramming::kGE, 20.0f);
|
LinearProgramming::kLE, 90.0f);
|
||||||
|
|
||||||
BButton* archiveButton = new BButton("clone", new BMessage('arcv'));
|
BButton* archiveButton = new BButton("clone", new BMessage('arcv'));
|
||||||
archiveButton->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED,
|
archiveButton->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED,
|
||||||
|
|||||||
Reference in New Issue
Block a user