diff options
Diffstat (limited to 'examples/graphicsview')
-rw-r--r-- | examples/graphicsview/cubeicon.png | bin | 0 -> 703 bytes | |||
-rw-r--r-- | examples/graphicsview/cubeitem.cpp | 193 | ||||
-rw-r--r-- | examples/graphicsview/cubeitem.h | 61 | ||||
-rw-r--r-- | examples/graphicsview/edge.cpp | 151 | ||||
-rw-r--r-- | examples/graphicsview/edge.h | 77 | ||||
-rw-r--r-- | examples/graphicsview/graph.cpp | 130 | ||||
-rw-r--r-- | examples/graphicsview/graph.h | 67 | ||||
-rw-r--r-- | examples/graphicsview/graphicsview.pro | 26 | ||||
-rw-r--r-- | examples/graphicsview/graphicsview.qrc | 6 | ||||
-rw-r--r-- | examples/graphicsview/main.cpp | 58 | ||||
-rw-r--r-- | examples/graphicsview/modelitem.cpp | 220 | ||||
-rw-r--r-- | examples/graphicsview/modelitem.h | 89 | ||||
-rw-r--r-- | examples/graphicsview/node.cpp | 185 | ||||
-rw-r--r-- | examples/graphicsview/node.h | 83 | ||||
-rw-r--r-- | examples/graphicsview/scene.cpp | 54 | ||||
-rw-r--r-- | examples/graphicsview/scene.h | 56 | ||||
-rw-r--r-- | examples/graphicsview/teapoticon.png | bin | 0 -> 4969 bytes | |||
-rw-r--r-- | examples/graphicsview/teapotitem.cpp | 129 | ||||
-rw-r--r-- | examples/graphicsview/teapotitem.h | 63 | ||||
-rw-r--r-- | examples/graphicsview/view.cpp | 121 | ||||
-rw-r--r-- | examples/graphicsview/view.h | 87 |
21 files changed, 1856 insertions, 0 deletions
diff --git a/examples/graphicsview/cubeicon.png b/examples/graphicsview/cubeicon.png Binary files differnew file mode 100644 index 000000000..9979fb582 --- /dev/null +++ b/examples/graphicsview/cubeicon.png 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 Binary files differnew file mode 100644 index 000000000..17392361d --- /dev/null +++ b/examples/graphicsview/teapoticon.png 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 |