From 6bd756353d1be7eadcf56f9c8415283d0d1c4cc3 Mon Sep 17 00:00:00 2001 From: Caio Marcelo de Oliveira Filho Date: Fri, 14 Aug 2009 16:02:36 -0300 Subject: QGraphicsAnchorLayout: add both vertex information in anchor data Make AnchorData aware of both vertices instead only one (the origin). This information is useful for many functions when working in simplified mode. Changed the name "origin" to "from", and add an "to" field. Also change setAnchorSizeHintsFromItems() and its helpers to make use of this information. In a later commit we will rollback to using recursion for initializing the size hint information. Signed-off-by: Caio Marcelo de Oliveira Filho Reviewed-by: Artur Duque de Souza --- src/gui/graphicsview/qgraph_p.h | 2 +- src/gui/graphicsview/qgraphicsanchorlayout_p.cpp | 64 ++++++++++++------------ src/gui/graphicsview/qgraphicsanchorlayout_p.h | 23 ++++++--- 3 files changed, 48 insertions(+), 41 deletions(-) diff --git a/src/gui/graphicsview/qgraph_p.h b/src/gui/graphicsview/qgraph_p.h index 2666623..6cb843f 100644 --- a/src/gui/graphicsview/qgraph_p.h +++ b/src/gui/graphicsview/qgraph_p.h @@ -180,7 +180,7 @@ public: for (int i = 0; i < adjacents.count(); ++i) { Vertex *v1 = adjacents.at(i); EdgeData *data = edgeData(v, v1); - bool forward = data->origin == v; + bool forward = data->from == v; if (forward) { edges += QString::fromAscii("%1->%2 [label=\"[%3,%4,%5]\" dir=both color=\"#000000:#a0a0a0\"] \n") .arg(v->toString()) diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp index 9989e83..62e94a2 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp @@ -225,7 +225,16 @@ static bool simplifySequentialChunk(Graph *graph, sequence->sizeAtMaximum = pref; sequence->setVertices(vertices); - sequence->origin = data->origin == vertices.last() ? before : after; + + sequence->from = before; + sequence->to = after; + + // data here is the last edge in the sequence + // ### this seems to be here for supporting reverse order sequences, + // but doesnt seem to be used right now + if (data->from != vertices.last()) + qSwap(sequence->from, sequence->to); + AnchorData *newAnchor = sequence; if (AnchorData *oldAnchor = graph->takeEdge(before, after)) { newAnchor = new ParallelAnchorData(oldAnchor, sequence); @@ -362,7 +371,7 @@ bool QGraphicsAnchorLayoutPrivate::simplifyGraphIteration(QGraphicsAnchorLayoutP AnchorVertex *prev = beforeSequence; int intervalFrom = 0; - // Check for directionality (origin). We don't want to destroy that information, + // Check for directionality (from). We don't want to destroy that information, // thus we only combine anchors with the same direction. // "i" is the index *including* the beforeSequence and afterSequence vertices. @@ -372,10 +381,10 @@ bool QGraphicsAnchorLayoutPrivate::simplifyGraphIteration(QGraphicsAnchorLayoutP AnchorData *data = g.edgeData(prev, v1); Q_ASSERT(data); if (i == 1) { - forward = (prev == data->origin ? true : false); - } else if (forward != (prev == data->origin) || atVertexAfter) { + forward = (prev == data->from ? true : false); + } else if (forward != (prev == data->from) || atVertexAfter) { int intervalTo = i; - if (forward != (prev == data->origin)) + if (forward != (prev == data->from)) --intervalTo; // intervalFrom and intervalTo should now be indices to the vertex before and @@ -416,7 +425,7 @@ bool QGraphicsAnchorLayoutPrivate::simplifyGraphIteration(QGraphicsAnchorLayoutP } // finished simplification of chunk with same direction } - if (forward == (prev == data->origin)) + if (forward == (prev == data->from)) --intervalTo; intervalFrom = intervalTo; @@ -464,7 +473,7 @@ static void restoreSimplifiedAnchor(Graph &g, // restore the sequential anchor AnchorVertex *prev = before; AnchorVertex *last = after; - if (edge->origin != prev) + if (edge->from != prev) qSwap(last, prev); for (int i = 0; i < seqEdge->m_edges.count(); ++i) { @@ -894,7 +903,8 @@ void QGraphicsAnchorLayoutPrivate::addAnchor(QGraphicsLayoutItem *firstItem, // Create a bi-directional edge in the sense it can be transversed both // from v1 or v2. "data" however is shared between the two references // so we still know that the anchor direction is from 1 to 2. - data->origin = v1; + data->from = v1; + data->to = v2; data->name = QString::fromAscii("%1 --to--> %2").arg(v1->toString()).arg(v2->toString()); graph[edgeOrientation(firstEdge)].createEdge(v1, v2, data); @@ -1272,9 +1282,8 @@ void QGraphicsAnchorLayoutPrivate::calculateGraphs( graphPaths[orientation].clear(); // ### } -// ### -static QPair >, QList > -getAnchorsDependenciesFirst(Graph &g) +// ### REMOVE ME: call recursion using children methods before +static QList getAnchorsDependenciesFirst(Graph &g) { QList > conns(g.connections()); @@ -1290,14 +1299,12 @@ getAnchorsDependenciesFirst(Graph &g) anchors.push(data); } - QList > allVertices; QList allAnchors; // Build list of all edges while (!vertices.isEmpty()) { QPair vertexPair = vertices.pop(); AnchorData *data = anchors.pop(); - allVertices.prepend(vertexPair); allAnchors.prepend(data); if (data->type == AnchorData::Parallel) { @@ -1305,15 +1312,11 @@ getAnchorsDependenciesFirst(Graph &g) // Prepend dependencies so they are before the parent anchor in // the result list - allVertices.prepend(vertexPair); allAnchors.prepend(p->firstEdge); - allVertices.prepend(vertexPair); allAnchors.prepend(p->secondEdge); // Push dependencies so they are 'recursively' processed - vertices.push(vertexPair); anchors.push(p->firstEdge); - vertices.push(vertexPair); anchors.push(p->secondEdge); } else if (data->type == AnchorData::Sequential) { @@ -1322,7 +1325,7 @@ getAnchorsDependenciesFirst(Graph &g) AnchorVertex *prev = vertexPair.first; AnchorVertex *last = vertexPair.second; - if (s->origin != prev) + if (s->from != prev) qSwap(last, prev); for (int i = 0; i < s->m_edges.count(); ++i) { @@ -1331,11 +1334,9 @@ getAnchorsDependenciesFirst(Graph &g) QPair pair(prev, v1); // Prepend dependencies in result list - allVertices.prepend(pair); allAnchors.prepend(data); // Push dependencies in the stack so they are processed - vertices.push(pair); anchors.push(data); prev = v1; @@ -1343,7 +1344,7 @@ getAnchorsDependenciesFirst(Graph &g) } } - return qMakePair(allVertices, allAnchors); + return allAnchors; } static void setInternalAnchorSizeHint(AnchorVertex *from, AnchorVertex *to, @@ -1420,19 +1421,16 @@ void QGraphicsAnchorLayoutPrivate::setAnchorSizeHintsFromItems(Orientation orien // order of dependency, so an item dependencies appear before the // item. Then we traverse the list filling the size hint information. // - // This two stage is necessary because the leaves themselves (AnchorData) - // doesn't have access to the pair of Anchor Vertices that they represent. + // ### use recursion instead - QPair >, QList > all; - all = getAnchorsDependenciesFirst(g); - - QList > allVertices = all.first; - QList allAnchors = all.second; + QList allAnchors = getAnchorsDependenciesFirst(g); for (int i = 0; i < allAnchors.size(); ++i) { - AnchorVertex *from = allVertices.at(i).first; - AnchorVertex *to = allVertices.at(i).second; AnchorData *data = allAnchors.at(i); + AnchorVertex *from = data->from; + AnchorVertex *to = data->to; + + Q_ASSERT(from && to); // Internal anchor that is not the layout if (from->m_item != q && from->m_item == to->m_item) { @@ -1530,7 +1528,7 @@ void QGraphicsAnchorLayoutPrivate::findPaths(Orientation orientation) visited.insert(edge); GraphPath current = graphPaths[orientation].value(pair.first); - if (edge->origin == pair.first) + if (edge->from == pair.first) current.positives.insert(edge); else current.negatives.insert(edge); @@ -1774,7 +1772,7 @@ void QGraphicsAnchorLayoutPrivate::calculateVertexPositions( qreal distance; AnchorData *edge = graph[orientation].edgeData(pair.first, pair.second); - if (edge->origin == pair.first) { + if (edge->from == pair.first) { distance = pair.first->distance + interpolateEdge(edge); } else { distance = pair.first->distance - interpolateEdge(edge); @@ -1841,7 +1839,7 @@ qreal QGraphicsAnchorLayoutPrivate::interpolateEdge(AnchorData *edge) { qreal lower, upper; - Orientation orientation = edgeOrientation(edge->origin->m_edge); + Orientation orientation = edgeOrientation(edge->from->m_edge); if (interpolationInterval[orientation] == MinToPreferred) { lower = edge->sizeAtMinimum; diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.h b/src/gui/graphicsview/qgraphicsanchorlayout_p.h index 3951910..eb1f8f6 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.h +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.h @@ -130,18 +130,21 @@ struct AnchorData : public QSimplexVariable { Parallel }; AnchorData(qreal minimumSize, qreal preferredSize, qreal maximumSize) - : QSimplexVariable(), minSize(minimumSize), prefSize(preferredSize), + : QSimplexVariable(), from(0), to(0), + minSize(minimumSize), prefSize(preferredSize), maxSize(maximumSize), sizeAtMinimum(preferredSize), sizeAtPreferred(preferredSize), sizeAtMaximum(preferredSize), skipInPreferred(0), type(Normal), hasSize(true) {} AnchorData(qreal size) - : QSimplexVariable(), minSize(size), prefSize(size), maxSize(size), + : QSimplexVariable(), from(0), to(0), + minSize(size), prefSize(size), maxSize(size), sizeAtMinimum(size), sizeAtPreferred(size), sizeAtMaximum(size), skipInPreferred(0), type(Normal), hasSize(true) {} AnchorData() - : QSimplexVariable(), minSize(0), prefSize(0), maxSize(0), + : QSimplexVariable(), from(0), to(0), + minSize(0), prefSize(0), maxSize(0), sizeAtMinimum(0), sizeAtPreferred(0), sizeAtMaximum(0), skipInPreferred(0), type(Normal), hasSize(false) {} @@ -153,7 +156,8 @@ struct AnchorData : public QSimplexVariable { QString name; // Anchor is semantically directed - AnchorVertex *origin; + AnchorVertex *from; + AnchorVertex *to; // Size restrictions of this edge. For anchors internal to items, these // values are derived from the respective item size hints. For anchors @@ -175,7 +179,8 @@ struct AnchorData : public QSimplexVariable { uint hasSize : 1; // if false, get size from style. protected: AnchorData(Type type, qreal size = 0) - : QSimplexVariable(), minSize(size), prefSize(size), + : QSimplexVariable(), from(0), to(0), + minSize(size), prefSize(size), maxSize(size), sizeAtMinimum(size), sizeAtPreferred(size), sizeAtMaximum(size), skipInPreferred(0), type(type), hasSize(true) {} @@ -214,8 +219,12 @@ struct ParallelAnchorData : public AnchorData : AnchorData(AnchorData::Parallel), firstEdge(first), secondEdge(second) { - Q_ASSERT(first->origin == second->origin); - origin = first->origin; + // ### Those asserts force that both child anchors have the same direction, + // but can't we simplify a pair of anchors in opposite directions? + Q_ASSERT(first->from == second->from); + Q_ASSERT(first->to == second->to); + from = first->from; + to = first->to; name = QString::fromAscii("%1 | %2").arg(first->toString(), second->toString()); } -- cgit v0.12