aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Brasser <michael.brasser@nokia.com>2011-06-03 16:08:32 +1000
committerMichael Brasser <michael.brasser@nokia.com>2011-06-10 11:19:40 +1000
commit17bd3e24a18797e6b565235d2d922a807137041a (patch)
tree5b34d84f3fa3a27a523139313f776c67630cf3dd
parentdf4add062fc7368d9fee7c697405c43422b0af27 (diff)
Introduce StateChange element.
-rw-r--r--src/declarative/qml/v8/qv8qobjectwrapper_p.h1
-rw-r--r--src/declarative/util/qdeclarativestate.cpp22
-rw-r--r--src/declarative/util/qdeclarativestate_p.h5
-rw-r--r--src/declarative/util/qdeclarativestate_p_p.h23
-rw-r--r--src/declarative/util/qdeclarativestatechange.cpp194
-rw-r--r--src/declarative/util/qdeclarativestatechange_p.h104
-rw-r--r--src/declarative/util/qdeclarativeutilmodule.cpp3
-rw-r--r--src/declarative/util/util.pri6
8 files changed, 355 insertions, 3 deletions
diff --git a/src/declarative/qml/v8/qv8qobjectwrapper_p.h b/src/declarative/qml/v8/qv8qobjectwrapper_p.h
index 5100c3f51b..fafa2f2830 100644
--- a/src/declarative/qml/v8/qv8qobjectwrapper_p.h
+++ b/src/declarative/qml/v8/qv8qobjectwrapper_p.h
@@ -90,6 +90,7 @@ private:
friend class QDeclarativePropertyCache;
friend class QV8QObjectConnectionList;
friend class QV8QObjectInstance;
+ friend class QDeclarativeStateChange;
v8::Local<v8::Object> newQObject(QObject *, QDeclarativeData *, QV8Engine *);
static v8::Handle<v8::Value> GetProperty(QV8Engine *, QObject *, v8::Handle<v8::Value> *,
diff --git a/src/declarative/util/qdeclarativestate.cpp b/src/declarative/util/qdeclarativestate.cpp
index 9f56ccb02e..054d92ce7f 100644
--- a/src/declarative/util/qdeclarativestate.cpp
+++ b/src/declarative/util/qdeclarativestate.cpp
@@ -301,6 +301,14 @@ QDeclarativeState &QDeclarativeState::operator<<(QDeclarativeStateOperation *op)
return *this;
}
+QDeclarativeListProperty<QDeclarativeStateChange> QDeclarativeState::stateChanges()
+{
+ Q_D(QDeclarativeState);
+ return QDeclarativeListProperty<QDeclarativeStateChange>(this, &d->stateChanges, QDeclarativeStatePrivate::stateChanges_append,
+ QDeclarativeStatePrivate::stateChanges_count, QDeclarativeStatePrivate::stateChanges_at,
+ QDeclarativeStatePrivate::stateChanges_clear);
+}
+
void QDeclarativeStatePrivate::complete()
{
Q_Q(QDeclarativeState);
@@ -315,6 +323,9 @@ void QDeclarativeStatePrivate::complete()
}
reverting.clear();
+ for (int i = 0; i < stateChanges.count(); ++i)
+ stateChanges.at(i)->setActive(true);
+
emit q->completed();
}
@@ -364,6 +375,15 @@ void QDeclarativeState::cancel()
d->transitionManager.cancel();
}
+void QDeclarativeState::prepareForExit()
+{
+ Q_D(QDeclarativeState);
+ cancel();
+
+ for (int i = 0; i < d->stateChanges.count(); ++i)
+ d->stateChanges.at(i)->setActive(false);
+}
+
void QDeclarativeAction::deleteFromBinding()
{
if (fromBinding) {
@@ -567,7 +587,7 @@ void QDeclarativeState::apply(QDeclarativeStateGroup *group, QDeclarativeTransit
cancel();
if (revert)
- revert->cancel();
+ revert->prepareForExit();
d->revertList.clear();
d->reverting.clear();
diff --git a/src/declarative/util/qdeclarativestate_p.h b/src/declarative/util/qdeclarativestate_p.h
index d24304ccf5..a875621600 100644
--- a/src/declarative/util/qdeclarativestate_p.h
+++ b/src/declarative/util/qdeclarativestate_p.h
@@ -47,6 +47,7 @@
#include <QtCore/qobject.h>
#include <QtCore/qsharedpointer.h>
#include <private/qdeclarativeglobal_p.h>
+#include <private/qdeclarativestatechange_p.h>
QT_BEGIN_HEADER
@@ -148,6 +149,7 @@ class Q_DECLARATIVE_EXPORT QDeclarativeState : public QObject
Q_PROPERTY(QDeclarativeBinding *when READ when WRITE setWhen)
Q_PROPERTY(QString extend READ extends WRITE setExtends)
Q_PROPERTY(QDeclarativeListProperty<QDeclarativeStateOperation> changes READ changes)
+ Q_PROPERTY(QDeclarativeListProperty<QDeclarativeStateChange> stateChanges READ stateChanges)
Q_CLASSINFO("DefaultProperty", "changes")
Q_CLASSINFO("DeferredPropertyNames", "changes")
@@ -174,8 +176,11 @@ public:
QDeclarativeState &operator<<(QDeclarativeStateOperation *);
+ QDeclarativeListProperty<QDeclarativeStateChange> stateChanges();
+
void apply(QDeclarativeStateGroup *, QDeclarativeTransition *, QDeclarativeState *revert);
void cancel();
+ void prepareForExit();
QDeclarativeStateGroup *stateGroup() const;
void setStateGroup(QDeclarativeStateGroup *);
diff --git a/src/declarative/util/qdeclarativestate_p_p.h b/src/declarative/util/qdeclarativestate_p_p.h
index ec18f59b08..011498048f 100644
--- a/src/declarative/util/qdeclarativestate_p_p.h
+++ b/src/declarative/util/qdeclarativestate_p_p.h
@@ -236,6 +236,29 @@ public:
return list->at(index);
}
+ //### should use same "guarded" approach as above
+ QList<QDeclarativeStateChange*> stateChanges;
+ static void stateChanges_append(QDeclarativeListProperty<QDeclarativeStateChange> *prop, QDeclarativeStateChange *change) {
+ QList<QDeclarativeStateChange*> *list = static_cast<QList<QDeclarativeStateChange*> *>(prop->data);
+ change->setState(qobject_cast<QDeclarativeState*>(prop->object));
+ list->append(change);
+ }
+ static void stateChanges_clear(QDeclarativeListProperty<QDeclarativeStateChange> *prop) {
+ QList<QDeclarativeStateChange*> *list = static_cast<QList<QDeclarativeStateChange*> *>(prop->data);
+ QMutableListIterator<QDeclarativeStateChange*> listIterator(*list);
+ while(listIterator.hasNext())
+ listIterator.next()->setState(0);
+ list->clear();
+ }
+ static int stateChanges_count(QDeclarativeListProperty<QDeclarativeStateChange> *prop) {
+ QList<QDeclarativeStateChange*> *list = static_cast<QList<QDeclarativeStateChange*> *>(prop->data);
+ return list->count();
+ }
+ static QDeclarativeStateChange *stateChanges_at(QDeclarativeListProperty<QDeclarativeStateChange> *prop, int index) {
+ QList<QDeclarativeStateChange*> *list = static_cast<QList<QDeclarativeStateChange*> *>(prop->data);
+ return list->at(index);
+ }
+
QDeclarativeTransitionManager transitionManager;
SimpleActionList revertList;
diff --git a/src/declarative/util/qdeclarativestatechange.cpp b/src/declarative/util/qdeclarativestatechange.cpp
new file mode 100644
index 0000000000..d0b5800f77
--- /dev/null
+++ b/src/declarative/util/qdeclarativestatechange.cpp
@@ -0,0 +1,194 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdeclarativestatechange_p.h"
+
+#include <qdeclarativeexpression.h>
+#include "qdeclarativeinfo.h"
+#include "qdeclarativestate_p.h"
+#include "qdeclarativestategroup_p.h"
+#include "qdeclarativeexpression_p.h"
+#include "qv8qobjectwrapper_p.h"
+
+QT_BEGIN_NAMESPACE
+
+int QDeclarativeStateChange::m_activateIdx = -1;
+
+QDeclarativeStateChange::QDeclarativeStateChange(QObject *parent) :
+ QObject(parent), m_state(0), m_expression(0),
+ m_triggerObject(0), m_triggerIdx(-1), m_triggerDirty(false)
+{
+}
+
+QDeclarativeStateChange::~QDeclarativeStateChange()
+{
+ delete m_expression;
+}
+
+QString QDeclarativeStateChange::toState() const
+{
+ return m_toState;
+}
+
+void QDeclarativeStateChange::setToState(QString arg)
+{
+ if (m_toState == arg)
+ return;
+
+ m_toState = arg;
+ emit toStateChanged(arg);
+}
+
+QDeclarativeScriptString QDeclarativeStateChange::when() const
+{
+ return m_when;
+}
+
+void QDeclarativeStateChange::setWhen(QDeclarativeScriptString arg)
+{
+ if (!m_when.script().isEmpty()) {
+ qmlInfo(this) << "'when' clause cannot be changed (can only be set once).";
+ return;
+ }
+
+ m_when = arg;
+}
+
+QDeclarativeScriptString QDeclarativeStateChange::trigger() const
+{
+ return m_trigger;
+}
+
+void QDeclarativeStateChange::setTrigger(QDeclarativeScriptString arg)
+{
+ if (!m_when.script().isEmpty()) {
+ qmlInfo(this) << "'trigger' clause cannot be changed (can only be set once).";
+ return;
+ }
+
+ m_trigger = arg;
+ m_triggerDirty = true;
+}
+
+void QDeclarativeStateChange::createTrigger()
+{
+ if (!m_triggerDirty)
+ return;
+
+ QDeclarativeExpression triggerExpression(m_trigger.context(), m_trigger.scopeObject(), m_trigger.script());
+ QDeclarativeExpressionPrivate *exp = QDeclarativeExpressionPrivate::get(&triggerExpression);
+
+ QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(m_trigger.context());
+
+ QPair<QObject*, int> qtMethod;
+ {
+ v8::HandleScope handle_scope;
+ v8::Local<v8::Value> result = exp->v8value();
+ if (!result->IsFunction())
+ return; //### exception?
+
+ qtMethod = QV8QObjectWrapper::ExtractQtMethod(&ep->v8engine, v8::Handle<v8::Function>::Cast(result));
+ }
+
+ if (!qtMethod.first)
+ return; //### exception?
+
+ //verify that the method is a signal
+ QMetaMethod method = qtMethod.first->metaObject()->method(qtMethod.second);
+ if (method.methodType() != QMetaMethod::Signal)
+ return; //### exception?
+
+ m_triggerObject = qtMethod.first;
+ m_triggerIdx = qtMethod.second;
+
+ m_triggerDirty = false;
+}
+
+void QDeclarativeStateChange::setState(QDeclarativeState *state)
+{
+ m_state = state;
+
+ if (!m_state)
+ setActive(false);
+}
+
+void QDeclarativeStateChange::setActive(bool active)
+{
+ //qDebug() << "activating" << active << this;
+ if (active) {
+ createTrigger();
+ if (m_triggerObject) {
+ if (m_activateIdx < 0)
+ m_activateIdx = QDeclarativeStateChange::staticMetaObject.indexOfSlot("activate()");
+ QMetaObject::connect(m_triggerObject, m_triggerIdx, this, m_activateIdx);
+ }
+
+ if (!m_when.script().isEmpty()) {
+ if (!m_expression) {
+ m_expression = new QDeclarativeExpression(m_when.context(), m_when.scopeObject(), m_when.script());
+ connect(m_expression, SIGNAL(valueChanged()), this, SLOT(updateState()));
+ }
+ if (!m_triggerObject) //when is only 'active' if there is no trigger. Otherwise it is 'passive'
+ m_expression->setNotifyOnValueChanged(true);
+ m_expression->evaluate();
+ }
+ } else {
+ if (m_triggerObject)
+ QMetaObject::disconnect(m_triggerObject, m_triggerIdx, this, m_activateIdx);
+ if (m_expression)
+ m_expression->setNotifyOnValueChanged(false);
+ }
+}
+
+void QDeclarativeStateChange::updateState()
+{
+ QVariant value = !m_when.script().isEmpty() ? m_expression->evaluate() : QVariant(true);
+
+ if (value.toBool())
+ m_state->stateGroup()->setState(m_toState);
+}
+
+void QDeclarativeStateChange::activate()
+{
+ updateState();
+}
+
+QT_END_NAMESPACE
diff --git a/src/declarative/util/qdeclarativestatechange_p.h b/src/declarative/util/qdeclarativestatechange_p.h
new file mode 100644
index 0000000000..fe79182128
--- /dev/null
+++ b/src/declarative/util/qdeclarativestatechange_p.h
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDECLARATIVESTATECHANGE_P_H
+#define QDECLARATIVESTATECHANGE_P_H
+
+#include <QObject>
+#include <QtScript/qscriptvalue.h>
+#include <qdeclarativescriptstring.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QDeclarativeState;
+class QDeclarativeExpression;
+class QDeclarativeStateChange : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QString toState READ toState WRITE setToState NOTIFY toStateChanged)
+ Q_PROPERTY(QDeclarativeScriptString when READ when WRITE setWhen)
+ Q_PROPERTY(QDeclarativeScriptString trigger READ trigger WRITE setTrigger)
+public:
+ explicit QDeclarativeStateChange(QObject *parent = 0);
+ ~QDeclarativeStateChange();
+
+ QString toState() const;
+ void setToState(QString arg);
+
+
+ QDeclarativeScriptString when() const;
+ void setWhen(QDeclarativeScriptString arg);
+
+ QDeclarativeScriptString trigger() const;
+ void setTrigger(QDeclarativeScriptString arg);
+
+ void setState(QDeclarativeState *);
+ void setActive(bool active);
+
+Q_SIGNALS:
+ void toStateChanged(QString arg);
+
+private Q_SLOTS:
+ void updateState();
+ void activate();
+
+private:
+ void createTrigger();
+ QString m_toState;
+ QDeclarativeState *m_state;
+ QDeclarativeScriptString m_when;
+ QDeclarativeExpression *m_expression;
+ QDeclarativeScriptString m_trigger;
+ QObject *m_triggerObject;
+ int m_triggerIdx;
+ bool m_triggerDirty;
+ static int m_activateIdx;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QDECLARATIVESTATECHANGE_P_H
diff --git a/src/declarative/util/qdeclarativeutilmodule.cpp b/src/declarative/util/qdeclarativeutilmodule.cpp
index 4bea2e651a..dc7930bff0 100644
--- a/src/declarative/util/qdeclarativeutilmodule.cpp
+++ b/src/declarative/util/qdeclarativeutilmodule.cpp
@@ -73,6 +73,7 @@
#ifndef QT_NO_XMLPATTERNS
#include "private/qdeclarativexmllistmodel_p.h"
#endif
+#include "qdeclarativestatechange_p.h"
void QDeclarativeUtilModule::defineModule()
{
@@ -126,6 +127,8 @@ void QDeclarativeUtilModule::defineModule()
qmlRegisterCustomType<QDeclarativePropertyChanges>("QtQuick",1,0,"PropertyChanges", new QDeclarativePropertyChangesParser);
qmlRegisterCustomType<QDeclarativeConnections>("QtQuick",1,0,"Connections", new QDeclarativeConnectionsParser);
+ qmlRegisterType<QDeclarativeStateChange>("QtQuick",2,0,"StateChange");
+
#ifndef QT_NO_IMPORT_QT47_QML
qmlRegisterType<QDeclarativeAnchorAnimation>("Qt",4,7,"AnchorAnimation");
qmlRegisterType<QDeclarativeAnchorChanges>("Qt",4,7,"AnchorChanges");
diff --git a/src/declarative/util/util.pri b/src/declarative/util/util.pri
index 5bc8b117c0..157c736bcc 100644
--- a/src/declarative/util/util.pri
+++ b/src/declarative/util/util.pri
@@ -28,7 +28,8 @@ SOURCES += \
$$PWD/qdeclarativefontloader.cpp \
$$PWD/qdeclarativestyledtext.cpp \
$$PWD/qdeclarativelistmodelworkeragent.cpp \
- $$PWD/qlistmodelinterface.cpp
+ $$PWD/qlistmodelinterface.cpp \
+ util/qdeclarativestatechange.cpp
HEADERS += \
$$PWD/qdeclarativeapplication_p.h \
@@ -63,7 +64,8 @@ HEADERS += \
$$PWD/qdeclarativefontloader_p.h \
$$PWD/qdeclarativestyledtext_p.h \
$$PWD/qdeclarativelistmodelworkeragent_p.h \
- $$PWD/qlistmodelinterface_p.h
+ $$PWD/qlistmodelinterface_p.h \
+ util/qdeclarativestatechange_p.h
contains(QT_CONFIG, xmlpatterns) {
QT+=xmlpatterns