1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the QtDeclarative module of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #include "qquickflipable_p.h"
43 #include "qquickitem_p.h"
45 #include <private/qdeclarativeguard_p.h>
47 #include <QtDeclarative/qdeclarativeinfo.h>
51 // XXX todo - i think this needs work and a bit of a re-think
53 class QQuickLocalTransform : public QQuickTransform
57 QQuickLocalTransform(QObject *parent) : QQuickTransform(parent) {}
59 void setTransform(const QTransform &t) {
63 virtual void applyTo(QMatrix4x4 *matrix) const {
70 class QQuickFlipablePrivate : public QQuickItemPrivate
72 Q_DECLARE_PUBLIC(QQuickFlipable)
74 QQuickFlipablePrivate() : current(QQuickFlipable::Front), front(0), back(0), sideDirty(false) {}
76 virtual void transformChanged();
78 void setBackTransform();
80 QQuickFlipable::Side current;
81 QDeclarativeGuard<QQuickLocalTransform> backTransform;
82 QDeclarativeGuard<QQuickItem> front;
83 QDeclarativeGuard<QQuickItem> back;
86 bool wantBackXFlipped;
87 bool wantBackYFlipped;
91 \qmlclass Flipable QQuickFlipable
92 \inqmlmodule QtQuick 2
93 \ingroup qml-basic-interaction-elements
94 \brief The Flipable item provides a surface that can be flipped.
97 Flipable is an item that can be visibly "flipped" between its front and
98 back sides, like a card. It is used together with \l Rotation, \l State
99 and \l Transition elements to produce a flipping effect.
101 The \l front and \l back properties are used to hold the items that are
102 shown respectively on the front and back sides of the flipable item.
104 \section1 Example Usage
106 The following example shows a Flipable item that flips whenever it is
107 clicked, rotating about the y-axis.
109 This flipable item has a \c flipped boolean property that is toggled
110 whenever the MouseArea within the flipable is clicked. When
111 \c flipped is true, the item changes to the "back" state; in this
112 state, the \c angle of the \l Rotation item is changed to 180
113 degrees to produce the flipping effect. When \c flipped is false, the
114 item reverts to the default state, in which the \c angle value is 0.
116 \snippet doc/src/snippets/declarative/flipable/flipable.qml 0
120 The \l Transition creates the animation that changes the angle over
121 four seconds. When the item changes between its "back" and
122 default states, the NumberAnimation animates the angle between
123 its old and new values.
125 See \l {QML States} for details on state changes and the default
126 state, and \l {QML Animation and Transitions} for more information on how
127 animations work within transitions.
129 \sa {declarative/ui-components/flipable}{Flipable example}
131 QQuickFlipable::QQuickFlipable(QQuickItem *parent)
132 : QQuickItem(*(new QQuickFlipablePrivate), parent)
136 QQuickFlipable::~QQuickFlipable()
141 \qmlproperty Item QtQuick2::Flipable::front
142 \qmlproperty Item QtQuick2::Flipable::back
144 The front and back sides of the flipable.
147 QQuickItem *QQuickFlipable::front()
149 Q_D(const QQuickFlipable);
153 void QQuickFlipable::setFront(QQuickItem *front)
157 qmlInfo(this) << tr("front is a write-once property");
161 d->front->setParentItem(this);
162 if (Back == d->current)
163 d->front->setOpacity(0.);
167 QQuickItem *QQuickFlipable::back()
169 Q_D(const QQuickFlipable);
173 void QQuickFlipable::setBack(QQuickItem *back)
177 qmlInfo(this) << tr("back is a write-once property");
183 d->back->setParentItem(this);
185 d->backTransform = new QQuickLocalTransform(d->back);
186 d->backTransform->prependToItem(d->back);
188 if (Front == d->current)
189 d->back->setOpacity(0.);
190 connect(back, SIGNAL(widthChanged()),
191 this, SLOT(retransformBack()));
192 connect(back, SIGNAL(heightChanged()),
193 this, SLOT(retransformBack()));
197 void QQuickFlipable::retransformBack()
200 if (d->current == QQuickFlipable::Back && d->back)
201 d->setBackTransform();
205 \qmlproperty enumeration QtQuick2::Flipable::side
207 The side of the Flipable currently visible. Possible values are \c
208 Flipable.Front and \c Flipable.Back.
210 QQuickFlipable::Side QQuickFlipable::side() const
212 Q_D(const QQuickFlipable);
214 const_cast<QQuickFlipablePrivate *>(d)->updateSide();
218 void QQuickFlipablePrivate::transformChanged()
227 QQuickItemPrivate::transformChanged();
230 void QQuickFlipable::updatePolish()
236 // determination on the currently visible side of the flipable
237 // has to be done on the complete scene transform to give
239 void QQuickFlipablePrivate::updateSide()
248 QTransform sceneTransform;
249 itemToParentTransform(sceneTransform);
255 QPointF scenep1 = sceneTransform.map(p1);
256 QPointF scenep2 = sceneTransform.map(p2);
257 QPointF scenep3 = sceneTransform.map(p3);
259 p1 = q->mapToParent(p1);
260 p2 = q->mapToParent(p2);
261 p3 = q->mapToParent(p3);
264 qreal cross = (scenep1.x() - scenep2.x()) * (scenep3.y() - scenep2.y()) -
265 (scenep1.y() - scenep2.y()) * (scenep3.x() - scenep2.x());
267 wantBackYFlipped = scenep1.x() >= scenep2.x();
268 wantBackXFlipped = scenep2.y() >= scenep3.y();
270 QQuickFlipable::Side newSide;
272 newSide = QQuickFlipable::Back;
274 newSide = QQuickFlipable::Front;
277 if (newSide != current) {
279 if (current == QQuickFlipable::Back && back)
282 front->setOpacity((current==QQuickFlipable::Front)?1.:0.);
284 back->setOpacity((current==QQuickFlipable::Back)?1.:0.);
285 emit q->sideChanged();
289 /* Depends on the width/height of the back item, and so needs reevaulating
292 void QQuickFlipablePrivate::setBackTransform()
295 mat.translate(back->width()/2,back->height()/2);
296 if (back->width() && wantBackYFlipped)
297 mat.rotate(180, Qt::YAxis);
298 if (back->height() && wantBackXFlipped)
299 mat.rotate(180, Qt::XAxis);
300 mat.translate(-back->width()/2,-back->height()/2);
303 backTransform->setTransform(mat);
308 #include "qquickflipable.moc"