aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKnud Dollereder <knud.dollereder@qt.io>2020-02-21 15:28:31 +0100
committerThomas Hartmann <thomas.hartmann@qt.io>2020-03-17 17:19:14 +0000
commit5b000d17cb2f42891db7bd8c9c857866245eddd3 (patch)
tree97b2a33c6be95de50028e24e2d2f0e85ac262055
parent0f60f120d2e24b9912b43b5ba4859adcd5a1a803 (diff)
QmlDesigner: Add the ability to modify the animation rangev4.12.0-beta2
Add the ability to modify the animation range from the curve editor Fix a synchronization issue between timeline and curve editor when the animation contains pinned curves Change-Id: I89dda234063259f41d662749d696f5fc8a04f988 Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
-rw-r--r--src/plugins/qmldesigner/components/curveeditor/curveeditor.cpp47
-rw-r--r--src/plugins/qmldesigner/components/curveeditor/curveeditor.h2
-rw-r--r--src/plugins/qmldesigner/components/curveeditor/curveeditormodel.cpp23
-rw-r--r--src/plugins/qmldesigner/components/curveeditor/curveeditormodel.h19
-rw-r--r--src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.cpp68
-rw-r--r--src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.h8
-rw-r--r--src/plugins/qmldesigner/components/timelineeditor/animationcurveeditormodel.cpp14
-rw-r--r--src/plugins/qmldesigner/components/timelineeditor/animationcurveeditormodel.h8
-rw-r--r--src/plugins/qmldesigner/components/timelineeditor/timelinetoolbar.cpp22
-rw-r--r--src/plugins/qmldesigner/components/timelineeditor/timelinewidget.cpp2
10 files changed, 179 insertions, 34 deletions
diff --git a/src/plugins/qmldesigner/components/curveeditor/curveeditor.cpp b/src/plugins/qmldesigner/components/curveeditor/curveeditor.cpp
index c6eb2f6327..f5b2ffae1b 100644
--- a/src/plugins/qmldesigner/components/curveeditor/curveeditor.cpp
+++ b/src/plugins/qmldesigner/components/curveeditor/curveeditor.cpp
@@ -48,15 +48,18 @@ CurveEditor::CurveEditor(CurveEditorModel *model, QWidget *parent)
splitter->setStretchFactor(1, 2);
auto *box = new QVBoxLayout;
- box->addWidget(createToolBar());
+ box->addWidget(createToolBar(model));
box->addWidget(splitter);
setLayout(box);
- connect(m_tree, &TreeView::treeItemLocked, m_view, &GraphicsView::setLocked);
- connect(m_tree->selectionModel(), &SelectionModel::curvesSelected, m_view, &GraphicsView::reset);
-
connect(m_tree, &TreeView::treeItemLocked, model, &CurveEditorModel::curveChanged);
connect(m_tree, &TreeView::treeItemPinned, model, &CurveEditorModel::curveChanged);
+
+ connect(m_tree, &TreeView::treeItemLocked, m_view, &GraphicsView::setLocked);
+ connect(m_tree->selectionModel(),
+ &SelectionModel::curvesSelected,
+ m_view,
+ &GraphicsView::updateSelection);
}
void CurveEditor::zoomX(double zoom)
@@ -74,7 +77,7 @@ void CurveEditor::clearCanvas()
m_view->reset({});
}
-QToolBar *CurveEditor::createToolBar()
+QToolBar *CurveEditor::createToolBar(CurveEditorModel *model)
{
auto *bar = new QToolBar;
bar->setFloatable(false);
@@ -111,8 +114,38 @@ QToolBar *CurveEditor::createToolBar()
bar->addWidget(valueWidget);
auto *durationBox = new QHBoxLayout;
- durationBox->addWidget(new QLabel(tr("Duration")));
- durationBox->addWidget(new QSpinBox);
+ auto *startSpin = new QSpinBox;
+ auto *endSpin = new QSpinBox;
+
+ startSpin->setRange(std::numeric_limits<int>::lowest(), std::numeric_limits<int>::max());
+ startSpin->setValue(model->minimumTime());
+
+ auto updateStartFrame = [this, model](int frame) {
+ model->setMinimumTime(frame, false);
+ m_view->viewport()->update();
+ };
+ connect(startSpin, QOverload<int>::of(&QSpinBox::valueChanged), updateStartFrame);
+
+ endSpin->setRange(std::numeric_limits<int>::lowest(), std::numeric_limits<int>::max());
+ endSpin->setValue(model->maximumTime());
+
+ auto updateEndFrame = [this, model](int frame) {
+ model->setMaximumTime(frame, false);
+ m_view->viewport()->update();
+ };
+ connect(endSpin, QOverload<int>::of(&QSpinBox::valueChanged), updateEndFrame);
+
+ auto setStartSlot = [startSpin](int frame) { startSpin->setValue(frame); };
+ connect(model, &CurveEditorModel::updateStartFrame, setStartSlot);
+
+ auto setEndSlot = [endSpin](int frame) { endSpin->setValue(frame); };
+ connect(model, &CurveEditorModel::updateEndFrame, setEndSlot);
+
+ durationBox->addWidget(new QLabel(tr("Start Frame")));
+ durationBox->addWidget(startSpin);
+ durationBox->addWidget(new QLabel(tr("End Frame")));
+ durationBox->addWidget(endSpin);
+
auto *durationWidget = new QWidget;
durationWidget->setLayout(durationBox);
bar->addWidget(durationWidget);
diff --git a/src/plugins/qmldesigner/components/curveeditor/curveeditor.h b/src/plugins/qmldesigner/components/curveeditor/curveeditor.h
index c82204d83f..b6d9cfc013 100644
--- a/src/plugins/qmldesigner/components/curveeditor/curveeditor.h
+++ b/src/plugins/qmldesigner/components/curveeditor/curveeditor.h
@@ -48,7 +48,7 @@ public:
void clearCanvas();
private:
- QToolBar *createToolBar();
+ QToolBar *createToolBar(CurveEditorModel *model);
TreeView *m_tree;
diff --git a/src/plugins/qmldesigner/components/curveeditor/curveeditormodel.cpp b/src/plugins/qmldesigner/components/curveeditor/curveeditormodel.cpp
index 1769c1d6dd..e6f0f3e326 100644
--- a/src/plugins/qmldesigner/components/curveeditor/curveeditormodel.cpp
+++ b/src/plugins/qmldesigner/components/curveeditor/curveeditormodel.cpp
@@ -25,13 +25,16 @@
#include "curveeditormodel.h"
#include "treeitem.h"
+
#include "detail/graphicsview.h"
#include "detail/selectionmodel.h"
namespace DesignTools {
-CurveEditorModel::CurveEditorModel(QObject *parent)
+CurveEditorModel::CurveEditorModel(double minTime, double maxTime, QObject *parent)
: TreeModel(parent)
+ , m_minTime(minTime)
+ , m_maxTime(maxTime)
{}
CurveEditorModel::~CurveEditorModel() {}
@@ -42,6 +45,24 @@ void CurveEditorModel::setCurrentFrame(int frame)
graphicsView()->setCurrentFrame(frame);
}
+void CurveEditorModel::setMinimumTime(double time, bool internal)
+{
+ m_minTime = time;
+ if (internal)
+ emit updateStartFrame(m_minTime);
+ else
+ emit startFrameChanged(m_minTime);
+}
+
+void CurveEditorModel::setMaximumTime(double time, bool internal)
+{
+ m_maxTime = time;
+ if (internal)
+ emit updateEndFrame(m_maxTime);
+ else
+ emit endFrameChanged(m_maxTime);
+}
+
void CurveEditorModel::setCurve(unsigned int id, const AnimationCurve &curve)
{
if (TreeItem *item = find(id)) {
diff --git a/src/plugins/qmldesigner/components/curveeditor/curveeditormodel.h b/src/plugins/qmldesigner/components/curveeditor/curveeditormodel.h
index 6e212d4c6a..48d05586a2 100644
--- a/src/plugins/qmldesigner/components/curveeditor/curveeditormodel.h
+++ b/src/plugins/qmldesigner/components/curveeditor/curveeditormodel.h
@@ -48,6 +48,14 @@ class CurveEditorModel : public TreeModel
signals:
void currentFrameChanged(int frame);
+ void startFrameChanged(int frame);
+
+ void endFrameChanged(int frame);
+
+ void updateStartFrame(int frame);
+
+ void updateEndFrame(int frame);
+
void curveChanged(PropertyTreeItem *item);
public:
@@ -58,15 +66,24 @@ public:
virtual CurveEditorStyle style() const = 0;
public:
- CurveEditorModel(QObject *parent = nullptr);
+ CurveEditorModel(double minTime, double maxTime, QObject *parent = nullptr);
~CurveEditorModel() override;
void setCurrentFrame(int frame);
+ void setMinimumTime(double time, bool internal);
+
+ void setMaximumTime(double time, bool internal);
+
void setCurve(unsigned int id, const AnimationCurve &curve);
void reset(const std::vector<TreeItem *> &items);
+
+protected:
+ double m_minTime = 0.;
+
+ double m_maxTime = 0.;
};
} // End namespace DesignTools.
diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.cpp b/src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.cpp
index 51e4b35c88..b51d916fb0 100644
--- a/src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.cpp
+++ b/src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.cpp
@@ -231,6 +231,16 @@ void GraphicsView::scrollContent(double x, double y)
void GraphicsView::reset(const std::vector<CurveItem *> &items)
{
+ m_scene.clear();
+ for (auto *item : items)
+ m_scene.addCurveItem(item);
+
+ applyZoom(m_zoomX, m_zoomY);
+ viewport()->update();
+}
+
+void GraphicsView::updateSelection(const std::vector<CurveItem *> &items)
+{
const std::vector<CurveItem *> pinnedItems = m_scene.takePinnedItems();
auto notPinned = [pinnedItems](CurveItem *item) {
for (auto *pinned : pinnedItems) {
@@ -541,6 +551,38 @@ void GraphicsView::drawExtremaY(QPainter *painter, const QRectF &rect)
}
#endif
+void GraphicsView::drawRangeBar(QPainter *painter, const QRectF &rect)
+{
+ QFontMetrics fm(painter->font());
+ QRectF labelRect = fm.boundingRect(QString("0"));
+ labelRect.moveCenter(rect.center());
+
+ qreal bTick = rect.bottom() - 2;
+ qreal tTick = labelRect.bottom() + 2;
+ QRectF activeRect = QRectF(QPointF(mapTimeToX(m_model->minimumTime()), tTick),
+ QPointF(mapTimeToX(m_model->maximumTime()), bTick));
+
+ QColor color = Qt::white;
+ color.setAlpha(30);
+
+ painter->fillRect(activeRect, color);
+
+ QColor handleColor(Qt::green);
+ painter->setBrush(handleColor);
+ painter->setPen(handleColor);
+
+ const qreal radius = 5.;
+ QRectF minHandle = rangeMinHandle(rect);
+ painter->drawRoundedRect(minHandle, radius, radius);
+ minHandle.setLeft(minHandle.center().x());
+ painter->fillRect(minHandle, Qt::green);
+
+ QRectF maxHandle = rangeMaxHandle(rect);
+ painter->drawRoundedRect(maxHandle, radius, radius);
+ maxHandle.setRight(maxHandle.center().x());
+ painter->fillRect(maxHandle, Qt::green);
+}
+
void GraphicsView::drawTimeScale(QPainter *painter, const QRectF &rect)
{
painter->save();
@@ -565,6 +607,8 @@ void GraphicsView::drawTimeScale(QPainter *painter, const QRectF &rect)
for (double i = minimumTime(); i <= maximumTime(); i += timeIncrement)
paintLabeledTick(i);
+ drawRangeBar(painter, rect);
+
painter->restore();
}
@@ -619,4 +663,28 @@ double GraphicsView::timeLabelInterval(QPainter *painter, double maxTime)
return deltaTime;
}
+QRectF GraphicsView::rangeMinHandle(const QRectF &rect)
+{
+ QRectF labelRect = fontMetrics().boundingRect(QString("0"));
+ labelRect.moveCenter(rect.center());
+
+ qreal top = rect.bottom() - 2;
+ qreal bottom = labelRect.bottom() + 2;
+ QSize size(10, top - bottom);
+
+ int leftHandleLeft = mapTimeToX(m_model->minimumTime()) - size.width();
+ return QRectF(QPointF(leftHandleLeft, bottom), size);
+}
+
+QRectF GraphicsView::rangeMaxHandle(const QRectF &rect)
+{
+ QRectF labelRect = fontMetrics().boundingRect(QString("0"));
+ labelRect.moveCenter(rect.center());
+
+ qreal bottom = rect.bottom() - 2;
+ qreal top = labelRect.bottom() + 2;
+
+ return QRectF(QPointF(mapTimeToX(m_model->maximumTime()), bottom), QSize(10, top - bottom));
+}
+
} // End namespace DesignTools.
diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.h b/src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.h
index d56dfa7c57..7308d77608 100644
--- a/src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.h
+++ b/src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.h
@@ -108,6 +108,8 @@ public:
void reset(const std::vector<CurveItem *> &items);
+ void updateSelection(const std::vector<CurveItem *> &items);
+
void setInterpolation(Keyframe::Interpolation interpol);
protected:
@@ -148,8 +150,14 @@ private:
void drawValueScale(QPainter *painter, const QRectF &rect);
+ void drawRangeBar(QPainter *painter, const QRectF &rect);
+
double timeLabelInterval(QPainter *painter, double maxTime);
+ QRectF rangeMinHandle(const QRectF &rect);
+
+ QRectF rangeMaxHandle(const QRectF &rect);
+
private:
double m_zoomX;
diff --git a/src/plugins/qmldesigner/components/timelineeditor/animationcurveeditormodel.cpp b/src/plugins/qmldesigner/components/timelineeditor/animationcurveeditormodel.cpp
index ce7beba2c9..e09d09532d 100644
--- a/src/plugins/qmldesigner/components/timelineeditor/animationcurveeditormodel.cpp
+++ b/src/plugins/qmldesigner/components/timelineeditor/animationcurveeditormodel.cpp
@@ -35,9 +35,7 @@
namespace QmlDesigner {
AnimationCurveEditorModel::AnimationCurveEditorModel(double minTime, double maxTime)
- : CurveEditorModel()
- , m_minTime(minTime)
- , m_maxTime(maxTime)
+ : CurveEditorModel(minTime, maxTime)
{}
AnimationCurveEditorModel::~AnimationCurveEditorModel() {}
@@ -102,16 +100,6 @@ void AnimationCurveEditorModel::setTimeline(const QmlTimeline &timeline)
reset(items);
}
-void AnimationCurveEditorModel::setMinimumTime(double time)
-{
- m_minTime = time;
-}
-
-void AnimationCurveEditorModel::setMaximumTime(double time)
-{
- m_maxTime = time;
-}
-
DesignTools::ValueType typeFrom(const QmlTimelineKeyframeGroup &group)
{
if (group.valueType() == TypeName("double") || group.valueType() == TypeName("real")
diff --git a/src/plugins/qmldesigner/components/timelineeditor/animationcurveeditormodel.h b/src/plugins/qmldesigner/components/timelineeditor/animationcurveeditormodel.h
index fe85929cf1..4da0be62b0 100644
--- a/src/plugins/qmldesigner/components/timelineeditor/animationcurveeditormodel.h
+++ b/src/plugins/qmldesigner/components/timelineeditor/animationcurveeditormodel.h
@@ -49,20 +49,12 @@ public:
void setTimeline(const QmlTimeline &timeline);
- void setMinimumTime(double time);
-
- void setMaximumTime(double time);
-
private:
DesignTools::TreeItem *createTopLevelItem(const QmlTimeline &timeline, const ModelNode &node);
DesignTools::AnimationCurve createAnimationCurve(const QmlTimelineKeyframeGroup &group);
DesignTools::AnimationCurve createDoubleCurve(const QmlTimelineKeyframeGroup &group);
-
- double m_minTime;
-
- double m_maxTime;
};
} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/components/timelineeditor/timelinetoolbar.cpp b/src/plugins/qmldesigner/components/timelineeditor/timelinetoolbar.cpp
index ea065e49a1..5d693f5422 100644
--- a/src/plugins/qmldesigner/components/timelineeditor/timelinetoolbar.cpp
+++ b/src/plugins/qmldesigner/components/timelineeditor/timelinetoolbar.cpp
@@ -38,7 +38,6 @@
#include <variantproperty.h>
#include <qmlstate.h>
#include <qmltimeline.h>
-#include <qmltimelinekeyframegroup.h>
#include <coreplugin/actionmanager/actionmanager.h>
#include <coreplugin/actionmanager/command.h>
@@ -112,6 +111,23 @@ TimelineToolBar::TimelineToolBar(QWidget *parent)
&AnimationCurveEditorModel::currentFrameChanged,
this,
&TimelineToolBar::currentFrameChanged);
+
+ auto setStartFrameValue = [this](int val) {
+ if (m_firstFrame) {
+ m_firstFrame->setText(QString::number(val, 'f', 0));
+ emit startFrameChanged(val);
+ }
+ };
+ connect(m_curveModel, &AnimationCurveEditorModel::startFrameChanged, setStartFrameValue);
+
+ auto setEndFrameValue = [this](int val) {
+ if (m_lastFrame) {
+ m_lastFrame->setText(QString::number(val, 'f', 0));
+ emit endFrameChanged(val);
+ }
+ };
+ connect(m_curveModel, &AnimationCurveEditorModel::endFrameChanged, setEndFrameValue);
+
connect(m_curveModel,
&AnimationCurveEditorModel::curveChanged,
this,
@@ -181,7 +197,7 @@ void TimelineToolBar::setCurrentTimeline(const QmlTimeline &timeline)
void TimelineToolBar::setStartFrame(qreal frame)
{
- m_curveModel->setMinimumTime(frame);
+ m_curveModel->setMinimumTime(frame, true);
auto text = QString::number(frame, 'f', 0);
m_firstFrame->setText(text);
@@ -198,7 +214,7 @@ void TimelineToolBar::setCurrentFrame(qreal frame)
void TimelineToolBar::setEndFrame(qreal frame)
{
- m_curveModel->setMaximumTime(frame);
+ m_curveModel->setMaximumTime(frame, true);
auto text = QString::number(frame, 'f', 0);
m_lastFrame->setText(text);
diff --git a/src/plugins/qmldesigner/components/timelineeditor/timelinewidget.cpp b/src/plugins/qmldesigner/components/timelineeditor/timelinewidget.cpp
index e7f12fb5a2..d80749ad08 100644
--- a/src/plugins/qmldesigner/components/timelineeditor/timelinewidget.cpp
+++ b/src/plugins/qmldesigner/components/timelineeditor/timelinewidget.cpp
@@ -459,6 +459,8 @@ void TimelineWidget::invalidateTimelineDuration(const QmlTimeline &timeline)
if (timelineView() && timelineView()->model()) {
QmlTimeline currentTimeline = graphicsScene()->currentTimeline();
if (currentTimeline.isValid() && currentTimeline == timeline) {
+ m_toolbar->setStartFrame(timeline.startKeyframe());
+ m_toolbar->setEndFrame(timeline.endKeyframe());
graphicsScene()->setTimeline(timeline);
qreal playHeadFrame = getcurrentFrame(timeline);