summaryrefslogtreecommitdiffstats
path: root/examples/graphicsview
diff options
context:
space:
mode:
Diffstat (limited to 'examples/graphicsview')
-rw-r--r--examples/graphicsview/cubeicon.pngbin0 -> 703 bytes
-rw-r--r--examples/graphicsview/cubeitem.cpp193
-rw-r--r--examples/graphicsview/cubeitem.h61
-rw-r--r--examples/graphicsview/edge.cpp151
-rw-r--r--examples/graphicsview/edge.h77
-rw-r--r--examples/graphicsview/graph.cpp130
-rw-r--r--examples/graphicsview/graph.h67
-rw-r--r--examples/graphicsview/graphicsview.pro26
-rw-r--r--examples/graphicsview/graphicsview.qrc6
-rw-r--r--examples/graphicsview/main.cpp58
-rw-r--r--examples/graphicsview/modelitem.cpp220
-rw-r--r--examples/graphicsview/modelitem.h89
-rw-r--r--examples/graphicsview/node.cpp185
-rw-r--r--examples/graphicsview/node.h83
-rw-r--r--examples/graphicsview/scene.cpp54
-rw-r--r--examples/graphicsview/scene.h56
-rw-r--r--examples/graphicsview/teapoticon.pngbin0 -> 4969 bytes
-rw-r--r--examples/graphicsview/teapotitem.cpp129
-rw-r--r--examples/graphicsview/teapotitem.h63
-rw-r--r--examples/graphicsview/view.cpp121
-rw-r--r--examples/graphicsview/view.h87
21 files changed, 1856 insertions, 0 deletions
diff --git a/examples/graphicsview/cubeicon.png b/examples/graphicsview/cubeicon.png
new file mode 100644
index 000000000..9979fb582
--- /dev/null
+++ b/examples/graphicsview/cubeicon.png
Binary files differ
diff --git a/examples/graphicsview/cubeitem.cpp b/examples/graphicsview/cubeitem.cpp
new file mode 100644
index 000000000..10c7609f8
--- /dev/null
+++ b/examples/graphicsview/cubeitem.cpp
@@ -0,0 +1,193 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtQuick3D examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "cubeitem.h"
+#include "qglpainter.h"
+#include "qglcube.h"
+#include "qray3d.h"
+#include "qplane3d.h"
+#include "qtriangle3d.h"
+#include "qgraphicsembedscene.h"
+
+const qreal CubeSize = 2.0f;
+
+CubeItem::CubeItem(QGraphicsItem *parent)
+ : ModelItem(parent)
+{
+ QGLBuilder builder;
+ builder.newSection(QGL::Faceted);
+ builder << QGLCube(CubeSize);
+ cube = builder.finalizedSceneNode();
+}
+
+CubeItem::~CubeItem()
+{
+ delete cube;
+}
+
+void CubeItem::paintGL(QGLPainter *painter)
+{
+ GLuint textureId = this->textureId();
+ if (textureId) {
+ glDisable(GL_DEPTH_TEST);
+ glEnable(GL_BLEND);
+ painter->setFaceColor(QGL::AllFaces, QColor(0, 0, 0, 200));
+ painter->setStandardEffect(QGL::LitDecalTexture2D);
+ glBindTexture(GL_TEXTURE_2D, textureId);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ if (painter->isFixedFunction())
+ glEnable(GL_TEXTURE_2D);
+ glCullFace(GL_FRONT);
+ glEnable(GL_CULL_FACE);
+ cube->draw(painter);
+ glCullFace(GL_BACK);
+ cube->draw(painter);
+ glDisable(GL_CULL_FACE);
+ glBindTexture(GL_TEXTURE_2D, 0);
+ if (painter->isFixedFunction())
+ glDisable(GL_TEXTURE_2D);
+ } else {
+ painter->setStandardEffect(QGL::LitMaterial);
+ cube->draw(painter);
+ }
+}
+
+static const int vertexDataLen = 6 * 4 * 3;
+
+static const float vertexData[vertexDataLen] = {
+ -0.5f * CubeSize, -0.5f * CubeSize, -0.5f * CubeSize,
+ -0.5f * CubeSize, -0.5f * CubeSize, 0.5f * CubeSize,
+ -0.5f * CubeSize, 0.5f * CubeSize, 0.5f * CubeSize,
+ -0.5f * CubeSize, 0.5f * CubeSize, -0.5f * CubeSize,
+
+ -0.5f * CubeSize, 0.5f * CubeSize, -0.5f * CubeSize,
+ -0.5f * CubeSize, 0.5f * CubeSize, 0.5f * CubeSize,
+ 0.5f * CubeSize, 0.5f * CubeSize, 0.5f * CubeSize,
+ 0.5f * CubeSize, 0.5f * CubeSize, -0.5f * CubeSize,
+
+ 0.5f * CubeSize, 0.5f * CubeSize, -0.5f * CubeSize,
+ 0.5f * CubeSize, 0.5f * CubeSize, 0.5f * CubeSize,
+ 0.5f * CubeSize, -0.5f * CubeSize, 0.5f * CubeSize,
+ 0.5f * CubeSize, -0.5f * CubeSize, -0.5f * CubeSize,
+
+ 0.5f * CubeSize, -0.5f * CubeSize, -0.5f * CubeSize,
+ 0.5f * CubeSize, -0.5f * CubeSize, 0.5f * CubeSize,
+ -0.5f * CubeSize, -0.5f * CubeSize, 0.5f * CubeSize,
+ -0.5f * CubeSize, -0.5f * CubeSize, -0.5f * CubeSize,
+
+ 0.5f * CubeSize, -0.5f * CubeSize, 0.5f * CubeSize,
+ 0.5f * CubeSize, 0.5f * CubeSize, 0.5f * CubeSize,
+ -0.5f * CubeSize, 0.5f * CubeSize, 0.5f * CubeSize,
+ -0.5f * CubeSize, -0.5f * CubeSize, 0.5f * CubeSize,
+
+ 0.5f * CubeSize, 0.5f * CubeSize, -0.5f * CubeSize,
+ 0.5f * CubeSize, -0.5f * CubeSize, -0.5f * CubeSize,
+ -0.5f * CubeSize, -0.5f * CubeSize, -0.5f * CubeSize,
+ -0.5f * CubeSize, 0.5f * CubeSize, -0.5f * CubeSize
+};
+
+QPointF CubeItem::intersection(const QRay3D &ray, int *actualFace) const
+{
+ // Determine which face of the cube contains the point.
+ QMatrix4x4 mv = camera()->modelViewMatrix();
+ QVector3D pt1, pt2, pt3, pt4;
+ QVector2D tc1, tc2, tc3;
+ bool singleFace = (pressedFace() != -1);
+ for (int face = 0; face < 6; ++face) {
+ if (singleFace && face != pressedFace())
+ continue;
+
+ // Test the two triangles on the face for an intersection.
+ pt1 = QVector3D(vertexData[face * 4 * 3],
+ vertexData[face * 4 * 3 + 1],
+ vertexData[face * 4 * 3 + 2]);
+ pt2 = QVector3D(vertexData[face * 4 * 3 + 3],
+ vertexData[face * 4 * 3 + 4],
+ vertexData[face * 4 * 3 + 5]);
+ pt3 = QVector3D(vertexData[face * 4 * 3 + 6],
+ vertexData[face * 4 * 3 + 7],
+ vertexData[face * 4 * 3 + 8]);
+ pt4 = QVector3D(vertexData[face * 4 * 3 + 9],
+ vertexData[face * 4 * 3 + 10],
+ vertexData[face * 4 * 3 + 11]);
+ pt1 = mv.map(pt1);
+ pt2 = mv.map(pt2);
+ pt3 = mv.map(pt3);
+ pt4 = mv.map(pt4);
+ QTriangle3D triangle(pt1, pt2, pt3);
+ qreal t = triangle.intersection(ray);
+ if (qIsNaN(t)) {
+ triangle.setQ(pt3);
+ triangle.setR(pt4);
+ t = triangle.intersection(ray);
+ if (qIsNaN(t)) {
+ if (!singleFace)
+ continue;
+ // The mouse probably moved outside the face while the
+ // mouse button was held down. Use the triangle's plane
+ // to compute a virtual texture co-ordinate.
+ t = triangle.plane().intersection(ray);
+ }
+ tc1 = QVector2D(1.0f, 0.0f);
+ tc2 = QVector2D(0.0f, 1.0f);
+ tc3 = QVector2D(0.0f, 0.0f);
+ } else {
+ tc1 = QVector2D(1.0f, 0.0f);
+ tc2 = QVector2D(1.0f, 1.0f);
+ tc3 = QVector2D(0.0f, 1.0f);
+ }
+
+ // We want the face that is pointing towards the user.
+ QVector3D v = QVector3D::crossProduct(pt2 - pt1, pt3 - pt1);
+ if (!singleFace && v.z() <= 0.0f)
+ continue;
+
+ // Get the texture co-ordinate corresponding to the intersection.
+ QVector2D uv = triangle.uv(ray.point(t));
+ QVector2D tc =
+ uv.x() * tc1 + uv.y() * tc2 + (1 - uv.x() - uv.y()) * tc3;
+ *actualFace = face;
+ return QPointF(tc.x(), tc.y());
+ }
+
+ *actualFace = -1;
+ return QPointF();
+}
diff --git a/examples/graphicsview/cubeitem.h b/examples/graphicsview/cubeitem.h
new file mode 100644
index 000000000..67b4aa257
--- /dev/null
+++ b/examples/graphicsview/cubeitem.h
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtQuick3D examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef CUBEITEM_H
+#define CUBEITEM_H
+
+#include "modelitem.h"
+
+class CubeItem : public ModelItem
+{
+ Q_OBJECT
+public:
+ CubeItem(QGraphicsItem *parent = 0);
+ ~CubeItem();
+
+protected:
+ void paintGL(QGLPainter *painter);
+ QPointF intersection(const QRay3D &ray, int *actualFace) const;
+
+private:
+ QGLSceneNode *cube;
+};
+
+#endif
diff --git a/examples/graphicsview/edge.cpp b/examples/graphicsview/edge.cpp
new file mode 100644
index 000000000..bf480ec4b
--- /dev/null
+++ b/examples/graphicsview/edge.cpp
@@ -0,0 +1,151 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtQuick3D examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QPainter>
+
+#include "edge.h"
+#include "node.h"
+
+#include <math.h>
+
+static const double Pi = 3.14159265358979323846264338327950288419717;
+static double TwoPi = 2.0 * Pi;
+
+Edge::Edge(Node *sourceNode, Node *destNode)
+ : arrowSize(10)
+{
+ setAcceptedMouseButtons(0);
+ source = sourceNode;
+ dest = destNode;
+ source->addEdge(this);
+ dest->addEdge(this);
+ adjust();
+}
+
+Edge::~Edge()
+{
+}
+
+Node *Edge::sourceNode() const
+{
+ return source;
+}
+
+void Edge::setSourceNode(Node *node)
+{
+ source = node;
+ adjust();
+}
+
+Node *Edge::destNode() const
+{
+ return dest;
+}
+
+void Edge::setDestNode(Node *node)
+{
+ dest = node;
+ adjust();
+}
+
+void Edge::adjust()
+{
+ if (!source || !dest)
+ return;
+
+ QLineF line(mapFromItem(source, 0, 0), mapFromItem(dest, 0, 0));
+ qreal length = line.length();
+
+ prepareGeometryChange();
+
+ if (length > qreal(20.)) {
+ QPointF edgeOffset((line.dx() * 10) / length, (line.dy() * 10) / length);
+ sourcePoint = line.p1() + edgeOffset;
+ destPoint = line.p2() - edgeOffset;
+ } else {
+ sourcePoint = destPoint = line.p1();
+ }
+}
+
+QRectF Edge::boundingRect() const
+{
+ if (!source || !dest)
+ return QRectF();
+
+ qreal penWidth = 1;
+ qreal extra = (penWidth + arrowSize) / 2.0;
+
+ return QRectF(sourcePoint, QSizeF(destPoint.x() - sourcePoint.x(),
+ destPoint.y() - sourcePoint.y()))
+ .normalized()
+ .adjusted(-extra, -extra, extra, extra);
+}
+
+void Edge::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
+{
+ if (!source || !dest)
+ return;
+
+ QLineF line(sourcePoint, destPoint);
+ if (qFuzzyCompare(line.length(), qreal(0.)))
+ return;
+
+ // Draw the line itself
+ painter->setPen(QPen(Qt::black, 2, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
+ painter->drawLine(line);
+
+ // Draw the arrows
+ double angle = ::acos(line.dx() / line.length());
+ if (line.dy() >= 0)
+ angle = TwoPi - angle;
+
+ QPointF sourceArrowP1 = sourcePoint + QPointF(sin(angle + Pi / 3) * arrowSize,
+ cos(angle + Pi / 3) * arrowSize);
+ QPointF sourceArrowP2 = sourcePoint + QPointF(sin(angle + Pi - Pi / 3) * arrowSize,
+ cos(angle + Pi - Pi / 3) * arrowSize);
+ QPointF destArrowP1 = destPoint + QPointF(sin(angle - Pi / 3) * arrowSize,
+ cos(angle - Pi / 3) * arrowSize);
+ QPointF destArrowP2 = destPoint + QPointF(sin(angle - Pi + Pi / 3) * arrowSize,
+ cos(angle - Pi + Pi / 3) * arrowSize);
+
+ painter->setBrush(Qt::black);
+ painter->drawPolygon(QPolygonF() << line.p1() << sourceArrowP1 << sourceArrowP2);
+ painter->drawPolygon(QPolygonF() << line.p2() << destArrowP1 << destArrowP2);
+}
diff --git a/examples/graphicsview/edge.h b/examples/graphicsview/edge.h
new file mode 100644
index 000000000..d50c403a9
--- /dev/null
+++ b/examples/graphicsview/edge.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtQuick3D examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef EDGE_H
+#define EDGE_H
+
+#include <QGraphicsItem>
+
+class Node;
+
+class Edge : public QGraphicsItem
+{
+public:
+ Edge(Node *sourceNode, Node *destNode);
+ ~Edge();
+
+ Node *sourceNode() const;
+ void setSourceNode(Node *node);
+
+ Node *destNode() const;
+ void setDestNode(Node *node);
+
+ void adjust();
+
+ enum { Type = UserType + 2 };
+ int type() const { return Type; }
+
+protected:
+ QRectF boundingRect() const;
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
+
+private:
+ Node *source, *dest;
+
+ QPointF sourcePoint;
+ QPointF destPoint;
+ qreal arrowSize;
+};
+
+#endif
diff --git a/examples/graphicsview/graph.cpp b/examples/graphicsview/graph.cpp
new file mode 100644
index 000000000..2aa28b107
--- /dev/null
+++ b/examples/graphicsview/graph.cpp
@@ -0,0 +1,130 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtQuick3D examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "graph.h"
+#include "edge.h"
+#include "node.h"
+#include "scene.h"
+
+#include <QDebug>
+#include <QGraphicsScene>
+
+#include <math.h>
+
+Graph::Graph(QObject *parent)
+ : QObject(parent), timerId(0)
+{
+ QGraphicsEmbedScene *scene = new Scene(this);
+ sceneObject = scene;
+ scene->setItemIndexMethod(QGraphicsScene::NoIndex);
+ scene->setSceneRect(-128, -128, 256, 256);
+
+ Node *node1 = new Node(this);
+ Node *node2 = new Node(this);
+ Node *node3 = new Node(this);
+ Node *node4 = new Node(this);
+ centerNode = new Node(this);
+ Node *node6 = new Node(this);
+ Node *node7 = new Node(this);
+ Node *node8 = new Node(this);
+ Node *node9 = new Node(this);
+ scene->addItem(node1);
+ scene->addItem(node2);
+ scene->addItem(node3);
+ scene->addItem(node4);
+ scene->addItem(centerNode);
+ scene->addItem(node6);
+ scene->addItem(node7);
+ scene->addItem(node8);
+ scene->addItem(node9);
+ scene->addItem(new Edge(node1, node2));
+ scene->addItem(new Edge(node2, node3));
+ scene->addItem(new Edge(node2, centerNode));
+ scene->addItem(new Edge(node3, node6));
+ scene->addItem(new Edge(node4, node1));
+ scene->addItem(new Edge(node4, centerNode));
+ scene->addItem(new Edge(centerNode, node6));
+ scene->addItem(new Edge(centerNode, node8));
+ scene->addItem(new Edge(node6, node9));
+ scene->addItem(new Edge(node7, node4));
+ scene->addItem(new Edge(node8, node7));
+ scene->addItem(new Edge(node9, node8));
+
+ node1->setPos(-50, -50);
+ node2->setPos(0, -50);
+ node3->setPos(50, -50);
+ node4->setPos(-50, 0);
+ centerNode->setPos(0, 0);
+ node6->setPos(50, 0);
+ node7->setPos(-50, 50);
+ node8->setPos(0, 50);
+ node9->setPos(50, 50);
+}
+
+void Graph::itemMoved()
+{
+ if (!timerId)
+ timerId = startTimer(1000 / 25);
+}
+
+void Graph::timerEvent(QTimerEvent *event)
+{
+ Q_UNUSED(event);
+
+ QList<Node *> nodes;
+ foreach (QGraphicsItem *item, scene()->items()) {
+ if (Node *node = qgraphicsitem_cast<Node *>(item))
+ nodes << node;
+ }
+
+ foreach (Node *node, nodes)
+ node->calculateForces();
+
+ bool itemsMoved = false;
+ foreach (Node *node, nodes) {
+ if (node->advance())
+ itemsMoved = true;
+ }
+
+ if (!itemsMoved) {
+ killTimer(timerId);
+ timerId = 0;
+ }
+}
diff --git a/examples/graphicsview/graph.h b/examples/graphicsview/graph.h
new file mode 100644
index 000000000..0fa897ce8
--- /dev/null
+++ b/examples/graphicsview/graph.h
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtQuick3D examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef GRAPHWIDGET_H
+#define GRAPHWIDGET_H
+
+#include "qgraphicsembedscene.h"
+
+class Node;
+
+class Graph : public QObject
+{
+ Q_OBJECT
+public:
+ Graph(QObject *parent = 0);
+
+ QGraphicsEmbedScene *scene() const { return sceneObject; }
+
+ void itemMoved();
+
+protected:
+ void timerEvent(QTimerEvent *event);
+
+private:
+ QGraphicsEmbedScene *sceneObject;
+ int timerId;
+ Node *centerNode;
+};
+
+#endif
diff --git a/examples/graphicsview/graphicsview.pro b/examples/graphicsview/graphicsview.pro
new file mode 100644
index 000000000..98aba411d
--- /dev/null
+++ b/examples/graphicsview/graphicsview.pro
@@ -0,0 +1,26 @@
+TEMPLATE = app
+TARGET = graphicsview
+CONFIG += qt warn_on qt3d
+VPATH += $$PWD/../../src/threed/geometry
+SOURCES = \
+ cubeitem.cpp \
+ modelitem.cpp \
+ teapotitem.cpp \
+ main.cpp \
+ edge.cpp \
+ node.cpp \
+ graph.cpp \
+ scene.cpp \
+ view.cpp
+HEADERS = \
+ cubeitem.h \
+ modelitem.h \
+ teapotitem.h \
+ edge.h \
+ node.h \
+ graph.h \
+ scene.h \
+ view.h
+RESOURCES = \
+ graphicsview.qrc
+DESTDIR = ../../bin
diff --git a/examples/graphicsview/graphicsview.qrc b/examples/graphicsview/graphicsview.qrc
new file mode 100644
index 000000000..37a99a114
--- /dev/null
+++ b/examples/graphicsview/graphicsview.qrc
@@ -0,0 +1,6 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource>
+ <file>cubeicon.png</file>
+ <file>teapoticon.png</file>
+</qresource>
+</RCC>
diff --git a/examples/graphicsview/main.cpp b/examples/graphicsview/main.cpp
new file mode 100644
index 000000000..39a3d7a08
--- /dev/null
+++ b/examples/graphicsview/main.cpp
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtQuick3D examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QApplication>
+#include <QtOpenGL/qgl.h>
+#include <QtCore/qmath.h>
+#include <QtCore/qdatetime.h>
+#include "view.h"
+
+int main(int argc, char *argv[])
+{
+ QApplication app(argc, argv);
+
+ QGLFormat format(QGLFormat::defaultFormat());
+ format.setSampleBuffers(true);
+ View view;
+ view.setViewport(new QGLWidget(format));
+ view.show();
+
+ return app.exec();
+}
diff --git a/examples/graphicsview/modelitem.cpp b/examples/graphicsview/modelitem.cpp
new file mode 100644
index 000000000..41ba13833
--- /dev/null
+++ b/examples/graphicsview/modelitem.cpp
@@ -0,0 +1,220 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtQuick3D examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "modelitem.h"
+#include "qglpainter.h"
+#include "qgraphicsembedscene.h"
+#include <QtGui/qgraphicssceneevent.h>
+#include <QtGui/qapplication.h>
+
+const qreal CubeSize = 2.0f;
+
+ModelItem::ModelItem(QGraphicsItem *parent)
+ : QGLGraphicsViewportItem(parent)
+ , mScene(0)
+ , mTextureId(0)
+ , navigating(false)
+ , mPressedFace(-1)
+ , pressedButton(Qt::NoButton)
+{
+ startNavCamera = new QGLCamera();
+
+ setFlag(ItemIsFocusable, true);
+}
+
+ModelItem::~ModelItem()
+{
+ delete startNavCamera;
+}
+
+void ModelItem::setScene(QGraphicsEmbedScene *scene)
+{
+ mScene = scene;
+ connect(scene, SIGNAL(changed(QList<QRectF>)), this, SLOT(updateScene()));
+}
+
+void ModelItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+{
+ // Render the inner scene into a framebuffer object.
+ // We do this while the ordinary Qt paint engine has
+ // control of the GL context rather than later when the
+ // QGLPainter has control of the GL context.
+ if (mScene)
+ mTextureId = mScene->renderToTexture();
+
+ // Now render the GL parts of the item using QGLPainter.
+ QGLGraphicsViewportItem::paint(painter, option, widget);
+}
+
+void ModelItem::updateScene()
+{
+ update();
+}
+
+void ModelItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
+{
+ int face;
+ QPointF tc = intersection
+ (event->widget(), event->pos().toPoint(), &face);
+ if (!navigating && mPressedFace == -1 && face != -1) {
+ mPressedFace = face;
+ pressedButton = event->button();
+ mScene->deliverEvent(event, tc);
+ return;
+ } else if (!navigating && face == -1) {
+ navigating = true;
+ pressedButton = event->button();
+ pressedPos = event->pos().toPoint();
+ startNavCamera->setEye(camera()->eye());
+ startNavCamera->setCenter(camera()->center());
+ startNavCamera->setUpVector(camera()->upVector());
+#ifndef QT_NO_CURSOR
+ setCursor(Qt::ClosedHandCursor);
+#endif
+ return;
+ }
+ QGraphicsItem::mousePressEvent(event);
+}
+
+void ModelItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
+{
+ if (navigating) {
+ QPoint delta = event->pos().toPoint() - pressedPos;
+ int deltax = delta.x();
+ int deltay = delta.y();
+ QGLCamera *camera = this->camera();
+ int rotation = camera->screenRotation();
+ if (rotation == 90 || rotation == 270) {
+ qSwap(deltax, deltay);
+ }
+ if (rotation == 90 || rotation == 180) {
+ deltax = -deltax;
+ }
+ if (rotation == 180 || rotation == 270) {
+ deltay = -deltay;
+ }
+ qreal anglex = deltax * 90.0f / rect().width();
+ qreal angley = deltay * 90.0f / rect().height();
+ QQuaternion q = startNavCamera->pan(-anglex);
+ q *= startNavCamera->tilt(-angley);
+ camera->setEye(startNavCamera->eye());
+ camera->setCenter(startNavCamera->center());
+ camera->setUpVector(startNavCamera->upVector());
+ camera->rotateCenter(q);
+ } else if (mPressedFace != -1) {
+ int face;
+ QPointF tc = intersection
+ (event->widget(), event->pos().toPoint(), &face);
+ if (face != mPressedFace)
+ tc = QPointF(-1, -1);
+ mScene->deliverEvent(event, tc);
+ return;
+ }
+ QGraphicsItem::mouseMoveEvent(event);
+}
+
+void ModelItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
+{
+ if (navigating && pressedButton == event->button()) {
+ navigating = false;
+ pressedButton = Qt::NoButton;
+#ifndef QT_NO_CURSOR
+ unsetCursor();
+#endif
+ return;
+ } else if (mPressedFace != -1) {
+ int face;
+ QPointF tc = intersection
+ (event->widget(), event->pos().toPoint(), &face);
+ if (face != mPressedFace)
+ tc = QPoint(-1, -1);
+ if (pressedButton == event->button()) {
+ mPressedFace = -1;
+ pressedButton = Qt::NoButton;
+ }
+ mScene->deliverEvent(event, tc);
+ return;
+ }
+ QGraphicsItem::mouseReleaseEvent(event);
+}
+
+void ModelItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
+{
+ int face;
+ QPointF tc = intersection
+ (event->widget(), event->pos().toPoint(), &face);
+ if (mPressedFace == -1 && face != -1) {
+ mPressedFace = face;
+ pressedButton = event->button();
+ mScene->deliverEvent(event, tc);
+ return;
+ }
+ QGraphicsItem::mouseDoubleClickEvent(event);
+}
+
+QPointF ModelItem::intersection
+ (QWidget *widget, const QPoint &point, int *actualFace) const
+{
+ // Bail out if no scene.
+ if (!mScene) {
+ *actualFace = -1;
+ return QPointF();
+ }
+
+ // Get the combined matrix for the projection.
+ int dpiX = widget->logicalDpiX();
+ int dpiY = widget->logicalDpiY();
+ QRectF bounds = boundingRect();
+ qreal aspectRatio = (bounds.width() * dpiY) / (bounds.height() * dpiX);
+ QMatrix4x4 proj = camera()->projectionMatrix(aspectRatio);
+
+ // Find the relative position of the point within (-1, -1) to (1, 1).
+ QPointF relativePoint =
+ QPointF((point.x() - bounds.center().x()) * 2 / bounds.width(),
+ -(point.y() - bounds.center().y()) * 2 / bounds.height());
+
+ // Get the ray extending from the eye through the point the user selected.
+ QVector3D eyept = proj.inverted().map
+ (QVector3D(relativePoint.x(), relativePoint.y(), -1.0f));
+ QRay3D ray(QVector3D(0, 0, 0), eyept);
+
+ // Intersect with the ray using a model-specific intersection method.
+ return intersection(ray, actualFace);
+}
diff --git a/examples/graphicsview/modelitem.h b/examples/graphicsview/modelitem.h
new file mode 100644
index 000000000..063cbb2b2
--- /dev/null
+++ b/examples/graphicsview/modelitem.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtQuick3D examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef MODELITEM_H
+#define MODELITEM_H
+
+#include "qglgraphicsviewportitem.h"
+#include "qglbuilder.h"
+#include "qray3d.h"
+
+class QGraphicsEmbedScene;
+
+class ModelItem : public QObject, public QGLGraphicsViewportItem
+{
+ Q_OBJECT
+public:
+ ModelItem(QGraphicsItem *parent = 0);
+ ~ModelItem();
+
+ QGraphicsEmbedScene *scene() const { return mScene; }
+ void setScene(QGraphicsEmbedScene *scene);
+
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
+
+protected:
+ void mousePressEvent(QGraphicsSceneMouseEvent *event);
+ void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
+ void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
+ void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event);
+
+private Q_SLOTS:
+ void updateScene();
+
+protected:
+ virtual QPointF intersection(const QRay3D &ray, int *actualFace) const = 0;
+ GLuint textureId() const { return mTextureId; }
+ int pressedFace() const { return mPressedFace; }
+
+private:
+ QGraphicsEmbedScene *mScene;
+ GLuint mTextureId;
+ bool navigating;
+ int mPressedFace;
+ Qt::MouseButton pressedButton;
+ QPoint pressedPos;
+ QGLCamera *startNavCamera;
+
+ QPointF intersection
+ (QWidget *widget, const QPoint &point, int *actualFace) const;
+};
+
+#endif
diff --git a/examples/graphicsview/node.cpp b/examples/graphicsview/node.cpp
new file mode 100644
index 000000000..4723b0ab4
--- /dev/null
+++ b/examples/graphicsview/node.cpp
@@ -0,0 +1,185 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtQuick3D examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QGraphicsScene>
+#include <QGraphicsSceneMouseEvent>
+#include <QPainter>
+#include <QStyleOption>
+
+#include "edge.h"
+#include "node.h"
+#include "graph.h"
+
+Node::Node(Graph *graphWidget)
+ : graph(graphWidget)
+{
+ setFlag(ItemIsMovable);
+ setFlag(ItemSendsGeometryChanges);
+ //setCacheMode(DeviceCoordinateCache);
+ setZValue(-1);
+}
+
+void Node::addEdge(Edge *edge)
+{
+ edgeList << edge;
+ edge->adjust();
+}
+
+QList<Edge *> Node::edges() const
+{
+ return edgeList;
+}
+
+void Node::calculateForces()
+{
+ if (!scene() || scene()->mouseGrabberItem() == this) {
+ newPos = pos();
+ return;
+ }
+
+ // Sum up all forces pushing this item away
+ qreal xvel = 0;
+ qreal yvel = 0;
+ foreach (QGraphicsItem *item, scene()->items()) {
+ Node *node = qgraphicsitem_cast<Node *>(item);
+ if (!node)
+ continue;
+
+ QLineF line(mapFromItem(node, 0, 0), QPointF(0, 0));
+ qreal dx = line.dx();
+ qreal dy = line.dy();
+ double l = 2.0 * (dx * dx + dy * dy);
+ if (l > 0) {
+ xvel += (dx * 150.0) / l;
+ yvel += (dy * 150.0) / l;
+ }
+ }
+
+ // Now subtract all forces pulling items together
+ double weight = (edgeList.size() + 1) * 10;
+ foreach (Edge *edge, edgeList) {
+ QPointF pos;
+ if (edge->sourceNode() == this)
+ pos = mapFromItem(edge->destNode(), 0, 0);
+ else
+ pos = mapFromItem(edge->sourceNode(), 0, 0);
+ xvel += pos.x() / weight;
+ yvel += pos.y() / weight;
+ }
+
+ if (qAbs(xvel) < 0.1 && qAbs(yvel) < 0.1)
+ xvel = yvel = 0;
+
+ QRectF sceneRect = scene()->sceneRect();
+ newPos = pos() + QPointF(xvel, yvel);
+ newPos.setX(qMin(qMax(newPos.x(), sceneRect.left() + 10), sceneRect.right() - 10));
+ newPos.setY(qMin(qMax(newPos.y(), sceneRect.top() + 10), sceneRect.bottom() - 10));
+}
+
+bool Node::advance()
+{
+ if (newPos == pos())
+ return false;
+
+ setPos(newPos);
+ return true;
+}
+
+QRectF Node::boundingRect() const
+{
+ qreal adjust = 42;
+ return QRectF(-10 - adjust, -10 - adjust,
+ 23 + adjust * 2, 23 + adjust * 2);
+}
+
+QPainterPath Node::shape() const
+{
+ QPainterPath path;
+ path.addEllipse(-20, -20, 40, 40);
+ return path;
+}
+
+void Node::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *)
+{
+ painter->setPen(Qt::NoPen);
+ painter->setBrush(Qt::darkGray);
+ painter->drawEllipse(-7, -7, 20, 20);
+
+ QRadialGradient gradient(-3, -3, 10);
+ if (option->state & QStyle::State_Sunken) {
+ gradient.setCenter(3, 3);
+ gradient.setFocalPoint(3, 3);
+ gradient.setColorAt(1, QColor(Qt::yellow).light(120));
+ gradient.setColorAt(0, QColor(Qt::darkYellow).light(120));
+ } else {
+ gradient.setColorAt(0, Qt::yellow);
+ gradient.setColorAt(1, Qt::darkYellow);
+ }
+ painter->setBrush(gradient);
+ painter->setPen(QPen(Qt::black, 0));
+ painter->drawEllipse(-10, -10, 20, 20);
+}
+
+QVariant Node::itemChange(GraphicsItemChange change, const QVariant &value)
+{
+ switch (change) {
+ case ItemPositionHasChanged:
+ foreach (Edge *edge, edgeList)
+ edge->adjust();
+ graph->itemMoved();
+ break;
+ default:
+ break;
+ };
+
+ return QGraphicsItem::itemChange(change, value);
+}
+
+void Node::mousePressEvent(QGraphicsSceneMouseEvent *event)
+{
+ update();
+ QGraphicsItem::mousePressEvent(event);
+}
+
+void Node::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
+{
+ update();
+ QGraphicsItem::mouseReleaseEvent(event);
+}
diff --git a/examples/graphicsview/node.h b/examples/graphicsview/node.h
new file mode 100644
index 000000000..45208610a
--- /dev/null
+++ b/examples/graphicsview/node.h
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtQuick3D examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef NODE_H
+#define NODE_H
+
+#include <QGraphicsItem>
+#include <QList>
+
+class Edge;
+class Graph;
+QT_BEGIN_NAMESPACE
+class QGraphicsSceneMouseEvent;
+QT_END_NAMESPACE
+
+class Node : public QGraphicsItem
+{
+public:
+ Node(Graph *graphWidget);
+
+ void addEdge(Edge *edge);
+ QList<Edge *> edges() const;
+
+ enum { Type = UserType + 1 };
+ int type() const { return Type; }
+
+ void calculateForces();
+ bool advance();
+
+ QRectF boundingRect() const;
+ QPainterPath shape() const;
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
+
+protected:
+ QVariant itemChange(GraphicsItemChange change, const QVariant &value);
+
+ void mousePressEvent(QGraphicsSceneMouseEvent *event);
+ void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
+
+private:
+ QList<Edge *> edgeList;
+ QPointF newPos;
+ Graph *graph;
+};
+
+#endif
diff --git a/examples/graphicsview/scene.cpp b/examples/graphicsview/scene.cpp
new file mode 100644
index 000000000..5fe551058
--- /dev/null
+++ b/examples/graphicsview/scene.cpp
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtQuick3D examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "scene.h"
+#include <QtGui/qpainter.h>
+
+void Scene::drawBackground(QPainter *painter, const QRectF &rect)
+{
+ painter->save();
+ QLinearGradient gradient(rect.topLeft(), rect.bottomRight());
+ gradient.setColorAt(0, QColor(0, 128, 192, 255));
+ gradient.setColorAt(1, QColor(0, 0, 128, 255));
+ painter->setPen(QPen(Qt::black, 3));
+ painter->setBrush(gradient);
+ painter->drawRect(rect);
+ painter->restore();
+}
diff --git a/examples/graphicsview/scene.h b/examples/graphicsview/scene.h
new file mode 100644
index 000000000..73be795a8
--- /dev/null
+++ b/examples/graphicsview/scene.h
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtQuick3D examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef SCENE_H
+#define SCENE_H
+
+#include "qgraphicsembedscene.h"
+
+class Scene : public QGraphicsEmbedScene
+{
+ Q_OBJECT
+public:
+ Scene(QObject *parent = 0) : QGraphicsEmbedScene(parent) {}
+
+protected:
+ void drawBackground(QPainter *painter, const QRectF &rect);
+};
+
+#endif
diff --git a/examples/graphicsview/teapoticon.png b/examples/graphicsview/teapoticon.png
new file mode 100644
index 000000000..17392361d
--- /dev/null
+++ b/examples/graphicsview/teapoticon.png
Binary files differ
diff --git a/examples/graphicsview/teapotitem.cpp b/examples/graphicsview/teapotitem.cpp
new file mode 100644
index 000000000..72161a5a2
--- /dev/null
+++ b/examples/graphicsview/teapotitem.cpp
@@ -0,0 +1,129 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtQuick3D examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "teapotitem.h"
+#include "qglpainter.h"
+#include "qplane3d.h"
+#include "qtriangle3d.h"
+#include <QtCore/qnumeric.h>
+
+TeapotItem::TeapotItem(QGraphicsItem *parent)
+ : ModelItem(parent)
+{
+ QGLBuilder builder;
+ builder.newSection(QGL::Faceted);
+ builder << teapot;
+ teapotNode = builder.finalizedSceneNode();
+}
+
+TeapotItem::~TeapotItem()
+{
+ delete teapotNode;
+}
+
+void TeapotItem::paintGL(QGLPainter *painter)
+{
+ GLuint textureId = this->textureId();
+ if (textureId) {
+ glDisable(GL_DEPTH_TEST);
+ glEnable(GL_BLEND);
+ painter->setFaceColor(QGL::AllFaces, QColor(0, 0, 0, 200));
+ painter->setStandardEffect(QGL::LitDecalTexture2D);
+ glBindTexture(GL_TEXTURE_2D, textureId);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ if (painter->isFixedFunction())
+ glEnable(GL_TEXTURE_2D);
+ glCullFace(GL_FRONT);
+ glEnable(GL_CULL_FACE);
+ teapotNode->draw(painter);
+ glCullFace(GL_BACK);
+ teapotNode->draw(painter);
+ glDisable(GL_CULL_FACE);
+ glBindTexture(GL_TEXTURE_2D, 0);
+ if (painter->isFixedFunction())
+ glDisable(GL_TEXTURE_2D);
+ } else {
+ painter->setStandardEffect(QGL::LitMaterial);
+ teapotNode->draw(painter);
+ }
+}
+
+QPointF TeapotItem::intersection(const QRay3D &ray, int *actualFace) const
+{
+ QVector2D tc;
+ QGLBezierPatches patches = teapot.transformed(camera()->modelViewMatrix());
+ if (pressedFace() == -1) {
+ // Intersect with the whole teapot.
+ qreal t = patches.intersection(ray, &tc, actualFace);
+ if (!qIsNaN(t))
+ return QPointF(tc.x(), tc.y());
+ } else {
+ // Only intersect with the patch that was pressed previously.
+ QGLBezierPatches subpatches;
+ subpatches.setPositions
+ (patches.positions().mid(pressedFace() * 16, 16));
+ qreal t = subpatches.intersection(ray, &tc);
+ if (!qIsNaN(t)) {
+ *actualFace = pressedFace();
+ return QPointF(tc.x(), tc.y());
+ }
+
+ // The mouse has moved outside the boundary of the patch.
+ // Use the plane containing the patch to extend the hit
+ // area out to infinity.
+ QTriangle3D triangle(subpatches.positions()[0],
+ subpatches.positions()[3],
+ subpatches.positions()[12]);
+ t = triangle.plane().intersection(ray);
+ if (!qIsNaN(t)) {
+ *actualFace = pressedFace();
+ QVector2D uv = triangle.uv(ray.point(t));
+ QVector2D tc1(0, 0);
+ QVector2D tc2(1, 0);
+ QVector2D tc3(0, 1);
+ QVector2D tc =
+ uv.x() * tc1 + uv.y() * tc2 + (1 - uv.x() - uv.y()) * tc3;
+ return QPointF(tc.x(), tc.y());
+ }
+ }
+ *actualFace = -1;
+ return QPointF();
+}
diff --git a/examples/graphicsview/teapotitem.h b/examples/graphicsview/teapotitem.h
new file mode 100644
index 000000000..f2706eeb1
--- /dev/null
+++ b/examples/graphicsview/teapotitem.h
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtQuick3D examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TEAPOTITEM_H
+#define TEAPOTITEM_H
+
+#include "modelitem.h"
+#include "qglteapot.h"
+
+class TeapotItem : public ModelItem
+{
+ Q_OBJECT
+public:
+ TeapotItem(QGraphicsItem *parent = 0);
+ ~TeapotItem();
+
+protected:
+ void paintGL(QGLPainter *painter);
+ QPointF intersection(const QRay3D &ray, int *actualFace) const;
+
+private:
+ QGLTeapot teapot;
+ QGLSceneNode *teapotNode;
+};
+
+#endif
diff --git a/examples/graphicsview/view.cpp b/examples/graphicsview/view.cpp
new file mode 100644
index 000000000..73f4bb6c9
--- /dev/null
+++ b/examples/graphicsview/view.cpp
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtQuick3D examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "view.h"
+#include "cubeitem.h"
+#include "teapotitem.h"
+#include "graph.h"
+#include "qglcamera.h"
+#include <QtGui/qgraphicssceneevent.h>
+
+View::View(QWidget *parent)
+ : QGraphicsView(parent)
+{
+ setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
+
+ scene.setBackgroundBrush(Qt::black);
+ setScene(&scene);
+
+ cube = new CubeItem();
+ cube->setRect(0, 0, 600, 480);
+ cube->camera()->setEye(QVector3D(-5.0f, 3.0f, 6.0f));
+ cube->setVisible(false);
+
+ teapot = new TeapotItem();
+ teapot->setRect(0, 0, 600, 480);
+ teapot->camera()->setEye(QVector3D(-5.0f, 3.0f, 6.0f));
+
+ Button *cubeButton = new Button
+ (QPixmap(QLatin1String(":/cubeicon.png")), teapot);
+ Button *teapotButton = new Button
+ (QPixmap(QLatin1String(":/teapoticon.png")), cube);
+
+ connect(cubeButton, SIGNAL(clicked()), this, SLOT(switchToCube()));
+ connect(teapotButton, SIGNAL(clicked()), this, SLOT(switchToTeapot()));
+
+ scene.addItem(cube);
+ scene.addItem(teapot);
+
+ Graph *graph = new Graph(this);
+ cube->setScene(graph->scene());
+ teapot->setScene(graph->scene());
+}
+
+void View::resizeEvent(QResizeEvent *e)
+{
+ QGraphicsView::resizeEvent(e);
+ cube->setRect(0, 0, width(), height());
+ teapot->setRect(0, 0, width(), height());
+}
+
+void View::switchToCube()
+{
+ teapot->setVisible(false);
+ cube->setVisible(true);
+}
+
+void View::switchToTeapot()
+{
+ cube->setVisible(false);
+ teapot->setVisible(true);
+}
+
+Button::Button(const QPixmap &pixmap, QGraphicsItem *parent)
+ : QGraphicsPixmapItem(pixmap, parent)
+ , pressed(false)
+{
+ setFlag(ItemIsSelectable, true);
+}
+
+void Button::mousePressEvent(QGraphicsSceneMouseEvent *event)
+{
+ pressed = true;
+ QGraphicsItem::mousePressEvent(event);
+}
+
+void Button::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
+{
+ if (pressed && boundingRect().contains(event->scenePos()))
+ emit clicked();
+ pressed = false;
+ QGraphicsItem::mouseReleaseEvent(event);
+}
diff --git a/examples/graphicsview/view.h b/examples/graphicsview/view.h
new file mode 100644
index 000000000..f47a7249b
--- /dev/null
+++ b/examples/graphicsview/view.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtQuick3D examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef VIEW_H
+#define VIEW_H
+
+#include <QtGui/qgraphicsview.h>
+#include <QtGui/qgraphicsscene.h>
+#include <QtGui/qgraphicsitem.h>
+
+class CubeItem;
+class TeapotItem;
+
+class View : public QGraphicsView
+{
+ Q_OBJECT
+public:
+ View(QWidget *parent = 0);
+
+protected:
+ void resizeEvent(QResizeEvent *e);
+
+private Q_SLOTS:
+ void switchToCube();
+ void switchToTeapot();
+
+private:
+ QGraphicsScene scene;
+ CubeItem *cube;
+ TeapotItem *teapot;
+};
+
+class Button : public QObject, public QGraphicsPixmapItem
+{
+ Q_OBJECT
+public:
+ Button(const QPixmap &pixmap, QGraphicsItem *parent);
+
+Q_SIGNALS:
+ void clicked();
+
+protected:
+ void mousePressEvent(QGraphicsSceneMouseEvent *event);
+ void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
+
+private:
+ bool pressed;
+};
+
+#endif