summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCaio Marcelo de Oliveira Filho <caio.oliveira@openbossa.org>2009-10-08 23:09:21 (GMT)
committerEduardo M. Fleury <eduardo.fleury@openbossa.org>2009-10-15 14:37:52 (GMT)
commitaff8e7a24e5e8cc1f330a1b3c2947ba4d07d51ed (patch)
tree654d537eed396121ea15c28f47430fd6758d985d
parente7e67b26fcd6c53dd822b1ae36074d418d432b4a (diff)
downloadQt-aff8e7a24e5e8cc1f330a1b3c2947ba4d07d51ed.zip
Qt-aff8e7a24e5e8cc1f330a1b3c2947ba4d07d51ed.tar.gz
Qt-aff8e7a24e5e8cc1f330a1b3c2947ba4d07d51ed.tar.bz2
QGAL: refactor calculateGraphs() method
Create calculateTrunk() and calculateNonTrunk() methods, that calculate sizes for anchors in different parts of the simplified graph (using simplex when needed). Also fixes a minor leak when the nontrunk part is non-feasible. The old code left the loop leaving the contents of 'sizeHintConstraints' not allocated. Signed-off-by: Caio Marcelo de Oliveira Filho <caio.oliveira@openbossa.org> Reviewed-by: Artur Duque de Souza <artur.souza@openbossa.org>
-rw-r--r--src/gui/graphicsview/qgraphicsanchorlayout_p.cpp161
-rw-r--r--src/gui/graphicsview/qgraphicsanchorlayout_p.h7
2 files changed, 93 insertions, 75 deletions
diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp
index 260e8dc..c9821ae 100644
--- a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp
+++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp
@@ -1600,7 +1600,8 @@ void QGraphicsAnchorLayoutPrivate::calculateGraphs()
calculateGraphCacheDirty = 0;
}
-// ### remove me:
+// ### Maybe getGraphParts could return the variables when traversing, at least
+// for trunk...
QList<AnchorData *> getVariables(QList<QSimplexConstraint *> constraints)
{
QSet<AnchorData *> variableSet;
@@ -1664,8 +1665,7 @@ void QGraphicsAnchorLayoutPrivate::calculateGraphs(
// 2) The floating or semi-floating anchors (items) that are those which
// are connected to only one (or none) of the layout sides, thus are not
// influenced by the layout size.
- QList<QList<QSimplexConstraint *> > parts;
- parts = getGraphParts(orientation);
+ QList<QList<QSimplexConstraint *> > parts = getGraphParts(orientation);
// Now run the simplex solver to calculate Minimum, Preferred and Maximum sizes
// of the "trunk" set of constraints and variables.
@@ -1675,49 +1675,82 @@ void QGraphicsAnchorLayoutPrivate::calculateGraphs(
// For minimum and maximum, use the path between the two layout sides as the
// objective function.
-
- // Retrieve that path
AnchorVertex *v = internalVertex(q, pickEdge(Qt::AnchorRight, orientation));
GraphPath trunkPath = graphPaths[orientation].value(v);
+ bool feasible = calculateTrunk(orientation, trunkPath, trunkConstraints, trunkVariables);
+
+ // For the other parts that not the trunk, solve only for the preferred size
+ // that is the size they will remain at, since they are not stretched by the
+ // layout.
+
+ // Skipping the first (trunk)
+ for (int i = 1; i < parts.count(); ++i) {
+ if (!feasible)
+ break;
+
+ QList<QSimplexConstraint *> partConstraints = parts[i];
+ QList<AnchorData *> partVariables = getVariables(partConstraints);
+ Q_ASSERT(!partVariables.isEmpty());
+ feasible &= calculateNonTrunk(partConstraints, partVariables);
+ }
+
+ // Propagate the new sizes down the simplified graph, ie. tell the
+ // group anchors to set their children anchors sizes.
+ updateAnchorSizes(orientation);
+
+ graphHasConflicts[orientation] = !feasible;
+
+ // Clean up our data structures. They are not needed anymore since
+ // distribution uses just interpolation.
+ qDeleteAll(constraints[orientation]);
+ constraints[orientation].clear();
+ graphPaths[orientation].clear(); // ###
+}
+
+/*!
+ \internal
+
+ Calculate the sizes for all anchors which are part of the trunk. This works
+ on top of a (possibly) simplified graph.
+*/
+bool QGraphicsAnchorLayoutPrivate::calculateTrunk(Orientation orientation, const GraphPath &path,
+ const QList<QSimplexConstraint *> &constraints,
+ const QList<AnchorData *> &variables)
+{
bool feasible = true;
- if (!trunkConstraints.isEmpty()) {
-#if 0
- qDebug("Simplex used for trunk of %s",
- orientation == Horizontal ? "Horizontal" : "Vertical");
-#endif
+ bool needsSimplex = !constraints.isEmpty();
-#ifdef QT_DEBUG
- lastCalculationUsedSimplex[orientation] = true;
+#if 0
+ qDebug("Simplex %s for trunk of %s", needsSimplex ? "used" : "NOT used",
+ orientation == Horizontal ? "Horizontal" : "Vertical");
#endif
- // Solve min and max size hints for trunk
- qreal min, max;
+ if (needsSimplex) {
- QList<QSimplexConstraint *> sizeHintConstraints = constraintsFromSizeHints(trunkVariables);
- QList<QSimplexConstraint *> allTrunkConstraints = trunkConstraints + sizeHintConstraints;
+ QList<QSimplexConstraint *> sizeHintConstraints = constraintsFromSizeHints(variables);
+ QList<QSimplexConstraint *> allConstraints = constraints + sizeHintConstraints;
- feasible = solveMinMax(allTrunkConstraints, trunkPath, &min, &max);
+ // Solve min and max size hints
+ qreal min, max;
+ feasible = solveMinMax(allConstraints, path, &min, &max);
if (feasible) {
- // Solve for preferred. The objective function is calculated from the constraints
- // and variables internally.
- solvePreferred(allTrunkConstraints, trunkVariables);
+ solvePreferred(allConstraints, variables);
- // Solve for expanding. The objective function and the constraints from items
- // are calculated internally. Note that we don't include the sizeHintConstraints, since
- // they have a different logic for solveExpanding().
- solveExpanding(trunkConstraints, trunkVariables);
+ // Note that we don't include the sizeHintConstraints, since they
+ // have a different logic for solveExpanding().
+ solveExpanding(constraints, variables);
// Calculate and set the preferred and expanding sizes for the layout,
// from the edge sizes that were calculated above.
qreal pref(0.0);
qreal expanding(0.0);
- foreach (const AnchorData *ad, trunkPath.positives) {
+ foreach (const AnchorData *ad, path.positives) {
pref += ad->sizeAtPreferred;
expanding += ad->sizeAtExpanding;
}
- foreach (const AnchorData *ad, trunkPath.negatives) {
+ foreach (const AnchorData *ad, path.negatives) {
pref -= ad->sizeAtPreferred;
expanding -= ad->sizeAtExpanding;
}
@@ -1731,21 +1764,12 @@ void QGraphicsAnchorLayoutPrivate::calculateGraphs(
qDeleteAll(sizeHintConstraints);
} else {
-#if 0
- qDebug("Simplex NOT used for trunk of %s",
- orientation == Horizontal ? "Horizontal" : "Vertical");
-#endif
-
-#ifdef QT_DEBUG
- lastCalculationUsedSimplex[orientation] = false;
-#endif
-
// No Simplex is necessary because the path was simplified all the way to a single
// anchor.
- Q_ASSERT(trunkPath.positives.count() == 1);
- Q_ASSERT(trunkPath.negatives.count() == 0);
+ Q_ASSERT(path.positives.count() == 1);
+ Q_ASSERT(path.negatives.count() == 0);
- AnchorData *ad = trunkPath.positives.toList()[0];
+ AnchorData *ad = path.positives.toList()[0];
ad->sizeAtMinimum = ad->minSize;
ad->sizeAtPreferred = ad->prefSize;
ad->sizeAtExpanding = ad->expSize;
@@ -1757,49 +1781,36 @@ void QGraphicsAnchorLayoutPrivate::calculateGraphs(
sizeAtExpanding[orientation] = ad->sizeAtExpanding;
}
- // For the other parts that not the trunk, solve only for the preferred size
- // that is the size they will remain at, since they are not stretched by the
- // layout.
+#ifdef QT_DEBUG
+ lastCalculationUsedSimplex[orientation] = needsSimplex;
+#endif
- // Solve the other only for preferred, skip trunk
- if (feasible) {
- for (int i = 1; i < parts.count(); ++i) {
- QList<QSimplexConstraint *> partConstraints = parts[i];
- QList<AnchorData *> partVariables = getVariables(partConstraints);
- Q_ASSERT(!partVariables.isEmpty());
-
- QList<QSimplexConstraint *> sizeHintConstraints = constraintsFromSizeHints(partVariables);
- partConstraints += sizeHintConstraints;
- feasible &= solvePreferred(partConstraints, partVariables);
- if (!feasible)
- break;
+ return feasible;
+}
- // Propagate size at preferred to other sizes. Semi-floats
- // always will be in their sizeAtPreferred.
- for (int j = 0; j < partVariables.count(); ++j) {
- AnchorData *ad = partVariables[j];
- Q_ASSERT(ad);
- ad->sizeAtMinimum = ad->sizeAtPreferred;
- ad->sizeAtExpanding = ad->sizeAtPreferred;
- ad->sizeAtMaximum = ad->sizeAtPreferred;
- }
+/*!
+ \internal
+*/
+bool QGraphicsAnchorLayoutPrivate::calculateNonTrunk(const QList<QSimplexConstraint *> &constraints,
+ const QList<AnchorData *> &variables)
+{
+ QList<QSimplexConstraint *> sizeHintConstraints = constraintsFromSizeHints(variables);
+ bool feasible = solvePreferred(constraints + sizeHintConstraints, variables);
- // Delete the constraints, we won't use them anymore.
- qDeleteAll(sizeHintConstraints);
+ if (feasible) {
+ // Propagate size at preferred to other sizes. Semi-floats always will be
+ // in their sizeAtPreferred.
+ for (int j = 0; j < variables.count(); ++j) {
+ AnchorData *ad = variables[j];
+ Q_ASSERT(ad);
+ ad->sizeAtMinimum = ad->sizeAtPreferred;
+ ad->sizeAtExpanding = ad->sizeAtPreferred;
+ ad->sizeAtMaximum = ad->sizeAtPreferred;
}
}
- // Propagate the new sizes down the simplified graph, ie. tell the
- // group anchors to set their children anchors sizes.
- updateAnchorSizes(orientation);
-
- graphHasConflicts[orientation] = !feasible;
-
- // Clean up our data structures. They are not needed anymore since
- // distribution uses just interpolation.
- qDeleteAll(constraints[orientation]);
- constraints[orientation].clear();
- graphPaths[orientation].clear(); // ###
+ qDeleteAll(sizeHintConstraints);
+ return feasible;
}
/*!
diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.h b/src/gui/graphicsview/qgraphicsanchorlayout_p.h
index e045fbd..d96a035 100644
--- a/src/gui/graphicsview/qgraphicsanchorlayout_p.h
+++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.h
@@ -438,6 +438,13 @@ public:
void calculateGraphs();
void calculateGraphs(Orientation orientation);
+
+ bool calculateTrunk(Orientation orientation, const GraphPath &trunkPath,
+ const QList<QSimplexConstraint *> &constraints,
+ const QList<AnchorData *> &variables);
+ bool calculateNonTrunk(const QList<QSimplexConstraint *> &constraints,
+ const QList<AnchorData *> &variables);
+
void setAnchorSizeHintsFromItems(Orientation orientation);
void findPaths(Orientation orientation);
void constraintsFromPaths(Orientation orientation);