comparison examples/graphicsview/elasticnodes/node.d @ 371:12f60887ed15

add elasticnodes example and necessary changes to the library.
author Eldar Insafutdinov
date Wed, 07 Jul 2010 22:54:12 +0100
parents
children
comparison
equal deleted inserted replaced
370:7fd4b69378bf 371:12f60887ed15
1 /****************************************************************************
2 **
3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 **
7 ** This file is part of the examples of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** Commercial Usage
11 ** Licensees holding valid Qt Commercial licenses may use this file in
12 ** accordance with the Qt Commercial License Agreement provided with the
13 ** Software or, alternatively, in accordance with the terms contained in
14 ** a written agreement between you and Nokia.
15 **
16 ** GNU Lesser General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU Lesser
18 ** General Public License version 2.1 as published by the Free Software
19 ** Foundation and appearing in the file LICENSE.LGPL included in the
20 ** packaging of this file. Please review the following information to
21 ** ensure the GNU Lesser General Public License version 2.1 requirements
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23 **
24 ** In addition, as a special exception, Nokia gives you certain additional
25 ** rights. These rights are described in the Nokia Qt LGPL Exception
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27 **
28 ** GNU General Public License Usage
29 ** Alternatively, this file may be used under the terms of the GNU
30 ** General Public License version 3.0 as published by the Free Software
31 ** Foundation and appearing in the file LICENSE.GPL included in the
32 ** packaging of this file. Please review the following information to
33 ** ensure the GNU General Public License version 3.0 requirements will be
34 ** met: http://www.gnu.org/copyleft/gpl.html.
35 **
36 ** If you have questions regarding the use of this file, please contact
37 ** Nokia at qt-info@nokia.com.
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 module node;
43
44 import
45 qt.gui.QRadialGradient,
46 qt.gui.QGraphicsItem;
47
48 import
49 graphwidget,
50 edge;
51
52 class Node : QGraphicsItem
53 {
54 public:
55 this(GraphWidget graphWidget)
56 {
57 graph = graphWidget;
58 setFlag(ItemIsMovable);
59 setFlag(ItemSendsGeometryChanges);
60 setCacheMode(DeviceCoordinateCache);
61 setZValue(-1);
62 }
63
64 void addEdge(Edge edge)
65 {
66 edgeList ~= edge;
67 edge.adjust();
68 }
69 /*
70 Edge[] edges() const
71 {
72 return edgeList;
73 }
74 */
75 enum { Type = UserType + 1 };
76 int type() const { return Type; }
77
78 void calculateForces()
79 {
80 if (!scene() || scene().mouseGrabberItem() is this) {
81 newPos = pos();
82 return;
83 }
84
85 // Sum up all forces pushing this item away
86 qreal xvel = 0;
87 qreal yvel = 0;
88 foreach (IQGraphicsItem item; scene().items()) {
89 auto node = cast(Node)item;
90 if (!node)
91 continue;
92
93 auto line = QLineF(mapFromItem(node, 0, 0), QPointF(0, 0));
94 qreal dx = line.dx();
95 qreal dy = line.dy();
96 double l = 2.0 * (dx * dx + dy * dy);
97 if (l > 0) {
98 xvel += (dx * 150.0) / l;
99 yvel += (dy * 150.0) / l;
100 }
101 }
102
103 // Now subtract all forces pulling items together
104 double weight = (edgeList.length + 1) * 10;
105 foreach (Edge edge; edgeList) {
106 QPointF pos;
107 if (edge.sourceNode() == this)
108 pos = mapFromItem(edge.destNode(), 0, 0);
109 else
110 pos = mapFromItem(edge.sourceNode(), 0, 0);
111 xvel += pos.x() / weight;
112 yvel += pos.y() / weight;
113 }
114
115 if (qAbs(xvel) < 0.1 && qAbs(yvel) < 0.1)
116 xvel = yvel = 0;
117
118 QRectF sceneRect = scene().sceneRect();
119 newPos = pos() + QPointF(xvel, yvel);
120 newPos.x = qMin(qMax(newPos.x(), sceneRect.left() + 10), sceneRect.right() - 10);
121 newPos.y = qMin(qMax(newPos.y(), sceneRect.top() + 10), sceneRect.bottom() - 10);
122
123 }
124
125 bool advance()
126 {
127 auto pos_ = pos();
128 if (newPos == pos_)
129 return false;
130
131 setPos(newPos);
132 return true;
133 }
134
135 QRectF boundingRect() const
136 {
137 qreal adjust = 2;
138 return QRectF(-10 - adjust, -10 - adjust,
139 23 + adjust, 23 + adjust);
140 }
141
142 QPainterPath shape() const
143 {
144 QPainterPath path;
145 path.addEllipse(-10, -10, 20, 20);
146 return path;
147 }
148
149 override public void paint(QPainter painter, QStyleOptionGraphicsItem option, QWidget widget = null)
150 {
151 painter.setPen(Qt.NoPen);
152 painter.setBrush(new QBrush(Qt.darkGray));
153 painter.drawEllipse(-7, -7, 20, 20);
154
155 auto gradient = new QRadialGradient(-3, -3, 10);
156 if (option.state & QStyle.State_Sunken) {
157 gradient.setCenter(3, 3);
158 gradient.setFocalPoint(3, 3);
159 gradient.setColorAt(1, (new QColor(Qt.yellow)).lighter(120));
160 gradient.setColorAt(0, (new QColor(Qt.darkYellow)).lighter(120));
161 } else {
162 gradient.setColorAt(0, new QColor(Qt.yellow));
163 gradient.setColorAt(1, new QColor(Qt.darkYellow));
164 }
165 painter.setBrush(gradient);
166 painter.setPen(new QPen(new QBrush(Qt.black), 0));
167 painter.drawEllipse(-10, -10, 20, 20);
168 }
169
170 protected:
171 override QVariant itemChange(GraphicsItemChange change, QVariant value)
172 {
173 switch (change)
174 {
175 case ItemPositionHasChanged:
176 foreach (Edge edge; edgeList)
177 edge.adjust();
178 graph.itemMoved();
179 break;
180 default:
181 break;
182 };
183
184 return QGraphicsItem.itemChange(change, value);
185 }
186
187 override void mousePressEvent(QGraphicsSceneMouseEvent event)
188 {
189 update();
190 QGraphicsItem.mousePressEvent(event);
191 }
192
193 override void mouseReleaseEvent(QGraphicsSceneMouseEvent event)
194 {
195 update();
196 QGraphicsItem.mouseReleaseEvent(event);
197 }
198
199 private:
200 Edge[] edgeList;
201 QPointF newPos;
202 GraphWidget graph;
203 };