diff options
Diffstat (limited to 'src/declarative/util/qmlstateoperations.cpp')
-rw-r--r-- | src/declarative/util/qmlstateoperations.cpp | 416 |
1 files changed, 416 insertions, 0 deletions
diff --git a/src/declarative/util/qmlstateoperations.cpp b/src/declarative/util/qmlstateoperations.cpp new file mode 100644 index 0000000..c2ba4b8 --- /dev/null +++ b/src/declarative/util/qmlstateoperations.cpp @@ -0,0 +1,416 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <private/qobject_p.h> +#include <gfxeasing.h> +#include <qml.h> +#include <QtDeclarative/qmlcontext.h> +#include "qmlbindablevalue.h" +#include "qmlstateoperations.h" +#include <QtCore/qdebug.h> +#include <QtDeclarative/qmlinfo.h> + +QT_BEGIN_NAMESPACE + +class QmlParentChangePrivate : public QObjectPrivate +{ +public: + QmlParentChangePrivate() : target(0), parent(0) {} + + QObject *target; + QObject *parent; +}; + +/*! + \qmlclass ParentChange + \brief The ParentChange element allows you to reparent an object in a state. +*/ + +QML_DEFINE_TYPE(QmlParentChange,ParentChange); +QmlParentChange::QmlParentChange(QObject *parent) + : QmlStateOperation(*(new QmlParentChangePrivate), parent) +{ +} + +QmlParentChange::~QmlParentChange() +{ +} + +/*! + \qmlproperty Object ParentChange::target + This property holds the object to be reparented +*/ + +QObject *QmlParentChange::object() const +{ + Q_D(const QmlParentChange); + return d->target; +} +void QmlParentChange::setObject(QObject *target) +{ + Q_D(QmlParentChange); + d->target = target; +} + +/*! + \qmlproperty Object ParentChange::parent + This property holds the parent for the object in this state +*/ + +QObject *QmlParentChange::parent() const +{ + Q_D(const QmlParentChange); + return d->parent; +} + +void QmlParentChange::setParent(QObject *parent) +{ + Q_D(QmlParentChange); + d->parent = parent; +} + +QmlStateOperation::ActionList QmlParentChange::actions() +{ + Q_D(QmlParentChange); + if(!d->target || !d->parent) + return ActionList(); + + QString propName(QLatin1String("moveToParent")); + QmlMetaProperty prop(d->target, propName); + if (!prop.isValid()) { + qmlInfo(this) << d->target->metaObject()->className() + << "has no property named" << propName; + return ActionList(); + }else if(!prop.isWritable()){ + qmlInfo(this) << d->target->metaObject()->className() << propName + << "is not a writable property and cannot be set."; + return ActionList(); + } + QVariant cur = prop.read(); + + Action a; + a.property = prop; + a.fromValue = cur; + a.toValue = qVariantFromValue(d->parent); + + return ActionList() << a; +} + +class QmlRunScriptPrivate : public QObjectPrivate +{ +public: + QmlRunScriptPrivate() : ctxt(0) {} + + QmlContext *ctxt; + QString script; + QString name; +}; + +/*! + \qmlclass RunScript QmlRunScript + \brief The RunScript element allows you to run a script in a state. +*/ +QML_DEFINE_TYPE(QmlRunScript,RunScript); +QmlRunScript::QmlRunScript(QObject *parent) +: QmlStateOperation(*(new QmlRunScriptPrivate), parent) +{ + Q_D(QmlRunScript); + d->ctxt = QmlContext::activeContext(); +} + +QmlRunScript::~QmlRunScript() +{ +} + +/*! + \qmlproperty string RunScript::script + This property holds the script to run when the state is current. +*/ +QString QmlRunScript::script() const +{ + Q_D(const QmlRunScript); + return d->script; +} + +void QmlRunScript::setScript(const QString &s) +{ + Q_D(QmlRunScript); + d->script = s; +} + +QString QmlRunScript::name() const +{ + Q_D(const QmlRunScript); + return d->name; +} + +void QmlRunScript::setName(const QString &n) +{ + Q_D(QmlRunScript); + d->name = n; +} + +void QmlRunScript::execute() +{ + Q_D(QmlRunScript); + if(!d->script.isEmpty()) { + QmlExpression expr(d->ctxt, d->script, this); + expr.setTrackChange(false); + expr.value(); + } +} + +QmlRunScript::ActionList QmlRunScript::actions() +{ + ActionList rv; + Action a; + a.event = this; + rv << a; + return rv; +} + +/*! + \qmlclass SetProperty QmlSetProperty + \brief The SetProperty element describes a new property value or binding for a state. + + The code below changes the position of the Rect depending upon + the current state: + + \code + <Rect id="myrect" width="50" height="50" color="red"/> + + <states> + <State name="Position1"> + <SetProperty target="{myrect}" property="x" value="150"/> + <SetProperty target="{myrect}" property="y" value="50"/> + </State> + <State name="Position2"> + <SetProperty target="{myrect}" property="y" value="200"/> + </State> + </states> + \endcode + + \sa SetProperties +*/ + +/*! + \internal + \class QmlSetProperty + \brief The QmlSetProperty class describes a new property value or binding for a state. + + \ingroup states + + \sa QmlSetProperties +*/ + +class QmlSetPropertyPrivate : public QObjectPrivate +{ +public: + QmlSetPropertyPrivate() : obj(0) {} + + QObject *obj; + QString prop; + QVariant value; + QString binding; +}; + +QML_DEFINE_TYPE(QmlSetProperty,SetProperty); + +QmlSetProperty::QmlSetProperty(QObject *parent) + : QmlStateOperation(*(new QmlSetPropertyPrivate), parent) +{ +} + +QmlSetProperty::~QmlSetProperty() +{ +} + +/*! + \qmlproperty Object SetProperty::target + This property holds the object the property to change belongs to +*/ + +/*! + \property QmlSetProperty::target + \brief the object the property to change belongs to +*/ +QObject *QmlSetProperty::object() +{ + Q_D(QmlSetProperty); + return d->obj; +} + +void QmlSetProperty::setObject(QObject *o) +{ + Q_D(QmlSetProperty); + d->obj = o; +} + +/*! + \qmlproperty string SetProperty::property + This property holds the name of the property to change +*/ + +/*! + \property QmlSetProperty::property + \brief the name of the property to change +*/ +QString QmlSetProperty::property() const +{ + Q_D(const QmlSetProperty); + return d->prop; +} + +void QmlSetProperty::setProperty(const QString &p) +{ + Q_D(QmlSetProperty); + d->prop = p; +} + +/*! + \qmlproperty variant SetProperty::value + This property holds the value to assign to the property + + You should set either a \c value or a \c binding, but not both. +*/ + +/*! + \property QmlSetProperty::value + \brief the value to assign to the property + + You should set either a value or a binding, not both. +*/ +QVariant QmlSetProperty::value() const +{ + Q_D(const QmlSetProperty); + return d->value; +} + +void QmlSetProperty::setValue(const QVariant &v) +{ + Q_D(QmlSetProperty); + d->value = v; +} + +/*! + \qmlproperty string SetProperty::binding + This property holds the binding to assign to the property + + You should set either a \c value or a \c binding, but not both. +*/ + +/*! + \property QmlSetProperty::binding + \brief the binding to assign to the property + + You should set either a value or a binding, not both. +*/ +QString QmlSetProperty::binding() const +{ + Q_D(const QmlSetProperty); + return d->binding; +} + +void QmlSetProperty::setBinding(const QString &binding) +{ + Q_D(QmlSetProperty); + d->binding = binding; +} + +QmlSetProperty::ActionList QmlSetProperty::actions() +{ + Q_D(QmlSetProperty); + if(!d->obj) + return ActionList(); + + QObject *obj = d->obj; + QString propName = d->prop; + + if (d->prop.contains(QLatin1Char('.'))) { //handle dot properties + QStringList str = d->prop.split(QLatin1Char('.')); + for(int ii = 0; ii < str.count()-1; ++ii) { + const QString &s = str.at(ii); + QmlMetaProperty prop(obj, s); + if(!prop.isValid()) { + qmlInfo(this) << obj->metaObject()->className() + << "has no property named" << s; + return ActionList(); + } + QVariant v = prop.read(); + obj = QmlMetaType::toQObject(v); + if (!obj) { + qmlInfo(this) << "Unable to coerce value property" + << s << "into a QObject"; + return ActionList(); + } + } + propName = str.last(); + } + + QmlMetaProperty prop(obj, propName); + if (!prop.isValid()) { + qmlInfo(this) << obj->metaObject()->className() + << "has no property named" << propName; + return ActionList(); + }else if(!prop.isWritable()){ + qmlInfo(this) << obj->metaObject()->className() << propName + << "is not a writable property and cannot be set."; + return ActionList(); + } + QVariant cur = prop.read(); + + Action a; + a.property = prop; + a.fromValue = cur; + a.toValue = d->value; + if (!d->binding.isEmpty()) { + QmlBindableValue *bv = prop.binding(); + if(bv) { + a.fromBinding = bv->expression(); + a.bv = bv; + } + } + a.toBinding = d->binding; + + return ActionList() << a; +} + +QT_END_NAMESPACE |