aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKnud Dollereder <knud.dollereder@qt.io>2022-04-05 13:45:30 +0200
committerKnud Dollereder <knud.dollereder@qt.io>2022-04-28 10:01:46 +0000
commit9195d0dd2c420c1aa3051c60e97211ec082165a7 (patch)
treed4132db6ee6aae5e0b0575dec944a2c1e2b4ce5a
parent1811b381ebe195262a14bda86852aca055b99245 (diff)
Improve Animationcurve editor
- Prevent insertion of invalid animation ranges that may cause DS hanging - Properly update the toolbar when switching to a different qml file - Show an informative text instead of the empty curve editor when the current file does not contain a timeline - Move the toolbar into its own class - Add an implentation to the "Set Default" button Fixes: QDS-6543 Fixes: QDS-6542 Fixes: QDS-6545 Fixes: QDS-6544 Change-Id: Id6bc1457627ea23a670e74ea335fbb475711b9a6 Reviewed-by: <github-actions-qt-creator@cristianadam.eu> Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
-rw-r--r--src/plugins/qmldesigner/CMakeLists.txt1
-rw-r--r--src/plugins/qmldesigner/components/curveeditor/curveeditor.cpp165
-rw-r--r--src/plugins/qmldesigner/components/curveeditor/curveeditor.h6
-rw-r--r--src/plugins/qmldesigner/components/curveeditor/curveeditormodel.cpp21
-rw-r--r--src/plugins/qmldesigner/components/curveeditor/curveeditormodel.h4
-rw-r--r--src/plugins/qmldesigner/components/curveeditor/curveeditortoolbar.cpp174
-rw-r--r--src/plugins/qmldesigner/components/curveeditor/curveeditortoolbar.h81
-rw-r--r--src/plugins/qmldesigner/components/curveeditor/curveeditorview.cpp6
-rw-r--r--src/plugins/qmldesigner/components/curveeditor/detail/curveitem.cpp12
-rw-r--r--src/plugins/qmldesigner/components/curveeditor/detail/curveitem.h2
-rw-r--r--src/plugins/qmldesigner/components/curveeditor/detail/graphicsscene.cpp5
-rw-r--r--src/plugins/qmldesigner/components/curveeditor/detail/graphicsscene.h2
-rw-r--r--src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.cpp12
-rw-r--r--src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.h2
-rw-r--r--src/plugins/qmldesigner/components/curveeditor/detail/keyframeitem.cpp12
-rw-r--r--src/plugins/qmldesigner/components/curveeditor/detail/keyframeitem.h2
-rw-r--r--src/plugins/qmldesigner/components/curveeditor/keyframe.cpp11
-rw-r--r--src/plugins/qmldesigner/components/curveeditor/keyframe.h4
-rw-r--r--src/plugins/qmldesigner/qmldesignerplugin.qbs2
19 files changed, 405 insertions, 119 deletions
diff --git a/src/plugins/qmldesigner/CMakeLists.txt b/src/plugins/qmldesigner/CMakeLists.txt
index 2a2c2314ba..733051f308 100644
--- a/src/plugins/qmldesigner/CMakeLists.txt
+++ b/src/plugins/qmldesigner/CMakeLists.txt
@@ -526,6 +526,7 @@ extend_qtc_plugin(QmlDesigner
curveeditorview.cpp curveeditorview.h
animationcurve.cpp animationcurve.h
curveeditor.cpp curveeditor.h
+ curveeditortoolbar.cpp curveeditortoolbar.h
curveeditormodel.cpp curveeditormodel.h
curveeditorstyle.h
curvesegment.cpp curvesegment.h
diff --git a/src/plugins/qmldesigner/components/curveeditor/curveeditor.cpp b/src/plugins/qmldesigner/components/curveeditor/curveeditor.cpp
index c004055197..217e0e0eb7 100644
--- a/src/plugins/qmldesigner/components/curveeditor/curveeditor.cpp
+++ b/src/plugins/qmldesigner/components/curveeditor/curveeditor.cpp
@@ -25,6 +25,7 @@
#include "curveeditor.h"
#include "curveeditormodel.h"
+#include "curveeditortoolbar.h"
#include "detail/curveitem.h"
#include "detail/graphicsview.h"
#include "detail/treeview.h"
@@ -40,9 +41,17 @@ namespace QmlDesigner {
CurveEditor::CurveEditor(CurveEditorModel *model, QWidget *parent)
: QWidget(parent)
+ , m_infoText(nullptr)
+ , m_toolbar(new CurveEditorToolBar(model, this))
, m_tree(new TreeView(model, this))
, m_view(new GraphicsView(model, this))
{
+ const QString labelText = tr(
+ "This file does not contain a timeline. <br><br>"
+ "To create an animation, add a timeline by clicking the + button in the \"Timeline\" view."
+ );
+ m_infoText = new QLabel(labelText);
+
auto *splitter = new QSplitter;
splitter->addWidget(m_tree);
splitter->addWidget(m_view);
@@ -53,17 +62,63 @@ CurveEditor::CurveEditor(CurveEditorModel *model, QWidget *parent)
area->setWidgetResizable(true);
auto *box = new QVBoxLayout;
- box->addWidget(createToolBar(model));
+ box->addWidget(m_infoText);
+ box->addWidget(m_toolbar);
box->addWidget(area);
setLayout(box);
+ connect(m_toolbar, &CurveEditorToolBar::defaultClicked, [this]() {
+ m_view->setDefaultInterpolation();
+ });
+
+ connect(m_toolbar, &CurveEditorToolBar::unifyClicked, [this]() {
+ m_view->toggleUnified();
+ });
+
+ connect(m_toolbar, &CurveEditorToolBar::interpolationClicked, [this](Keyframe::Interpolation ipol) {
+ m_view->setInterpolation(ipol);
+ });
+
+ connect(m_toolbar, &CurveEditorToolBar::startFrameChanged, [this, model](int frame) {
+ model->setMinimumTime(frame);
+ m_view->viewport()->update();
+ });
+
+ connect(m_toolbar, &CurveEditorToolBar::endFrameChanged, [this, model](int frame) {
+ model->setMaximumTime(frame);
+ m_view->viewport()->update();
+ });
+
+ connect(
+ m_toolbar, &CurveEditorToolBar::currentFrameChanged,
+ model, &CurveEditorModel::commitCurrentFrame);
+
+ connect(
+ m_view, &GraphicsView::currentFrameChanged,
+ m_toolbar, &CurveEditorToolBar::setCurrentFrame);
+
connect(m_tree, &TreeView::treeItemLocked, model, &CurveEditorModel::setLocked);
connect(m_tree, &TreeView::treeItemPinned, model, &CurveEditorModel::setPinned);
- connect(m_tree->selectionModel(),
- &SelectionModel::curvesSelected,
- m_view,
- &GraphicsView::updateSelection);
+ connect(
+ m_tree->selectionModel(), &SelectionModel::curvesSelected,
+ m_view, &GraphicsView::updateSelection);
+
+ auto updateTimeline = [this, model](bool validTimeline) {
+ if (validTimeline) {
+ m_toolbar->updateBoundsSilent(model->minimumTime(), model->maximumTime());
+ m_toolbar->show();
+ m_tree->show();
+ m_view->show();
+ m_infoText->hide();
+ } else {
+ m_toolbar->hide();
+ m_tree->hide();
+ m_view->hide();
+ m_infoText->show();
+ }
+ };
+ connect(model, &CurveEditorModel::timelineChanged, this, updateTimeline);
}
bool CurveEditor::dragging() const
@@ -98,104 +153,4 @@ void CurveEditor::hideEvent(QHideEvent *event)
QWidget::hideEvent(event);
}
-QToolBar *CurveEditor::createToolBar(CurveEditorModel *model)
-{
- auto *bar = new QToolBar;
- bar->setFloatable(false);
-
- QAction *tangentLinearAction = bar->addAction(
- QIcon(":/curveeditor/images/tangetToolsLinearIcon.png"), "Linear");
- QAction *tangentStepAction = bar->addAction(QIcon(
- ":/curveeditor/images/tangetToolsStepIcon.png"),
- "Step");
- QAction *tangentSplineAction = bar->addAction(
- QIcon(":/curveeditor/images/tangetToolsSplineIcon.png"), "Spline");
-
- QAction *tangentDefaultAction = bar->addAction(tr("Set Default"));
- QAction *tangentUnifyAction = bar->addAction(tr("Unify"));
-
- auto setLinearInterpolation = [this]() {
- m_view->setInterpolation(Keyframe::Interpolation::Linear);
- };
- auto setStepInterpolation = [this]() {
- m_view->setInterpolation(Keyframe::Interpolation::Step);
- };
- auto setSplineInterpolation = [this]() {
- m_view->setInterpolation(Keyframe::Interpolation::Bezier);
- };
-
- auto toggleUnifyKeyframe = [this]() { m_view->toggleUnified(); };
-
- connect(tangentLinearAction, &QAction::triggered, setLinearInterpolation);
- connect(tangentStepAction, &QAction::triggered, setStepInterpolation);
- connect(tangentSplineAction, &QAction::triggered, setSplineInterpolation);
- connect(tangentUnifyAction, &QAction::triggered, toggleUnifyKeyframe);
-
- Q_UNUSED(tangentLinearAction);
- Q_UNUSED(tangentSplineAction);
- Q_UNUSED(tangentStepAction);
- Q_UNUSED(tangentDefaultAction);
-
- auto *durationBox = new QHBoxLayout;
- 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);
- 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);
- m_view->viewport()->update();
- };
- connect(endSpin, QOverload<int>::of(&QSpinBox::valueChanged), updateEndFrame);
-
- auto setStartSlot = [startSpin](int frame) { startSpin->setValue(frame); };
- connect(model, &CurveEditorModel::commitStartFrame, setStartSlot);
-
- auto setEndSlot = [endSpin](int frame) { endSpin->setValue(frame); };
- connect(model, &CurveEditorModel::commitEndFrame, 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);
-
- auto *cfspin = new QSpinBox;
- cfspin->setMinimum(0);
- cfspin->setMaximum(std::numeric_limits<int>::max());
-
- auto intSignal = static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged);
- connect(cfspin, intSignal, [model](int val) { emit model->commitCurrentFrame(val); });
- connect(m_view, &GraphicsView::currentFrameChanged, [cfspin](int val, bool notify) {
- if (notify) {
- cfspin->setValue(val);
- } else {
- const QSignalBlocker blocker(cfspin);
- cfspin->setValue(val);
- }
- });
-
- auto *positionBox = new QHBoxLayout;
- positionBox->addWidget(new QLabel(tr("Current Frame")));
- positionBox->addWidget(cfspin);
- auto *positionWidget = new QWidget;
- positionWidget->setLayout(positionBox);
- bar->addWidget(positionWidget);
-
- return bar;
-}
-
} // End namespace QmlDesigner.
diff --git a/src/plugins/qmldesigner/components/curveeditor/curveeditor.h b/src/plugins/qmldesigner/components/curveeditor/curveeditor.h
index e297e31a9b..9d1a6f68f9 100644
--- a/src/plugins/qmldesigner/components/curveeditor/curveeditor.h
+++ b/src/plugins/qmldesigner/components/curveeditor/curveeditor.h
@@ -27,10 +27,12 @@
#include <QToolBar>
#include <QWidget>
+#include <QLabel>
namespace QmlDesigner {
class CurveEditorModel;
+class CurveEditorToolBar;
class GraphicsView;
class TreeView;
@@ -57,7 +59,9 @@ protected:
void hideEvent(QHideEvent *event) override;
private:
- QToolBar *createToolBar(CurveEditorModel *model);
+ QLabel *m_infoText;
+
+ CurveEditorToolBar *m_toolbar;
TreeView *m_tree;
diff --git a/src/plugins/qmldesigner/components/curveeditor/curveeditormodel.cpp b/src/plugins/qmldesigner/components/curveeditor/curveeditormodel.cpp
index d357d555f7..4377671817 100644
--- a/src/plugins/qmldesigner/components/curveeditor/curveeditormodel.cpp
+++ b/src/plugins/qmldesigner/components/curveeditor/curveeditormodel.cpp
@@ -43,6 +43,7 @@ namespace QmlDesigner {
CurveEditorModel::CurveEditorModel(QObject *parent)
: TreeModel(parent)
+ , m_hasTimeline(false)
, m_minTime(CurveEditorStyle::defaultTimeMin)
, m_maxTime(CurveEditorStyle::defaultTimeMax)
{}
@@ -98,15 +99,19 @@ CurveEditorStyle CurveEditorModel::style() const
void CurveEditorModel::setTimeline(const QmlDesigner::QmlTimeline &timeline)
{
- m_minTime = timeline.startKeyframe();
- m_maxTime = timeline.endKeyframe();
- std::vector<TreeItem *> items;
- for (auto &&target : timeline.allTargets()) {
- if (TreeItem *item = createTopLevelItem(timeline, target))
- items.push_back(item);
+ m_hasTimeline = timeline.isValid();
+
+ if (m_hasTimeline) {
+ m_minTime = timeline.startKeyframe();
+ m_maxTime = timeline.endKeyframe();
+ std::vector<TreeItem *> items;
+ for (auto &&target : timeline.allTargets()) {
+ if (TreeItem *item = createTopLevelItem(timeline, target))
+ items.push_back(item);
+ }
+ reset(items);
}
-
- reset(items);
+ emit timelineChanged(m_hasTimeline);
}
void CurveEditorModel::setCurrentFrame(int frame)
diff --git a/src/plugins/qmldesigner/components/curveeditor/curveeditormodel.h b/src/plugins/qmldesigner/components/curveeditor/curveeditormodel.h
index 71fca7de03..041642aa61 100644
--- a/src/plugins/qmldesigner/components/curveeditor/curveeditormodel.h
+++ b/src/plugins/qmldesigner/components/curveeditor/curveeditormodel.h
@@ -54,6 +54,8 @@ signals:
void commitEndFrame(int frame);
+ void timelineChanged(bool valid);
+
void curveChanged(TreeItem *item);
public:
@@ -92,6 +94,8 @@ private:
AnimationCurve createDoubleCurve(const QmlDesigner::QmlTimelineKeyframeGroup &group);
+ bool m_hasTimeline = false;
+
double m_minTime = 0.;
double m_maxTime = 0.;
diff --git a/src/plugins/qmldesigner/components/curveeditor/curveeditortoolbar.cpp b/src/plugins/qmldesigner/components/curveeditor/curveeditortoolbar.cpp
new file mode 100644
index 0000000000..b7bbf37051
--- /dev/null
+++ b/src/plugins/qmldesigner/components/curveeditor/curveeditortoolbar.cpp
@@ -0,0 +1,174 @@
+/****************************************************************************
+**
+** Copyright (C) 2022 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Design Tooling
+**
+** 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 "curveeditortoolbar.h"
+#include "curveeditormodel.h"
+
+#include <QAction>
+#include <QHBoxLayout>
+#include <QLabel>
+#include <QSignalBlocker>
+
+namespace QmlDesigner {
+
+ValidatableSpinBox::ValidatableSpinBox(std::function<bool(int)> validator, QWidget* parent)
+ : QSpinBox(parent)
+ , m_validator(validator)
+{ }
+
+QValidator::State ValidatableSpinBox::validate(QString &text, int &pos) const
+{
+ auto result = QSpinBox::validate(text, pos);
+ if (result==QValidator::Acceptable) {
+ if (int val = text.toInt(); m_validator(val))
+ return result;
+
+ result = QValidator::Intermediate;
+ }
+ return result;
+}
+
+
+CurveEditorToolBar::CurveEditorToolBar(CurveEditorModel *model, QWidget* parent)
+ : QToolBar(parent)
+ , m_startSpin(nullptr)
+ , m_endSpin(nullptr)
+ , m_currentSpin(new QSpinBox)
+
+{
+ setFloatable(false);
+
+ QAction *tangentLinearAction = addAction(
+ QIcon(":/curveeditor/images/tangetToolsLinearIcon.png"), "Linear");
+ QAction *tangentStepAction = addAction(
+ QIcon(":/curveeditor/images/tangetToolsStepIcon.png"), "Step");
+ QAction *tangentSplineAction = addAction(
+ QIcon(":/curveeditor/images/tangetToolsSplineIcon.png"), "Spline");
+
+ QAction *tangentDefaultAction = addAction(tr("Set Default"));
+ QAction *tangentUnifyAction = addAction(tr("Unify"));
+
+ auto setLinearInterpolation = [this]() {
+ emit interpolationClicked(Keyframe::Interpolation::Linear);
+ };
+ auto setStepInterpolation = [this]() {
+ emit interpolationClicked(Keyframe::Interpolation::Step);
+ };
+ auto setSplineInterpolation = [this]() {
+ emit interpolationClicked(Keyframe::Interpolation::Bezier);
+ };
+ auto setDefaultKeyframe = [this]() {
+ emit defaultClicked();
+ };
+ auto toggleUnifyKeyframe = [this]() {
+ emit unifyClicked();
+ };
+
+ connect(tangentLinearAction, &QAction::triggered, setLinearInterpolation);
+ connect(tangentStepAction, &QAction::triggered, setStepInterpolation);
+ connect(tangentSplineAction, &QAction::triggered, setSplineInterpolation);
+ connect(tangentDefaultAction, &QAction::triggered, setDefaultKeyframe);
+ connect(tangentUnifyAction, &QAction::triggered, toggleUnifyKeyframe);
+
+ auto validateStart = [this](int val) -> bool {
+ if (m_endSpin==nullptr)
+ return false;
+ return m_endSpin->value() > val;
+ };
+ m_startSpin = new ValidatableSpinBox(validateStart);
+ m_startSpin->setRange(std::numeric_limits<int>::lowest(), std::numeric_limits<int>::max());
+ m_startSpin->setValue(model->minimumTime());
+
+ connect(
+ m_startSpin, QOverload<int>::of(&QSpinBox::valueChanged),
+ this, &CurveEditorToolBar::startFrameChanged);
+
+ connect(
+ model, &CurveEditorModel::commitStartFrame,
+ [this](int frame) { m_startSpin->setValue(frame); });
+
+ auto validateEnd = [this](int val) -> bool {
+ if (m_startSpin==nullptr)
+ return false;
+ return m_startSpin->value() < val;
+ };
+ m_endSpin = new ValidatableSpinBox(validateEnd);
+ m_endSpin->setRange(std::numeric_limits<int>::lowest(), std::numeric_limits<int>::max());
+ m_endSpin->setValue(model->maximumTime());
+
+ connect(
+ m_endSpin, QOverload<int>::of(&QSpinBox::valueChanged),
+ this, &CurveEditorToolBar::endFrameChanged);
+
+ connect(
+ model, &CurveEditorModel::commitEndFrame,
+ [this](int frame) { m_endSpin->setValue(frame); });
+
+ m_currentSpin->setMinimum(0);
+ m_currentSpin->setMaximum(std::numeric_limits<int>::max());
+
+ connect(
+ m_currentSpin, QOverload<int>::of(&QSpinBox::valueChanged),
+ this, &CurveEditorToolBar::currentFrameChanged);
+
+ auto *durationBox = new QHBoxLayout;
+ durationBox->addWidget(new QLabel(tr("Start Frame")));
+ durationBox->addWidget(m_startSpin);
+ durationBox->addWidget(new QLabel(tr("End Frame")));
+ durationBox->addWidget(m_endSpin);
+
+ auto *durationWidget = new QWidget;
+ durationWidget->setLayout(durationBox);
+ addWidget(durationWidget);
+
+ auto *positionBox = new QHBoxLayout;
+ positionBox->addWidget(new QLabel(tr("Current Frame")));
+ positionBox->addWidget(m_currentSpin);
+
+ auto *positionWidget = new QWidget;
+ positionWidget->setLayout(positionBox);
+ addWidget(positionWidget);
+}
+
+void CurveEditorToolBar::setCurrentFrame(int current, bool notify)
+{
+ if (notify) {
+ m_currentSpin->setValue(current);
+ } else {
+ QSignalBlocker blocker(m_currentSpin);
+ m_currentSpin->setValue(current);
+ }
+}
+
+void CurveEditorToolBar::updateBoundsSilent(int start, int end)
+{
+ QSignalBlocker startBlocker(m_startSpin);
+ m_startSpin->setValue(start);
+
+ QSignalBlocker endBlocker(m_endSpin);
+ m_endSpin->setValue(end);
+}
+
+} // End namespace QmlDesigner.
diff --git a/src/plugins/qmldesigner/components/curveeditor/curveeditortoolbar.h b/src/plugins/qmldesigner/components/curveeditor/curveeditortoolbar.h
new file mode 100644
index 0000000000..25271245c6
--- /dev/null
+++ b/src/plugins/qmldesigner/components/curveeditor/curveeditortoolbar.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2022 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Design Tooling
+**
+** 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 <QSpinBox>
+#include <QToolBar>
+#include <QValidator>
+#include <QWidget>
+
+#include "keyframe.h"
+
+namespace QmlDesigner {
+
+class CurveEditorModel;
+
+class ValidatableSpinBox : public QSpinBox
+{
+ Q_OBJECT
+public:
+ ValidatableSpinBox(std::function<bool(int)> validator, QWidget* parent=nullptr);
+protected:
+ QValidator::State validate(QString &text, int &pos) const override;
+private:
+ std::function<bool(int)> m_validator;
+};
+
+
+class CurveEditorToolBar : public QToolBar
+{
+ Q_OBJECT
+
+signals:
+ void defaultClicked();
+
+ void unifyClicked();
+
+ void interpolationClicked(Keyframe::Interpolation interpol);
+
+ void startFrameChanged(int start);
+
+ void endFrameChanged(int end);
+
+ void currentFrameChanged(int current);
+
+public:
+ CurveEditorToolBar(CurveEditorModel *model, QWidget* parent = nullptr);
+
+ void setCurrentFrame(int current, bool notify);
+
+ void updateBoundsSilent(int start, int end);
+
+private:
+ ValidatableSpinBox *m_startSpin;
+ ValidatableSpinBox *m_endSpin;
+ QSpinBox *m_currentSpin;
+};
+
+} // End namespace QmlDesigner.
diff --git a/src/plugins/qmldesigner/components/curveeditor/curveeditorview.cpp b/src/plugins/qmldesigner/components/curveeditor/curveeditorview.cpp
index 0c535ec48d..c449d0e864 100644
--- a/src/plugins/qmldesigner/components/curveeditor/curveeditorview.cpp
+++ b/src/plugins/qmldesigner/components/curveeditor/curveeditorview.cpp
@@ -396,11 +396,7 @@ void CurveEditorView::commitEndFrame(int frame)
void CurveEditorView::init()
{
- QmlTimeline timeline = activeTimeline();
- if (timeline.isValid()) {
- m_model->setTimeline(timeline);
- }
-
+ m_model->setTimeline(activeTimeline());
}
} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/curveitem.cpp b/src/plugins/qmldesigner/components/curveeditor/detail/curveitem.cpp
index ef8cf9f2f2..0b7ab9d391 100644
--- a/src/plugins/qmldesigner/components/curveeditor/detail/curveitem.cpp
+++ b/src/plugins/qmldesigner/components/curveeditor/detail/curveitem.cpp
@@ -457,6 +457,18 @@ void CurveItem::setInterpolation(Keyframe::Interpolation interpolation)
emit curveChanged(id(), curve());
}
+void CurveItem::setDefaultInterpolation()
+{
+ if (m_keyframes.empty())
+ return;
+
+ for (auto *frame : qAsConst(m_keyframes)) {
+ if (frame->selected())
+ frame->setDefaultInterpolation();
+ }
+ emit curveChanged(id(), curve());
+}
+
void CurveItem::toggleUnified()
{
if (m_keyframes.empty())
diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/curveitem.h b/src/plugins/qmldesigner/components/curveeditor/detail/curveitem.h
index f6857f7c06..5a2f363df7 100644
--- a/src/plugins/qmldesigner/components/curveeditor/detail/curveitem.h
+++ b/src/plugins/qmldesigner/components/curveeditor/detail/curveitem.h
@@ -125,6 +125,8 @@ public:
void setInterpolation(Keyframe::Interpolation interpolation);
+ void setDefaultInterpolation();
+
void toggleUnified();
void connect(GraphicsScene *scene);
diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/graphicsscene.cpp b/src/plugins/qmldesigner/components/curveeditor/detail/graphicsscene.cpp
index 9198a4d9e5..9eda7f8934 100644
--- a/src/plugins/qmldesigner/components/curveeditor/detail/graphicsscene.cpp
+++ b/src/plugins/qmldesigner/components/curveeditor/detail/graphicsscene.cpp
@@ -208,6 +208,11 @@ SelectableItem *GraphicsScene::intersect(const QPointF &pos) const
return nullptr;
}
+void GraphicsScene::setDirty(bool dirty)
+{
+ m_dirty = dirty;
+}
+
void GraphicsScene::reset()
{
m_curves.clear();
diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/graphicsscene.h b/src/plugins/qmldesigner/components/curveeditor/detail/graphicsscene.h
index cd42ffbd4d..2e6bc3b080 100644
--- a/src/plugins/qmldesigner/components/curveeditor/detail/graphicsscene.h
+++ b/src/plugins/qmldesigner/components/curveeditor/detail/graphicsscene.h
@@ -88,6 +88,8 @@ public:
SelectableItem *intersect(const QPointF &pos) const;
+ void setDirty(bool dirty);
+
void reset();
void deleteSelectedKeyframes();
diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.cpp b/src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.cpp
index 89084bc98b..5b4e6e3cfb 100644
--- a/src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.cpp
+++ b/src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.cpp
@@ -334,6 +334,18 @@ void GraphicsView::setInterpolation(Keyframe::Interpolation interpol)
viewport()->update();
}
+void GraphicsView::setDefaultInterpolation()
+{
+ const auto selectedCurves = m_scene->selectedCurves();
+ for (auto *curve : selectedCurves)
+ curve->setDefaultInterpolation();
+
+ m_scene->setDirty(true);
+
+ applyZoom(m_zoomX, m_zoomY);
+ viewport()->update();
+}
+
void GraphicsView::toggleUnified()
{
const auto selectedCurves = m_scene->selectedCurves();
diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.h b/src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.h
index 22b474d1bb..917a8e7e2c 100644
--- a/src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.h
+++ b/src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.h
@@ -112,6 +112,8 @@ public:
void setInterpolation(Keyframe::Interpolation interpol);
+ void setDefaultInterpolation();
+
void toggleUnified();
protected:
diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/keyframeitem.cpp b/src/plugins/qmldesigner/components/curveeditor/detail/keyframeitem.cpp
index 025f5eb6ed..ef0a886d52 100644
--- a/src/plugins/qmldesigner/components/curveeditor/detail/keyframeitem.cpp
+++ b/src/plugins/qmldesigner/components/curveeditor/detail/keyframeitem.cpp
@@ -239,6 +239,18 @@ void KeyframeItem::setKeyframe(const Keyframe &keyframe)
setPos(m_transform.map(m_frame.position()));
}
+void KeyframeItem::setDefaultInterpolation()
+{
+ if (!m_left || !m_right)
+ return;
+
+ m_frame.setDefaultInterpolation();
+
+ setKeyframe(m_frame);
+
+ emit redrawCurve();
+}
+
void KeyframeItem::toggleUnified()
{
if (!m_left || !m_right)
diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/keyframeitem.h b/src/plugins/qmldesigner/components/curveeditor/detail/keyframeitem.h
index c0d3364027..3e566c84b7 100644
--- a/src/plugins/qmldesigner/components/curveeditor/detail/keyframeitem.h
+++ b/src/plugins/qmldesigner/components/curveeditor/detail/keyframeitem.h
@@ -90,6 +90,8 @@ public:
void setKeyframe(const Keyframe &keyframe);
+ void setDefaultInterpolation();
+
void toggleUnified();
void setActivated(bool active, HandleItem::Slot slot);
diff --git a/src/plugins/qmldesigner/components/curveeditor/keyframe.cpp b/src/plugins/qmldesigner/components/curveeditor/keyframe.cpp
index 02b2adc636..085c230335 100644
--- a/src/plugins/qmldesigner/components/curveeditor/keyframe.cpp
+++ b/src/plugins/qmldesigner/components/curveeditor/keyframe.cpp
@@ -25,6 +25,8 @@
#include "keyframe.h"
+#include <QLineF>
+
#include <sstream>
namespace QmlDesigner {
@@ -152,6 +154,15 @@ void Keyframe::setPosition(const QPointF &pos)
m_position = pos;
}
+void Keyframe::setDefaultInterpolation()
+{
+ auto leftToRight = QLineF(m_leftHandle, m_rightHandle);
+ leftToRight.translate(m_position - leftToRight.center());
+
+ m_leftHandle = leftToRight.p1();
+ m_rightHandle = leftToRight.p2();
+}
+
void Keyframe::setUnified(bool unified)
{
m_unified = unified;
diff --git a/src/plugins/qmldesigner/components/curveeditor/keyframe.h b/src/plugins/qmldesigner/components/curveeditor/keyframe.h
index d16e7d7a01..fd3c2cb88b 100644
--- a/src/plugins/qmldesigner/components/curveeditor/keyframe.h
+++ b/src/plugins/qmldesigner/components/curveeditor/keyframe.h
@@ -28,6 +28,8 @@
#include <QPointF>
#include <QVariant>
+#include <string>
+
namespace QmlDesigner {
class Keyframe
@@ -65,6 +67,8 @@ public:
Interpolation interpolation() const;
+ void setDefaultInterpolation();
+
void setUnified(bool unified);
void setPosition(const QPointF &pos);
diff --git a/src/plugins/qmldesigner/qmldesignerplugin.qbs b/src/plugins/qmldesigner/qmldesignerplugin.qbs
index a0427d3780..c8597a2d8a 100644
--- a/src/plugins/qmldesigner/qmldesignerplugin.qbs
+++ b/src/plugins/qmldesigner/qmldesignerplugin.qbs
@@ -828,6 +828,8 @@ Project {
"curveeditor/curveeditor.qrc",
"curveeditor/curveeditormodel.cpp",
"curveeditor/curveeditormodel.h",
+ "curveeditor/curveeditortoolbar.cpp",
+ "curveeditor/curveeditortoolbar.h",
"curveeditor/curveeditorstyle.h",
"curveeditor/curvesegment.cpp",
"curveeditor/curvesegment.h",