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