diff options
author | Eduardo M. Fleury <eduardo.fleury@openbossa.org> | 2009-05-28 17:41:37 (GMT) |
---|---|---|
committer | Eduardo M. Fleury <eduardo.fleury@openbossa.org> | 2009-07-22 18:04:12 (GMT) |
commit | 35f33618ec766e4922977c31a5f522c261b19c61 (patch) | |
tree | 893236423058a733d881cd0b2e86a4122a5c6879 /src | |
parent | 4cb58c203242e6e24d1628673b145a038c93531f (diff) | |
download | Qt-35f33618ec766e4922977c31a5f522c261b19c61.zip Qt-35f33618ec766e4922977c31a5f522c261b19c61.tar.gz Qt-35f33618ec766e4922977c31a5f522c261b19c61.tar.bz2 |
QGraphicsAnchorLayout: Apply Jan-Arve's patch
Applying the patch sent by email.
Signed-off-by: Eduardo M. Fleury <eduardo.fleury@openbossa.org>
Diffstat (limited to 'src')
-rw-r--r-- | src/gui/graphicsview/qgraph_p.h | 27 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsanchorlayout.cpp | 16 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsanchorlayout.h | 9 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsanchorlayout_p.cpp | 142 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsanchorlayout_p.h | 22 |
5 files changed, 136 insertions, 80 deletions
diff --git a/src/gui/graphicsview/qgraph_p.h b/src/gui/graphicsview/qgraph_p.h index 4a6bc8f..e487eca 100644 --- a/src/gui/graphicsview/qgraph_p.h +++ b/src/gui/graphicsview/qgraph_p.h @@ -68,7 +68,8 @@ public: return iterator(this,false); } - EdgeData *edgeData(Vertex *first, Vertex *second) { + EdgeData *edgeData(Vertex* first, Vertex* second) { + Q_ASSERT(m_graph.value(first)); return m_graph.value(first)->value(second); } @@ -81,11 +82,20 @@ public: void removeEdge(Vertex *first, Vertex *second) { - // Creates a bidirectional edge + // Removes a bidirectional edge EdgeData *data = edgeData(first, second); + removeDirectedEdge(first, second); + removeDirectedEdge(second, first); if (data) delete data; + } + + EdgeData *takeEdge(Vertex* first, Vertex* second) + { + // Removes a bidirectional edge + EdgeData *data = edgeData(first, second); removeDirectedEdge(first, second); removeDirectedEdge(second, first); + return data; } QList<Vertex *> adjacentVertices(Vertex *vertex) const @@ -163,12 +173,13 @@ protected: void removeDirectedEdge(Vertex *from, Vertex *to) { QHash<Vertex *, EdgeData *> *adjacentToFirst = m_graph.value(from); - adjacentToFirst->remove(to); - if (adjacentToFirst->isEmpty()) { - //nobody point to 'from' so we can remove it from the graph - QHash<Vertex *, EdgeData *> *adjacentToFirst = m_graph.take(from); - delete adjacentToFirst; - delete from; + if (adjacentToFirst) { + adjacentToFirst->remove(to); + if (adjacentToFirst->isEmpty()) { + //nobody point to 'from' so we can remove it from the graph + m_graph.remove(from); + delete adjacentToFirst; + } } } diff --git a/src/gui/graphicsview/qgraphicsanchorlayout.cpp b/src/gui/graphicsview/qgraphicsanchorlayout.cpp index 260c823..631ce0c 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout.cpp @@ -160,6 +160,21 @@ void QGraphicsAnchorLayout::removeAnchor(QGraphicsLayoutItem *firstItem, Edge fi invalidate(); } +void QGraphicsAnchorLayout::setSpacing(qreal spacing, Qt::Orientations orientations /*= Qt::Horizontal|Qt::Vertical*/) +{ + Q_D(QGraphicsAnchorLayout); + if (orientations & Qt::Horizontal) + d->spacing[0] = spacing; + if (orientations & Qt::Vertical) + d->spacing[1] = spacing; +} + +qreal QGraphicsAnchorLayout::spacing(Qt::Orientation orientation) const +{ + Q_D(const QGraphicsAnchorLayout); + return d->spacing[orientation & Qt::Vertical]; +} + void QGraphicsAnchorLayout::setGeometry(const QRectF &geom) { Q_D(QGraphicsAnchorLayout); @@ -179,6 +194,7 @@ void QGraphicsAnchorLayout::removeAt(int index) d->removeAnchors(item); item->setParentLayoutItem(0); } + invalidate(); } int QGraphicsAnchorLayout::count() const diff --git a/src/gui/graphicsview/qgraphicsanchorlayout.h b/src/gui/graphicsview/qgraphicsanchorlayout.h index 2093b15..fb6c396 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout.h +++ b/src/gui/graphicsview/qgraphicsanchorlayout.h @@ -45,7 +45,7 @@ #include <QtGui/qgraphicsitem.h> #include <QtGui/qgraphicslayout.h> -/* + QT_BEGIN_HEADER QT_BEGIN_NAMESPACE @@ -53,7 +53,6 @@ QT_BEGIN_NAMESPACE QT_MODULE(Gui) #if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW -*/ class QGraphicsAnchorLayoutPrivate; @@ -79,6 +78,9 @@ public: void removeAnchor(QGraphicsLayoutItem *firstItem, Edge firstEdge, QGraphicsLayoutItem *secondItem, Edge secondEdge); + void setSpacing(qreal spacing, Qt::Orientations orientations = Qt::Horizontal|Qt::Vertical); + qreal spacing(Qt::Orientation) const; + void removeAt(int index); void setGeometry(const QRectF &rect); int count() const; @@ -97,12 +99,11 @@ private: Q_DECLARE_PRIVATE(QGraphicsAnchorLayout) }; -/* + #endif QT_END_NAMESPACE QT_END_HEADER -*/ #endif diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp index 6bcc1f4..1f6813f 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp @@ -73,12 +73,12 @@ QSimplexConstraint *GraphPath::constraint(const GraphPath &path) const QString GraphPath::toString() const { - QString string("Path: "); + QString string(QLatin1String("Path: ")); foreach(AnchorData *edge, positives) - string += QString(" (+++) %1").arg(edge->toString()); + string += QString::fromAscii(" (+++) %1").arg(edge->toString()); foreach(AnchorData *edge, negatives) - string += QString(" (---) %1").arg(edge->toString()); + string += QString::fromAscii(" (---) %1").arg(edge->toString()); return string; } @@ -148,8 +148,7 @@ void QGraphicsAnchorLayoutPrivate::createLayoutEdges() itemCenterConstraints[Horizontal].append(c); // Set the Layout Left edge as the root of the horizontal graph. - AnchorVertex *v; - v = m_vertexList.value(qMakePair(layout, QGraphicsAnchorLayout::Left)); + AnchorVertex *v = internalVertex(layout, QGraphicsAnchorLayout::Left); graph[Horizontal].setRootVertex(v); // Vertical @@ -169,7 +168,7 @@ void QGraphicsAnchorLayoutPrivate::createLayoutEdges() itemCenterConstraints[Vertical].append(c); // Set the Layout Top edge as the root of the vertical graph. - v = m_vertexList.value(qMakePair(layout, QGraphicsAnchorLayout::Top)); + v = internalVertex(layout, QGraphicsAnchorLayout::Top); graph[Vertical].setRootVertex(v); } @@ -232,53 +231,65 @@ void QGraphicsAnchorLayoutPrivate::addAnchor(QGraphicsLayoutItem *firstItem, QGraphicsAnchorLayout::Edge secondEdge, AnchorData *data) { - AnchorVertex *v1; - AnchorVertex *v2; - // Is the Vertex (firstItem, firstEdge) already represented in our // internal structure? - v1 = m_vertexList.value(qMakePair(firstItem, firstEdge)); - if (!v1) { - v1 = new AnchorVertex(firstItem, firstEdge); - m_vertexList.insert(qMakePair(firstItem, firstEdge), v1); - } - - // The same for the second vertex - v2 = m_vertexList.value(qMakePair(secondItem, secondEdge)); - if (!v2) { - v2 = new AnchorVertex(secondItem, secondEdge); - m_vertexList.insert(qMakePair(secondItem, secondEdge), v2); - } + AnchorVertex *v1 = addInternalVertex(firstItem, firstEdge); + AnchorVertex *v2 = addInternalVertex(secondItem, secondEdge); // 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->name = QString("%1 --to--> %2").arg(v1->toString()).arg(v2->toString()); + data->name = QString::fromAscii("%1 --to--> %2").arg(v1->toString()).arg(v2->toString()); graph[edgeOrientation(firstEdge)].createEdge(v1, v2, data); } +AnchorVertex *QGraphicsAnchorLayoutPrivate::addInternalVertex(QGraphicsLayoutItem *item, + QGraphicsAnchorLayout::Edge edge) +{ + QPair<QGraphicsLayoutItem *, QGraphicsAnchorLayout::Edge> pair(item, edge); + QPair<AnchorVertex *, int> v = m_vertexList.value(pair); + if (!v.first) { + Q_ASSERT(v.second == 0); + v.first = new AnchorVertex(item, edge); + m_vertexList.insert(pair, v); + } + v.second++; + return v.first; +} + +/** + * \internal + * + * returns the AnchorVertex that was dereferenced, also when it was removed. + * returns 0 if it did not exist. + */ +AnchorVertex *QGraphicsAnchorLayoutPrivate::removeInternalVertex(QGraphicsLayoutItem *item, + QGraphicsAnchorLayout::Edge edge) +{ + QPair<QGraphicsLayoutItem *, QGraphicsAnchorLayout::Edge> pair(item, edge); + QPair<AnchorVertex *, int> v = m_vertexList.value(pair); + if (v.first) { + v.second--; + if (v.second == 0) { + m_vertexList.remove(pair); + } + } else { + qWarning("This item with this edge is not in the graph"); + } + return v.first; +} + void QGraphicsAnchorLayoutPrivate::removeAnchor(QGraphicsLayoutItem *firstItem, QGraphicsAnchorLayout::Edge firstEdge, QGraphicsLayoutItem *secondItem, QGraphicsAnchorLayout::Edge secondEdge) { - AnchorVertex *v1 = 0; - AnchorVertex *v2 = 0; - // Is there a representation for the Vertex (firstItem, firstEdge) // in our internal structure? - if ((v1 = m_vertexList.value(qMakePair(firstItem,firstEdge)))) - m_vertexList.remove(qMakePair(firstItem,firstEdge)); - else - qWarning()<<"This item with this edge is not in the graph"; - - // The same for the second vertex - if ((v2 = m_vertexList.value(qMakePair(secondItem,secondEdge)))) - m_vertexList.remove(qMakePair(secondItem,secondEdge)); - else - qWarning()<<"This item with this edge is not in the graph"; + AnchorVertex *v1 = removeInternalVertex(firstItem, firstEdge); + AnchorVertex *v2 = removeInternalVertex(secondItem, secondEdge); if (v1 && v2) { graph[edgeOrientation(firstEdge)].removeEdge(v1, v2); @@ -292,18 +303,26 @@ void QGraphicsAnchorLayoutPrivate::removeAnchors(QGraphicsLayoutItem *item) QList<AnchorVertex *> allVertex; int edge; - for (edge = QGraphicsAnchorLayout::Left; edge != QGraphicsAnchorLayout::Bottom; ++edge) { + for (edge = QGraphicsAnchorLayout::Left; edge <= QGraphicsAnchorLayout::Bottom; ++edge) { // Remove all vertex for all edges QGraphicsAnchorLayout::Edge e = static_cast<QGraphicsAnchorLayout::Edge>(edge); - if ((v1 = m_vertexList.value(qMakePair(item, e)))) { - m_vertexList.remove(qMakePair(item, e)); - + if ((v1 = removeInternalVertex(item, e))) { // Remove all edges allVertex = graph[edgeOrientation(e)].adjacentVertices(v1); - foreach (v2, allVertex) - graph[edgeOrientation(e)].removeEdge(v1, v2); + QList<QSimplexConstraint *> constraints = itemCenterConstraints[edgeOrientation(e)]; + foreach (v2, allVertex) { + AnchorData *data = graph[edgeOrientation(e)].takeEdge(v1, v2); + Q_ASSERT(data); + for (int i = 0; i < constraints.count(); ++i) { + QSimplexConstraint *c = constraints.at(i); + c->variables.remove(data); + } + delete data; + } + qDebug("removing anchor: %s", qPrintable(v1->toString())); + delete v1; } } } @@ -467,8 +486,7 @@ void QGraphicsAnchorLayoutPrivate::calculateGraphs( } else { end = QGraphicsAnchorLayout::Bottom; } - AnchorVertex *v = - m_vertexList.value(qMakePair(static_cast<QGraphicsLayoutItem *>(q), end)); + AnchorVertex *v = internalVertex(q, end); GraphPath trunkPath = graphPaths[orientation].value(v); // Solve min and max size hints for trunk @@ -509,7 +527,8 @@ void QGraphicsAnchorLayoutPrivate::calculateGraphs( // 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 = static_cast<AnchorData *>(partVariables[j]); + AnchorData *ad = partVariables[j]; + Q_ASSERT(ad); ad->sizeAtMinimum = ad->sizeAtPreferred; ad->sizeAtMaximum = ad->sizeAtPreferred; } @@ -546,9 +565,9 @@ void QGraphicsAnchorLayoutPrivate::setAnchorSizeHintsFromItems(Orientation orien centerKey.first = item; endKey.first = item; - beginning = m_vertexList.value(beginningKey); - center = m_vertexList.value(centerKey); - end = m_vertexList.value(endKey); + beginning = internalVertex(beginningKey); + center = internalVertex(centerKey); + end = internalVertex(endKey); if (orientation == Horizontal) { min = item->minimumWidth(); @@ -690,19 +709,16 @@ QGraphicsAnchorLayoutPrivate::getGraphParts(Orientation orientation) // Find layout vertices and edges for the current orientation. AnchorVertex *layoutFirstVertex = - m_vertexList.value(qMakePair(static_cast<QGraphicsLayoutItem *>(q), - orientation == Horizontal ? - QGraphicsAnchorLayout::Left :QGraphicsAnchorLayout::Top)); + internalVertex(q, orientation == Horizontal ? + QGraphicsAnchorLayout::Left : QGraphicsAnchorLayout::Top); AnchorVertex *layoutCentralVertex = - m_vertexList.value(qMakePair(static_cast<QGraphicsLayoutItem *>(q), - orientation == Horizontal ? - QGraphicsAnchorLayout::HCenter : QGraphicsAnchorLayout::VCenter)); + internalVertex(q, orientation == Horizontal ? + QGraphicsAnchorLayout::HCenter : QGraphicsAnchorLayout::VCenter); AnchorVertex *layoutLastVertex = - m_vertexList.value(qMakePair(static_cast<QGraphicsLayoutItem *>(q), - orientation == Horizontal ? - QGraphicsAnchorLayout::Right : QGraphicsAnchorLayout::Bottom)); + internalVertex(q, orientation == Horizontal ? + QGraphicsAnchorLayout::Right : QGraphicsAnchorLayout::Bottom); AnchorData *edgeL1 = graph[orientation].edgeData(layoutFirstVertex, layoutCentralVertex); AnchorData *edgeL2 = graph[orientation].edgeData(layoutCentralVertex, layoutLastVertex); @@ -779,14 +795,10 @@ void QGraphicsAnchorLayoutPrivate::setItemsGeometries() AnchorVertex *firstH, *secondH, *firstV, *secondV; foreach (QGraphicsLayoutItem *item, items) { - firstH = - m_vertexList.value(qMakePair(item, QGraphicsAnchorLayout::Left)); - secondH = - m_vertexList.value(qMakePair(item, QGraphicsAnchorLayout::Right)); - firstV = - m_vertexList.value(qMakePair(item, QGraphicsAnchorLayout::Top)); - secondV = - m_vertexList.value(qMakePair(item, QGraphicsAnchorLayout::Bottom)); + firstH = internalVertex(item, QGraphicsAnchorLayout::Left); + secondH = internalVertex(item, QGraphicsAnchorLayout::Right); + firstV = internalVertex(item, QGraphicsAnchorLayout::Top); + secondV = internalVertex(item, QGraphicsAnchorLayout::Bottom); QPointF topLeft(firstH->distance, firstV->distance); QPointF bottomRight(secondH->distance, secondV->distance); @@ -1057,7 +1069,7 @@ void QGraphicsAnchorLayoutPrivate::solvePreferred(QList<QSimplexConstraint *> co simplex.setObjective(&objective); // Calculate minimum values - qreal min = simplex.solveMin(); + simplex.solveMin(); // Save sizeAtPreferred results for (int i = 0; i < variables.size(); ++i) { diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.h b/src/gui/graphicsview/qgraphicsanchorlayout_p.h index 89d3bfc..ee1a181 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.h +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.h @@ -161,7 +161,7 @@ struct AnchorData : public QSimplexVariable { inline QString AnchorData::toString() const { - return QString("Anchor(%1)").arg(name); + return QString::fromAscii("Anchor(%1)").arg(name); //return QString().sprintf("Anchor %%1 <Min %.1f Pref %.1f Max %.1f>", // minSize, prefSize, maxSize).arg(name); } @@ -218,7 +218,8 @@ public: // Orientation is used to reference the right structure in each context enum Orientation { Horizontal = 0, - Vertical + Vertical, + NOrientations }; QGraphicsAnchorLayoutPrivate(); @@ -264,6 +265,19 @@ public: void constraintsFromPaths(Orientation orientation); QList<QList<QSimplexConstraint *> > getGraphParts(Orientation orientation); + inline AnchorVertex *internalVertex(const QPair<QGraphicsLayoutItem*, QGraphicsAnchorLayout::Edge> &itemEdge) + { + return m_vertexList.value(itemEdge).first; + } + + inline AnchorVertex *internalVertex(QGraphicsLayoutItem *item, QGraphicsAnchorLayout::Edge edge) + { + return internalVertex(qMakePair(item, edge)); + } + + AnchorVertex *addInternalVertex(QGraphicsLayoutItem *item, QGraphicsAnchorLayout::Edge edge); + AnchorVertex *removeInternalVertex(QGraphicsLayoutItem *item, QGraphicsAnchorLayout::Edge edge); + // Geometry interpolation methods void setItemsGeometries(); void calculateVertexPositions(Orientation orientation); @@ -275,6 +289,7 @@ public: GraphPath path); void solvePreferred(QList<QSimplexConstraint *> constraints); + qreal spacing[NOrientations]; // Size hints from simplex engine qreal sizeHints[2][3]; @@ -283,7 +298,8 @@ public: // Mapping between high level anchorage points (Item, Edge) to low level // ones (Graph Vertices) - QHash<QPair<QGraphicsLayoutItem*, QGraphicsAnchorLayout::Edge>, AnchorVertex *> m_vertexList; + + QHash<QPair<QGraphicsLayoutItem*, QGraphicsAnchorLayout::Edge>, QPair<AnchorVertex *, int> > m_vertexList; // Internal graph of anchorage points and anchors, for both orientations Graph<AnchorVertex, AnchorData> graph[2]; |