示例#1
0
QQuickTransitionInstance *QQuickTransition::prepare(QQuickStateOperation::ActionList &actions,
                            QList<QQmlProperty> &after,
                            QQuickTransitionManager *manager,
                            QObject *defaultTarget)
{
    Q_D(QQuickTransition);

    qmlExecuteDeferred(this);

    ParallelAnimationWrapper *group = new ParallelAnimationWrapper();
    group->manager = manager;

    QQuickAbstractAnimation::TransitionDirection direction = d->reversed ? QQuickAbstractAnimation::Backward : QQuickAbstractAnimation::Forward;
    int start = d->reversed ? d->animations.count() - 1 : 0;
    int end = d->reversed ? -1 : d->animations.count();

    QAbstractAnimationJob *anim = 0;
    for (int i = start; i != end;) {
        anim = d->animations.at(i)->transition(actions, after, direction, defaultTarget);
        if (anim) {
            if (d->animations.at(i)->threadingModel() == QQuickAbstractAnimation::RenderThread)
                anim = new QQuickAnimatorProxyJob(anim, d->animations.at(i));
            d->reversed ? group->prependAnimation(anim) : group->appendAnimation(anim);
        }
        d->reversed ? --i : ++i;
    }

    group->setDirection(d->reversed ? QAbstractAnimationJob::Backward : QAbstractAnimationJob::Forward);

    group->addAnimationChangeListener(d, QAbstractAnimationJob::StateChange);
    QQuickTransitionInstance *wrapper = new QQuickTransitionInstance(d, group);
    return wrapper;
}
示例#2
0
void QDeclarativeBehavior::write(const QVariant &value)
{
    Q_D(QDeclarativeBehavior);
    qmlExecuteDeferred(this);
    if (!d->animation || !d->enabled || !d->finalized) {
        QDeclarativePropertyPrivate::write(d->property, value, QDeclarativePropertyPrivate::BypassInterceptor | QDeclarativePropertyPrivate::DontRemoveBinding);
        d->targetValue = value;
        return;
    }

    if (d->animation->isRunning() && value == d->targetValue)
        return;

    d->currentValue = d->property.read();
    d->targetValue = value;

    if (d->animation->qtAnimation()->duration() != -1
            && d->animation->qtAnimation()->state() != QAbstractAnimation::Stopped) {
        d->blockRunningChanged = true;
        d->animation->qtAnimation()->stop();
    }

    QDeclarativeStateOperation::ActionList actions;
    QDeclarativeAction action;
    action.property = d->property;
    action.fromValue = d->currentValue;
    action.toValue = value;
    actions << action;

    QList<QDeclarativeProperty> after;
    d->animation->transition(actions, after, QDeclarativeAbstractAnimation::Forward);
    d->animation->qtAnimation()->start();
    d->blockRunningChanged = false;
    if (!after.contains(d->property))
        QDeclarativePropertyPrivate::write(d->property, value, QDeclarativePropertyPrivate::BypassInterceptor | QDeclarativePropertyPrivate::DontRemoveBinding);
}
示例#3
0
void QQuickBehavior::write(const QVariant &value)
{
    Q_D(QQuickBehavior);
    bool bypass = !d->enabled || !d->finalized || QQmlEnginePrivate::designerMode();
    if (!bypass)
        qmlExecuteDeferred(this);
    if (!d->animation || bypass) {
        if (d->animationInstance)
            d->animationInstance->stop();
        QQmlPropertyPrivate::write(d->property, value, QQmlPropertyPrivate::BypassInterceptor | QQmlPropertyPrivate::DontRemoveBinding);
        d->targetValue = value;
        return;
    }

    bool behaviorActive = d->animation->isRunning();
    if (behaviorActive && value == d->targetValue)
        return;

    d->targetValue = value;

    if (d->animationInstance
            && (d->animationInstance->duration() != -1
                || d->animationInstance->isRenderThreadProxy())
            && !d->animationInstance->isStopped()) {
        d->blockRunningChanged = true;
        d->animationInstance->stop();
    }
    // Render thread animations use "stop" to synchronize the property back
    // to the item, so we need to read the value after.
    const QVariant &currentValue = d->property.read();

    // Don't unnecessarily wake up the animation system if no real animation
    // is needed (value has not changed). If the Behavior was already
    // running, let it continue as normal to ensure correct behavior and state.
    if (!behaviorActive && d->targetValue == currentValue) {
        QQmlPropertyPrivate::write(d->property, value, QQmlPropertyPrivate::BypassInterceptor | QQmlPropertyPrivate::DontRemoveBinding);
        return;
    }

    QQuickStateOperation::ActionList actions;
    QQuickStateAction action;
    action.property = d->property;
    action.fromValue = currentValue;
    action.toValue = value;
    actions << action;

    QList<QQmlProperty> after;
    QAbstractAnimationJob *prev = d->animationInstance;
    d->animationInstance = d->animation->transition(actions, after, QQuickAbstractAnimation::Forward);

    if (d->animationInstance && d->animation->threadingModel() == QQuickAbstractAnimation::RenderThread)
        d->animationInstance = new QQuickAnimatorProxyJob(d->animationInstance, d->animation);

    if (prev && prev != d->animationInstance)
        delete prev;

    if (d->animationInstance) {
        if (d->animationInstance != prev)
            d->animationInstance->addAnimationChangeListener(d, QAbstractAnimationJob::StateChange);
        d->animationInstance->start();
        d->blockRunningChanged = false;
    }
    if (!after.contains(d->property))
        QQmlPropertyPrivate::write(d->property, value, QQmlPropertyPrivate::BypassInterceptor | QQmlPropertyPrivate::DontRemoveBinding);
}