aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/qmldesigner/components/timelineeditor
diff options
context:
space:
mode:
authorMahmoud Badri <mahmoud.badri@qt.io>2019-10-03 11:51:13 +0300
committerMahmoud Badri <mahmoud.badri@qt.io>2019-10-07 07:14:04 +0000
commit2c2ffa8273bbf5da041002f64a76dfa223705c29 (patch)
tree1adee54101c921a7eb702af9dbb10e72a7d65e5e /src/plugins/qmldesigner/components/timelineeditor
parent69719e7b3e6efd30856700ac67d0a108918561bb (diff)
Implement keyframes snapping
When shift is down while dragging keyframe(s), they snap to ruler ticks, keyframes, and the playhead. Task-number: QDS-1068 Change-Id: Iea5fec9e578d3f1db51c429cbd565ad145a90fe8 Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io> Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
Diffstat (limited to 'src/plugins/qmldesigner/components/timelineeditor')
-rw-r--r--src/plugins/qmldesigner/components/timelineeditor/timelinegraphicsscene.cpp31
-rw-r--r--src/plugins/qmldesigner/components/timelineeditor/timelinegraphicsscene.h3
-rw-r--r--src/plugins/qmldesigner/components/timelineeditor/timelinemovetool.cpp12
3 files changed, 31 insertions, 15 deletions
diff --git a/src/plugins/qmldesigner/components/timelineeditor/timelinegraphicsscene.cpp b/src/plugins/qmldesigner/components/timelineeditor/timelinegraphicsscene.cpp
index f212d52916..96d37f395a 100644
--- a/src/plugins/qmldesigner/components/timelineeditor/timelinegraphicsscene.cpp
+++ b/src/plugins/qmldesigner/components/timelineeditor/timelinegraphicsscene.cpp
@@ -181,10 +181,10 @@ void TimelineGraphicsScene::updateKeyframePositionsCache()
}
// snap a frame to nearest keyframe or ruler tick
-qreal TimelineGraphicsScene::snap(qreal frame)
+qreal TimelineGraphicsScene::snap(qreal frame, bool snapToPlayhead)
{
- qreal frameTick = m_layout->ruler()->getFrameTick();
- qreal rulerTicksSnapframe = qRound(frame / frameTick) * frameTick;
+ qreal rulerFrameTick = m_layout->ruler()->getFrameTick();
+ qreal nearestRulerTickFrame = qRound(frame / rulerFrameTick) * rulerFrameTick;
// get nearest keyframe to the input frame
bool nearestKeyframeFound = false;
qreal nearestKeyframe = 0;
@@ -202,23 +202,30 @@ qreal TimelineGraphicsScene::snap(qreal frame)
}
}
- if (!nearestKeyframeFound && !m_keyframePositionsCache.empty()) {
- // playhead past last keyframe case
+ // playhead past last keyframe case
+ if (!nearestKeyframeFound && !m_keyframePositionsCache.empty())
nearestKeyframe = m_keyframePositionsCache.last();
- nearestKeyframeFound = true;
- }
- // return nearest snappable keyframe or ruler tick
- return nearestKeyframeFound && qAbs(nearestKeyframe - frame)
- < qAbs(rulerTicksSnapframe - frame) ? nearestKeyframe
- : rulerTicksSnapframe;
+ qreal playheadFrame = m_currentFrameIndicator->position();
+
+ qreal dKeyframe = qAbs(nearestKeyframe - frame);
+ qreal dPlayhead = snapToPlayhead ? qAbs(playheadFrame - frame) : 99999.;
+ qreal dRulerTick = qAbs(nearestRulerTickFrame - frame);
+
+ if (dKeyframe <= qMin(dPlayhead, dRulerTick))
+ return nearestKeyframe;
+
+ if (dRulerTick <= dPlayhead)
+ return nearestRulerTickFrame;
+
+ return playheadFrame;
}
void TimelineGraphicsScene::setCurrenFrame(const QmlTimeline &timeline, qreal frame)
{
if (timeline.isValid()) {
if (QApplication::keyboardModifiers() & Qt::ShiftModifier) // playhead snapping
- frame = snap(frame);
+ frame = snap(frame, false);
m_currentFrameIndicator->setPosition(frame);
} else {
m_currentFrameIndicator->setPosition(0);
diff --git a/src/plugins/qmldesigner/components/timelineeditor/timelinegraphicsscene.h b/src/plugins/qmldesigner/components/timelineeditor/timelinegraphicsscene.h
index fd2c641dd4..ba0c10bcd5 100644
--- a/src/plugins/qmldesigner/components/timelineeditor/timelinegraphicsscene.h
+++ b/src/plugins/qmldesigner/components/timelineeditor/timelinegraphicsscene.h
@@ -97,6 +97,8 @@ public:
QVector<qreal> keyframePositions() const;
QVector<qreal> keyframePositions(const QmlTimelineKeyframeGroup &frames) const;
+ qreal snap(qreal frame, bool snapToPlayhead = true);
+
void setRulerScaling(int scaling);
void commitCurrentFrame(qreal frame);
@@ -167,7 +169,6 @@ private:
QList<QGraphicsItem *> itemsAt(const QPointF &pos);
private:
- qreal snap(qreal frame);
TimelineWidget *m_parent = nullptr;
diff --git a/src/plugins/qmldesigner/components/timelineeditor/timelinemovetool.cpp b/src/plugins/qmldesigner/components/timelineeditor/timelinemovetool.cpp
index 785b1bb268..7c3d7a79e4 100644
--- a/src/plugins/qmldesigner/components/timelineeditor/timelinemovetool.cpp
+++ b/src/plugins/qmldesigner/components/timelineeditor/timelinemovetool.cpp
@@ -90,7 +90,7 @@ void TimelineMoveTool::mouseMoveEvent(TimelineMovableAbstractItem *item,
return;
const qreal sourceFrame = qRound(current->mapFromSceneToFrame(current->rect().center().x()));
- const qreal targetFrame = qRound(current->mapFromSceneToFrame(event->scenePos().x()));
+ qreal targetFrame = qRound(current->mapFromSceneToFrame(event->scenePos().x()));
qreal deltaFrame = targetFrame - sourceFrame - m_pressKeyframeDelta;
const qreal minFrame = scene()->startFrame();
@@ -106,8 +106,16 @@ void TimelineMoveTool::mouseMoveEvent(TimelineMovableAbstractItem *item,
else if (firstFrame + deltaFrame < minFrame)
deltaFrame = minFrame - firstFrame;
+ targetFrame = sourceFrame + deltaFrame;
+
+ if (QApplication::keyboardModifiers() & Qt::ShiftModifier) { // keyframe snapping
+ qreal snappedTargetFrame = scene()->snap(targetFrame);
+ deltaFrame += snappedTargetFrame - targetFrame;
+ targetFrame = snappedTargetFrame;
+ }
+
scene()->statusBarMessageChanged(tr(TimelineConstants::statusBarKeyframe)
- .arg(sourceFrame + deltaFrame));
+ .arg(targetFrame));
const QList<TimelineKeyframeItem *> selectedKeyframes = scene()->selectedKeyframes();
for (auto *keyframe : selectedKeyframes) {