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 <thomas.hartmann@qt.io>
This commit is contained in:
Mahmoud Badri
2019-09-25 14:36:28 +03:00
parent e48b4aa44e
commit c6b0c549cc
9 changed files with 93 additions and 42 deletions

View File

@@ -26,14 +26,24 @@
#include "setframevaluedialog.h"
#include "ui_setframevaluedialog.h"
#include <QIntValidator>
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

View File

@@ -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;

View File

@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>184</width>
<height>79</height>
<height>93</height>
</rect>
</property>
<property name="windowTitle">
@@ -15,16 +15,13 @@
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label">
<widget class="QLabel" name="labelFrame">
<property name="text">
<string>Value</string>
<string>Frame</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="lineEdit"/>
</item>
<item row="1" column="0" colspan="2">
<item row="2" column="0" colspan="2">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
@@ -34,6 +31,19 @@
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="lineEditFrame"/>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="lineEditValue"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="labelValue">
<property name="text">
<string>Value</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>

View File

@@ -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();

View File

@@ -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;

View File

@@ -106,31 +106,40 @@ static void setEasingCurve(TimelineGraphicsScene *scene, const QList<ModelNode>
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<qreal, qreal> &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<qreal, qreal> 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<qreal, qreal> 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<qreal, qreal> timelineRange = {timelineScene()->currentTimeline().startKeyframe(),
timelineScene()->currentTimeline().endKeyframe()};
editValue(m_frame, timelineRange, propertyItem()->propertyName());
});
mainMenu.exec(event->screenPos());

View File

@@ -63,6 +63,8 @@ public:
void commitPosition(const QPointF &point) override;
void itemDoubleClicked() override;
TimelineKeyframeItem *asTimelineKeyframeItem() override;
protected:

View File

@@ -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();
}

View File

@@ -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();
}