source: trunk/examples/graphicsview/elasticnodes/graphwidget.cpp@ 1028

Last change on this file since 1028 was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

File size: 7.2 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the examples of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:BSD$
10** You may use this file under the terms of the BSD license as follows:
11**
12** "Redistribution and use in source and binary forms, with or without
13** modification, are permitted provided that the following conditions are
14** met:
15** * Redistributions of source code must retain the above copyright
16** notice, this list of conditions and the following disclaimer.
17** * Redistributions in binary form must reproduce the above copyright
18** notice, this list of conditions and the following disclaimer in
19** the documentation and/or other materials provided with the
20** distribution.
21** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
22** the names of its contributors may be used to endorse or promote
23** products derived from this software without specific prior written
24** permission.
25**
26** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
37** $QT_END_LICENSE$
38**
39****************************************************************************/
40
41#include "graphwidget.h"
42#include "edge.h"
43#include "node.h"
44
45#include <QtGui>
46
47#include <math.h>
48
49//! [0]
50GraphWidget::GraphWidget(QWidget *parent)
51 : QGraphicsView(parent), timerId(0)
52{
53 QGraphicsScene *scene = new QGraphicsScene(this);
54 scene->setItemIndexMethod(QGraphicsScene::NoIndex);
55 scene->setSceneRect(-200, -200, 400, 400);
56 setScene(scene);
57 setCacheMode(CacheBackground);
58 setViewportUpdateMode(BoundingRectViewportUpdate);
59 setRenderHint(QPainter::Antialiasing);
60 setTransformationAnchor(AnchorUnderMouse);
61 scale(qreal(0.8), qreal(0.8));
62 setMinimumSize(400, 400);
63 setWindowTitle(tr("Elastic Nodes"));
64//! [0]
65
66//! [1]
67 Node *node1 = new Node(this);
68 Node *node2 = new Node(this);
69 Node *node3 = new Node(this);
70 Node *node4 = new Node(this);
71 centerNode = new Node(this);
72 Node *node6 = new Node(this);
73 Node *node7 = new Node(this);
74 Node *node8 = new Node(this);
75 Node *node9 = new Node(this);
76 scene->addItem(node1);
77 scene->addItem(node2);
78 scene->addItem(node3);
79 scene->addItem(node4);
80 scene->addItem(centerNode);
81 scene->addItem(node6);
82 scene->addItem(node7);
83 scene->addItem(node8);
84 scene->addItem(node9);
85 scene->addItem(new Edge(node1, node2));
86 scene->addItem(new Edge(node2, node3));
87 scene->addItem(new Edge(node2, centerNode));
88 scene->addItem(new Edge(node3, node6));
89 scene->addItem(new Edge(node4, node1));
90 scene->addItem(new Edge(node4, centerNode));
91 scene->addItem(new Edge(centerNode, node6));
92 scene->addItem(new Edge(centerNode, node8));
93 scene->addItem(new Edge(node6, node9));
94 scene->addItem(new Edge(node7, node4));
95 scene->addItem(new Edge(node8, node7));
96 scene->addItem(new Edge(node9, node8));
97
98 node1->setPos(-50, -50);
99 node2->setPos(0, -50);
100 node3->setPos(50, -50);
101 node4->setPos(-50, 0);
102 centerNode->setPos(0, 0);
103 node6->setPos(50, 0);
104 node7->setPos(-50, 50);
105 node8->setPos(0, 50);
106 node9->setPos(50, 50);
107}
108//! [1]
109
110//! [2]
111void GraphWidget::itemMoved()
112{
113 if (!timerId)
114 timerId = startTimer(1000 / 25);
115}
116//! [2]
117
118//! [3]
119void GraphWidget::keyPressEvent(QKeyEvent *event)
120{
121 switch (event->key()) {
122 case Qt::Key_Up:
123 centerNode->moveBy(0, -20);
124 break;
125 case Qt::Key_Down:
126 centerNode->moveBy(0, 20);
127 break;
128 case Qt::Key_Left:
129 centerNode->moveBy(-20, 0);
130 break;
131 case Qt::Key_Right:
132 centerNode->moveBy(20, 0);
133 break;
134 case Qt::Key_Plus:
135 scaleView(qreal(1.2));
136 break;
137 case Qt::Key_Minus:
138 scaleView(1 / qreal(1.2));
139 break;
140 case Qt::Key_Space:
141 case Qt::Key_Enter:
142 foreach (QGraphicsItem *item, scene()->items()) {
143 if (qgraphicsitem_cast<Node *>(item))
144 item->setPos(-150 + qrand() % 300, -150 + qrand() % 300);
145 }
146 break;
147 default:
148 QGraphicsView::keyPressEvent(event);
149 }
150}
151//! [3]
152
153//! [4]
154void GraphWidget::timerEvent(QTimerEvent *event)
155{
156 Q_UNUSED(event);
157
158 QList<Node *> nodes;
159 foreach (QGraphicsItem *item, scene()->items()) {
160 if (Node *node = qgraphicsitem_cast<Node *>(item))
161 nodes << node;
162 }
163
164 foreach (Node *node, nodes)
165 node->calculateForces();
166
167 bool itemsMoved = false;
168 foreach (Node *node, nodes) {
169 if (node->advance())
170 itemsMoved = true;
171 }
172
173 if (!itemsMoved) {
174 killTimer(timerId);
175 timerId = 0;
176 }
177}
178//! [4]
179
180//! [5]
181void GraphWidget::wheelEvent(QWheelEvent *event)
182{
183 scaleView(pow((double)2, -event->delta() / 240.0));
184}
185//! [5]
186
187//! [6]
188void GraphWidget::drawBackground(QPainter *painter, const QRectF &rect)
189{
190 Q_UNUSED(rect);
191
192 // Shadow
193 QRectF sceneRect = this->sceneRect();
194 QRectF rightShadow(sceneRect.right(), sceneRect.top() + 5, 5, sceneRect.height());
195 QRectF bottomShadow(sceneRect.left() + 5, sceneRect.bottom(), sceneRect.width(), 5);
196 if (rightShadow.intersects(rect) || rightShadow.contains(rect))
197 painter->fillRect(rightShadow, Qt::darkGray);
198 if (bottomShadow.intersects(rect) || bottomShadow.contains(rect))
199 painter->fillRect(bottomShadow, Qt::darkGray);
200
201 // Fill
202 QLinearGradient gradient(sceneRect.topLeft(), sceneRect.bottomRight());
203 gradient.setColorAt(0, Qt::white);
204 gradient.setColorAt(1, Qt::lightGray);
205 painter->fillRect(rect.intersect(sceneRect), gradient);
206 painter->setBrush(Qt::NoBrush);
207 painter->drawRect(sceneRect);
208
209 // Text
210 QRectF textRect(sceneRect.left() + 4, sceneRect.top() + 4,
211 sceneRect.width() - 4, sceneRect.height() - 4);
212 QString message(tr("Click and drag the nodes around, and zoom with the mouse "
213 "wheel or the '+' and '-' keys"));
214
215 QFont font = painter->font();
216 font.setBold(true);
217 font.setPointSize(14);
218 painter->setFont(font);
219 painter->setPen(Qt::lightGray);
220 painter->drawText(textRect.translated(2, 2), message);
221 painter->setPen(Qt::black);
222 painter->drawText(textRect, message);
223}
224//! [6]
225
226//! [7]
227void GraphWidget::scaleView(qreal scaleFactor)
228{
229 qreal factor = transform().scale(scaleFactor, scaleFactor).mapRect(QRectF(0, 0, 1, 1)).width();
230 if (factor < 0.07 || factor > 100)
231 return;
232
233 scale(scaleFactor, scaleFactor);
234}
235//! [7]
Note: See TracBrowser for help on using the repository browser.