From c6b0c549cc4375b01d0c413075c55f7de147aea0 Mon Sep 17 00:00:00 2001 From: Mahmoud Badri Date: Wed, 25 Sep 2019 14:36:28 +0300 Subject: [PATCH] Allow setting a keyframe's time in the Edit keyframe dialog - rename keyframe context menu item "Edit Value for keyframe..." to "Edit Keyframe..." - add a field to set the frame, this allows accurately setting a keyframe's frame. - allow showing the dialog by double clicking a keyframe. - several relavant tweaks. Task-number: QDS-1072 Change-Id: I3c6a490c335911b2f6fefd3e788468686e827969 Reviewed-by: Thomas Hartmann --- .../timelineeditor/setframevaluedialog.cpp | 21 ++++-- .../timelineeditor/setframevaluedialog.h | 8 +-- .../timelineeditor/setframevaluedialog.ui | 24 +++++-- .../timelinemovableabstractitem.cpp | 5 ++ .../timelinemovableabstractitem.h | 1 + .../timelineeditor/timelinepropertyitem.cpp | 65 ++++++++++++------- .../timelineeditor/timelinepropertyitem.h | 2 + .../timelineeditor/timelineselectiontool.cpp | 5 +- .../timelineeditor/timelinetooldelegate.cpp | 4 +- 9 files changed, 93 insertions(+), 42 deletions(-) diff --git a/src/plugins/qmldesigner/components/timelineeditor/setframevaluedialog.cpp b/src/plugins/qmldesigner/components/timelineeditor/setframevaluedialog.cpp index 4120aaee218..29c3cd8eed5 100644 --- a/src/plugins/qmldesigner/components/timelineeditor/setframevaluedialog.cpp +++ b/src/plugins/qmldesigner/components/timelineeditor/setframevaluedialog.cpp @@ -26,14 +26,24 @@ #include "setframevaluedialog.h" #include "ui_setframevaluedialog.h" +#include + namespace QmlDesigner { -SetFrameValueDialog::SetFrameValueDialog(QWidget *parent) +SetFrameValueDialog::SetFrameValueDialog(qreal frame, const QVariant &value, + const QString &propertyName, QWidget *parent) : QDialog(parent) , ui(new Ui::SetFrameValueDialog) { setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); + setWindowTitle(tr("Edit Keyframe")); ui->setupUi(this); + + ui->lineEditFrame->setValidator(new QIntValidator(0, 99999, this)); + + ui->lineEditFrame->setText(QString::number(frame)); + ui->lineEditValue->setText(value.toString()); + ui->labelValue->setText(propertyName); } SetFrameValueDialog::~SetFrameValueDialog() @@ -41,15 +51,14 @@ SetFrameValueDialog::~SetFrameValueDialog() delete ui; } -QLineEdit *SetFrameValueDialog::lineEdit() const +qreal SetFrameValueDialog::frame() const { - return ui->lineEdit; + return ui->lineEditFrame->text().toDouble(); } -void SetFrameValueDialog::setPropertName(const QString &name) +QVariant SetFrameValueDialog::value() const { - setWindowTitle(tr("Change %1").arg(name)); - ui->label->setText(name); + return QVariant(ui->lineEditValue->text()); } } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/timelineeditor/setframevaluedialog.h b/src/plugins/qmldesigner/components/timelineeditor/setframevaluedialog.h index e7ed226b674..799e3fadc52 100644 --- a/src/plugins/qmldesigner/components/timelineeditor/setframevaluedialog.h +++ b/src/plugins/qmldesigner/components/timelineeditor/setframevaluedialog.h @@ -40,12 +40,12 @@ class SetFrameValueDialog : public QDialog Q_OBJECT public: - explicit SetFrameValueDialog(QWidget *parent = nullptr); + explicit SetFrameValueDialog(qreal frame, const QVariant &value, const QString &propertyName, + QWidget *parent = nullptr); ~SetFrameValueDialog() override; - QLineEdit *lineEdit() const; - - void setPropertName(const QString &name); + qreal frame() const; + QVariant value() const; private: Ui::SetFrameValueDialog *ui; diff --git a/src/plugins/qmldesigner/components/timelineeditor/setframevaluedialog.ui b/src/plugins/qmldesigner/components/timelineeditor/setframevaluedialog.ui index 2fa1241e4a2..1fe2468a6bf 100644 --- a/src/plugins/qmldesigner/components/timelineeditor/setframevaluedialog.ui +++ b/src/plugins/qmldesigner/components/timelineeditor/setframevaluedialog.ui @@ -7,7 +7,7 @@ 0 0 184 - 79 + 93 @@ -15,16 +15,13 @@ - + - Value + Frame - - - - + Qt::Horizontal @@ -34,6 +31,19 @@ + + + + + + + + + + Value + + + diff --git a/src/plugins/qmldesigner/components/timelineeditor/timelinemovableabstractitem.cpp b/src/plugins/qmldesigner/components/timelineeditor/timelinemovableabstractitem.cpp index 4db4567fd69..1d700cf063f 100644 --- a/src/plugins/qmldesigner/components/timelineeditor/timelinemovableabstractitem.cpp +++ b/src/plugins/qmldesigner/components/timelineeditor/timelinemovableabstractitem.cpp @@ -46,6 +46,11 @@ void TimelineMovableAbstractItem::itemMoved(const QPointF & /*start*/, const QPo setPositionInteractive(end); } +void TimelineMovableAbstractItem::itemDoubleClicked() +{ + // to be overridden by child classes if needed +} + int TimelineMovableAbstractItem::scrollOffset() const { return timelineScene()->scrollOffset(); diff --git a/src/plugins/qmldesigner/components/timelineeditor/timelinemovableabstractitem.h b/src/plugins/qmldesigner/components/timelineeditor/timelinemovableabstractitem.h index 0830facfbfb..cf71397225e 100644 --- a/src/plugins/qmldesigner/components/timelineeditor/timelinemovableabstractitem.h +++ b/src/plugins/qmldesigner/components/timelineeditor/timelinemovableabstractitem.h @@ -57,6 +57,7 @@ public: virtual void setPositionInteractive(const QPointF &point); virtual void commitPosition(const QPointF &point); virtual void itemMoved(const QPointF &start, const QPointF &end); + virtual void itemDoubleClicked(); int xPosScrollOffset(int x) const; diff --git a/src/plugins/qmldesigner/components/timelineeditor/timelinepropertyitem.cpp b/src/plugins/qmldesigner/components/timelineeditor/timelinepropertyitem.cpp index beeca23183b..920a8b35ca9 100644 --- a/src/plugins/qmldesigner/components/timelineeditor/timelinepropertyitem.cpp +++ b/src/plugins/qmldesigner/components/timelineeditor/timelinepropertyitem.cpp @@ -106,31 +106,40 @@ static void setEasingCurve(TimelineGraphicsScene *scene, const QList EasingCurveDialog::runDialog(keys); } -static void editValue(const ModelNode &frame, const QString &propertyName) +// display and handle the edit keyframe dialog +static void editValue(const ModelNode &frameNode, const std::pair &timelineRange, + const QString &propertyName) { - const QVariant value = frame.variantProperty("value").value(); - auto dialog = new SetFrameValueDialog(Core::ICore::dialogParent()); - - dialog->lineEdit()->setText(value.toString()); - dialog->setPropertName(propertyName); + const qreal frame = frameNode.variantProperty("frame").value().toReal(); + const QVariant value = frameNode.variantProperty("value").value(); + auto dialog = new SetFrameValueDialog(frame, value, propertyName, + Core::ICore::dialogParent()); QObject::connect(dialog, &SetFrameValueDialog::rejected, [dialog]() { dialog->deleteLater(); }); - QObject::connect(dialog, &SetFrameValueDialog::accepted, [dialog, frame, value]() { + QObject::connect(dialog, &SetFrameValueDialog::accepted, [dialog, frameNode, frame, value, + timelineRange]() { dialog->deleteLater(); - int userType = value.userType(); - const QVariant result = dialog->lineEdit()->text(); - if (result.canConvert(userType)) { - QVariant newValue = result; - newValue.convert(userType); - // canConvert gives true in case if the result is a double but the usertype was interger - // try to fix that with a workaround to convert it to double if convertion resulted in isNull - if (newValue.isNull()) { - newValue = result; - newValue.convert(QMetaType::Double); + qreal newFrame = qBound(timelineRange.first, dialog->frame(), timelineRange.second); + if (newFrame != frame) + frameNode.variantProperty("frame").setValue(newFrame); + + int userType = value.userType(); + QVariant newValue = dialog->value(); + + if (newValue.canConvert(userType)) { + QVariant newValueConverted = newValue; + bool converted = newValueConverted.convert(userType); + + if (!converted) { + // convert() fails for int to double, so we try this combination + newValueConverted = newValue; + converted = newValueConverted.convert(QMetaType::Double); } - frame.variantProperty("value").setValue(result); + + if (converted) + frameNode.variantProperty("value").setValue(newValueConverted); } }); @@ -431,9 +440,12 @@ void TimelinePropertyItem::contextMenuEvent(QGraphicsSceneContextMenuEvent *even setEasingCurve(timelineScene(), {currentFrameNode}); }); - QAction *editValueAction = mainMenu.addAction(tr("Edit Value for Keyframe...")); + QAction *editValueAction = mainMenu.addAction(tr("Edit Keyframe...")); QObject::connect(editValueAction, &QAction::triggered, [this, currentFrameNode]() { - editValue(currentFrameNode, propertyName()); + std::pair timelineRange + = {timelineScene()->currentTimeline().startKeyframe(), + timelineScene()->currentTimeline().endKeyframe()}; + editValue(currentFrameNode, timelineRange, propertyName()); }); const bool hasKeyframe = currentFrameNode.isValid(); @@ -541,6 +553,13 @@ void TimelineKeyframeItem::commitPosition(const QPointF &point) enableUpdates(); } +void TimelineKeyframeItem::itemDoubleClicked() +{ + std::pair timelineRange = {timelineScene()->currentTimeline().startKeyframe(), + timelineScene()->currentTimeline().endKeyframe()}; + editValue(m_frame, timelineRange, propertyItem()->propertyName()); +} + TimelineKeyframeItem *TimelineKeyframeItem::asTimelineKeyframeItem() { return this; @@ -630,9 +649,11 @@ void TimelineKeyframeItem::contextMenuEvent(QGraphicsSceneContextMenuEvent *even setEasingCurve(timelineScene(), keys); }); - QAction *editValueAction = mainMenu.addAction(tr("Edit Value for Keyframe...")); + QAction *editValueAction = mainMenu.addAction(tr("Edit Keyframe...")); QObject::connect(editValueAction, &QAction::triggered, [this]() { - editValue(m_frame, propertyItem()->propertyName()); + std::pair timelineRange = {timelineScene()->currentTimeline().startKeyframe(), + timelineScene()->currentTimeline().endKeyframe()}; + editValue(m_frame, timelineRange, propertyItem()->propertyName()); }); mainMenu.exec(event->screenPos()); diff --git a/src/plugins/qmldesigner/components/timelineeditor/timelinepropertyitem.h b/src/plugins/qmldesigner/components/timelineeditor/timelinepropertyitem.h index 2b8c00c59bc..4544b403029 100644 --- a/src/plugins/qmldesigner/components/timelineeditor/timelinepropertyitem.h +++ b/src/plugins/qmldesigner/components/timelineeditor/timelinepropertyitem.h @@ -63,6 +63,8 @@ public: void commitPosition(const QPointF &point) override; + void itemDoubleClicked() override; + TimelineKeyframeItem *asTimelineKeyframeItem() override; protected: diff --git a/src/plugins/qmldesigner/components/timelineeditor/timelineselectiontool.cpp b/src/plugins/qmldesigner/components/timelineeditor/timelineselectiontool.cpp index 987ac4935a6..c9ab3044976 100644 --- a/src/plugins/qmldesigner/components/timelineeditor/timelineselectiontool.cpp +++ b/src/plugins/qmldesigner/components/timelineeditor/timelineselectiontool.cpp @@ -98,7 +98,6 @@ void TimelineSelectionTool::mouseReleaseEvent(TimelineMovableAbstractItem *item, QGraphicsSceneMouseEvent *event) { Q_UNUSED(item) - Q_UNUSED(event) commitSelection(selectionMode(event)); @@ -108,9 +107,11 @@ void TimelineSelectionTool::mouseReleaseEvent(TimelineMovableAbstractItem *item, void TimelineSelectionTool::mouseDoubleClickEvent(TimelineMovableAbstractItem *item, QGraphicsSceneMouseEvent *event) { - Q_UNUSED(item) Q_UNUSED(event) + if (item) + item->itemDoubleClicked(); + reset(); } diff --git a/src/plugins/qmldesigner/components/timelineeditor/timelinetooldelegate.cpp b/src/plugins/qmldesigner/components/timelineeditor/timelinetooldelegate.cpp index 51c5a7d0889..d84a4619998 100644 --- a/src/plugins/qmldesigner/components/timelineeditor/timelinetooldelegate.cpp +++ b/src/plugins/qmldesigner/components/timelineeditor/timelinetooldelegate.cpp @@ -92,8 +92,10 @@ void TimelineToolDelegate::mouseReleaseEvent(TimelineMovableAbstractItem *item, void TimelineToolDelegate::mouseDoubleClickEvent(TimelineMovableAbstractItem *item, QGraphicsSceneMouseEvent *event) { - if (m_currentTool) + if (hitCanvas(event)) { + m_currentTool = m_selectTool.get(); m_currentTool->mouseDoubleClickEvent(item, event); + } reset(); }