diff options
author | Knud Dollereder <knud.dollereder@qt.io> | 2022-04-05 13:45:30 +0200 |
---|---|---|
committer | Knud Dollereder <knud.dollereder@qt.io> | 2022-04-28 10:01:46 +0000 |
commit | 9195d0dd2c420c1aa3051c60e97211ec082165a7 (patch) | |
tree | d4132db6ee6aae5e0b0575dec944a2c1e2b4ce5a | |
parent | 1811b381ebe195262a14bda86852aca055b99245 (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>
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", |