forked from qt-creator/qt-creator
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:
@@ -54,7 +54,8 @@ const char timelineInsertKeyframesDisplayName[] = QT_TRANSLATE_NOOP("QmlDesigner
|
|||||||
const char timelineDeleteKeyframesDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu",
|
const char timelineDeleteKeyframesDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu",
|
||||||
"Delete All Keyframes");
|
"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_QMLTIMELINE[] = "QmlDesigner::Timeline";
|
||||||
const char C_SETTINGS[] = "QmlDesigner.Settings";
|
const char C_SETTINGS[] = "QmlDesigner.Settings";
|
||||||
|
@@ -194,7 +194,7 @@ void TimelineGraphicsScene::setCurrentFrame(int frame)
|
|||||||
|
|
||||||
invalidateCurrentValues();
|
invalidateCurrentValues();
|
||||||
|
|
||||||
emitStatusBarFrameMessageChanged(frame);
|
emitStatusBarPlayheadFrameChanged(frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TimelineGraphicsScene::setStartFrame(int frame)
|
void TimelineGraphicsScene::setStartFrame(int frame)
|
||||||
@@ -318,7 +318,7 @@ void TimelineGraphicsScene::commitCurrentFrame(qreal frame)
|
|||||||
setCurrenFrame(timeline, qRound(frame));
|
setCurrenFrame(timeline, qRound(frame));
|
||||||
invalidateCurrentValues();
|
invalidateCurrentValues();
|
||||||
}
|
}
|
||||||
emitStatusBarFrameMessageChanged(int(frame));
|
emitStatusBarPlayheadFrameChanged(int(frame));
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<TimelineKeyframeItem *> TimelineGraphicsScene::selectedKeyframes() const
|
QList<TimelineKeyframeItem *> TimelineGraphicsScene::selectedKeyframes() const
|
||||||
@@ -700,10 +700,10 @@ void TimelineGraphicsScene::emitScrollOffsetChanged()
|
|||||||
TimelineMovableAbstractItem::emitScrollOffsetChanged(item);
|
TimelineMovableAbstractItem::emitScrollOffsetChanged(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TimelineGraphicsScene::emitStatusBarFrameMessageChanged(int frame)
|
void TimelineGraphicsScene::emitStatusBarPlayheadFrameChanged(int frame)
|
||||||
{
|
{
|
||||||
emit statusBarMessageChanged(
|
emit statusBarMessageChanged(
|
||||||
QString(TimelineConstants::timelineStatusBarFrameNumber).arg(frame));
|
tr(TimelineConstants::statusBarPlayheadFrame).arg(frame));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TimelineGraphicsScene::event(QEvent *event)
|
bool TimelineGraphicsScene::event(QEvent *event)
|
||||||
|
@@ -160,7 +160,7 @@ private:
|
|||||||
ModelNode timelineModelNode() const;
|
ModelNode timelineModelNode() const;
|
||||||
|
|
||||||
void emitScrollOffsetChanged();
|
void emitScrollOffsetChanged();
|
||||||
void emitStatusBarFrameMessageChanged(int frame);
|
void emitStatusBarPlayheadFrameChanged(int frame);
|
||||||
|
|
||||||
QList<QGraphicsItem *> itemsAt(const QPointF &pos);
|
QList<QGraphicsItem *> itemsAt(const QPointF &pos);
|
||||||
|
|
||||||
|
@@ -100,6 +100,9 @@ void TimelineMoveTool::mouseMoveEvent(TimelineMovableAbstractItem *item,
|
|||||||
|
|
||||||
current->setPosition(sourceFrame + deltaFrame);
|
current->setPosition(sourceFrame + deltaFrame);
|
||||||
|
|
||||||
|
scene()->statusBarMessageChanged(tr(TimelineConstants::statusBarKeyframe)
|
||||||
|
.arg(sourceFrame + deltaFrame));
|
||||||
|
|
||||||
for (auto *keyframe : scene()->selectedKeyframes()) {
|
for (auto *keyframe : scene()->selectedKeyframes()) {
|
||||||
if (keyframe != current) {
|
if (keyframe != current) {
|
||||||
qreal pos = std::round(current->mapFromSceneToFrame(keyframe->rect().center().x()));
|
qreal pos = std::round(current->mapFromSceneToFrame(keyframe->rect().center().x()));
|
||||||
@@ -125,29 +128,36 @@ void TimelineMoveTool::mouseReleaseEvent(TimelineMovableAbstractItem *item,
|
|||||||
double start = current->mapFromFrameToScene(scene()->startFrame());
|
double start = current->mapFromFrameToScene(scene()->startFrame());
|
||||||
double end = current->mapFromFrameToScene(scene()->endFrame());
|
double end = current->mapFromFrameToScene(scene()->endFrame());
|
||||||
|
|
||||||
if (mousePos < start) {
|
double limitFrame = -999999.;
|
||||||
scene()->setCurrentFrame(scene()->startFrame());
|
if (mousePos < start)
|
||||||
scene()->statusBarMessageChanged(QObject::tr("Frame %1").arg(scene()->startFrame()));
|
limitFrame = scene()->startFrame();
|
||||||
return;
|
else if (mousePos > end)
|
||||||
} else if (mousePos > end) {
|
limitFrame = scene()->endFrame();
|
||||||
scene()->setCurrentFrame(scene()->endFrame());
|
|
||||||
scene()->statusBarMessageChanged(QObject::tr("Frame %1").arg(scene()->endFrame()));
|
if (limitFrame > -999999.) {
|
||||||
|
scene()->setCurrentFrame(limitFrame);
|
||||||
|
scene()->statusBarMessageChanged(
|
||||||
|
tr(TimelineConstants::statusBarPlayheadFrame).arg(limitFrame));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
scene()->timelineView()->executeInTransaction("TimelineMoveTool::mouseReleaseEvent", [this, current](){
|
scene()->timelineView()->executeInTransaction("TimelineMoveTool::mouseReleaseEvent",
|
||||||
|
[this, current]() {
|
||||||
current->commitPosition(mapToItem(current, current->rect().center()));
|
current->commitPosition(mapToItem(current, current->rect().center()));
|
||||||
|
|
||||||
if (current->asTimelineKeyframeItem()) {
|
if (current->asTimelineKeyframeItem()) {
|
||||||
double frame = std::round(
|
double frame = std::round(
|
||||||
current->mapFromSceneToFrame(current->rect().center().x()));
|
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)
|
if (keyframe != current)
|
||||||
keyframe->commitPosition(mapToItem(current, keyframe->rect().center()));
|
keyframe->commitPosition(mapToItem(current, keyframe->rect().center()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@@ -37,6 +37,8 @@ class TimelineMovableAbstractItem;
|
|||||||
|
|
||||||
class TimelineMoveTool : public TimelineAbstractTool
|
class TimelineMoveTool : public TimelineAbstractTool
|
||||||
{
|
{
|
||||||
|
Q_DECLARE_TR_FUNCTIONS(TimelineMoveTool)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit TimelineMoveTool(TimelineGraphicsScene *scene, TimelineToolDelegate *delegate);
|
explicit TimelineMoveTool(TimelineGraphicsScene *scene, TimelineToolDelegate *delegate);
|
||||||
void mousePressEvent(TimelineMovableAbstractItem *item,
|
void mousePressEvent(TimelineMovableAbstractItem *item,
|
||||||
|
@@ -405,14 +405,18 @@ void TimelineWidget::contextHelp(const Core::IContext::HelpCallback &callback) c
|
|||||||
void TimelineWidget::init()
|
void TimelineWidget::init()
|
||||||
{
|
{
|
||||||
QmlTimeline currentTimeline = m_timelineView->timelineForState(m_timelineView->currentState());
|
QmlTimeline currentTimeline = m_timelineView->timelineForState(m_timelineView->currentState());
|
||||||
if (currentTimeline.isValid())
|
if (currentTimeline.isValid()) {
|
||||||
setTimelineId(currentTimeline.modelNode().id());
|
setTimelineId(currentTimeline.modelNode().id());
|
||||||
else
|
m_statusBar->setText(tr(TimelineConstants::statusBarPlayheadFrame)
|
||||||
|
.arg(getcurrentFrame(currentTimeline)));
|
||||||
|
} else {
|
||||||
setTimelineId({});
|
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.
|
// setScaleFactor uses QSignalBlocker.
|
||||||
m_toolbar->setScaleFactor(0);
|
m_toolbar->setScaleFactor(0);
|
||||||
@@ -442,7 +446,14 @@ void TimelineWidget::invalidateTimelineDuration(const QmlTimeline &timeline)
|
|||||||
QmlTimeline currentTimeline = graphicsScene()->currentTimeline();
|
QmlTimeline currentTimeline = graphicsScene()->currentTimeline();
|
||||||
if (currentTimeline.isValid() && currentTimeline == timeline) {
|
if (currentTimeline.isValid() && currentTimeline == timeline) {
|
||||||
graphicsScene()->setTimeline(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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user