1 /* |
|
2 * Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #include "graphicsitemrotater.h" |
|
20 #include <QtGui> |
|
21 #include <QPainter> |
|
22 #include <QStyleOptionGraphicsItem> |
|
23 #include "utilities.h" |
|
24 #include <assert.h> |
|
25 |
|
26 |
|
27 GraphicsItemRotater::GraphicsItemRotater() |
|
28 : m_lastRotationValue(0) |
|
29 { |
|
30 m_timeLine.setFrameRange(0, 50); |
|
31 safe_connect(&m_timeLine, SIGNAL(valueChanged(qreal)), this, SLOT(updateRotationStep(qreal))); |
|
32 safe_connect(&m_timeLine, SIGNAL(finished()), this, SIGNAL(finished())); |
|
33 } |
|
34 |
|
35 GraphicsItemRotater::~GraphicsItemRotater() { |
|
36 if(m_pixmapItem) delete m_pixmapItem; |
|
37 } |
|
38 |
|
39 void GraphicsItemRotater::start(QGraphicsItem *item, int angle, int duration, QTimeLine::CurveShape shape) { |
|
40 m_timeLine.setDuration(duration); |
|
41 m_timeLine.setCurveShape(shape); |
|
42 |
|
43 // Grab a pixmap of the item. |
|
44 QRectF rect = item->boundingRect(); |
|
45 QPixmap *pixmap = new QPixmap(rect.size().toSize()); |
|
46 QPainter painter(pixmap); |
|
47 QStyleOptionGraphicsItem options; |
|
48 options.exposedRect = QRect(rect.toRect()); |
|
49 grabItem(item, &painter, &options); |
|
50 painter.end(); |
|
51 // QLabel *l = new QLabel; |
|
52 // l->setPixmap(*pixmap); |
|
53 // l->show(); |
|
54 |
|
55 // Create a pixmap item to represent the real item during the rotation. |
|
56 m_pixmapItem = new QGraphicsPixmapItem(item->parentItem()); |
|
57 item->scene()->addItem(m_pixmapItem); |
|
58 m_pixmapItem->setPos(item->pos()); |
|
59 m_pixmapItem->setTransform(item->transform()); |
|
60 m_pixmapItem->setPixmap(*pixmap); |
|
61 m_pixmapItem->setZValue(item->zValue()); |
|
62 m_pixmapItem->show(); |
|
63 |
|
64 m_rotationAngle = angle; |
|
65 if(m_rotationAngle < -180) |
|
66 m_rotationAngle = 360 + m_rotationAngle; |
|
67 else if(m_rotationAngle > 180) |
|
68 m_rotationAngle = m_rotationAngle - 360; |
|
69 |
|
70 m_rotationAngle = m_rotationAngle % 360; |
|
71 |
|
72 m_lastRotationValue = 0; |
|
73 m_timeLine.start(); |
|
74 } |
|
75 |
|
76 void GraphicsItemRotater::updateRotationStep(qreal value) // slot |
|
77 { |
|
78 QSizeF size = m_pixmapItem->boundingRect().size(); |
|
79 qreal dx = size.width()/2; |
|
80 qreal dy = size.height()/2; |
|
81 QTransform transform = m_pixmapItem->transform(); |
|
82 transform.translate(dx, dy); |
|
83 transform.rotate((value - m_lastRotationValue) * m_rotationAngle); |
|
84 transform.translate(-dx, -dy); |
|
85 m_pixmapItem->setTransform(transform); |
|
86 |
|
87 m_lastRotationValue = value; |
|
88 } |
|
89 |
|
90 static bool zValueSort(const QGraphicsItem *item1, const QGraphicsItem *item2) { |
|
91 return item1->zValue() < item2->zValue(); |
|
92 } |
|
93 |
|
94 void GraphicsItemRotater::grabItem(QGraphicsItem *item, QPainter *painter, const QStyleOptionGraphicsItem *option, |
|
95 QWidget *widget) { |
|
96 QList<QGraphicsItem *> childs = item->childItems(); |
|
97 qSort(childs.begin(), childs.end(), zValueSort); |
|
98 foreach(QGraphicsItem *child, childs) { |
|
99 if(child->isVisible()) { |
|
100 QTransform transform = painter->transform(); |
|
101 transform.translate(child->pos().x(), child->pos().y()); |
|
102 painter->setTransform(transform); |
|
103 child->paint(painter, option, widget); |
|
104 transform.translate(-child->pos().x(), -child->pos().y()); |
|
105 painter->setTransform(transform); |
|
106 } |
|
107 } |
|
108 } |
|