|
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 QtDeclarative module of the Qt Toolkit. |
|
8 ** |
|
9 ** $QT_BEGIN_LICENSE:LGPL$ |
|
10 ** No Commercial Usage |
|
11 ** This file contains pre-release code and may not be distributed. |
|
12 ** You may use this file in accordance with the terms and conditions |
|
13 ** contained in the Technology Preview License Agreement accompanying |
|
14 ** this package. |
|
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 ** If you have questions regarding the use of this file, please contact |
|
29 ** Nokia at qt-info@nokia.com. |
|
30 ** |
|
31 ** |
|
32 ** |
|
33 ** |
|
34 ** |
|
35 ** |
|
36 ** |
|
37 ** |
|
38 ** $QT_END_LICENSE$ |
|
39 ** |
|
40 ****************************************************************************/ |
|
41 |
|
42 #include "private/qdeclarativeflipable_p.h" |
|
43 |
|
44 #include "private/qdeclarativeitem_p.h" |
|
45 #include "private/qdeclarativeguard_p.h" |
|
46 |
|
47 #include <qdeclarativeinfo.h> |
|
48 |
|
49 #include <QtGui/qgraphicstransform.h> |
|
50 |
|
51 QT_BEGIN_NAMESPACE |
|
52 |
|
53 class QDeclarativeFlipablePrivate : public QDeclarativeItemPrivate |
|
54 { |
|
55 Q_DECLARE_PUBLIC(QDeclarativeFlipable) |
|
56 public: |
|
57 QDeclarativeFlipablePrivate() : current(QDeclarativeFlipable::Front), front(0), back(0) {} |
|
58 |
|
59 void updateSceneTransformFromParent(); |
|
60 void setBackTransform(); |
|
61 |
|
62 QDeclarativeFlipable::Side current; |
|
63 QDeclarativeGuard<QGraphicsObject> front; |
|
64 QDeclarativeGuard<QGraphicsObject> back; |
|
65 |
|
66 bool wantBackXFlipped; |
|
67 bool wantBackYFlipped; |
|
68 }; |
|
69 |
|
70 /*! |
|
71 \qmlclass Flipable QDeclarativeFlipable |
|
72 \since 4.7 |
|
73 \brief The Flipable item provides a surface that can be flipped. |
|
74 \inherits Item |
|
75 |
|
76 Flipable is an item that can be visibly "flipped" between its front and |
|
77 back sides. It is used together with Rotation and State/Transition to |
|
78 produce a flipping effect. |
|
79 |
|
80 Here is a Flipable that flips whenever it is clicked: |
|
81 |
|
82 \snippet doc/src/snippets/declarative/flipable.qml 0 |
|
83 |
|
84 \image flipable.gif |
|
85 |
|
86 The Rotation element is used to specify the angle and axis of the flip, |
|
87 and the State defines the changes in angle which produce the flipping |
|
88 effect. Finally, the Transition creates the animation that changes the |
|
89 angle over one second. |
|
90 */ |
|
91 |
|
92 /*! |
|
93 \internal |
|
94 \class QDeclarativeFlipable |
|
95 \brief The Flipable item provides a surface that can be flipped. |
|
96 |
|
97 Flipable is an item that can be visibly "flipped" between its front and |
|
98 back sides. |
|
99 */ |
|
100 |
|
101 QDeclarativeFlipable::QDeclarativeFlipable(QDeclarativeItem *parent) |
|
102 : QDeclarativeItem(*(new QDeclarativeFlipablePrivate), parent) |
|
103 { |
|
104 } |
|
105 |
|
106 QDeclarativeFlipable::~QDeclarativeFlipable() |
|
107 { |
|
108 } |
|
109 |
|
110 /*! |
|
111 \qmlproperty Item Flipable::front |
|
112 \qmlproperty Item Flipable::back |
|
113 |
|
114 The front and back sides of the flipable. |
|
115 */ |
|
116 |
|
117 QGraphicsObject *QDeclarativeFlipable::front() |
|
118 { |
|
119 Q_D(const QDeclarativeFlipable); |
|
120 return d->front; |
|
121 } |
|
122 |
|
123 void QDeclarativeFlipable::setFront(QGraphicsObject *front) |
|
124 { |
|
125 Q_D(QDeclarativeFlipable); |
|
126 if (d->front) { |
|
127 qmlInfo(this) << tr("front is a write-once property"); |
|
128 return; |
|
129 } |
|
130 d->front = front; |
|
131 d->front->setParentItem(this); |
|
132 if (Back == d->current) |
|
133 d->front->setOpacity(0.); |
|
134 } |
|
135 |
|
136 QGraphicsObject *QDeclarativeFlipable::back() |
|
137 { |
|
138 Q_D(const QDeclarativeFlipable); |
|
139 return d->back; |
|
140 } |
|
141 |
|
142 void QDeclarativeFlipable::setBack(QGraphicsObject *back) |
|
143 { |
|
144 Q_D(QDeclarativeFlipable); |
|
145 if (d->back) { |
|
146 qmlInfo(this) << tr("back is a write-once property"); |
|
147 return; |
|
148 } |
|
149 d->back = back; |
|
150 d->back->setParentItem(this); |
|
151 if (Front == d->current) |
|
152 d->back->setOpacity(0.); |
|
153 connect(back, SIGNAL(widthChanged()), |
|
154 this, SLOT(retransformBack())); |
|
155 connect(back, SIGNAL(heightChanged()), |
|
156 this, SLOT(retransformBack())); |
|
157 } |
|
158 |
|
159 void QDeclarativeFlipable::retransformBack() |
|
160 { |
|
161 Q_D(QDeclarativeFlipable); |
|
162 if (d->current == QDeclarativeFlipable::Back && d->back) |
|
163 d->setBackTransform(); |
|
164 } |
|
165 |
|
166 /*! |
|
167 \qmlproperty enumeration Flipable::side |
|
168 |
|
169 The side of the Flippable currently visible. Possible values are \c |
|
170 Flippable.Front and \c Flippable.Back. |
|
171 */ |
|
172 QDeclarativeFlipable::Side QDeclarativeFlipable::side() const |
|
173 { |
|
174 Q_D(const QDeclarativeFlipable); |
|
175 if (d->dirtySceneTransform) |
|
176 const_cast<QDeclarativeFlipablePrivate *>(d)->ensureSceneTransform(); |
|
177 |
|
178 return d->current; |
|
179 } |
|
180 |
|
181 // determination on the currently visible side of the flipable |
|
182 // has to be done on the complete scene transform to give |
|
183 // correct results. |
|
184 void QDeclarativeFlipablePrivate::updateSceneTransformFromParent() |
|
185 { |
|
186 Q_Q(QDeclarativeFlipable); |
|
187 |
|
188 QDeclarativeItemPrivate::updateSceneTransformFromParent(); |
|
189 QPointF p1(0, 0); |
|
190 QPointF p2(1, 0); |
|
191 QPointF p3(1, 1); |
|
192 |
|
193 QPointF scenep1 = sceneTransform.map(p1); |
|
194 QPointF scenep2 = sceneTransform.map(p2); |
|
195 QPointF scenep3 = sceneTransform.map(p3); |
|
196 p1 = q->mapToParent(p1); |
|
197 p2 = q->mapToParent(p2); |
|
198 p3 = q->mapToParent(p3); |
|
199 |
|
200 qreal cross = (scenep1.x() - scenep2.x()) * (scenep3.y() - scenep2.y()) - |
|
201 (scenep1.y() - scenep2.y()) * (scenep3.x() - scenep2.x()); |
|
202 |
|
203 wantBackYFlipped = p1.x() >= p2.x(); |
|
204 wantBackXFlipped = p2.y() >= p3.y(); |
|
205 |
|
206 QDeclarativeFlipable::Side newSide; |
|
207 if (cross > 0) { |
|
208 newSide = QDeclarativeFlipable::Back; |
|
209 } else { |
|
210 newSide = QDeclarativeFlipable::Front; |
|
211 } |
|
212 |
|
213 if (newSide != current) { |
|
214 current = newSide; |
|
215 if (current == QDeclarativeFlipable::Back && back) |
|
216 setBackTransform(); |
|
217 if (front) |
|
218 front->setOpacity((current==QDeclarativeFlipable::Front)?1.:0.); |
|
219 if (back) |
|
220 back->setOpacity((current==QDeclarativeFlipable::Back)?1.:0.); |
|
221 emit q->sideChanged(); |
|
222 } |
|
223 } |
|
224 |
|
225 /* Depends on the width/height of the back item, and so needs reevaulating |
|
226 if those change. |
|
227 */ |
|
228 void QDeclarativeFlipablePrivate::setBackTransform() |
|
229 { |
|
230 QTransform mat; |
|
231 QGraphicsItemPrivate *dBack = QGraphicsItemPrivate::get(back); |
|
232 mat.translate(dBack->width()/2,dBack->height()/2); |
|
233 if (dBack->width() && wantBackYFlipped) |
|
234 mat.rotate(180, Qt::YAxis); |
|
235 if (dBack->height() && wantBackXFlipped) |
|
236 mat.rotate(180, Qt::XAxis); |
|
237 mat.translate(-dBack->width()/2,-dBack->height()/2); |
|
238 back->setTransform(mat); |
|
239 } |
|
240 |
|
241 QT_END_NAMESPACE |