From 1cf58f62e8c3cc5efe90b9b36605f6e52debe134 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Mardelle Date: Wed, 27 Nov 2019 13:21:43 +0100 Subject: [PATCH] Cleanup seeking logic, get rid of confusing blue bar indicating real MLT position, pause on seek --- src/core.cpp | 4 +- src/mainwindow.cpp | 2 +- src/monitor/glwidget.cpp | 65 ++++------------- src/monitor/glwidget.h | 5 +- src/monitor/monitor.cpp | 42 +++++++---- src/monitor/monitor.h | 7 +- src/monitor/monitorproxy.cpp | 56 +++------------ src/monitor/monitorproxy.h | 20 ++---- src/monitor/view/MonitorRuler.qml | 10 +-- src/monitor/view/kdenliveclipmonitor.qml | 2 +- src/project/projectmanager.cpp | 3 +- src/timeline2/view/qml/Clip.qml | 2 +- src/timeline2/view/qml/Composition.qml | 2 +- src/timeline2/view/qml/KeyframeView.qml | 5 +- src/timeline2/view/qml/Timeline.js | 2 +- src/timeline2/view/qml/timeline.qml | 72 +++++++++---------- src/timeline2/view/timelinecontroller.cpp | 88 +++++++++-------------- src/timeline2/view/timelinecontroller.h | 14 ---- src/timeline2/view/timelinetabs.cpp | 8 --- src/timeline2/view/timelinewidget.cpp | 7 +- src/timeline2/view/timelinewidget.h | 3 +- 21 files changed, 153 insertions(+), 266 deletions(-) diff --git a/src/core.cpp b/src/core.cpp index be3a9f3977..0722123038 100644 --- a/src/core.cpp +++ b/src/core.cpp @@ -713,8 +713,8 @@ Mlt::Profile *Core::thumbProfile() int Core::getTimelinePosition() const { - if (m_mainWindow && m_guiConstructed) { - return m_mainWindow->getCurrentTimeline()->controller()->timelinePosition(); + if (m_guiConstructed) { + return m_monitorManager->projectMonitor()->position(); } return 0; } diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 85c5feef35..609c605ab3 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -346,7 +346,7 @@ void MainWindow::init() case ObjectType::TimelineClip: case ObjectType::TimelineComposition: case ObjectType::Master: - getCurrentTimeline()->controller()->setPosition(pos); + m_projectMonitor->requestSeek(pos); break; case ObjectType::BinClip: m_clipMonitor->requestSeek(pos); diff --git a/src/monitor/glwidget.cpp b/src/monitor/glwidget.cpp index c253105d39..c982409c3f 100644 --- a/src/monitor/glwidget.cpp +++ b/src/monitor/glwidget.cpp @@ -130,7 +130,6 @@ GLWidget::GLWidget(int id, QObject *parent) registerTimelineItems(); m_proxy = new MonitorProxy(this); - connect(m_proxy, &MonitorProxy::seekRequestChanged, this, &GLWidget::requestSeek); rootContext()->setContextProperty("controller", m_proxy); } @@ -645,42 +644,20 @@ void GLWidget::wheelEvent(QWheelEvent *event) event->accept(); } -void GLWidget::requestSeek() +void GLWidget::requestSeek(int position) { - if (!m_producer) { - return; - } - if (m_proxy->seeking()) { - m_producer->seek(m_proxy->seekPosition()); - if (!qFuzzyIsNull(m_producer->get_speed())) { - m_consumer->purge(); - } - if (m_consumer->is_stopped()) { - m_consumer->start(); - } - m_consumer->set("refresh", 1); + m_producer->seek(position); + if (!qFuzzyIsNull(m_producer->get_speed())) { + m_consumer->purge(); } -} - -void GLWidget::seek(int pos) -{ - if (!m_proxy->seeking()) { - m_producer->seek(pos); - if (m_consumer->is_stopped()) { - m_consumer->start(); - } else { - m_consumer->purge(); - m_consumer->set("refresh", 1); - } + if (m_consumer->is_stopped()) { + m_consumer->start(); } - m_proxy->setSeekPosition(pos); + m_consumer->set("refresh", 1); } void GLWidget::requestRefresh() { - if (m_proxy->seeking()) { - return; - } if (m_producer && qFuzzyIsNull(m_producer->get_speed())) { m_refreshTimer.start(); } @@ -694,9 +671,6 @@ QString GLWidget::frameToTime(int frames) const void GLWidget::refresh() { m_refreshTimer.stop(); - if (m_proxy->seeking()) { - return; - } QMutexLocker locker(&m_mltMutex); if (m_consumer->is_stopped()) { m_consumer->start(); @@ -707,19 +681,10 @@ void GLWidget::refresh() bool GLWidget::checkFrameNumber(int pos, int offset) { emit consumerPosition(pos); - if (!m_proxy->setPosition(pos)) { - emit seekPosition(m_proxy->seekOrCurrentPosition()); - } const double speed = m_producer->get_speed(); - if (m_proxy->seeking()) { - m_producer->set_speed(0); - m_producer->seek(m_proxy->seekPosition()); - if (qFuzzyIsNull(speed)) { - m_consumer->set("refresh", 1); - } else { - m_producer->set_speed(speed); - } - return true; + bool isPlaying = !qFuzzyIsNull(speed); + if (isPlaying) { + m_proxy->positionFromConsumer(pos); } int maxPos = m_producer->get_int("out"); if (m_isLoopMode || m_isZoneMode) { @@ -951,7 +916,7 @@ int GLWidget::setProducer(const std::shared_ptr &producer, bool i if (isActive) { startConsumer(); } - m_proxy->requestSeekPosition(position > 0 ? position : m_producer->position()); + m_proxy->setPosition(position > 0 ? position : m_producer->position()); return error; } @@ -1301,7 +1266,7 @@ void GLWidget::purgeCache() { if (m_consumer) { m_consumer->purge(); - m_producer->seek(m_proxy->position() + 1); + m_producer->seek(m_proxy->getPosition() + 1); } } @@ -1639,7 +1604,6 @@ void GLWidget::refreshSceneLayout() void GLWidget::switchPlay(bool play, double speed) { - m_proxy->setSeekPosition(-1); if (!m_producer || !m_consumer) { return; } @@ -1668,7 +1632,6 @@ bool GLWidget::playZone(bool loop) pCore->displayMessage(i18n("Select a zone to play"), InformationMessage, 500); return false; } - m_proxy->setSeekPosition(-1); m_producer->seek(m_proxy->zoneIn()); m_producer->set_speed(0); m_consumer->purge(); @@ -1689,7 +1652,6 @@ bool GLWidget::loopClip() pCore->displayMessage(i18n("Select a zone to play"), InformationMessage, 500); return false; } - m_proxy->setSeekPosition(-1); m_producer->seek(0); m_producer->set_speed(0); m_consumer->purge(); @@ -1721,7 +1683,7 @@ MonitorProxy *GLWidget::getControllerProxy() int GLWidget::getCurrentPos() const { - return m_proxy->seeking() ? m_proxy->seekPosition() : m_consumer->position(); + return m_consumer->position(); } void GLWidget::setRulerInfo(int duration, const std::shared_ptr &model) @@ -1756,7 +1718,6 @@ void GLWidget::startConsumer() void GLWidget::stop() { m_refreshTimer.stop(); - m_proxy->setSeekPosition(-1); // why this lock? QMutexLocker locker(&m_mltMutex); if (m_producer) { diff --git a/src/monitor/glwidget.h b/src/monitor/glwidget.h index b527923fdb..3a66ba6566 100644 --- a/src/monitor/glwidget.h +++ b/src/monitor/glwidget.h @@ -151,8 +151,8 @@ class GLWidget : public QQuickView, protected QOpenGLFunctions QString frameToTime(int frames) const; public slots: - void seek(int pos); - void requestSeek(); + //void seek(int pos); + void requestSeek(int position); void setZoom(float zoom); void setOffsetX(int x, int max); void setOffsetY(int y, int max); @@ -182,7 +182,6 @@ public slots: void lockMonitor(bool); void passKeyEvent(QKeyEvent *); void panView(const QPoint &diff); - void seekPosition(int); void consumerPosition(int); void activateMonitor(); diff --git a/src/monitor/monitor.cpp b/src/monitor/monitor.cpp index 7510b52fe3..a29d86775e 100644 --- a/src/monitor/monitor.cpp +++ b/src/monitor/monitor.cpp @@ -156,7 +156,8 @@ Monitor::Monitor(Kdenlive::MonitorId id, MonitorManager *manager, QWidget *paren m_glMonitor = new GLWidget((int)id); connect(m_glMonitor, &GLWidget::passKeyEvent, this, &Monitor::doKeyPressEvent); connect(m_glMonitor, &GLWidget::panView, this, &Monitor::panView); - connect(m_glMonitor, &GLWidget::seekPosition, this, &Monitor::seekPosition, Qt::DirectConnection); + connect(m_glMonitor->getControllerProxy(), &MonitorProxy::requestSeek, this, &Monitor::processSeek, Qt::DirectConnection); + connect(m_glMonitor, &GLWidget::consumerPosition, this, &Monitor::seekPosition, Qt::DirectConnection); connect(m_glMonitor, &GLWidget::consumerPosition, this, &Monitor::slotSeekPosition); connect(m_glMonitor, &GLWidget::activateMonitor, this, &AbstractMonitor::slotActivateMonitor, Qt::DirectConnection); m_videoWidget = QWidget::createWindowContainer(qobject_cast(m_glMonitor)); @@ -614,20 +615,20 @@ void Monitor::setGuides(const QMap &guides) void Monitor::slotSeekToPreviousSnap() { if (m_controller) { - m_glMonitor->seek(getSnapForPos(true).frames(m_monitorManager->timecode().fps())); + m_glMonitor->getControllerProxy()->setPosition(getSnapForPos(true).frames(m_monitorManager->timecode().fps())); } } void Monitor::slotSeekToNextSnap() { if (m_controller) { - m_glMonitor->seek(getSnapForPos(false).frames(m_monitorManager->timecode().fps())); + m_glMonitor->getControllerProxy()->setPosition(getSnapForPos(false).frames(m_monitorManager->timecode().fps())); } } int Monitor::position() { - return m_glMonitor->getCurrentPos(); + return m_glMonitor->getControllerProxy()->getPosition(); } GenTime Monitor::getSnapForPos(bool previous) @@ -947,7 +948,7 @@ void Monitor::slotMouseSeek(int eventDelta, uint modifiers) if (eventDelta > 0) { delta = 0 - delta; } - m_glMonitor->seek(m_glMonitor->getCurrentPos() - delta); + m_glMonitor->getControllerProxy()->setPosition(m_glMonitor->getCurrentPos() - delta); } else if ((modifiers & Qt::AltModifier) != 0u) { if (eventDelta >= 0) { emit seekToPreviousSnap(); @@ -1082,7 +1083,7 @@ void Monitor::slotSeek() void Monitor::slotSeek(int pos) { slotActivateMonitor(); - m_glMonitor->seek(pos); + m_glMonitor->getControllerProxy()->setPosition(pos); m_monitorManager->cleanMixer(); } @@ -1128,13 +1129,13 @@ int Monitor::getZoneEnd() void Monitor::slotZoneStart() { slotActivateMonitor(); - m_glMonitor->getControllerProxy()->pauseAndSeek(m_glMonitor->getControllerProxy()->zoneIn()); + m_glMonitor->getControllerProxy()->setPosition(m_glMonitor->getControllerProxy()->zoneIn()); } void Monitor::slotZoneEnd() { slotActivateMonitor(); - m_glMonitor->getControllerProxy()->pauseAndSeek(m_glMonitor->getControllerProxy()->zoneOut() - 1); + m_glMonitor->getControllerProxy()->setPosition(m_glMonitor->getControllerProxy()->zoneOut() - 1); } void Monitor::slotRewind(double speed) @@ -1170,13 +1171,13 @@ void Monitor::slotForward(double speed) void Monitor::slotRewindOneFrame(int diff) { slotActivateMonitor(); - m_glMonitor->seek(m_glMonitor->getCurrentPos() - diff); + m_glMonitor->getControllerProxy()->setPosition(m_glMonitor->getCurrentPos() - diff); } void Monitor::slotForwardOneFrame(int diff) { slotActivateMonitor(); - m_glMonitor->seek(m_glMonitor->getCurrentPos() + diff); + m_glMonitor->getControllerProxy()->setPosition(m_glMonitor->getCurrentPos() + diff); } void Monitor::adjustRulerSize(int length, const std::shared_ptr &markerModel) @@ -2036,12 +2037,18 @@ void Monitor::panView(QPoint diff) } } -void Monitor::requestSeek(int pos) +void Monitor::processSeek(int pos) { - m_glMonitor->seek(pos); + pause(); + m_glMonitor->requestSeek(pos); m_monitorManager->cleanMixer(); } +void Monitor::requestSeek(int pos) +{ + m_glMonitor->getControllerProxy()->setPosition(pos); +} + void Monitor::setProducer(std::shared_ptr producer, int pos) { m_glMonitor->setProducer(std::move(producer), isActive(), pos); @@ -2062,7 +2069,7 @@ void Monitor::slotStart() { slotActivateMonitor(); m_glMonitor->switchPlay(false); - m_glMonitor->seek(0); + m_glMonitor->getControllerProxy()->setPosition(0); } void Monitor::slotEnd() @@ -2070,9 +2077,9 @@ void Monitor::slotEnd() slotActivateMonitor(); m_glMonitor->switchPlay(false); if (m_id == Kdenlive::ClipMonitor) { - m_glMonitor->seek(m_glMonitor->duration()); + m_glMonitor->getControllerProxy()->setPosition(m_glMonitor->duration()); } else { - m_glMonitor->seek(pCore->projectDuration() - 1); + m_glMonitor->getControllerProxy()->setPosition(pCore->projectDuration() - 1); } } @@ -2115,3 +2122,8 @@ void Monitor::updateBgColor() { m_glMonitor->m_bgColor = KdenliveSettings::window_background(); } + +MonitorProxy *Monitor::getControllerProxy() +{ + return m_glMonitor->getControllerProxy(); +} diff --git a/src/monitor/monitor.h b/src/monitor/monitor.h index 67aefaeba8..7256e626d7 100644 --- a/src/monitor/monitor.h +++ b/src/monitor/monitor.h @@ -45,6 +45,7 @@ class RecManager; class QmlManager; class GLWidget; class MonitorAudioLevel; +class MonitorProxy; namespace Mlt { class Profile; @@ -153,6 +154,8 @@ class Monitor : public AbstractMonitor void setConsumerProperty(const QString &name, const QString &value); /** @brief Play or Loop zone sets a fake "out" on the producer. It is necessary to reset this before reloading the producer */ void resetPlayOrLoopZone(const QString &binId); + /** @brief Returns a pointer to monitor proxy, allowing to manage seek and consumer position */ + MonitorProxy *getControllerProxy(); protected: void mousePressEvent(QMouseEvent *event) override; @@ -263,6 +266,8 @@ private slots: void slotSeekPosition(int); void addSnapPoint(int pos); void removeSnapPoint(int pos); + /** @brief Pause monitor and process seek */ + void processSeek(int pos); public slots: void slotSetScreen(int screenIndex); @@ -324,8 +329,6 @@ public slots: void screenChanged(int screenIndex); void seekPosition(int pos); void updateScene(); - /** @brief Request a timeline seeking if diff is true, position is a relative offset, otherwise an absolute position */ - void seekTimeline(int position); void durationChanged(int); void refreshClipThumbnail(const QString &); void zoneUpdated(const QPoint &); diff --git a/src/monitor/monitorproxy.cpp b/src/monitor/monitorproxy.cpp index 973919c4af..c090a176fd 100644 --- a/src/monitor/monitorproxy.cpp +++ b/src/monitor/monitorproxy.cpp @@ -32,13 +32,10 @@ #include #include -#define SEEK_INACTIVE (-1) - MonitorProxy::MonitorProxy(GLWidget *parent) : QObject(parent) , q(parent) , m_position(0) - , m_seekPosition(-1) , m_zoneIn(0) , m_zoneOut(-1) , m_hasAV(false) @@ -46,17 +43,7 @@ MonitorProxy::MonitorProxy(GLWidget *parent) { } -int MonitorProxy::seekPosition() const -{ - return m_seekPosition; -} - -bool MonitorProxy::seeking() const -{ - return m_seekPosition != SEEK_INACTIVE; -} - -int MonitorProxy::position() const +int MonitorProxy::getPosition() const { return m_position; } @@ -85,34 +72,23 @@ QString MonitorProxy::markerComment() const return m_markerComment; } -void MonitorProxy::requestSeekPosition(int pos) -{ - q->activateMonitor(); - m_seekPosition = pos; - emit seekPositionChanged(); - emit seekRequestChanged(); -} - -int MonitorProxy::seekOrCurrentPosition() const -{ - return m_seekPosition == SEEK_INACTIVE ? m_position : m_seekPosition; -} - bool MonitorProxy::setPosition(int pos) { - if (m_seekPosition == pos) { - m_position = pos; - m_seekPosition = SEEK_INACTIVE; - emit seekPositionChanged(); - } else if (m_position == pos) { + if (m_position == pos) { return true; - } else { - m_position = pos; } + m_position = pos; + emit requestSeek(pos); emit positionChanged(); return false; } +void MonitorProxy::positionFromConsumer(int pos) +{ + m_position = pos; + emit positionChanged(); +} + void MonitorProxy::setMarkerComment(const QString &comment) { if (m_markerComment == comment) { @@ -122,18 +98,6 @@ void MonitorProxy::setMarkerComment(const QString &comment) emit markerCommentChanged(); } -void MonitorProxy::setSeekPosition(int pos) -{ - m_seekPosition = pos; - emit seekPositionChanged(); -} - -void MonitorProxy::pauseAndSeek(int pos) -{ - q->switchPlay(false); - requestSeekPosition(pos); -} - int MonitorProxy::zoneIn() const { return m_zoneIn; diff --git a/src/monitor/monitorproxy.h b/src/monitor/monitorproxy.h index e5497ef050..691c7f7ff2 100644 --- a/src/monitor/monitorproxy.h +++ b/src/monitor/monitorproxy.h @@ -37,8 +37,7 @@ class MonitorProxy : public QObject { Q_OBJECT // Q_PROPERTY(int consumerPosition READ consumerPosition NOTIFY consumerPositionChanged) - Q_PROPERTY(int position READ position NOTIFY positionChanged) - Q_PROPERTY(int seekPosition READ seekPosition WRITE setSeekPosition NOTIFY seekPositionChanged) + Q_PROPERTY(int position MEMBER m_position WRITE setPosition NOTIFY positionChanged) Q_PROPERTY(int zoneIn READ zoneIn WRITE setZoneIn NOTIFY zoneChanged) Q_PROPERTY(int zoneOut READ zoneOut WRITE setZoneOut NOTIFY zoneChanged) Q_PROPERTY(int rulerHeight READ rulerHeight NOTIFY rulerHeightChanged) @@ -57,26 +56,19 @@ class MonitorProxy : public QObject public: MonitorProxy(GLWidget *parent); - int seekPosition() const; /** brief: Returns true if we are still in a seek operation * */ - bool seeking() const; - int position() const; int rulerHeight() const; int overlayType() const; void setOverlayType(int ix); QString markerComment() const; - Q_INVOKABLE void requestSeekPosition(int pos); - /** brief: Returns seek position or consumer position when not seeking - * */ - int seekOrCurrentPosition() const; /** brief: update position and end seeking if we reached the requested seek position. * returns true if the position was unchanged, false otherwise * */ - bool setPosition(int pos); + int getPosition() const; + Q_INVOKABLE bool setPosition(int pos); + void positionFromConsumer(int pos); void setMarkerComment(const QString &comment); - void setSeekPosition(int pos); - void pauseAndSeek(int pos); int zoneIn() const; int zoneOut() const; void setZoneIn(int pos); @@ -96,8 +88,7 @@ class MonitorProxy : public QObject signals: void positionChanged(); - void seekPositionChanged(); - void seekRequestChanged(); + void requestSeek(int pos); void zoneChanged(); void saveZone(); void markerCommentChanged(); @@ -118,7 +109,6 @@ class MonitorProxy : public QObject private: GLWidget *q; int m_position; - int m_seekPosition; int m_zoneIn; int m_zoneOut; bool m_hasAV; diff --git a/src/monitor/view/MonitorRuler.qml b/src/monitor/view/MonitorRuler.qml index aa355a1306..2d8aa093fa 100644 --- a/src/monitor/view/MonitorRuler.qml +++ b/src/monitor/view/MonitorRuler.qml @@ -62,7 +62,7 @@ Rectangle { onPressed: { if (mouse.buttons === Qt.LeftButton) { var pos = Math.max(mouseX, 0) - controller.requestSeekPosition(Math.min(pos / root.timeScale, root.duration)); + controller.position = Math.min(pos / root.timeScale, root.duration); } } onPositionChanged: { @@ -70,7 +70,7 @@ Rectangle { var pos = Math.max(mouseX, 0) root.mouseRulerPos = pos if (pressed) { - controller.requestSeekPosition(Math.min(pos / root.timeScale, root.duration)); + controller.position = Math.min(pos / root.timeScale, root.duration); } } } @@ -232,14 +232,14 @@ Rectangle { hoverEnabled: true //onDoubleClicked: timeline.editMarker(clipRoot.binId, model.frame) onClicked: { - controller.requestSeekPosition(model.frame) + controller.position = model.frame } } } } } - Rectangle { + /*Rectangle { id: seekCursor visible: controller.seekPosition > -1 color: activePalette.highlight @@ -248,5 +248,5 @@ Rectangle { opacity: 0.5 x: controller.seekPosition * root.timeScale y: 0 - } + }*/ } diff --git a/src/monitor/view/kdenliveclipmonitor.qml b/src/monitor/view/kdenliveclipmonitor.qml index ae91540f2e..4311293ee2 100644 --- a/src/monitor/view/kdenliveclipmonitor.qml +++ b/src/monitor/view/kdenliveclipmonitor.qml @@ -181,7 +181,7 @@ Item { onPositionChanged: { if (mouse.modifiers & Qt.ShiftModifier) { var pos = Math.max(mouseX, 0) - controller.requestSeekPosition(Math.min(pos / root.timeScale, root.duration)); + controller.setPosition(Math.min(pos / root.timeScale, root.duration)); } } } diff --git a/src/project/projectmanager.cpp b/src/project/projectmanager.cpp index 8c414e250d..bf661c4400 100644 --- a/src/project/projectmanager.cpp +++ b/src/project/projectmanager.cpp @@ -862,7 +862,7 @@ bool ProjectManager::updateTimeline(int pos, int scrollPos) return false; } m_mainTimelineModel = TimelineItemModel::construct(&pCore->getCurrentProfile()->profile(), m_project->getGuideModel(), m_project->commandStack()); - pCore->window()->getMainTimeline()->setModel(m_mainTimelineModel); + pCore->window()->getMainTimeline()->setModel(m_mainTimelineModel, pCore->monitorManager()->projectMonitor()->getControllerProxy()); if (!constructTimelineFromMelt(m_mainTimelineModel, tractor, m_progressDialog)) { //TODO: act on project load failure qDebug()<<"// Project failed to load!!"; @@ -878,6 +878,7 @@ bool ProjectManager::updateTimeline(int pos, int scrollPos) m_mainTimelineModel->loadGroups(groupsData); } connect(pCore->window()->getMainTimeline()->controller(), &TimelineController::durationChanged, this, &ProjectManager::adjustProjectDuration); + pCore->monitorManager()->projectMonitor()->slotActivateMonitor(); pCore->monitorManager()->projectMonitor()->setProducer(m_mainTimelineModel->producer(), pos); pCore->monitorManager()->projectMonitor()->adjustRulerSize(m_mainTimelineModel->duration() - 1, m_project->getGuideModel()); pCore->window()->getMainTimeline()->controller()->setZone(m_project->zone()); diff --git a/src/timeline2/view/qml/Clip.qml b/src/timeline2/view/qml/Clip.qml index df2cedcffc..23015776eb 100644 --- a/src/timeline2/view/qml/Clip.qml +++ b/src/timeline2/view/qml/Clip.qml @@ -441,7 +441,7 @@ Rectangle { cursorShape: Qt.PointingHandCursor hoverEnabled: true onDoubleClicked: timeline.editMarker(clipRoot.clipId, model.frame) - onClicked: timeline.position = (clipRoot.x + markerBase.x) / timeline.scaleFactor + onClicked: proxy.position = (clipRoot.x + markerBase.x) / timeline.scaleFactor } } Text { diff --git a/src/timeline2/view/qml/Composition.qml b/src/timeline2/view/qml/Composition.qml index dff8726d53..0e495a3feb 100644 --- a/src/timeline2/view/qml/Composition.qml +++ b/src/timeline2/view/qml/Composition.qml @@ -176,7 +176,7 @@ Item { var yPos = (compositionRoot.height - mouse.y) / compositionRoot.height keyframeModel.addKeyframe(xPos + compositionRoot.inPoint, yPos) } else { - timeline.position = compositionRoot.x / timeline.scaleFactor + proxy.position = compositionRoot.x / timeline.scaleFactor } } else { timeline.editItemDuration(clipId) diff --git a/src/timeline2/view/qml/KeyframeView.qml b/src/timeline2/view/qml/KeyframeView.qml index dbe26ba455..716efe3323 100644 --- a/src/timeline2/view/qml/KeyframeView.qml +++ b/src/timeline2/view/qml/KeyframeView.qml @@ -185,9 +185,8 @@ Rectangle var newPos = frame == inPoint ? inPoint : Math.round((keyframe.x + parent.x + root.baseUnit / 2) / timeScale) + inPoint if (newPos == frame && keyframe.value == keyframe.height - parent.y - root.baseUnit / 2) { var pos = masterObject.modelStart + frame - inPoint - if (timeline.position != pos) { - timeline.seekPosition = pos - timeline.position = timeline.seekPosition + if (proxy.position != pos) { + proxy.position = pos } return } diff --git a/src/timeline2/view/qml/Timeline.js b/src/timeline2/view/qml/Timeline.js index 4b0b87c2af..a1ce45c258 100644 --- a/src/timeline2/view/qml/Timeline.js +++ b/src/timeline2/view/qml/Timeline.js @@ -18,7 +18,7 @@ function scrollIfNeeded() { if (!scrollView) return; - var x = timeline.position * timeline.scaleFactor; + var x = root.consumerPosition * timeline.scaleFactor; if (x > scrollView.flickableItem.contentX + scrollView.width - 50) scrollView.flickableItem.contentX = x - scrollView.width + 50; else if (x < 50) diff --git a/src/timeline2/view/qml/timeline.qml b/src/timeline2/view/qml/timeline.qml index 62d9fee9b3..f0f176dc07 100644 --- a/src/timeline2/view/qml/timeline.qml +++ b/src/timeline2/view/qml/timeline.qml @@ -56,7 +56,7 @@ Rectangle { playhead.fillColor = activePalette.windowText ruler.repaintRuler() } - + function moveSelectedTrack(offset) { var cTrack = Logic.getTrackIndexFromId(timeline.activeTrack) var newTrack = cTrack + offset @@ -234,6 +234,7 @@ Rectangle { property int droppedPosition: -1 property int droppedTrack: -1 property int clipBeingMovedId: -1 + property int consumerPosition: proxy.position property int spacerGroup: -1 property int spacerFrame: -1 property int spacerClickFrame: -1 @@ -253,7 +254,7 @@ Rectangle { scrollView.flickableItem.contentX = Math.max(0, root.zoomOnMouse * timeline.scaleFactor - tracksArea.mouseX) root.zoomOnMouse = -1 } else { - scrollView.flickableItem.contentX = Math.max(0, (timeline.seekPosition > -1 ? timeline.seekPosition : timeline.position) * timeline.scaleFactor - (scrollView.width / 2)) + scrollView.flickableItem.contentX = Math.max(0, root.consumerPosition * timeline.scaleFactor - (scrollView.width / 2)) } //root.snapping = timeline.snap ? 10 / Math.sqrt(root.timeScale) : -1 ruler.adjustStepSize() @@ -263,6 +264,11 @@ Rectangle { } } + onConsumerPositionChanged: { + console.log('CONSUMER POS CHANGED') + if (autoScrolling) Logic.scrollIfNeeded() + } + onViewActiveTrackChanged: { var tk = Logic.getTrackById(timeline.activeTrack) if (tk.y < scrollView.flickableItem.contentY) { @@ -408,7 +414,7 @@ Rectangle { // we want insert/overwrite mode, make a fake insert at end of timeline, then move to position clipBeingDroppedId = insertAndMaybeGroup(timeline.activeTrack, timeline.fullDuration, clipBeingDroppedData) if (clipBeingDroppedId > -1) { - fakeFrame = controller.suggestClipMove(clipBeingDroppedId, timeline.activeTrack, frame, timeline.position, Math.floor(root.snapping)) + fakeFrame = controller.suggestClipMove(clipBeingDroppedId, timeline.activeTrack, frame, root.consumerPosition, Math.floor(root.snapping)) fakeTrack = timeline.activeTrack } else { drag.accepted = false @@ -433,7 +439,7 @@ Rectangle { timeline.activeTrack = tracksRepeater.itemAt(track).trackInternalId var frame = Math.round((drag.x + scrollView.flickableItem.contentX) / timeline.scaleFactor) if (clipBeingDroppedId >= 0){ - fakeFrame = controller.suggestClipMove(clipBeingDroppedId, timeline.activeTrack, frame, timeline.position, Math.floor(root.snapping)) + fakeFrame = controller.suggestClipMove(clipBeingDroppedId, timeline.activeTrack, frame, root.consumerPosition, Math.floor(root.snapping)) fakeTrack = timeline.activeTrack //controller.requestClipMove(clipBeingDroppedId, timeline.activeTrack, frame, true, false, false) continuousScrolling(drag.x + scrollView.flickableItem.contentX) @@ -444,7 +450,7 @@ Rectangle { } else { // we want insert/overwrite mode, make a fake insert at end of timeline, then move to position clipBeingDroppedId = insertAndMaybeGroup(timeline.activeTrack, timeline.fullDuration, clipBeingDroppedData) - fakeFrame = controller.suggestClipMove(clipBeingDroppedId, timeline.activeTrack, frame, timeline.position, Math.floor(root.snapping)) + fakeFrame = controller.suggestClipMove(clipBeingDroppedId, timeline.activeTrack, frame, root.consumerPosition, Math.floor(root.snapping)) fakeTrack = timeline.activeTrack } continuousScrolling(drag.x + scrollView.flickableItem.contentX) @@ -533,7 +539,7 @@ Rectangle { id: addGuideMenu text: i18n("Add Guide") onTriggered: { - timeline.switchGuide(timeline.position); + timeline.switchGuide(root.consumerPosition); } } GuidesMenu { @@ -541,7 +547,7 @@ Rectangle { menuModel: guidesModel enabled: guidesDelegateModel.count > 0 onGuideSelected: { - timeline.position = assetFrame + proxy.position = assetFrame } } OLD.MenuItem { @@ -549,7 +555,7 @@ Rectangle { text: i18n("Edit Guide") visible: false onTriggered: { - timeline.editGuide(timeline.position); + timeline.editGuide(root.consumerPosition); } } AssetMenu { @@ -566,7 +572,7 @@ Rectangle { } } onAboutToShow: { - if (guidesModel.hasMarker(timeline.position)) { + if (guidesModel.hasMarker(root.consumerPosition)) { // marker at timeline position addGuideMenu.text = i18n("Remove Guide") editGuideMenu.visible = true @@ -588,7 +594,7 @@ Rectangle { id: addGuideMenu2 text: i18n("Add Guide") onTriggered: { - timeline.switchGuide(timeline.position); + timeline.switchGuide(root.consumerPosition); } } GuidesMenu { @@ -596,7 +602,7 @@ Rectangle { menuModel: guidesModel enabled: guidesDelegateModel.count > 0 onGuideSelected: { - timeline.position = assetFrame + proxy.position = assetFrame } } OLD.MenuItem { @@ -604,7 +610,7 @@ Rectangle { text: i18n("Edit Guide") visible: false onTriggered: { - timeline.editGuide(timeline.position); + timeline.editGuide(root.consumerPosition); } } OLD.MenuItem { @@ -615,7 +621,7 @@ Rectangle { } } onAboutToShow: { - if (guidesModel.hasMarker(timeline.position)) { + if (guidesModel.hasMarker(root.consumerPosition)) { // marker at timeline position addGuideMenu2.text = i18n("Remove Guide") editGuideMenu2.visible = true @@ -881,11 +887,7 @@ Rectangle { } } else { var delta = wheel.modifiers & Qt.ShiftModifier ? timeline.fps() : 1 - if (timeline.seekPosition > -1) { - timeline.position = Math.min(timeline.seekPosition - (wheel.angleDelta.y > 0 ? delta : -delta), timeline.fullDuration - 1) - } else { - timeline.position = Math.min(timeline.position - (wheel.angleDelta.y > 0 ? delta : -delta), timeline.fullDuration - 1) - } + proxy.position = Math.min(root.consumerPosition - (wheel.angleDelta.y > 0 ? delta : -delta), timeline.fullDuration - 1) } } onPressed: { @@ -933,7 +935,7 @@ Rectangle { if (mouse.y > ruler.height) { controller.requestClearSelection(); } - timeline.position = Math.min((scrollView.flickableItem.contentX + mouse.x) / timeline.scaleFactor, timeline.fullDuration - 1) + proxy.position = Math.min((scrollView.flickableItem.contentX + mouse.x) / timeline.scaleFactor, timeline.fullDuration - 1) } } else if (mouse.button & Qt.RightButton) { menu.clickedX = mouse.x @@ -964,7 +966,7 @@ Rectangle { if (!pressed && !rubberSelect.visible && root.activeTool === 1) { cutLine.x = Math.floor((scrollView.flickableItem.contentX + mouse.x) / timeline.scaleFactor) * timeline.scaleFactor - scrollView.flickableItem.contentX if (mouse.modifiers & Qt.ShiftModifier) { - timeline.position = Math.floor((scrollView.flickableItem.contentX + mouse.x) / timeline.scaleFactor) + proxy.position = Math.floor((scrollView.flickableItem.contentX + mouse.x) / timeline.scaleFactor) } } var mousePos = Math.max(0, Math.round((mouse.x + scrollView.flickableItem.contentX) / timeline.scaleFactor)) @@ -993,12 +995,12 @@ Rectangle { } } else if (mouse.buttons === Qt.LeftButton) { if (root.activeTool === 0 || mouse.y < ruler.height) { - timeline.position = Math.max(0, Math.min((scrollView.flickableItem.contentX + mouse.x) / timeline.scaleFactor, timeline.fullDuration - 1)) + proxy.position = Math.max(0, Math.min((scrollView.flickableItem.contentX + mouse.x) / timeline.scaleFactor, timeline.fullDuration - 1)) } else if (root.activeTool === 2 && spacerGroup > -1) { // Move group var track = controller.getItemTrackId(spacerGroup) var frame = Math.round((mouse.x + scrollView.flickableItem.contentX) / timeline.scaleFactor) + spacerFrame - spacerClickFrame - frame = controller.suggestItemMove(spacerGroup, track, frame, timeline.position, Math.floor(root.snapping)) + frame = controller.suggestItemMove(spacerGroup, track, frame, root.consumerPosition, Math.floor(root.snapping)) continuousScrolling(mouse.x + scrollView.flickableItem.contentX) } scim = true @@ -1025,7 +1027,7 @@ Rectangle { } else if (mouse.modifiers & Qt.ShiftModifier) { if (root.activeTool == 1) { // Shift click, process seek - timeline.position = Math.min((scrollView.flickableItem.contentX + mouse.x) / timeline.scaleFactor, timeline.fullDuration - 1) + proxy.position = Math.min((scrollView.flickableItem.contentX + mouse.x) / timeline.scaleFactor, timeline.fullDuration - 1) } else if (dragProxy.draggedItem > -1){ // Select item if (timeline.selection.indexOf(dragProxy.draggedItem) == -1) { @@ -1062,23 +1064,22 @@ Rectangle { id: ruler width: rulercontainer.contentWidth height: parent.height - Rectangle { + /*Rectangle { id: seekCursor - visible: timeline.seekPosition > -1 + visible: proxy.seekPosition > -1 color: activePalette.highlight width: 4 height: ruler.height opacity: 0.5 - x: timeline.seekPosition * timeline.scaleFactor - } + x: proxy.seekPosition * timeline.scaleFactor + }*/ TimelinePlayhead { id: playhead - visible: timeline.position > -1 height: baseUnit width: baseUnit * 1.5 fillColor: activePalette.windowText anchors.bottom: parent.bottom - x: timeline.position * timeline.scaleFactor - (width / 2) + x: root.consumerPosition * timeline.scaleFactor - (width / 2) } MouseArea { anchors.fill: parent @@ -1216,7 +1217,7 @@ Rectangle { } } if (dragProxy.isComposition) { - dragFrame = controller.suggestCompositionMove(dragProxy.draggedItem, tId, posx, timeline.position, Math.floor(root.snapping)) + dragFrame = controller.suggestCompositionMove(dragProxy.draggedItem, tId, posx, root.consumerPosition, Math.floor(root.snapping)) timeline.activeTrack = timeline.getItemMovingTrack(dragProxy.draggedItem) } else { if (!controller.normalEdit() && dragProxy.masterObject.parent != dragContainer) { @@ -1227,7 +1228,7 @@ Rectangle { dragProxy.masterObject.y = pos.y //console.log('bringing item to front') } - dragFrame = controller.suggestClipMove(dragProxy.draggedItem, tId, posx, timeline.position, Math.floor(root.snapping), moveMirrorTracks) + dragFrame = controller.suggestClipMove(dragProxy.draggedItem, tId, posx, root.consumerPosition, Math.floor(root.snapping), moveMirrorTracks) timeline.activeTrack = timeline.getItemMovingTrack(dragProxy.draggedItem) } var delta = dragFrame - dragProxy.sourceFrame @@ -1305,12 +1306,12 @@ Rectangle { } Rectangle { id: cursor - visible: timeline.position > -1 + visible: root.consumerPosition > -1 color: root.textColor width: Math.max(1, 1 * timeline.scaleFactor) opacity: (width > 2) ? 0.5 : 1 height: parent.height - x: timeline.position * timeline.scaleFactor + x: root.consumerPosition * timeline.scaleFactor } } } @@ -1338,7 +1339,7 @@ Rectangle { opacity: (width > 2) ? 0.5 : 1 height: root.height - scrollView.__horizontalScrollBar.height - ruler.height x: 0 - //x: timeline.position * timeline.scaleFactor - scrollView.flickableItem.contentX + //x: root.consumerPosition * timeline.scaleFactor - scrollView.flickableItem.contentX y: ruler.height } } @@ -1480,7 +1481,7 @@ Rectangle { timeline.editGuide(model.frame) drag.target = undefined } - onClicked: timeline.position = guideBase.x / timeline.scaleFactor + onClicked: proxy.position = guideBase.x / timeline.scaleFactor } } Text { @@ -1498,7 +1499,6 @@ Rectangle { Connections { target: timeline - onPositionChanged: if (autoScrolling) Logic.scrollIfNeeded() onFrameFormatChanged: ruler.adjustFormat() onSelectionChanged: { if (dragProxy.draggedItem > -1 && !timeline.exists(dragProxy.draggedItem)) { diff --git a/src/timeline2/view/timelinecontroller.cpp b/src/timeline2/view/timelinecontroller.cpp index c69ac199b7..64635dcac9 100644 --- a/src/timeline2/view/timelinecontroller.cpp +++ b/src/timeline2/view/timelinecontroller.cpp @@ -63,8 +63,6 @@ TimelineController::TimelineController(QObject *parent) : QObject(parent) , m_root(nullptr) , m_usePreview(false) - , m_position(0) - , m_seekPosition(-1) , m_activeTrack(0) , m_audioRef(-1) , m_zone(-1, -1) @@ -248,8 +246,8 @@ int TimelineController::selectedTrack() const void TimelineController::selectCurrentItem(ObjectType type, bool select, bool addToCurrent) { QList toSelect; - int currentClip = type == ObjectType::TimelineClip ? m_model->getClipByPosition(m_activeTrack, timelinePosition()) - : m_model->getCompositionByPosition(m_activeTrack, timelinePosition()); + int currentClip = type == ObjectType::TimelineClip ? m_model->getClipByPosition(m_activeTrack, pCore->getTimelinePosition()) + : m_model->getCompositionByPosition(m_activeTrack, pCore->getTimelinePosition()); if (currentClip == -1) { pCore->displayMessage(i18n("No item under timeline cursor in active track"), InformationMessage, 500); return; @@ -316,7 +314,7 @@ int TimelineController::insertClip(int tid, int position, const QString &data_st tid = m_activeTrack; } if (position == -1) { - position = timelinePosition(); + position = pCore->getTimelinePosition(); } if (!m_model->requestClipInsertion(data_str, tid, position, id, logUndo, refreshView, useTargets)) { id = -1; @@ -331,7 +329,7 @@ QList TimelineController::insertClips(int tid, int position, const QStringL tid = m_activeTrack; } if (position == -1) { - position = timelinePosition(); + position = pCore->getTimelinePosition(); } TimelineFunctions::requestMultipleClipsInsertion(m_model, binIds, tid, position, clipIds, logUndo, refreshView); // we don't need to check the return value of the above function, in case of failure it will return an empty list of ids. @@ -456,7 +454,7 @@ int TimelineController::getMainSelectedItem(bool restrictToCurrentPos, bool allo } } if (m_model->isClip(itemId)) { - int position = timelinePosition(); + int position = pCore->getTimelinePosition(); int start = m_model->getClipPosition(itemId); int end = start + m_model->getClipPlaytime(itemId); if (position >= start && position <= end) { @@ -494,7 +492,7 @@ bool TimelineController::pasteItem(int position, int tid) tid = m_activeTrack; } if (position == -1) { - position = timelinePosition(); + position = pCore->getTimelinePosition(); } return TimelineFunctions::pasteClips(m_model, txt, tid, position); } @@ -620,16 +618,16 @@ void TimelineController::showConfig(int page, int tab) void TimelineController::gotoNextSnap() { - int nextSnap = m_model->getNextSnapPos(timelinePosition()); - if (nextSnap > timelinePosition()) { + int nextSnap = m_model->getNextSnapPos(pCore->getTimelinePosition()); + if (nextSnap > pCore->getTimelinePosition()) { setPosition(nextSnap); } } void TimelineController::gotoPreviousSnap() { - if (timelinePosition() > 0) { - setPosition(m_model->getPreviousSnapPos(timelinePosition())); + if (pCore->getTimelinePosition() > 0) { + setPosition(m_model->getPreviousSnapPos(pCore->getTimelinePosition())); } } @@ -673,7 +671,7 @@ void TimelineController::setInPoint() return; } - int cursorPos = timelinePosition(); + int cursorPos = pCore->getTimelinePosition(); const auto selection = m_model->getCurrentSelection(); bool selectionFound = false; if (!selection.empty()) { @@ -708,11 +706,6 @@ void TimelineController::setInPoint() } } -int TimelineController::timelinePosition() const -{ - return m_seekPosition >= 0 ? m_seekPosition : m_position; -} - void TimelineController::setOutPoint() { if (dragOperationRunning()) { @@ -720,7 +713,7 @@ void TimelineController::setOutPoint() qDebug() << "Cannot operate while dragging"; return; } - int cursorPos = timelinePosition(); + int cursorPos = pCore->getTimelinePosition(); const auto selection = m_model->getCurrentSelection(); bool selectionFound = false; if (!selection.empty()) { @@ -759,7 +752,7 @@ void TimelineController::editMarker(int cid, int position) double speed = m_model->getClipSpeed(cid); if (position == -1) { // Calculate marker position relative to timeline cursor - position = timelinePosition() - m_model->getClipPosition(cid) + m_model->getClipIn(cid); + position = pCore->getTimelinePosition() - m_model->getClipPosition(cid) + m_model->getClipIn(cid); position = position * speed; } if (position < (m_model->getClipIn(cid) * speed) || position > (m_model->getClipIn(cid) * speed + m_model->getClipPlaytime(cid))) { @@ -781,7 +774,7 @@ void TimelineController::addMarker(int cid, int position) double speed = m_model->getClipSpeed(cid); if (position == -1) { // Calculate marker position relative to timeline cursor - position = timelinePosition() - m_model->getClipPosition(cid) + m_model->getClipIn(cid); + position = pCore->getTimelinePosition() - m_model->getClipPosition(cid) + m_model->getClipIn(cid); position = position * speed; } if (position < (m_model->getClipIn(cid) * speed) || position > (m_model->getClipIn(cid) * speed + m_model->getClipPlaytime(cid))) { @@ -799,7 +792,7 @@ void TimelineController::addQuickMarker(int cid, int position) double speed = m_model->getClipSpeed(cid); if (position == -1) { // Calculate marker position relative to timeline cursor - position = timelinePosition() - m_model->getClipPosition(cid) + m_model->getClipIn(cid); + position = pCore->getTimelinePosition() - m_model->getClipPosition(cid) + m_model->getClipIn(cid); position = position * speed; } if (position < (m_model->getClipIn(cid) * speed) || position > (m_model->getClipIn(cid) * speed + m_model->getClipPlaytime(cid))) { @@ -818,7 +811,7 @@ void TimelineController::deleteMarker(int cid, int position) double speed = m_model->getClipSpeed(cid); if (position == -1) { // Calculate marker position relative to timeline cursor - position = timelinePosition() - m_model->getClipPosition(cid) + m_model->getClipIn(cid); + position = pCore->getTimelinePosition() - m_model->getClipPosition(cid) + m_model->getClipIn(cid); position = position * speed; } if (position < (m_model->getClipIn(cid) * speed) || position > (m_model->getClipIn(cid) * speed + m_model->getClipPlaytime(cid))) { @@ -840,7 +833,7 @@ void TimelineController::deleteAllMarkers(int cid) void TimelineController::editGuide(int frame) { if (frame == -1) { - frame = timelinePosition(); + frame = pCore->getTimelinePosition(); } auto guideModel = pCore->projectManager()->current()->getGuideModel(); GenTime pos(frame, pCore->getCurrentFps()); @@ -859,7 +852,7 @@ void TimelineController::switchGuide(int frame, bool deleteOnly) { bool markerFound = false; if (frame == -1) { - frame = timelinePosition(); + frame = pCore->getTimelinePosition(); } CommentedTime marker = pCore->projectManager()->current()->getGuideModel()->getMarker(GenTime(frame, pCore->getCurrentFps()), &markerFound); if (!markerFound) { @@ -942,7 +935,7 @@ void TimelineController::adjustAllTrackHeight(int trackId, int height) void TimelineController::setPosition(int position) { - setSeekPosition(position); + // Process seek request emit seeked(position); } @@ -983,22 +976,6 @@ void TimelineController::setActiveTrack(int track) emit activeTrackChanged(); } -void TimelineController::setSeekPosition(int position) -{ - m_seekPosition = position; - emit seekPositionChanged(); -} - -void TimelineController::onSeeked(int position) -{ - m_position = position; - emit positionChanged(); - if (m_seekPosition > -1 && position == m_seekPosition) { - m_seekPosition = -1; - emit seekPositionChanged(); - } -} - void TimelineController::setZone(const QPoint &zone) { if (m_zone.x() > 0) { @@ -1060,7 +1037,7 @@ void TimelineController::selectItems(const QVariantList &tracks, int startFrame, void TimelineController::requestClipCut(int clipId, int position) { if (position == -1) { - position = timelinePosition(); + position = pCore->getTimelinePosition(); } TimelineFunctions::requestClipCut(m_model, clipId, position); } @@ -1068,7 +1045,7 @@ void TimelineController::requestClipCut(int clipId, int position) void TimelineController::cutClipUnderCursor(int position, int track) { if (position == -1) { - position = timelinePosition(); + position = pCore->getTimelinePosition(); } QMutexLocker lk(&m_metaMutex); bool foundClip = false; @@ -1163,10 +1140,11 @@ int TimelineController::getMouseTrack() void TimelineController::refreshItem(int id) { int in = m_model->getItemPosition(id); - if (in > m_position || (m_model->isClip(id) && m_model->m_allClips[id]->isAudioOnly())) { + int position = pCore->getTimelinePosition(); + if (in > position || (m_model->isClip(id) && m_model->m_allClips[id]->isAudioOnly())) { return; } - if (m_position <= in + m_model->getItemPlaytime(id)) { + if (position <= in + m_model->getItemPlaytime(id)) { pCore->requestMonitorRefresh(); } } @@ -1190,7 +1168,7 @@ void TimelineController::addEffectToCurrentClip(const QStringList &effectData) QList activeClips; for (int track = m_model->getTracksCount() - 1; track >= 0; track--) { int trackIx = m_model->getTrackIndexFromPosition(track); - int cid = m_model->getClipByPosition(trackIx, timelinePosition()); + int cid = m_model->getClipByPosition(trackIx, pCore->getTimelinePosition()); if (cid > -1) { activeClips << cid; } @@ -1497,7 +1475,7 @@ QMap TimelineController::documentProperties() props.insert(QStringLiteral("audioTarget"), QString::number(audioTarget)); props.insert(QStringLiteral("videoTarget"), QString::number(videoTarget)); props.insert(QStringLiteral("activeTrack"), QString::number(activeTrack)); - props.insert(QStringLiteral("position"), QString::number(timelinePosition())); + props.insert(QStringLiteral("position"), QString::number(pCore->getTimelinePosition())); QVariant returnedValue; QMetaObject::invokeMethod(m_root, "getScrollPos", Q_RETURN_ARG(QVariant, returnedValue)); int scrollPos = returnedValue.toInt(); @@ -1516,7 +1494,7 @@ QMap TimelineController::documentProperties() void TimelineController::insertSpace(int trackId, int frame) { if (frame == -1) { - frame = timelinePosition(); + frame = pCore->getTimelinePosition(); } if (trackId == -1) { trackId = m_activeTrack; @@ -1540,7 +1518,7 @@ void TimelineController::insertSpace(int trackId, int frame) void TimelineController::removeSpace(int trackId, int frame, bool affectAllTracks) { if (frame == -1) { - frame = timelinePosition(); + frame = pCore->getTimelinePosition(); } if (trackId == -1) { trackId = m_activeTrack; @@ -1679,8 +1657,8 @@ void TimelineController::extractZone(QPoint zone, bool liftOnly) } if (m_zone == QPoint()) { // Use current timeline position and clip zone length - zone.setY(timelinePosition() + zone.y() - zone.x()); - zone.setX(timelinePosition()); + zone.setY(pCore->getTimelinePosition() + zone.y() - zone.x()); + zone.setX(pCore->getTimelinePosition()); } TimelineFunctions::extractZone(m_model, tracks, m_zone == QPoint() ? zone : m_zone, liftOnly); } @@ -1773,7 +1751,7 @@ int TimelineController::insertZone(const QString &binId, QPoint zone, bool overw sourceZone = QPoint(zone.x(), zone.x() + m_zone.y() - m_zone.x()); } else { // Use current timeline pos and clip zone for in/out - insertPoint = timelinePosition(); + insertPoint = pCore->getTimelinePosition(); sourceZone = zone; } QList target_tracks; @@ -2601,7 +2579,7 @@ void TimelineController::switchRecording(int trackId) pCore->displayMessage(i18n("Impossible to capture on a locked track"), ErrorMessage, 500); return; } - m_recordStart.first = timelinePosition(); + m_recordStart.first = pCore->getTimelinePosition(); m_recordTrack = trackId; int maximumSpace = m_model->getTrackById_const(trackId)->getBlankEnd(m_recordStart.first); if (maximumSpace == INT_MAX) { @@ -2708,7 +2686,7 @@ bool TimelineController::refreshIfVisible(int cid) ++it; continue; } - int child = m_model->getClipByPosition(target_track, timelinePosition()); + int child = m_model->getClipByPosition(target_track, pCore->getTimelinePosition()); if (child > 0) { if (m_model->m_allClips[child]->binId().toInt() == cid) { return true; diff --git a/src/timeline2/view/timelinecontroller.h b/src/timeline2/view/timelinecontroller.h index 58a03c6f41..e1133fcde7 100644 --- a/src/timeline2/view/timelinecontroller.h +++ b/src/timeline2/view/timelinecontroller.h @@ -48,12 +48,8 @@ class TimelineController : public QObject Q_PROPERTY(int duration READ duration NOTIFY durationChanged) Q_PROPERTY(int fullDuration READ fullDuration NOTIFY durationChanged) Q_PROPERTY(bool audioThumbFormat READ audioThumbFormat NOTIFY audioThumbFormatChanged) - /* @brief holds the current timeline position - */ - Q_PROPERTY(int position READ position WRITE setPosition NOTIFY positionChanged) Q_PROPERTY(int zoneIn READ zoneIn WRITE setZoneIn NOTIFY zoneChanged) Q_PROPERTY(int zoneOut READ zoneOut WRITE setZoneOut NOTIFY zoneChanged) - Q_PROPERTY(int seekPosition READ seekPosition WRITE setSeekPosition NOTIFY seekPositionChanged) Q_PROPERTY(bool ripple READ ripple NOTIFY rippleChanged) Q_PROPERTY(bool scrub READ scrub NOTIFY scrubChanged) Q_PROPERTY(bool snap READ snap NOTIFY snapChanged) @@ -147,10 +143,8 @@ class TimelineController : public QObject Q_INVOKABLE int fullDuration() const; /* @brief Returns the current cursor position (frame currently displayed by MLT) */ - Q_INVOKABLE int position() const { return m_position; } /* @brief Returns the seek request position (-1 = no seek pending) */ - Q_INVOKABLE int seekPosition() const { return m_seekPosition; } Q_INVOKABLE int audioTarget() const; Q_INVOKABLE int videoTarget() const; Q_INVOKABLE bool hasAudioTarget() const; @@ -452,8 +446,6 @@ class TimelineController : public QObject void updateClip(int clipId, const QVector &roles); void showClipKeyframes(int clipId, bool value); void showCompositionKeyframes(int clipId, bool value); - /** @brief Returns last usable timeline position (seek request or current pos) */ - int timelinePosition() const; /** @brief Adjust all timeline tracks height */ void resetTrackHeight(); /** @brief timeline preview params changed, reset */ @@ -482,12 +474,10 @@ class TimelineController : public QObject public slots: void resetView(); - Q_INVOKABLE void setSeekPosition(int position); Q_INVOKABLE void setAudioTarget(int track); void setIntAudioTarget(QList tracks); Q_INVOKABLE void setVideoTarget(int track); Q_INVOKABLE void setActiveTrack(int track); - void onSeeked(int position); void addEffectToCurrentClip(const QStringList &effectData); /** @brief Dis / enable timeline preview. */ void disablePreview(bool disable); @@ -516,8 +506,6 @@ private slots: KActionCollection *m_actionCollection; std::shared_ptr m_model; bool m_usePreview; - int m_position; - int m_seekPosition; int m_audioTarget; int m_videoTarget; int m_activeTrack; @@ -549,8 +537,6 @@ private slots: void scaleFactorChanged(); void audioThumbFormatChanged(); void durationChanged(); - void positionChanged(); - void seekPositionChanged(); void audioTargetChanged(); void videoTargetChanged(); void hasAudioTargetChanged(); diff --git a/src/timeline2/view/timelinetabs.cpp b/src/timeline2/view/timelinetabs.cpp index 2855218aee..74bb10b9ec 100644 --- a/src/timeline2/view/timelinetabs.cpp +++ b/src/timeline2/view/timelinetabs.cpp @@ -69,11 +69,7 @@ TimelineWidget *TimelineTabs::getCurrentTimeline() const void TimelineTabs::connectTimeline(TimelineWidget *timeline) { - connect(pCore->monitorManager()->projectMonitor(), &Monitor::seekTimeline, timeline->controller(), &TimelineController::setPosition, Qt::DirectConnection); - connect(timeline->controller(), &TimelineController::seeked, pCore->monitorManager()->projectMonitor(), &Monitor::requestSeek, Qt::DirectConnection); - connect(pCore->monitorManager()->projectMonitor(), &Monitor::seekPosition, timeline->controller(), &TimelineController::onSeeked, Qt::DirectConnection); connect(timeline, &TimelineWidget::focusProjectMonitor, pCore->monitorManager(), &MonitorManager::focusProjectMonitor); - connect(this, &TimelineTabs::audioThumbFormatChanged, timeline->controller(), &TimelineController::audioThumbFormatChanged); connect(this, &TimelineTabs::showThumbnailsChanged, timeline->controller(), &TimelineController::showThumbnailsChanged); connect(this, &TimelineTabs::showAudioThumbnailsChanged, timeline->controller(), &TimelineController::showAudioThumbnailsChanged); @@ -86,12 +82,8 @@ void TimelineTabs::connectTimeline(TimelineWidget *timeline) void TimelineTabs::disconnectTimeline(TimelineWidget *timeline) { - disconnect(pCore->monitorManager()->projectMonitor(), &Monitor::seekTimeline, timeline->controller(), &TimelineController::setPosition); - disconnect(timeline->controller(), &TimelineController::seeked, pCore->monitorManager()->projectMonitor(), &Monitor::requestSeek); - disconnect(pCore->monitorManager()->projectMonitor(), &Monitor::seekPosition, timeline->controller(), &TimelineController::onSeeked); disconnect(timeline, &TimelineWidget::focusProjectMonitor, pCore->monitorManager(), &MonitorManager::focusProjectMonitor); disconnect(timeline->controller(), &TimelineController::durationChanged, pCore->projectManager(), &ProjectManager::adjustProjectDuration); - disconnect(this, &TimelineTabs::audioThumbFormatChanged, timeline->controller(), &TimelineController::audioThumbFormatChanged); disconnect(this, &TimelineTabs::showThumbnailsChanged, timeline->controller(), &TimelineController::showThumbnailsChanged); disconnect(this, &TimelineTabs::showAudioThumbnailsChanged, timeline->controller(), &TimelineController::showAudioThumbnailsChanged); diff --git a/src/timeline2/view/timelinewidget.cpp b/src/timeline2/view/timelinewidget.cpp index 8fd9991240..ee631664de 100644 --- a/src/timeline2/view/timelinewidget.cpp +++ b/src/timeline2/view/timelinewidget.cpp @@ -33,6 +33,7 @@ #include "mainwindow.h" #include "profiles/profilemodel.hpp" #include "project/projectmanager.h" +#include "monitor/monitorproxy.h" #include "qml/timelineitems.h" #include "qmltypes/thumbnailprovider.h" #include "timelinecontroller.h" @@ -87,7 +88,6 @@ TimelineWidget::TimelineWidget(QWidget *parent) engine()->addImageProvider(QStringLiteral("thumbnail"), m_thumbnailer); setVisible(false); setFocusPolicy(Qt::StrongFocus); - // connect(&*m_model, SIGNAL(seeked(int)), this, SLOT(onSeeked(int))); } TimelineWidget::~TimelineWidget() @@ -114,7 +114,7 @@ const QStringList TimelineWidget::sortedItems(const QStringList &items, bool isT return sortedItems.values(); } -void TimelineWidget::setModel(const std::shared_ptr &model) +void TimelineWidget::setModel(const std::shared_ptr &model, MonitorProxy *proxy) { m_thumbnailer->resetProject(); m_sortModel = std::make_unique(this); @@ -126,6 +126,7 @@ void TimelineWidget::setModel(const std::shared_ptr &model) rootContext()->setContextProperty("multitrack", m_sortModel.get()); rootContext()->setContextProperty("controller", model.get()); rootContext()->setContextProperty("timeline", m_proxy); + rootContext()->setContextProperty("proxy", proxy); rootContext()->setContextProperty("transitionModel", sortedItems(KdenliveSettings::favorite_transitions(), true)); // m_transitionProxyModel.get()); // rootContext()->setContextProperty("effectModel", m_effectsProxyModel.get()); rootContext()->setContextProperty("effectModel", sortedItems(KdenliveSettings::favorite_effects(), false)); @@ -137,11 +138,11 @@ void TimelineWidget::setModel(const std::shared_ptr &model) connect(rootObject(), SIGNAL(zoomIn(bool)), pCore->window(), SLOT(slotZoomIn(bool))); connect(rootObject(), SIGNAL(zoomOut(bool)), pCore->window(), SLOT(slotZoomOut(bool))); connect(rootObject(), SIGNAL(processingDrag(bool)), pCore->window(), SIGNAL(enableUndo(bool))); + connect(m_proxy, &TimelineController::seeked, proxy, &MonitorProxy::setPosition); m_proxy->setRoot(rootObject()); setVisible(true); loading = false; m_proxy->checkDuration(); - m_proxy->positionChanged(); } void TimelineWidget::mousePressEvent(QMouseEvent *event) diff --git a/src/timeline2/view/timelinewidget.h b/src/timeline2/view/timelinewidget.h index b295ee39e6..1d474b42d0 100644 --- a/src/timeline2/view/timelinewidget.h +++ b/src/timeline2/view/timelinewidget.h @@ -30,6 +30,7 @@ class ThumbnailProvider; class TimelineController; class QSortFilterProxyModel; +class MonitorProxy; class TimelineWidget : public QQuickWidget { @@ -39,7 +40,7 @@ class TimelineWidget : public QQuickWidget TimelineWidget(QWidget *parent = Q_NULLPTR); ~TimelineWidget() override; /* @brief Sets the model shown by this widget */ - void setModel(const std::shared_ptr &model); + void setModel(const std::shared_ptr &model, MonitorProxy *proxy); /* @brief Return the project's tractor */