src/declarative/util/qdeclarativebehavior.cpp
changeset 33 3e2da88830cd
parent 30 5dc02b23752f
child 37 758a864f9613
equal deleted inserted replaced
30:5dc02b23752f 33:3e2da88830cd
    56 
    56 
    57 class QDeclarativeBehaviorPrivate : public QObjectPrivate
    57 class QDeclarativeBehaviorPrivate : public QObjectPrivate
    58 {
    58 {
    59     Q_DECLARE_PUBLIC(QDeclarativeBehavior)
    59     Q_DECLARE_PUBLIC(QDeclarativeBehavior)
    60 public:
    60 public:
    61     QDeclarativeBehaviorPrivate() : animation(0), enabled(true), finalized(false) {}
    61     QDeclarativeBehaviorPrivate() : animation(0), enabled(true), finalized(false)
       
    62       , blockRunningChanged(false) {}
    62 
    63 
    63     QDeclarativeProperty property;
    64     QDeclarativeProperty property;
    64     QVariant currentValue;
    65     QVariant currentValue;
    65     QVariant targetValue;
    66     QVariant targetValue;
    66     QDeclarativeGuard<QDeclarativeAbstractAnimation> animation;
    67     QDeclarativeGuard<QDeclarativeAbstractAnimation> animation;
    67     bool enabled;
    68     bool enabled;
    68     bool finalized;
    69     bool finalized;
       
    70     bool blockRunningChanged;
    69 };
    71 };
    70 
    72 
    71 /*!
    73 /*!
    72     \qmlclass Behavior QDeclarativeBehavior
    74     \qmlclass Behavior QDeclarativeBehavior
    73     \since 4.7
    75     \since 4.7
    74     \brief The Behavior element allows you to specify a default animation for a property change.
    76     \brief The Behavior element allows you to specify a default animation for a property change.
    75 
    77 
    76     Behaviors provide one way to specify \l{qdeclarativeanimation.html}{animations} in QML.
    78     A Behavior defines the default animation to be applied whenever a 
    77 
    79     particular property value changes.
    78     In the example below, the rectangle will use a bounce easing curve over 200 millisecond for any changes to its y property:
    80 
    79     \code
    81     For example, the following Behavior defines a NumberAnimation to be run
    80     Rectangle {
    82     whenever the \l Rectangle's \c width value changes. When the MouseArea
    81         width: 20; height: 20
    83     is clicked, the \c width is changed, triggering the behavior's animation:
    82         color: "#00ff00"
    84 
    83         y: 200  // initial value
    85     \snippet doc/src/snippets/declarative/behavior.qml 0
    84         Behavior on y {
    86 
    85             NumberAnimation {
    87     To run multiple animations within a Behavior, use ParallelAnimation or
    86                 easing.type: Easing.OutBounce
    88     SequentialAnimation.
    87                 easing.amplitude: 100
    89 
    88                 duration: 200
    90     Note that a property cannot have more than one assigned Behavior.
    89             }
    91 
    90         }
    92     \sa {Property Behaviors}, {declarative/animation/behaviors}{Behavior example}, QtDeclarative
    91     }
       
    92     \endcode
       
    93 
       
    94     Currently only a single Behavior may be specified for a property;
       
    95     this Behavior can be enabled and disabled via the \l{enabled} property.
       
    96 
       
    97     \sa QtDeclarative
       
    98 */
    93 */
    99 
    94 
   100 
    95 
   101 QDeclarativeBehavior::QDeclarativeBehavior(QObject *parent)
    96 QDeclarativeBehavior::QDeclarativeBehavior(QObject *parent)
   102     : QObject(*(new QDeclarativeBehaviorPrivate), parent)
    97     : QObject(*(new QDeclarativeBehaviorPrivate), parent)
   109 
   104 
   110 /*!
   105 /*!
   111     \qmlproperty Animation Behavior::animation
   106     \qmlproperty Animation Behavior::animation
   112     \default
   107     \default
   113 
   108 
   114     The animation to use when the behavior is triggered.
   109     This property holds the animation to run when the behavior is triggered.
   115 */
   110 */
   116 
   111 
   117 QDeclarativeAbstractAnimation *QDeclarativeBehavior::animation()
   112 QDeclarativeAbstractAnimation *QDeclarativeBehavior::animation()
   118 {
   113 {
   119     Q_D(QDeclarativeBehavior);
   114     Q_D(QDeclarativeBehavior);
   130 
   125 
   131     d->animation = animation;
   126     d->animation = animation;
   132     if (d->animation) {
   127     if (d->animation) {
   133         d->animation->setDefaultTarget(d->property);
   128         d->animation->setDefaultTarget(d->property);
   134         d->animation->setDisableUserControl();
   129         d->animation->setDisableUserControl();
   135     }
   130         connect(d->animation->qtAnimation(),
   136 }
   131                 SIGNAL(stateChanged(QAbstractAnimation::State,QAbstractAnimation::State)),
       
   132                 this,
       
   133                 SLOT(qtAnimationStateChanged(QAbstractAnimation::State,QAbstractAnimation::State)));
       
   134     }
       
   135 }
       
   136 
       
   137 
       
   138 void QDeclarativeBehavior::qtAnimationStateChanged(QAbstractAnimation::State newState,QAbstractAnimation::State)
       
   139 {
       
   140     Q_D(QDeclarativeBehavior);
       
   141     if (!d->blockRunningChanged)
       
   142         d->animation->notifyRunningChanged(newState == QAbstractAnimation::Running);
       
   143 }
       
   144 
   137 
   145 
   138 /*!
   146 /*!
   139     \qmlproperty bool Behavior::enabled
   147     \qmlproperty bool Behavior::enabled
   140     Whether the Behavior will be triggered when the property it is tracking changes.
   148 
       
   149     This property holds whether the behavior will be triggered when the tracked
       
   150     property changes value.
   141 
   151 
   142     By default a Behavior is enabled.
   152     By default a Behavior is enabled.
   143 */
   153 */
   144 
   154 
   145 bool QDeclarativeBehavior::enabled() const
   155 bool QDeclarativeBehavior::enabled() const
   165         QDeclarativePropertyPrivate::write(d->property, value, QDeclarativePropertyPrivate::BypassInterceptor | QDeclarativePropertyPrivate::DontRemoveBinding);
   175         QDeclarativePropertyPrivate::write(d->property, value, QDeclarativePropertyPrivate::BypassInterceptor | QDeclarativePropertyPrivate::DontRemoveBinding);
   166         d->targetValue = value;
   176         d->targetValue = value;
   167         return;
   177         return;
   168     }
   178     }
   169 
   179 
   170     if (value == d->targetValue)
   180     if (d->animation->isRunning() && value == d->targetValue)
   171         return;
   181         return;
   172 
   182 
   173     d->currentValue = d->property.read();
   183     d->currentValue = d->property.read();
   174     d->targetValue = value;
   184     d->targetValue = value;
   175 
   185 
   176     if (d->animation->qtAnimation()->duration() != -1)
   186     if (d->animation->qtAnimation()->duration() != -1
       
   187             && d->animation->qtAnimation()->state() != QAbstractAnimation::Stopped) {
       
   188         d->blockRunningChanged = true;
   177         d->animation->qtAnimation()->stop();
   189         d->animation->qtAnimation()->stop();
       
   190     }
   178 
   191 
   179     QDeclarativeStateOperation::ActionList actions;
   192     QDeclarativeStateOperation::ActionList actions;
   180     QDeclarativeAction action;
   193     QDeclarativeAction action;
   181     action.property = d->property;
   194     action.property = d->property;
   182     action.fromValue = d->currentValue;
   195     action.fromValue = d->currentValue;
   184     actions << action;
   197     actions << action;
   185 
   198 
   186     QList<QDeclarativeProperty> after;
   199     QList<QDeclarativeProperty> after;
   187     d->animation->transition(actions, after, QDeclarativeAbstractAnimation::Forward);
   200     d->animation->transition(actions, after, QDeclarativeAbstractAnimation::Forward);
   188     d->animation->qtAnimation()->start();
   201     d->animation->qtAnimation()->start();
       
   202     d->blockRunningChanged = false;
   189     if (!after.contains(d->property))
   203     if (!after.contains(d->property))
   190         QDeclarativePropertyPrivate::write(d->property, value, QDeclarativePropertyPrivate::BypassInterceptor | QDeclarativePropertyPrivate::DontRemoveBinding);    
   204         QDeclarativePropertyPrivate::write(d->property, value, QDeclarativePropertyPrivate::BypassInterceptor | QDeclarativePropertyPrivate::DontRemoveBinding);    
   191 }
   205 }
   192 
   206 
   193 void QDeclarativeBehavior::setTarget(const QDeclarativeProperty &property)
   207 void QDeclarativeBehavior::setTarget(const QDeclarativeProperty &property)