diff options
author | Mahmoud Badri <mahmoud.badri@qt.io> | 2019-10-03 11:51:13 +0300 |
---|---|---|
committer | Mahmoud Badri <mahmoud.badri@qt.io> | 2019-10-07 07:14:04 +0000 |
commit | 2c2ffa8273bbf5da041002f64a76dfa223705c29 (patch) | |
tree | 1adee54101c921a7eb702af9dbb10e72a7d65e5e /src/plugins/qmldesigner/components/timelineeditor | |
parent | 69719e7b3e6efd30856700ac67d0a108918561bb (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')
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) { |