Playhead range check and status bar improvements

- distinguish between playhead and keyframe value on the status bar.
- update the status bar frame value when a keyframe is being moved.
- when changing or deleting timelines, update the status bar.
- when changing timelines, make sure the playhead is within the new
timeline's range.
- keep playhead in range after changing timeline's start/end.

Task-number: QDS-1071
Change-Id: Id9758e3097d34df9334d6284a6a56ba38b509a31
Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
Mahmoud Badri
2019-09-26 15:04:52 +03:00
parent c6b0c549cc
commit 0ffe31bec3
6 changed files with 45 additions and 21 deletions

View File

@@ -54,7 +54,8 @@ const char timelineInsertKeyframesDisplayName[] = QT_TRANSLATE_NOOP("QmlDesigner
const char timelineDeleteKeyframesDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu",
"Delete All Keyframes");
const char timelineStatusBarFrameNumber[] = QT_TRANSLATE_NOOP("QmlDesignerTimeline", "Frame %1");
const char statusBarPlayheadFrame[] = QT_TRANSLATE_NOOP("QmlDesignerTimeline", "Playhead frame %1");
const char statusBarKeyframe[] = QT_TRANSLATE_NOOP("QmlDesignerTimeline", "Keyframe %1");
const char C_QMLTIMELINE[] = "QmlDesigner::Timeline";
const char C_SETTINGS[] = "QmlDesigner.Settings";

View File

@@ -194,7 +194,7 @@ void TimelineGraphicsScene::setCurrentFrame(int frame)
invalidateCurrentValues();
emitStatusBarFrameMessageChanged(frame);
emitStatusBarPlayheadFrameChanged(frame);
}
void TimelineGraphicsScene::setStartFrame(int frame)
@@ -318,7 +318,7 @@ void TimelineGraphicsScene::commitCurrentFrame(qreal frame)
setCurrenFrame(timeline, qRound(frame));
invalidateCurrentValues();
}
emitStatusBarFrameMessageChanged(int(frame));
emitStatusBarPlayheadFrameChanged(int(frame));
}
QList<TimelineKeyframeItem *> TimelineGraphicsScene::selectedKeyframes() const
@@ -700,10 +700,10 @@ void TimelineGraphicsScene::emitScrollOffsetChanged()
TimelineMovableAbstractItem::emitScrollOffsetChanged(item);
}
void TimelineGraphicsScene::emitStatusBarFrameMessageChanged(int frame)
void TimelineGraphicsScene::emitStatusBarPlayheadFrameChanged(int frame)
{
emit statusBarMessageChanged(
QString(TimelineConstants::timelineStatusBarFrameNumber).arg(frame));
tr(TimelineConstants::statusBarPlayheadFrame).arg(frame));
}
bool TimelineGraphicsScene::event(QEvent *event)

View File

@@ -160,7 +160,7 @@ private:
ModelNode timelineModelNode() const;
void emitScrollOffsetChanged();
void emitStatusBarFrameMessageChanged(int frame);
void emitStatusBarPlayheadFrameChanged(int frame);
QList<QGraphicsItem *> itemsAt(const QPointF &pos);

View File

