summaryrefslogtreecommitdiffstats
path: root/src/declarative/util
diff options
context:
space:
mode:
Diffstat (limited to 'src/declarative/util')
-rw-r--r--src/declarative/util/qmlanimation.cpp6
-rw-r--r--src/declarative/util/qmlsetproperties.cpp28
-rw-r--r--src/declarative/util/qmlsetproperties.h4
-rw-r--r--src/declarative/util/qmlstate.cpp84
-rw-r--r--src/declarative/util/qmlstate.h13
-rw-r--r--src/declarative/util/qmlstate_p.h8
-rw-r--r--src/declarative/util/qmlstateoperations.cpp10
7 files changed, 100 insertions, 53 deletions
diff --git a/src/declarative/util/qmlanimation.cpp b/src/declarative/util/qmlanimation.cpp
index 2a6cad9..e5f1138 100644
--- a/src/declarative/util/qmlanimation.cpp
+++ b/src/declarative/util/qmlanimation.cpp
@@ -958,8 +958,6 @@ void QmlColorAnimation::transition(QmlStateActions &actions,
myAction.fromValue = QVariant(d->fromValue);
myAction.toValue = QVariant(d->toValue);
- myAction.bv = 0;
- myAction.event = 0;
data->actions << myAction;
}
}
@@ -1766,8 +1764,6 @@ void QmlNumericAnimation::transition(QmlStateActions &actions,
myAction.fromValue = QVariant(d->from);
myAction.toValue = QVariant(d->to);
- myAction.bv = 0;
- myAction.event = 0;
data->actions << myAction;
}
}
@@ -2332,8 +2328,6 @@ void QmlVariantAnimation::transition(QmlStateActions &actions,
d->convertVariant(d->to, (QVariant::Type)myAction.property.propertyType());
myAction.toValue = d->to;
- myAction.bv = 0;
- myAction.event = 0;
data->actions << myAction;
}
}
diff --git a/src/declarative/util/qmlsetproperties.cpp b/src/declarative/util/qmlsetproperties.cpp
index cb97ed9..240e37b 100644
--- a/src/declarative/util/qmlsetproperties.cpp
+++ b/src/declarative/util/qmlsetproperties.cpp
@@ -47,6 +47,7 @@
#include <private/qmlcustomparser_p.h>
#include <private/qmlparser_p.h>
#include <QtDeclarative/qmlexpression.h>
+#include <QtDeclarative/qmlbindablevalue.h>
QT_BEGIN_NAMESPACE
@@ -113,7 +114,8 @@ class QmlSetPropertiesPrivate : public QObjectPrivate
{
Q_DECLARE_PUBLIC(QmlSetProperties)
public:
- QmlSetPropertiesPrivate() : object(0), decoded(true), restore(true) {}
+ QmlSetPropertiesPrivate() : object(0), decoded(true), restore(true),
+ isExplicit(false) {}
QObject *object;
QByteArray data;
@@ -121,6 +123,7 @@ public:
void decode();
bool restore;
+ bool isExplicit;
QList<QPair<QByteArray, QVariant> > properties;
QList<QPair<QByteArray, QmlExpression *> > expressions;
@@ -205,6 +208,7 @@ QmlSetPropertiesParser::compile(const QList<QmlCustomParserProperty> &props,
void QmlSetPropertiesPrivate::decode()
{
+ Q_Q(QmlSetProperties);
if (decoded)
return;
@@ -221,7 +225,7 @@ void QmlSetPropertiesPrivate::decode()
ds >> data;
if (isScript) {
- QmlExpression *expression = new QmlExpression(qmlContext(object), data.toString(), object);
+ QmlExpression *expression = new QmlExpression(qmlContext(q), data.toString(), object);
expression->setTrackChange(false);
expressions << qMakePair(name, expression);
} else {
@@ -347,7 +351,13 @@ QmlSetProperties::ActionList QmlSetProperties::actions()
a.restore = restoreEntryValues();
a.property = prop;
a.fromValue = a.property.read();
- a.toValue = d->expressions.at(ii).second->value();
+
+ if (d->isExplicit) {
+ a.toValue = d->expressions.at(ii).second->value();
+ } else {
+ a.toBinding = new QmlBindableValue(d->expressions.at(ii).second->expression(), object(), qmlContext(this));
+ a.toBinding->setTarget(prop);
+ }
list << a;
}
@@ -357,6 +367,18 @@ QmlSetProperties::ActionList QmlSetProperties::actions()
return list;
}
+bool QmlSetProperties::isExplicit() const
+{
+ Q_D(const QmlSetProperties);
+ return d->isExplicit;
+}
+
+void QmlSetProperties::setIsExplicit(bool e)
+{
+ Q_D(QmlSetProperties);
+ d->isExplicit = e;
+}
+
QML_DEFINE_CUSTOM_TYPE(QmlSetProperties,SetProperties,QmlSetPropertiesParser)
QT_END_NAMESPACE
diff --git a/src/declarative/util/qmlsetproperties.h b/src/declarative/util/qmlsetproperties.h
index da5fcf2..fe98900 100644
--- a/src/declarative/util/qmlsetproperties.h
+++ b/src/declarative/util/qmlsetproperties.h
@@ -59,6 +59,7 @@ class Q_DECLARATIVE_EXPORT QmlSetProperties : public QmlStateOperation
Q_PROPERTY(QObject *target READ object WRITE setObject)
Q_PROPERTY(bool restoreEntryValues READ restoreEntryValues WRITE setRestoreEntryValues)
+ Q_PROPERTY(bool explicit READ isExplicit WRITE setIsExplicit);
public:
QmlSetProperties();
~QmlSetProperties();
@@ -69,6 +70,9 @@ public:
bool restoreEntryValues() const;
void setRestoreEntryValues(bool);
+ bool isExplicit() const;
+ void setIsExplicit(bool);
+
virtual ActionList actions();
};
QML_DECLARE_TYPE(QmlSetProperties)
diff --git a/src/declarative/util/qmlstate.cpp b/src/declarative/util/qmlstate.cpp
index 0574224..fe215e7 100644
--- a/src/declarative/util/qmlstate.cpp
+++ b/src/declarative/util/qmlstate.cpp
@@ -53,7 +53,7 @@ QT_BEGIN_NAMESPACE
DEFINE_BOOL_CONFIG_OPTION(stateChangeDebug, STATECHANGE_DEBUG);
-Action::Action() : restore(true), bv(0), event(0), actionDone(false)
+Action::Action() : restore(true), actionDone(false), fromBinding(0), toBinding(0), event(0)
{
}
@@ -237,8 +237,9 @@ QmlState &QmlState::operator<<(QmlStateOperation *op)
void QmlStatePrivate::applyBindings()
{
foreach(const Action &action, bindingsList) {
- if (action.bv && !action.toBinding.isEmpty()) {
- action.bv->setExpression(action.toBinding);
+ if (action.toBinding) {
+ action.property.setBinding(action.toBinding);
+ action.toBinding->forceUpdate();
}
}
}
@@ -246,6 +247,7 @@ void QmlStatePrivate::applyBindings()
void QmlStatePrivate::complete()
{
Q_Q(QmlState);
+
//apply bindings (now that all transitions are complete)
applyBindings();
@@ -316,6 +318,15 @@ void QmlState::cancel()
}
}
+void Action::deleteFromBinding()
+{
+ if (fromBinding) {
+ property.setBinding(0);
+ delete fromBinding;
+ fromBinding = 0;
+ }
+}
+
void QmlState::apply(QmlStateGroup *group, QmlTransition *trans, QmlState *revert)
{
Q_D(QmlState);
@@ -341,20 +352,36 @@ void QmlState::apply(QmlStateGroup *group, QmlTransition *trans, QmlState *rever
QmlStatePrivate::SimpleActionList additionalReverts;
// First add the reverse of all the applyList actions
for (int ii = 0; ii < applyList.count(); ++ii) {
- const Action &action = applyList.at(ii);
- if (action.event || !action.restore)
+ Action &action = applyList[ii];
+
+ if (action.event)
continue;
+ action.fromBinding = action.property.binding();
+
bool found = false;
- for (int jj = 0; !found && jj < d->revertList.count(); ++jj) {
- if (d->revertList.at(jj).property == action.property)
+ int jj;
+ for (jj = 0; jj < d->revertList.count(); ++jj) {
+ if (d->revertList.at(jj).property == action.property) {
found = true;
+ break;
+ }
}
+
if (!found) {
- // Only need to revert the applyList action if the previous
- // state doesn't have a higher priority revert already
- SimpleAction r(action);
- additionalReverts << r;
+ if (!action.restore) {
+ action.deleteFromBinding();
+ } else {
+ // Only need to revert the applyList action if the previous
+ // state doesn't have a higher priority revert already
+ SimpleAction r(action);
+ additionalReverts << r;
+ }
+ } else {
+
+ if (!found || d->revertList.at(jj).binding != action.fromBinding) {
+ action.deleteFromBinding();
+ }
}
}
@@ -369,15 +396,13 @@ void QmlState::apply(QmlStateGroup *group, QmlTransition *trans, QmlState *rever
}
if (!found) {
QVariant cur = d->revertList.at(ii).property.read();
+ delete d->revertList.at(ii).property.setBinding(0);
+
Action a;
a.property = d->revertList.at(ii).property;
a.fromValue = cur;
a.toValue = d->revertList.at(ii).value;
a.toBinding = d->revertList.at(ii).binding;
- if (!a.toBinding.isEmpty()) {
- a.fromBinding = d->revertList.at(ii).bv->expression();
- a.bv = d->revertList.at(ii).bv;
- }
applyList << a;
// Store these special reverts in the reverting list
d->reverting << d->revertList.at(ii).property;
@@ -396,9 +421,12 @@ void QmlState::apply(QmlStateGroup *group, QmlTransition *trans, QmlState *rever
// Determine which actions are binding changes.
foreach(const Action &action, applyList) {
- if (action.bv && !action.toBinding.isEmpty()) {
+ if (action.toBinding) {
d->bindingsList << action;
- action.bv->clearExpression();
+ if (action.fromBinding)
+ action.property.setBinding(0); // Disable current binding
+ } else if (action.fromBinding) {
+ action.property.setBinding(0); // Disable current binding
}
}
@@ -415,8 +443,9 @@ void QmlState::apply(QmlStateGroup *group, QmlTransition *trans, QmlState *rever
// Apply all the property and binding changes
foreach(const Action &action, applyList) {
- if (action.bv && !action.toBinding.isEmpty()) {
- action.bv->setExpression(action.toBinding);
+ if (action.toBinding) {
+ action.property.setBinding(action.toBinding);
+ action.toBinding->forceUpdate();
} else if (!action.event) {
action.property.write(action.toValue);
}
@@ -429,9 +458,8 @@ void QmlState::apply(QmlStateGroup *group, QmlTransition *trans, QmlState *rever
continue;
const QmlMetaProperty &prop = action->property;
- if (action->bv && !action->toBinding.isEmpty()) {
+ if (action->toBinding)
action->toValue = prop.read();
- }
}
// Revert back to the original values
@@ -439,8 +467,9 @@ void QmlState::apply(QmlStateGroup *group, QmlTransition *trans, QmlState *rever
if (action.event)
continue;
- if (action.bv && !action.toBinding.isEmpty())
- action.bv->clearExpression();
+ if (action.toBinding)
+ action.property.setBinding(0);
+
action.property.write(action.fromValue);
}
}
@@ -480,12 +509,15 @@ void QmlState::apply(QmlStateGroup *group, QmlTransition *trans, QmlState *rever
}
// Any actions remaining have not been handled by the transition and should
- // be applied immediately
+ // be applied immediately. We skip applying transitions, as they are all
+ // applied at the end in applyBindings() to avoid any nastiness mid
+ // transition
foreach(const Action &action, applyList) {
- if (action.event)
+ if (action.event) {
action.event->execute();
- else
+ } else {
action.property.write(action.toValue);
+ }
}
if (!trans)
d->applyBindings(); //### merge into above foreach?
diff --git a/src/declarative/util/qmlstate.h b/src/declarative/util/qmlstate.h
index 59ef812..e9a173c 100644
--- a/src/declarative/util/qmlstate.h
+++ b/src/declarative/util/qmlstate.h
@@ -60,15 +60,18 @@ class Action
public:
Action();
+ bool restore:1;
+ bool actionDone:1;
+
QmlMetaProperty property;
- bool restore;
QVariant fromValue;
QVariant toValue;
- QString fromBinding;
- QString toBinding;
- QmlBindableValue *bv;
+
+ QmlBindableValue *fromBinding;
+ QmlBindableValue *toBinding;
ActionEvent *event;
- bool actionDone;
+
+ void deleteFromBinding();
};
class ActionEvent
diff --git a/src/declarative/util/qmlstate_p.h b/src/declarative/util/qmlstate_p.h
index 7fcbcd7..b4ec476 100644
--- a/src/declarative/util/qmlstate_p.h
+++ b/src/declarative/util/qmlstate_p.h
@@ -52,23 +52,21 @@ class SimpleAction
{
public:
enum State { StartState, EndState };
- SimpleAction(const Action &a, State state = StartState) : bv(0)
+ SimpleAction(const Action &a, State state = StartState)
{
property = a.property;
if (state == StartState) {
value = a.fromValue;
- binding = a.fromBinding;
+ binding = property.binding();
} else {
value = a.toValue;
binding = a.toBinding;
}
- bv = a.bv;
}
QmlMetaProperty property;
QVariant value;
- QString binding;
- QmlBindableValue *bv;
+ QmlBindableValue *binding;
};
class QmlStatePrivate : public QObjectPrivate
diff --git a/src/declarative/util/qmlstateoperations.cpp b/src/declarative/util/qmlstateoperations.cpp
index 02b54f8..b7398a3 100644
--- a/src/declarative/util/qmlstateoperations.cpp
+++ b/src/declarative/util/qmlstateoperations.cpp
@@ -417,14 +417,8 @@ QmlSetProperty::ActionList QmlSetProperty::actions()
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;
+ if (!d->binding.isEmpty())
+ a.toBinding = new QmlBindableValue(d->binding, object(), qmlContext(this));
return ActionList() << a;
}