summaryrefslogtreecommitdiffstats
path: root/src/gui/graphicsview
diff options
context:
space:
mode:
authorEduardo M. Fleury <eduardo.fleury@openbossa.org>2009-05-28 17:41:37 (GMT)
committerEduardo M. Fleury <eduardo.fleury@openbossa.org>2009-07-22 18:04:12 (GMT)
commit35f33618ec766e4922977c31a5f522c261b19c61 (patch)
tree893236423058a733d881cd0b2e86a4122a5c6879 /src/gui/graphicsview
parent4cb58c203242e6e24d1628673b145a038c93531f (diff)
downloadQt-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/gui/graphicsview')
-rw-r--r--src/gui/graphicsview/qgraph_p.h27
-rw-r--r--src/gui/graphicsview/qgraphicsanchorlayout.cpp16
-rw-r--r--src/gui/graphicsview/qgraphicsanchorlayout.h9
-rw-r--r--src/gui/graphicsview/qgraphicsanchorlayout_p.cpp142
-rw-r--r--src/gui/graphicsview/qgraphicsanchorlayout_p.h22
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];