1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the QtDeclarative module of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #include "QtQuick1/private/qdeclarativeflipable_p.h"
44 #include "QtQuick1/private/qdeclarativeitem_p.h"
45 #include "QtDeclarative/private/qdeclarativeguard_p.h"
47 #include <QtDeclarative/qdeclarativeinfo.h>
49 #include <QtGui/qgraphicstransform.h>
55 class QDeclarative1FlipablePrivate : public QDeclarativeItemPrivate
57 Q_DECLARE_PUBLIC(QDeclarative1Flipable)
59 QDeclarative1FlipablePrivate() : current(QDeclarative1Flipable::Front), front(0), back(0) {}
61 void updateSceneTransformFromParent();
62 void setBackTransform();
64 QDeclarative1Flipable::Side current;
65 QDeclarativeGuard<QGraphicsObject> front;
66 QDeclarativeGuard<QGraphicsObject> back;
68 bool wantBackXFlipped;
69 bool wantBackYFlipped;
73 \qmlclass Flipable QDeclarative1Flipable
75 \ingroup qml-basic-interaction-elements
76 \brief The Flipable item provides a surface that can be flipped.
79 Flipable is an item that can be visibly "flipped" between its front and
80 back sides, like a card. It is used together with \l Rotation, \l State
81 and \l Transition elements to produce a flipping effect.
83 The \l front and \l back properties are used to hold the items that are
84 shown respectively on the front and back sides of the flipable item.
86 \section1 Example Usage
88 The following example shows a Flipable item that flips whenever it is
89 clicked, rotating about the y-axis.
91 This flipable item has a \c flipped boolean property that is toggled
92 whenever the MouseArea within the flipable is clicked. When
93 \c flipped is true, the item changes to the "back" state; in this
94 state, the \c angle of the \l Rotation item is changed to 180
95 degrees to produce the flipping effect. When \c flipped is false, the
96 item reverts to the default state, in which the \c angle value is 0.
98 \snippet doc/src/snippets/declarative/flipable/flipable.qml 0
102 The \l Transition creates the animation that changes the angle over
103 four seconds. When the item changes between its "back" and
104 default states, the NumberAnimation animates the angle between
105 its old and new values.
107 See \l {QML States} for details on state changes and the default
108 state, and \l {QML Animation and Transitions} for more information on how
109 animations work within transitions.
111 \sa {declarative/ui-components/flipable}{Flipable example}
114 QDeclarative1Flipable::QDeclarative1Flipable(QDeclarativeItem *parent)
115 : QDeclarativeItem(*(new QDeclarative1FlipablePrivate), parent)
119 QDeclarative1Flipable::~QDeclarative1Flipable()
124 \qmlproperty Item Flipable::front
125 \qmlproperty Item Flipable::back
127 The front and back sides of the flipable.
130 QGraphicsObject *QDeclarative1Flipable::front()
132 Q_D(const QDeclarative1Flipable);
136 void QDeclarative1Flipable::setFront(QGraphicsObject *front)
138 Q_D(QDeclarative1Flipable);
140 qmlInfo(this) << tr("front is a write-once property");
144 d->front->setParentItem(this);
145 if (Back == d->current)
146 d->front->setOpacity(0.);
150 QGraphicsObject *QDeclarative1Flipable::back()
152 Q_D(const QDeclarative1Flipable);
156 void QDeclarative1Flipable::setBack(QGraphicsObject *back)
158 Q_D(QDeclarative1Flipable);
160 qmlInfo(this) << tr("back is a write-once property");
164 d->back->setParentItem(this);
165 if (Front == d->current)
166 d->back->setOpacity(0.);
167 connect(back, SIGNAL(widthChanged()),
168 this, SLOT(retransformBack()));
169 connect(back, SIGNAL(heightChanged()),
170 this, SLOT(retransformBack()));
174 void QDeclarative1Flipable::retransformBack()
176 Q_D(QDeclarative1Flipable);
177 if (d->current == QDeclarative1Flipable::Back && d->back)
178 d->setBackTransform();
182 \qmlproperty enumeration Flipable::side
184 The side of the Flipable currently visible. Possible values are \c
185 Flipable.Front and \c Flipable.Back.
187 QDeclarative1Flipable::Side QDeclarative1Flipable::side() const
189 Q_D(const QDeclarative1Flipable);
190 if (d->dirtySceneTransform)
191 const_cast<QDeclarative1FlipablePrivate *>(d)->ensureSceneTransform();
196 // determination on the currently visible side of the flipable
197 // has to be done on the complete scene transform to give
199 void QDeclarative1FlipablePrivate::updateSceneTransformFromParent()
201 Q_Q(QDeclarative1Flipable);
203 QDeclarativeItemPrivate::updateSceneTransformFromParent();
208 QPointF scenep1 = sceneTransform.map(p1);
209 QPointF scenep2 = sceneTransform.map(p2);
210 QPointF scenep3 = sceneTransform.map(p3);
211 p1 = q->mapToParent(p1);
212 p2 = q->mapToParent(p2);
213 p3 = q->mapToParent(p3);
215 qreal cross = (scenep1.x() - scenep2.x()) * (scenep3.y() - scenep2.y()) -
216 (scenep1.y() - scenep2.y()) * (scenep3.x() - scenep2.x());
218 wantBackYFlipped = p1.x() >= p2.x();
219 wantBackXFlipped = p2.y() >= p3.y();
221 QDeclarative1Flipable::Side newSide;
223 newSide = QDeclarative1Flipable::Back;
225 newSide = QDeclarative1Flipable::Front;
228 if (newSide != current) {
230 if (current == QDeclarative1Flipable::Back && back)
233 front->setOpacity((current==QDeclarative1Flipable::Front)?1.:0.);
235 back->setOpacity((current==QDeclarative1Flipable::Back)?1.:0.);
236 emit q->sideChanged();
240 /* Depends on the width/height of the back item, and so needs reevaulating
243 void QDeclarative1FlipablePrivate::setBackTransform()
246 QGraphicsItemPrivate *dBack = QGraphicsItemPrivate::get(back);
247 mat.translate(dBack->width()/2,dBack->height()/2);
248 if (dBack->width() && wantBackYFlipped)
249 mat.rotate(180, Qt::YAxis);
250 if (dBack->height() && wantBackXFlipped)
251 mat.rotate(180, Qt::XAxis);
252 mat.translate(-dBack->width()/2,-dBack->height()/2);
253 back->setTransform(mat);