forked from qt-creator/qt-creator
QmlDesigner: Implement model support for timeline
This patch implements the basic support for the timelien in the model. The type names will most likely change. Change-Id: Ib3161d480468cf88e9f155130f7cba70451a8c7e Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
This commit is contained in:
@@ -78,7 +78,9 @@ SOURCES += $$PWD/model/abstractview.cpp \
|
||||
$$PWD/model/signalhandlerproperty.cpp \
|
||||
$$PWD/model/internalsignalhandlerproperty.cpp \
|
||||
$$PWD/model/anchorline.cpp \
|
||||
$$PWD/instances/puppetdialog.cpp
|
||||
$$PWD/instances/puppetdialog.cpp \
|
||||
$$PWD/model/qmltimelinemutator.cpp \
|
||||
$$PWD/model/qmltimelinekeyframes.cpp
|
||||
|
||||
HEADERS += $$PWD/include/qmldesignercorelib_global.h \
|
||||
$$PWD/include/abstractview.h \
|
||||
@@ -152,7 +154,9 @@ HEADERS += $$PWD/include/qmldesignercorelib_global.h \
|
||||
$$PWD/include/signalhandlerproperty.h \
|
||||
$$PWD/model/internalsignalhandlerproperty.h \
|
||||
$$PWD/include/anchorline.h \
|
||||
$$PWD/instances/puppetdialog.h
|
||||
$$PWD/instances/puppetdialog.h \
|
||||
$$PWD/include/qmltimelinemutator.h \
|
||||
$$PWD/include/qmltimelinekeyframes.h \
|
||||
|
||||
FORMS += \
|
||||
$$PWD/instances/puppetdialog.ui
|
||||
|
@@ -55,6 +55,7 @@ namespace QmlDesigner {
|
||||
class NodeInstanceView;
|
||||
class RewriterView;
|
||||
class QmlModelState;
|
||||
class QmlTimelineMutator;
|
||||
|
||||
enum DesignerWidgetFlags {
|
||||
DisableOnError,
|
||||
@@ -232,6 +233,8 @@ public:
|
||||
|
||||
virtual void documentMessagesChanged(const QList<DocumentMessage> &errors, const QList<DocumentMessage> &warnings);
|
||||
|
||||
virtual void currentTimelineChanged(const ModelNode &node);
|
||||
|
||||
void changeRootNodeType(const TypeName &type, int majorVersion, int minorVersion);
|
||||
|
||||
NodeInstanceView *nodeInstanceView() const;
|
||||
@@ -240,6 +243,7 @@ public:
|
||||
void setCurrentStateNode(const ModelNode &node);
|
||||
ModelNode currentStateNode() const;
|
||||
QmlModelState currentState() const;
|
||||
QmlTimelineMutator currentTimeline() const;
|
||||
|
||||
int majorQtQuickVersion() const;
|
||||
int minorQtQuickVersion() const;
|
||||
@@ -253,6 +257,9 @@ public:
|
||||
|
||||
virtual QString contextHelpId() const;
|
||||
|
||||
void activateTimelineRecording(const ModelNode &mutator);
|
||||
void deactivateTimelineRecording();
|
||||
|
||||
protected:
|
||||
void setModel(Model * model);
|
||||
void removeModel();
|
||||
|
@@ -28,6 +28,7 @@
|
||||
#include <qmldesignercorelib_global.h>
|
||||
#include "qmlmodelnodefacade.h"
|
||||
#include "qmlstate.h"
|
||||
#include "qmltimelinemutator.h"
|
||||
#include "qmlchangeset.h"
|
||||
|
||||
#include <nodeinstance.h>
|
||||
@@ -63,6 +64,7 @@ public:
|
||||
QString validId();
|
||||
|
||||
QmlModelState currentState() const;
|
||||
QmlTimelineMutator currentTimeline() const;
|
||||
void setVariantProperty(const PropertyName &name, const QVariant &value);
|
||||
void setBindingProperty(const PropertyName &name, const QString &expression);
|
||||
NodeAbstractProperty nodeAbstractProperty(const PropertyName &name) const;
|
||||
@@ -83,6 +85,7 @@ public:
|
||||
QString stripedTranslatableText(const PropertyName &name) const;
|
||||
QString expression(const PropertyName &name) const;
|
||||
bool isInBaseState() const;
|
||||
bool timelineIsActive() const;
|
||||
QmlPropertyChanges propertyChangeForCurrentState() const;
|
||||
|
||||
virtual bool instanceCanReparent() const;
|
||||
|
@@ -72,7 +72,6 @@ public:
|
||||
protected:
|
||||
void addChangeSetIfNotExists(const ModelNode &node);
|
||||
static QmlModelState createBaseState(const AbstractView *view);
|
||||
|
||||
};
|
||||
|
||||
} //QmlDesigner
|
||||
|
@@ -0,0 +1,65 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <qmldesignercorelib_global.h>
|
||||
#include "qmlmodelnodefacade.h"
|
||||
#include "qmlchangeset.h"
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
class AbstractViewAbstractVieweGroup;
|
||||
class QmlObjectNode;
|
||||
|
||||
class QMLDESIGNERCORE_EXPORT QmlTimelineFrames : public QmlModelNodeFacade
|
||||
{
|
||||
|
||||
public:
|
||||
QmlTimelineFrames();
|
||||
QmlTimelineFrames(const ModelNode &modelNode);
|
||||
|
||||
bool isValid() const;
|
||||
static bool isValidQmlTimelineFrames(const ModelNode &modelNode);
|
||||
void destroy();
|
||||
|
||||
ModelNode target() const;
|
||||
void setTarget(const ModelNode &target);
|
||||
|
||||
PropertyName propertyName() const;
|
||||
void setPropertyName(const PropertyName &propertyName);
|
||||
|
||||
void setValue(const QVariant &value, qreal frame);
|
||||
QVariant value(qreal frame) const;
|
||||
|
||||
qreal currentFrame() const;
|
||||
|
||||
bool hasKeyframe(qreal frame);
|
||||
|
||||
static bool isValidKeyframe(const ModelNode &node);
|
||||
static QmlTimelineFrames keyframesForKeyframe(const ModelNode &node);
|
||||
};
|
||||
|
||||
} //QmlDesigner
|
@@ -0,0 +1,62 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <qmldesignercorelib_global.h>
|
||||
#include "qmlmodelnodefacade.h"
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
class AbstractViewAbstractVieweGroup;
|
||||
class QmlObjectNode;
|
||||
class QmlModelStateGroup;
|
||||
class QmlTimelineFrames;
|
||||
|
||||
class QMLDESIGNERCORE_EXPORT QmlTimelineMutator : public QmlModelNodeFacade
|
||||
{
|
||||
|
||||
public:
|
||||
QmlTimelineMutator();
|
||||
QmlTimelineMutator(const ModelNode &modelNode);
|
||||
|
||||
bool isValid() const;
|
||||
static bool isValidQmlTimelineMutator(const ModelNode &modelNode);
|
||||
void destroy();
|
||||
|
||||
QmlTimelineFrames timelineFrames(const ModelNode &modelNode, const PropertyName &propertyName);
|
||||
bool hasTimeline(const ModelNode &modelNode, const PropertyName &propertyName);
|
||||
|
||||
qreal startFrame() const;
|
||||
qreal endFrame() const;
|
||||
qreal currentFrame() const;
|
||||
|
||||
private:
|
||||
void addFramesIfNotExists(const ModelNode &node, const PropertyName &propertyName);
|
||||
bool hasFrames(const ModelNode &node, const PropertyName &propertyName) const;
|
||||
QList<QmlTimelineFrames> frames() const;
|
||||
};
|
||||
|
||||
} //QmlDesigner
|
@@ -43,6 +43,8 @@
|
||||
#include "nodelistproperty.h"
|
||||
#include "nodeproperty.h"
|
||||
#include "qmlchangeset.h"
|
||||
#include "qmltimelinemutator.h"
|
||||
#include "qmltimelinekeyframes.h"
|
||||
|
||||
#include "createscenecommand.h"
|
||||
#include "createinstancescommand.h"
|
||||
@@ -690,6 +692,21 @@ void NodeInstanceView::updatePosition(const QList<VariantProperty> &propertyList
|
||||
NodeInstance instance = instanceForModelNode(modelNode);
|
||||
setYValue(instance, variantProperty, informationChangeHash);
|
||||
}
|
||||
} else if (currentTimeline().isValid()
|
||||
&& variantProperty.name() == "value"
|
||||
&& QmlTimelineFrames::isValidKeyframe(variantProperty.parentModelNode())) {
|
||||
|
||||
QmlTimelineFrames frames = QmlTimelineFrames::keyframesForKeyframe(variantProperty.parentModelNode());
|
||||
|
||||
if (frames.isValid() && frames.propertyName() == "x" && frames.target().isValid()) {
|
||||
|
||||
NodeInstance instance = instanceForModelNode(frames.target());
|
||||
setXValue(instance, variantProperty, informationChangeHash);
|
||||
} else if (frames.isValid() && frames.propertyName() == "y" && frames.target().isValid()) {
|
||||
NodeInstance instance = instanceForModelNode(frames.target());
|
||||
setYValue(instance, variantProperty, informationChangeHash);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -30,6 +30,7 @@
|
||||
#include "internalnode_p.h"
|
||||
#include "nodeinstanceview.h"
|
||||
#include <qmlstate.h>
|
||||
#include <qmltimelinemutator.h>
|
||||
|
||||
#ifndef QMLDESIGNER_TEST
|
||||
#include <qmldesignerplugin.h>
|
||||
@@ -359,6 +360,11 @@ void AbstractView::documentMessagesChanged(const QList<DocumentMessage> &/*error
|
||||
{
|
||||
}
|
||||
|
||||
void AbstractView::currentTimelineChanged(const ModelNode & /*node*/)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QList<ModelNode> AbstractView::toModelNodeList(const QList<Internal::InternalNode::Pointer> &nodeList) const
|
||||
{
|
||||
return QmlDesigner::toModelNodeList(nodeList, const_cast<AbstractView*>(this));
|
||||
@@ -565,6 +571,21 @@ QString AbstractView::contextHelpId() const
|
||||
return helpId;
|
||||
}
|
||||
|
||||
void AbstractView::activateTimelineRecording(const ModelNode &mutator)
|
||||
{
|
||||
Internal::WriteLocker locker(m_model.data());
|
||||
if (model())
|
||||
model()->d->notifyCurrentTimelineChanged(mutator);
|
||||
|
||||
}
|
||||
|
||||
void AbstractView::deactivateTimelineRecording()
|
||||
{
|
||||
Internal::WriteLocker locker(m_model.data());
|
||||
if (model())
|
||||
model()->d->notifyCurrentTimelineChanged(ModelNode());
|
||||
}
|
||||
|
||||
QList<ModelNode> AbstractView::allModelNodes() const
|
||||
{
|
||||
return toModelNodeList(model()->d->allNodes());
|
||||
@@ -688,6 +709,16 @@ QmlModelState AbstractView::currentState() const
|
||||
return QmlModelState(currentStateNode());
|
||||
}
|
||||
|
||||
QmlTimelineMutator AbstractView::currentTimeline() const
|
||||
{
|
||||
if (model())
|
||||
return QmlTimelineMutator(ModelNode(m_model.data()->d->currentTimelineNode(),
|
||||
m_model.data(),
|
||||
const_cast<AbstractView*>(this)));
|
||||
|
||||
return QmlTimelineMutator();
|
||||
}
|
||||
|
||||
static int getMinorVersionFromImport(const Model *model)
|
||||
{
|
||||
foreach (const Import &import, model->imports()) {
|
||||
|
@@ -85,6 +85,7 @@ ModelPrivate::ModelPrivate(Model *model) :
|
||||
{
|
||||
m_rootInternalNode = createNode("QtQuick.Item", 1, 0, PropertyListType(), PropertyListType(), QString(), ModelNode::NodeWithoutSource,true);
|
||||
m_currentStateNode = m_rootInternalNode;
|
||||
m_currentTimelineMutatorNode = m_rootInternalNode;
|
||||
}
|
||||
|
||||
ModelPrivate::~ModelPrivate()
|
||||
@@ -641,6 +642,33 @@ void ModelPrivate::notifyCurrentStateChanged(const ModelNode &node)
|
||||
resetModelByRewriter(description);
|
||||
}
|
||||
|
||||
void ModelPrivate::notifyCurrentTimelineChanged(const ModelNode &node)
|
||||
{
|
||||
bool resetModel = false;
|
||||
QString description;
|
||||
|
||||
m_currentTimelineMutatorNode = node.internalNode();
|
||||
|
||||
try {
|
||||
if (rewriterView())
|
||||
rewriterView()->currentTimelineChanged(ModelNode(node.internalNode(), model(), rewriterView()));
|
||||
} catch (const RewritingException &e) {
|
||||
description = e.description();
|
||||
resetModel = true;
|
||||
}
|
||||
|
||||
for (const QPointer<AbstractView> &view : m_viewList) {
|
||||
Q_ASSERT(view != 0);
|
||||
view->currentTimelineChanged(ModelNode(node.internalNode(), model(), view.data()));
|
||||
}
|
||||
|
||||
if (nodeInstanceView())
|
||||
nodeInstanceView()->currentTimelineChanged(ModelNode(node.internalNode(), model(), nodeInstanceView()));
|
||||
|
||||
if (resetModel)
|
||||
resetModelByRewriter(description);
|
||||
}
|
||||
|
||||
void ModelPrivate::notifyRewriterBeginTransaction()
|
||||
{
|
||||
bool resetModel = false;
|
||||
@@ -1707,6 +1735,11 @@ NodeInstanceView *ModelPrivate::nodeInstanceView() const
|
||||
return m_nodeInstanceView.data();
|
||||
}
|
||||
|
||||
InternalNodePointer ModelPrivate::currentTimelineNode() const
|
||||
{
|
||||
return m_currentTimelineMutatorNode;
|
||||
}
|
||||
|
||||
InternalNodePointer ModelPrivate::nodeForId(const QString &id) const
|
||||
{
|
||||
return m_idNodeHash.value(id);
|
||||
|
@@ -157,6 +157,7 @@ public:
|
||||
void notifyInstanceToken(const QString &token, int number, const QVector<ModelNode> &nodeVector);
|
||||
|
||||
void notifyCurrentStateChanged(const ModelNode &node);
|
||||
void notifyCurrentTimelineChanged(const ModelNode &node);
|
||||
|
||||
void setDocumentMessages(const QList<DocumentMessage> &errors, const QList<DocumentMessage> &warnings);
|
||||
|
||||
@@ -226,6 +227,7 @@ public:
|
||||
NodeInstanceView *nodeInstanceView() const;
|
||||
|
||||
InternalNodePointer currentStateNode() const;
|
||||
InternalNodePointer currentTimelineNode() const;
|
||||
|
||||
private: //functions
|
||||
void removePropertyWithoutNotification(const InternalPropertyPointer &property);
|
||||
@@ -249,6 +251,7 @@ private:
|
||||
QSet<InternalNodePointer> m_nodeSet;
|
||||
InternalNodePointer m_currentStateNode;
|
||||
InternalNodePointer m_rootInternalNode;
|
||||
InternalNodePointer m_currentTimelineMutatorNode;
|
||||
QUrl m_fileUrl;
|
||||
QPointer<RewriterView> m_rewriterView;
|
||||
QPointer<NodeInstanceView> m_nodeInstanceView;
|
||||
|
@@ -26,6 +26,7 @@
|
||||
#include "qmlobjectnode.h"
|
||||
#include "qmlitemnode.h"
|
||||
#include "qmlstate.h"
|
||||
#include "qmltimelinekeyframes.h"
|
||||
#include "variantproperty.h"
|
||||
#include "nodeproperty.h"
|
||||
#include <invalidmodelnodeexception.h>
|
||||
@@ -48,6 +49,19 @@ void QmlObjectNode::setVariantProperty(const PropertyName &name, const QVariant
|
||||
if (!isValid())
|
||||
throw new InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__);
|
||||
|
||||
if (timelineIsActive()) {
|
||||
modelNode().validId();
|
||||
|
||||
QmlTimelineFrames timelineFrames(currentTimeline().timelineFrames(modelNode(), name));
|
||||
|
||||
Q_ASSERT(timelineFrames.isValid());
|
||||
|
||||
qreal frame = currentTimeline().modelNode().auxiliaryData("currentFrame@NodeInstance").toReal();
|
||||
timelineFrames.setValue(value, frame);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (isInBaseState()) {
|
||||
modelNode().variantProperty(name).setValue(value); //basestate
|
||||
} else {
|
||||
@@ -83,6 +97,14 @@ QmlModelState QmlObjectNode::currentState() const
|
||||
return QmlModelState();
|
||||
}
|
||||
|
||||
QmlTimelineMutator QmlObjectNode::currentTimeline() const
|
||||
{
|
||||
if (isValid())
|
||||
return view()->currentTimeline();
|
||||
else
|
||||
return QmlTimelineMutator();
|
||||
}
|
||||
|
||||
bool QmlObjectNode::isRootModelNode() const
|
||||
{
|
||||
return modelNode().isRootNode();
|
||||
@@ -161,6 +183,9 @@ bool QmlObjectNode::propertyAffectedByCurrentState(const PropertyName &name) con
|
||||
if (currentState().isBaseState())
|
||||
return modelNode().hasProperty(name);
|
||||
|
||||
if (timelineIsActive() && currentTimeline().hasTimeline(modelNode(), name))
|
||||
return true;
|
||||
|
||||
if (!currentState().hasPropertyChanges(modelNode()))
|
||||
return false;
|
||||
|
||||
@@ -172,6 +197,21 @@ QVariant QmlObjectNode::modelValue(const PropertyName &name) const
|
||||
if (!isValid())
|
||||
throw new InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__);
|
||||
|
||||
if (timelineIsActive() && currentTimeline().hasTimeline(modelNode(), name)) {
|
||||
QmlTimelineFrames timelineFrames(currentTimeline().timelineFrames(modelNode(), name));
|
||||
|
||||
Q_ASSERT(timelineFrames.isValid());
|
||||
|
||||
qreal frame = currentTimeline().modelNode().auxiliaryData("currentFrame@NodeInstance").toReal();
|
||||
|
||||
QVariant value = timelineFrames.value(frame);
|
||||
|
||||
if (!value.isValid()) //interpolation is not done in the model
|
||||
value = instanceValue(name);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
if (currentState().isBaseState())
|
||||
return modelNode().variantProperty(name).value();
|
||||
|
||||
@@ -239,6 +279,11 @@ bool QmlObjectNode::isInBaseState() const
|
||||
return currentState().isBaseState();
|
||||
}
|
||||
|
||||
bool QmlObjectNode::timelineIsActive() const
|
||||
{
|
||||
return currentTimeline().isValid();
|
||||
}
|
||||
|
||||
bool QmlObjectNode::instanceCanReparent() const
|
||||
{
|
||||
return isInBaseState();
|
||||
|
@@ -0,0 +1,147 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qmltimelinekeyframes.h"
|
||||
#include "abstractview.h"
|
||||
#include <nodelistproperty.h>
|
||||
#include <variantproperty.h>
|
||||
#include <metainfo.h>
|
||||
#include <invalidmodelnodeexception.h>
|
||||
#include "bindingproperty.h"
|
||||
#include "qmlitemnode.h"
|
||||
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
QmlTimelineFrames::QmlTimelineFrames()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QmlTimelineFrames::QmlTimelineFrames(const ModelNode &modelNode) : QmlModelNodeFacade(modelNode)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool QmlTimelineFrames::isValid() const
|
||||
{
|
||||
return isValidQmlTimelineFrames(modelNode());
|
||||
}
|
||||
|
||||
bool QmlTimelineFrames::isValidQmlTimelineFrames(const ModelNode &modelNode)
|
||||
{
|
||||
return isValidQmlModelNodeFacade(modelNode)
|
||||
&& modelNode.metaInfo().isValid()
|
||||
&& modelNode.metaInfo().isSubclassOf("QtQuick.Timeline.Keyframes");
|
||||
}
|
||||
|
||||
void QmlTimelineFrames::destroy()
|
||||
{
|
||||
Q_ASSERT(isValid());
|
||||
modelNode().destroy();
|
||||
}
|
||||
|
||||
ModelNode QmlTimelineFrames::target() const
|
||||
{
|
||||
if (modelNode().property("target").isBindingProperty())
|
||||
return modelNode().bindingProperty("target").resolveToModelNode();
|
||||
else
|
||||
return ModelNode(); //exception?
|
||||
}
|
||||
|
||||
void QmlTimelineFrames::setTarget(const ModelNode &target)
|
||||
{
|
||||
modelNode().bindingProperty("target").setExpression(target.id());
|
||||
}
|
||||
|
||||
|
||||
PropertyName QmlTimelineFrames::propertyName() const
|
||||
{
|
||||
return modelNode().variantProperty("property").value().toString().toUtf8();
|
||||
}
|
||||
|
||||
void QmlTimelineFrames::setPropertyName(const PropertyName &propertyName)
|
||||
{
|
||||
modelNode().variantProperty("property").setValue(QString::fromUtf8(propertyName));
|
||||
}
|
||||
|
||||
void QmlTimelineFrames::setValue(const QVariant &value, qreal currentFrame)
|
||||
{
|
||||
|
||||
for (const ModelNode &childNode : modelNode().defaultNodeListProperty().toModelNodeList()) {
|
||||
if (qFuzzyCompare(childNode.variantProperty("frame").value().toReal(), currentFrame)) {
|
||||
childNode.variantProperty("value").setValue(value);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const QList<QPair<PropertyName, QVariant> > propertyPairList{{PropertyName("frame"), QVariant(currentFrame)},
|
||||
{PropertyName("value"), value}};
|
||||
|
||||
ModelNode frame = modelNode().view()->createModelNode("QtQuick.Timeline.Keyframe", 1, 0, propertyPairList);
|
||||
modelNode().defaultNodeListProperty().reparentHere(frame);
|
||||
}
|
||||
|
||||
QVariant QmlTimelineFrames::value(qreal frame) const
|
||||
{
|
||||
for (const ModelNode &childNode : modelNode().defaultNodeListProperty().toModelNodeList()) {
|
||||
if (qFuzzyCompare(childNode.variantProperty("frame").value().toReal(), frame)) {
|
||||
return childNode.variantProperty("value").value();
|
||||
}
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
bool QmlTimelineFrames::hasKeyframe(qreal frame)
|
||||
{
|
||||
for (const ModelNode &childNode : modelNode().defaultNodeListProperty().toModelNodeList()) {
|
||||
if (qFuzzyCompare(childNode.variantProperty("frame").value().toReal(), frame))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool QmlTimelineFrames::isValidKeyframe(const ModelNode &node)
|
||||
{
|
||||
return isValidQmlModelNodeFacade(node)
|
||||
&& node.metaInfo().isValid()
|
||||
&& node.metaInfo().isSubclassOf("QtQuick.Timeline.Keyframe");
|
||||
}
|
||||
|
||||
QmlTimelineFrames QmlTimelineFrames::keyframesForKeyframe(const ModelNode &node)
|
||||
{
|
||||
if (isValidKeyframe(node) && node.hasParentProperty()) {
|
||||
const QmlTimelineFrames timeline(node.parentProperty().parentModelNode());
|
||||
if (timeline.isValid())
|
||||
return timeline;
|
||||
}
|
||||
|
||||
return QmlTimelineFrames();
|
||||
}
|
||||
|
||||
} // QmlDesigner
|
@@ -0,0 +1,167 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qmltimelinemutator.h"
|
||||
#include "qmltimelinekeyframes.h"
|
||||
#include "abstractview.h"
|
||||
#include <nodelistproperty.h>
|
||||
#include <variantproperty.h>
|
||||
#include <nodelistproperty.h>
|
||||
#include <metainfo.h>
|
||||
#include <invalidmodelnodeexception.h>
|
||||
#include "bindingproperty.h"
|
||||
#include "qmlitemnode.h"
|
||||
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
QmlTimelineMutator::QmlTimelineMutator()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QmlTimelineMutator::QmlTimelineMutator(const ModelNode &modelNode) : QmlModelNodeFacade(modelNode)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool QmlTimelineMutator::isValid() const
|
||||
{
|
||||
return isValidQmlTimelineMutator(modelNode());
|
||||
}
|
||||
|
||||
bool QmlTimelineMutator::isValidQmlTimelineMutator(const ModelNode &modelNode)
|
||||
{
|
||||
return isValidQmlModelNodeFacade(modelNode)
|
||||
&& modelNode.metaInfo().isValid()
|
||||
&& modelNode.metaInfo().isSubclassOf("QtQuick.Timeline.KeyframeMutator");
|
||||
}
|
||||
|
||||
void QmlTimelineMutator::destroy()
|
||||
{
|
||||
Q_ASSERT(isValid());
|
||||
modelNode().destroy();
|
||||
}
|
||||
|
||||
QmlTimelineFrames QmlTimelineMutator::timelineFrames(const ModelNode &node, const PropertyName &propertyName)
|
||||
{
|
||||
if (isValid()) {
|
||||
addFramesIfNotExists(node, propertyName);
|
||||
for (const ModelNode &childNode : modelNode().defaultNodeListProperty().toModelNodeList()) {
|
||||
if (QmlTimelineFrames::isValidQmlTimelineFrames(childNode)) {
|
||||
const QmlTimelineFrames frames(childNode);
|
||||
|
||||
if (frames.target().isValid()
|
||||
&& frames.target() == node
|
||||
&& frames.propertyName() == propertyName)
|
||||
return frames;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return QmlTimelineFrames(); //not found
|
||||
}
|
||||
|
||||
bool QmlTimelineMutator::hasTimeline(const ModelNode &node, const PropertyName &propertyName)
|
||||
{
|
||||
if (isValid()) {
|
||||
for (const ModelNode &childNode : modelNode().defaultNodeListProperty().toModelNodeList()) {
|
||||
if (QmlTimelineFrames::isValidQmlTimelineFrames(childNode)) {
|
||||
const QmlTimelineFrames frames(childNode);
|
||||
|
||||
if (frames.target().isValid()
|
||||
&& frames.target() == node
|
||||
&& frames.propertyName() == propertyName)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
qreal QmlTimelineMutator::startFrame() const
|
||||
{
|
||||
if (isValid())
|
||||
return QmlObjectNode(modelNode()).instanceValue("startFrame").toReal();
|
||||
return 0;
|
||||
}
|
||||
|
||||
qreal QmlTimelineMutator::endFrame() const
|
||||
{
|
||||
if (isValid())
|
||||
return QmlObjectNode(modelNode()).instanceValue("endFrame").toReal();
|
||||
return 0;
|
||||
}
|
||||
|
||||
qreal QmlTimelineMutator::currentFrame() const
|
||||
{
|
||||
if (isValid())
|
||||
return QmlObjectNode(modelNode()).instanceValue("currentFrame").toReal();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void QmlTimelineMutator::addFramesIfNotExists(const ModelNode &node, const PropertyName &propertyName)
|
||||
{
|
||||
if (!isValid())
|
||||
throw new InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__);
|
||||
|
||||
if (!hasFrames(node, propertyName)) {
|
||||
ModelNode frames = modelNode().view()->createModelNode("QtQuick.Timeline.Keyframes", 1, 0);
|
||||
modelNode().defaultNodeListProperty().reparentHere(frames);
|
||||
|
||||
QmlTimelineFrames(frames).setTarget(node);
|
||||
QmlTimelineFrames(frames).setPropertyName(propertyName);
|
||||
|
||||
Q_ASSERT(QmlTimelineFrames::isValidQmlTimelineFrames(frames));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool QmlTimelineMutator::hasFrames(const ModelNode &node, const PropertyName &propertyName) const
|
||||
{
|
||||
for (const QmlTimelineFrames &frames : frames()) {
|
||||
if (frames.target().isValid()
|
||||
&& frames.target() == node
|
||||
&& frames.propertyName() == propertyName)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
QList<QmlTimelineFrames> QmlTimelineMutator::frames() const
|
||||
{
|
||||
QList<QmlTimelineFrames> returnList;
|
||||
|
||||
for (const ModelNode &childNode : modelNode().defaultNodeListProperty().toModelNodeList()) {
|
||||
if (QmlTimelineFrames::isValidQmlTimelineFrames(childNode))
|
||||
returnList.append(QmlTimelineFrames(childNode));
|
||||
}
|
||||
|
||||
return returnList;
|
||||
}
|
||||
|
||||
} // QmlDesigner
|
@@ -280,6 +280,8 @@ Project {
|
||||
"include/subcomponentmanager.h",
|
||||
"include/textmodifier.h",
|
||||
"include/variantproperty.h",
|
||||
"include/qmltimelinekeyframes.h",
|
||||
"include/qmltimelinemutator.h",
|
||||
"instances/nodeinstance.cpp",
|
||||
"instances/nodeinstanceserverproxy.cpp",
|
||||
"instances/nodeinstanceserverproxy.h",
|
||||
@@ -357,6 +359,8 @@ Project {
|
||||
"model/texttomodelmerger.h",
|
||||
"model/variantproperty.cpp",
|
||||
"model/viewmanager.cpp",
|
||||
"model/qmltimelinekeyframes.cpp",
|
||||
"model/qmltimelinemutator.cpp",
|
||||
"pluginmanager/widgetpluginmanager.cpp",
|
||||
"pluginmanager/widgetpluginmanager.h",
|
||||
"pluginmanager/widgetpluginpath.cpp",
|
||||
|
Reference in New Issue
Block a user