@@ -100,6 +100,9 @@ void TimelineMoveTool::mouseMoveEvent(TimelineMovableAbstractItem *item,
current->setPosition(sourceFrame + deltaFrame);
scene()->statusBarMessageChanged(tr(TimelineConstants::statusBarKeyframe)
.arg(sourceFrame + deltaFrame));
for (auto *keyframe : scene()->selectedKeyframes()) {
if (keyframe != current) {
qreal pos = std::round(current->mapFromSceneToFrame(keyframe->rect().center().x()));
@@ -125,30 +128,37 @@ void TimelineMoveTool::mouseReleaseEvent(TimelineMovableAbstractItem *item,
double start = current->mapFromFrameToScene(scene()->startFrame());
double end = current->mapFromFrameToScene(scene()->endFrame());
if (mousePos < start) {
scene()->setCurrentFrame(scene()->startFrame());
scene()->statusBarMessageChanged(QObject::tr("Frame %1").arg(scene()->startFrame()));
return;
} else if (mousePos > end) {
scene()->setCurrentFrame(scene()->endFrame());
scene()->statusBarMessageChanged(QObject::tr("Frame %1").arg(scene()->endFrame()));
double limitFrame = -999999.;
if (mousePos < start)
limitFrame = scene()->startFrame();
else if (mousePos > end)
limitFrame = scene()->endFrame();
if (limitFrame > -999999.) {
scene()->setCurrentFrame(limitFrame);
scene()->statusBarMessageChanged(
tr(TimelineConstants::statusBarPlayheadFrame).arg(limitFrame));
return;
}
}
scene()->timelineView()->executeInTransaction("TimelineMoveTool::mouseReleaseEvent", [this, current](){
scene()->timelineView()->executeInTransaction("TimelineMoveTool::mouseReleaseEvent",
[this, current]() {
current->commitPosition(mapToItem(current, current->rect().center()));
if (current->asTimelineKeyframeItem()) {
double frame = std::round(
current->mapFromSceneToFrame(current->rect().center().x()));
scene()->statusBarMessageChanged(QObject::tr("Frame %1").arg(frame));
scene()->statusBarMessageChanged(
tr(TimelineConstants::statusBarKeyframe).arg(frame));
for (auto keyframe : scene()->selectedKeyframes())
const auto selectedKeyframes = scene()->selectedKeyframes();
for (auto keyframe : selectedKeyframes) {
if (keyframe != current)
keyframe->commitPosition(mapToItem(current, keyframe->rect().center()));
}
}
});
}
}

View File

@@ -37,6 +37,8 @@ class TimelineMovableAbstractItem;
class TimelineMoveTool : public TimelineAbstractTool
{
Q_DECLARE_TR_FUNCTIONS(TimelineMoveTool)
public:
explicit TimelineMoveTool(TimelineGraphicsScene *scene, TimelineToolDelegate *delegate);
void mousePressEvent(TimelineMovableAbstractItem *item,

View File

@@ -405,14 +405,18 @@ void TimelineWidget::contextHelp(const Core::IContext::HelpCallback &callback) c
void TimelineWidget::init()
{
QmlTimeline currentTimeline = m_timelineView->timelineForState(m_timelineView->currentState());
if (currentTimeline.isValid())
if (currentTimeline.isValid()) {
setTimelineId(currentTimeline.modelNode().id());
else
m_statusBar->setText(tr(TimelineConstants::statusBarPlayheadFrame)
.arg(getcurrentFrame(currentTimeline)));
} else {
setTimelineId({});
m_statusBar->clear();
}
invalidateTimelineDuration(graphicsScene()->currentTimeline());
invalidateTimelineDuration(m_graphicsScene->currentTimeline());
graphicsScene()->setWidth(m_graphicsView->viewport()->width());
m_graphicsScene->setWidth(m_graphicsView->viewport()->width());
// setScaleFactor uses QSignalBlocker.
m_toolbar->setScaleFactor(0);
@@ -442,7 +446,14 @@ void TimelineWidget::invalidateTimelineDuration(const QmlTimeline &timeline)
QmlTimeline currentTimeline = graphicsScene()->currentTimeline();
if (currentTimeline.isValid() && currentTimeline == timeline) {
graphicsScene()->setTimeline(timeline);
graphicsScene()->setCurrenFrame(timeline, getcurrentFrame(timeline));
qreal playHeadFrame = getcurrentFrame(timeline);
if (playHeadFrame < timeline.startKeyframe())
playHeadFrame = timeline.startKeyframe();
else if (playHeadFrame > timeline.endKeyframe())
playHeadFrame = timeline.endKeyframe();
graphicsScene()->setCurrentFrame(playHeadFrame);
}
}
}