1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2016 The Qt Company Ltd. |
4 | ** Contact: https://www.qt.io/licensing/ |
5 | ** |
6 | ** This file is part of the examples of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:BSD$ |
9 | ** Commercial License Usage |
10 | ** Licensees holding valid commercial Qt licenses may use this file in |
11 | ** accordance with the commercial license agreement provided with the |
12 | ** Software or, alternatively, in accordance with the terms contained in |
13 | ** a written agreement between you and The Qt Company. For licensing terms |
14 | ** and conditions see https://www.qt.io/terms-conditions. For further |
15 | ** information use the contact form at https://www.qt.io/contact-us. |
16 | ** |
17 | ** BSD License Usage |
18 | ** Alternatively, you may use this file under the terms of the BSD license |
19 | ** as follows: |
20 | ** |
21 | ** "Redistribution and use in source and binary forms, with or without |
22 | ** modification, are permitted provided that the following conditions are |
23 | ** met: |
24 | ** * Redistributions of source code must retain the above copyright |
25 | ** notice, this list of conditions and the following disclaimer. |
26 | ** * Redistributions in binary form must reproduce the above copyright |
27 | ** notice, this list of conditions and the following disclaimer in |
28 | ** the documentation and/or other materials provided with the |
29 | ** distribution. |
30 | ** * Neither the name of The Qt Company Ltd nor the names of its |
31 | ** contributors may be used to endorse or promote products derived |
32 | ** from this software without specific prior written permission. |
33 | ** |
34 | ** |
35 | ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
36 | ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
37 | ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
38 | ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
39 | ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
40 | ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
41 | ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
42 | ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
43 | ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
44 | ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
45 | ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." |
46 | ** |
47 | ** $QT_END_LICENSE$ |
48 | ** |
49 | ****************************************************************************/ |
50 | |
51 | #include "robot.h" |
52 | |
53 | #include <QGraphicsSceneDragDropEvent> |
54 | #include <QMimeData> |
55 | #include <QPainter> |
56 | #include <QParallelAnimationGroup> |
57 | #include <QPropertyAnimation> |
58 | |
59 | //! [0] |
60 | RobotPart::RobotPart(QGraphicsItem *parent) |
61 | : QGraphicsObject(parent), color(Qt::lightGray) |
62 | { |
63 | setAcceptDrops(true); |
64 | } |
65 | //! [0] |
66 | |
67 | //! [1] |
68 | void RobotPart::dragEnterEvent(QGraphicsSceneDragDropEvent *event) |
69 | { |
70 | if (event->mimeData()->hasColor()) { |
71 | event->setAccepted(true); |
72 | dragOver = true; |
73 | update(); |
74 | } else { |
75 | event->setAccepted(false); |
76 | } |
77 | } |
78 | //! [1] |
79 | |
80 | //! [2] |
81 | void RobotPart::dragLeaveEvent(QGraphicsSceneDragDropEvent *event) |
82 | { |
83 | Q_UNUSED(event); |
84 | dragOver = false; |
85 | update(); |
86 | } |
87 | //! [2] |
88 | |
89 | //! [3] |
90 | void RobotPart::dropEvent(QGraphicsSceneDragDropEvent *event) |
91 | { |
92 | dragOver = false; |
93 | if (event->mimeData()->hasColor()) |
94 | color = qvariant_cast<QColor>(v: event->mimeData()->colorData()); |
95 | update(); |
96 | } |
97 | //! [3] |
98 | |
99 | //! [4] |
100 | RobotHead::RobotHead(QGraphicsItem *parent) |
101 | : RobotPart(parent) |
102 | { |
103 | } |
104 | //! [4] |
105 | |
106 | //! [5] |
107 | QRectF RobotHead::boundingRect() const |
108 | { |
109 | return QRectF(-15, -50, 30, 50); |
110 | } |
111 | //! [5] |
112 | |
113 | //! [6] |
114 | void RobotHead::paint(QPainter *painter, |
115 | const QStyleOptionGraphicsItem *option, QWidget *widget) |
116 | { |
117 | Q_UNUSED(option); |
118 | Q_UNUSED(widget); |
119 | if (pixmap.isNull()) { |
120 | painter->setBrush(dragOver ? color.lighter(f: 130) : color); |
121 | painter->drawRoundedRect(x: -10, y: -30, w: 20, h: 30, xRadius: 25, yRadius: 25, mode: Qt::RelativeSize); |
122 | painter->setBrush(Qt::white); |
123 | painter->drawEllipse(x: -7, y: -3 - 20, w: 7, h: 7); |
124 | painter->drawEllipse(x: 0, y: -3 - 20, w: 7, h: 7); |
125 | painter->setBrush(Qt::black); |
126 | painter->drawEllipse(x: -5, y: -1 - 20, w: 2, h: 2); |
127 | painter->drawEllipse(x: 2, y: -1 - 20, w: 2, h: 2); |
128 | painter->setPen(QPen(Qt::black, 2)); |
129 | painter->setBrush(Qt::NoBrush); |
130 | painter->drawArc(x: -6, y: -2 - 20, w: 12, h: 15, a: 190 * 16, alen: 160 * 16); |
131 | } else { |
132 | painter->scale(sx: .2272, sy: .2824); |
133 | painter->drawPixmap(p: QPointF(-15 * 4.4, -50 * 3.54), pm: pixmap); |
134 | } |
135 | } |
136 | //! [6] |
137 | |
138 | //! [7] |
139 | void RobotHead::dragEnterEvent(QGraphicsSceneDragDropEvent *event) |
140 | { |
141 | if (event->mimeData()->hasImage()) { |
142 | event->setAccepted(true); |
143 | dragOver = true; |
144 | update(); |
145 | } else { |
146 | RobotPart::dragEnterEvent(event); |
147 | } |
148 | } |
149 | //! [7] |
150 | |
151 | //! [8] |
152 | void RobotHead::dropEvent(QGraphicsSceneDragDropEvent *event) |
153 | { |
154 | if (event->mimeData()->hasImage()) { |
155 | dragOver = false; |
156 | pixmap = qvariant_cast<QPixmap>(v: event->mimeData()->imageData()); |
157 | update(); |
158 | } else { |
159 | RobotPart::dropEvent(event); |
160 | } |
161 | } |
162 | //! [8] |
163 | |
164 | QRectF RobotTorso::boundingRect() const |
165 | { |
166 | return QRectF(-30, -20, 60, 60); |
167 | } |
168 | |
169 | void RobotTorso::paint(QPainter *painter, |
170 | const QStyleOptionGraphicsItem *option, QWidget *widget) |
171 | { |
172 | Q_UNUSED(option); |
173 | Q_UNUSED(widget); |
174 | |
175 | painter->setBrush(dragOver ? color.lighter(f: 130) : color); |
176 | painter->drawRoundedRect(x: -20, y: -20, w: 40, h: 60, xRadius: 25, yRadius: 25, mode: Qt::RelativeSize); |
177 | painter->drawEllipse(x: -25, y: -20, w: 20, h: 20); |
178 | painter->drawEllipse(x: 5, y: -20, w: 20, h: 20); |
179 | painter->drawEllipse(x: -20, y: 22, w: 20, h: 20); |
180 | painter->drawEllipse(x: 0, y: 22, w: 20, h: 20); |
181 | } |
182 | |
183 | RobotLimb::RobotLimb(QGraphicsItem *parent) |
184 | : RobotPart(parent) |
185 | { |
186 | } |
187 | |
188 | QRectF RobotLimb::boundingRect() const |
189 | { |
190 | return QRectF(-5, -5, 40, 10); |
191 | } |
192 | |
193 | void RobotLimb::paint(QPainter *painter, |
194 | const QStyleOptionGraphicsItem *option, QWidget *widget) |
195 | { |
196 | Q_UNUSED(option); |
197 | Q_UNUSED(widget); |
198 | |
199 | painter->setBrush(dragOver ? color.lighter(f: 130) : color); |
200 | painter->drawRoundedRect(rect: boundingRect(), xRadius: 50, yRadius: 50, mode: Qt::RelativeSize); |
201 | painter->drawEllipse(x: -5, y: -5, w: 10, h: 10); |
202 | } |
203 | |
204 | //! [10] |
205 | Robot::Robot(QGraphicsItem *parent) |
206 | : RobotPart(parent) |
207 | { |
208 | setFlag(flag: ItemHasNoContents); |
209 | |
210 | QGraphicsObject *torsoItem = new RobotTorso(this); |
211 | QGraphicsObject *headItem = new RobotHead(torsoItem); |
212 | QGraphicsObject *upperLeftArmItem = new RobotLimb(torsoItem); |
213 | QGraphicsObject *lowerLeftArmItem = new RobotLimb(upperLeftArmItem); |
214 | QGraphicsObject *upperRightArmItem = new RobotLimb(torsoItem); |
215 | QGraphicsObject *lowerRightArmItem = new RobotLimb(upperRightArmItem); |
216 | QGraphicsObject *upperRightLegItem = new RobotLimb(torsoItem); |
217 | QGraphicsObject *lowerRightLegItem = new RobotLimb(upperRightLegItem); |
218 | QGraphicsObject *upperLeftLegItem = new RobotLimb(torsoItem); |
219 | QGraphicsObject *lowerLeftLegItem = new RobotLimb(upperLeftLegItem); |
220 | //! [10] |
221 | |
222 | //! [11] |
223 | headItem->setPos(ax: 0, ay: -18); |
224 | upperLeftArmItem->setPos(ax: -15, ay: -10); |
225 | lowerLeftArmItem->setPos(ax: 30, ay: 0); |
226 | upperRightArmItem->setPos(ax: 15, ay: -10); |
227 | lowerRightArmItem->setPos(ax: 30, ay: 0); |
228 | upperRightLegItem->setPos(ax: 10, ay: 32); |
229 | lowerRightLegItem->setPos(ax: 30, ay: 0); |
230 | upperLeftLegItem->setPos(ax: -10, ay: 32); |
231 | lowerLeftLegItem->setPos(ax: 30, ay: 0); |
232 | //! [11] |
233 | |
234 | //! [12] |
235 | QParallelAnimationGroup *animation = new QParallelAnimationGroup(this); |
236 | |
237 | QPropertyAnimation *headAnimation = new QPropertyAnimation(headItem, "rotation" ); |
238 | headAnimation->setStartValue(20); |
239 | headAnimation->setEndValue(-20); |
240 | QPropertyAnimation *headScaleAnimation = new QPropertyAnimation(headItem, "scale" ); |
241 | headScaleAnimation->setEndValue(1.1); |
242 | animation->addAnimation(animation: headAnimation); |
243 | animation->addAnimation(animation: headScaleAnimation); |
244 | //! [12] |
245 | |
246 | QPropertyAnimation *upperLeftArmAnimation = new QPropertyAnimation(upperLeftArmItem, "rotation" ); |
247 | upperLeftArmAnimation->setStartValue(190); |
248 | upperLeftArmAnimation->setEndValue(180); |
249 | animation->addAnimation(animation: upperLeftArmAnimation); |
250 | |
251 | QPropertyAnimation *lowerLeftArmAnimation = new QPropertyAnimation(lowerLeftArmItem, "rotation" ); |
252 | lowerLeftArmAnimation->setStartValue(50); |
253 | lowerLeftArmAnimation->setEndValue(10); |
254 | animation->addAnimation(animation: lowerLeftArmAnimation); |
255 | |
256 | QPropertyAnimation *upperRightArmAnimation = new QPropertyAnimation(upperRightArmItem, "rotation" ); |
257 | upperRightArmAnimation->setStartValue(300); |
258 | upperRightArmAnimation->setEndValue(310); |
259 | animation->addAnimation(animation: upperRightArmAnimation); |
260 | |
261 | QPropertyAnimation *lowerRightArmAnimation = new QPropertyAnimation(lowerRightArmItem, "rotation" ); |
262 | lowerRightArmAnimation->setStartValue(0); |
263 | lowerRightArmAnimation->setEndValue(-70); |
264 | animation->addAnimation(animation: lowerRightArmAnimation); |
265 | |
266 | QPropertyAnimation *upperLeftLegAnimation = new QPropertyAnimation(upperLeftLegItem, "rotation" ); |
267 | upperLeftLegAnimation->setStartValue(150); |
268 | upperLeftLegAnimation->setEndValue(80); |
269 | animation->addAnimation(animation: upperLeftLegAnimation); |
270 | |
271 | QPropertyAnimation *lowerLeftLegAnimation = new QPropertyAnimation(lowerLeftLegItem, "rotation" ); |
272 | lowerLeftLegAnimation->setStartValue(70); |
273 | lowerLeftLegAnimation->setEndValue(10); |
274 | animation->addAnimation(animation: lowerLeftLegAnimation); |
275 | |
276 | QPropertyAnimation *upperRightLegAnimation = new QPropertyAnimation(upperRightLegItem, "rotation" ); |
277 | upperRightLegAnimation->setStartValue(40); |
278 | upperRightLegAnimation->setEndValue(120); |
279 | animation->addAnimation(animation: upperRightLegAnimation); |
280 | |
281 | QPropertyAnimation *lowerRightLegAnimation = new QPropertyAnimation(lowerRightLegItem, "rotation" ); |
282 | lowerRightLegAnimation->setStartValue(10); |
283 | lowerRightLegAnimation->setEndValue(50); |
284 | animation->addAnimation(animation: lowerRightLegAnimation); |
285 | |
286 | QPropertyAnimation *torsoAnimation = new QPropertyAnimation(torsoItem, "rotation" ); |
287 | torsoAnimation->setStartValue(5); |
288 | torsoAnimation->setEndValue(-20); |
289 | animation->addAnimation(animation: torsoAnimation); |
290 | |
291 | //! [13] |
292 | for (int i = 0; i < animation->animationCount(); ++i) { |
293 | QPropertyAnimation *anim = qobject_cast<QPropertyAnimation *>(object: animation->animationAt(index: i)); |
294 | anim->setEasingCurve(QEasingCurve::SineCurve); |
295 | anim->setDuration(2000); |
296 | } |
297 | |
298 | animation->setLoopCount(-1); |
299 | animation->start(); |
300 | //! [13] |
301 | } |
302 | |
303 | //! [9] |
304 | QRectF Robot::boundingRect() const |
305 | { |
306 | return QRectF(); |
307 | } |
308 | |
309 | void Robot::paint(QPainter *painter, |
310 | const QStyleOptionGraphicsItem *option, QWidget *widget) |
311 | { |
312 | Q_UNUSED(painter); |
313 | Q_UNUSED(option); |
314 | Q_UNUSED(widget); |
315 | } |
316 | //! [9] |
317 | |