From 8014408e95b920b98214040a340f68750f38a53b Mon Sep 17 00:00:00 2001 From: Caio Marcelo de Oliveira Filho Date: Thu, 13 Aug 2009 18:04:50 -0300 Subject: QGraphicsAnchorLayout: implement "deep" simplification Re-start the simplification procedure every time there's a change it the adjacent count of a vertex -- which happens when a new parallel anchor is created. The original algorithm stopped some simplifications too early, demanding the simplex unnecessarily. Signed-off-by: Caio Marcelo de Oliveira Filho Reviewed-by: Artur Duque de Souza --- src/gui/graphicsview/qgraphicsanchorlayout_p.cpp | 39 ++++++++++++++++++++---- src/gui/graphicsview/qgraphicsanchorlayout_p.h | 2 ++ 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp index 09fe1b9..73fc025 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp @@ -218,7 +218,7 @@ inline static qreal checkAdd(qreal a, qreal b) * anchors between \a before and \a after, and can be restored back to the anchors it is a * placeholder for. */ -static void simplifySequentialChunk(Graph *graph, +static bool simplifySequentialChunk(Graph *graph, AnchorVertex *before, const QVector &vertices, AnchorVertex *after) @@ -281,6 +281,23 @@ static void simplifySequentialChunk(Graph *graph, newAnchor->sizeAtMaximum = pref; } graph->createEdge(before, after, newAnchor); + + // True if we created a parallel anchor + return newAnchor != sequence; +} + +void QGraphicsAnchorLayoutPrivate::simplifyGraph(Orientation orientation) +{ + AnchorVertex *rootVertex = graph[orientation].rootVertex(); + + if (!rootVertex) + return; + + bool dirty; + int count = 0; + do { + dirty = simplifyGraphIteration(orientation); + } while (dirty); } /*! @@ -312,15 +329,13 @@ static void simplifySequentialChunk(Graph *graph, * sequence. This is ok, but that sequence should not be affected by stretch factors. * */ -void QGraphicsAnchorLayoutPrivate::simplifyGraph(QGraphicsAnchorLayoutPrivate::Orientation orientation) +bool QGraphicsAnchorLayoutPrivate::simplifyGraphIteration(QGraphicsAnchorLayoutPrivate::Orientation orientation) { Q_Q(QGraphicsAnchorLayout); Graph &g = graph[orientation]; AnchorVertex *v = g.rootVertex(); - if (!v) - return; - QSet visited; + QSet visited; QStack stack; stack.push(v); QVector candidates; @@ -328,6 +343,8 @@ void QGraphicsAnchorLayoutPrivate::simplifyGraph(QGraphicsAnchorLayoutPrivate::O const QGraphicsAnchorLayout::Edge centerEdge = pickEdge(QGraphicsAnchorLayout::HCenter, orientation); const QGraphicsAnchorLayout::Edge layoutEdge = oppositeEdge(v->m_edge); + bool dirty = false; + // walk depth-first. while (!stack.isEmpty()) { v = stack.pop(); @@ -422,7 +439,10 @@ void QGraphicsAnchorLayoutPrivate::simplifyGraph(QGraphicsAnchorLayoutPrivate::O subCandidates.prepend(candidates.at(intervalFrom - 1)); } while (intervalFrom < intervalTo - 1); } - simplifySequentialChunk(&g, intervalVertexFrom, subCandidates, intervalVertexTo); + if (simplifySequentialChunk(&g, intervalVertexFrom, subCandidates, intervalVertexTo)) { + dirty = true; + break; + } // finished simplification of chunk with same direction } if (forward == (prev == data->origin)) @@ -433,7 +453,11 @@ void QGraphicsAnchorLayoutPrivate::simplifyGraph(QGraphicsAnchorLayoutPrivate::O } prev = v1; } + + if (dirty) + break; } + if (endOfSequence) candidates.clear(); @@ -445,8 +469,11 @@ void QGraphicsAnchorLayoutPrivate::simplifyGraph(QGraphicsAnchorLayoutPrivate::O continue; stack.push(next); } + visited.insert(v); } + + return dirty; } static void restoreSimplifiedAnchor(Graph &g, diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.h b/src/gui/graphicsview/qgraphicsanchorlayout_p.h index fa79f6b..af58065 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.h +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.h @@ -343,7 +343,9 @@ public: // Activation methods void simplifyGraph(Orientation orientation); + bool simplifyGraphIteration(Orientation orientation); void restoreSimplifiedGraph(Orientation orientation); + void calculateGraphs(); void calculateGraphs(Orientation orientation); void setAnchorSizeHintsFromItems(Orientation orientation); -- cgit v0.12