Connect project monitor to new timeline

parent d209e6ec
......@@ -57,6 +57,8 @@ static ClientWaitSync_fp ClientWaitSync = nullptr;
using namespace Mlt;
#define SEEK_INACTIVE (-1)
GLWidget::GLWidget(int id, QObject *parent)
: QQuickView((QWindow *) parent)
, sendFrameForAnalysis(false)
......@@ -65,6 +67,7 @@ GLWidget::GLWidget(int id, QObject *parent)
, m_glslManager(nullptr)
, m_consumer(nullptr)
, m_producer(nullptr)
, m_requestedSeekPosition(SEEK_INACTIVE)
, m_initSem(0)
, m_analyseSem(1)
, m_isInitialized(false)
......@@ -565,6 +568,60 @@ void GLWidget::wheelEvent(QWheelEvent *event)
event->accept();
}
void GLWidget::seek(int pos)
{
// Testing puspose only
if (m_requestedSeekPosition == SEEK_INACTIVE) {
m_requestedSeekPosition = pos;
if (m_producer->get_speed() != 0) {
m_consumer->purge();
}
m_producer->seek(pos);
if (m_consumer->is_stopped()) {
m_consumer->start();
}
m_consumer->set("refresh", 1);
} else {
m_requestedSeekPosition = pos;
}
}
bool GLWidget::checkFrameNumber(int pos)
{
emit seekPosition(pos);
if (pos == m_requestedSeekPosition) {
m_requestedSeekPosition = SEEK_INACTIVE;
}
if (m_requestedSeekPosition != SEEK_INACTIVE) {
double speed = m_producer->get_speed();
m_producer->set_speed(0);
m_producer->seek(m_requestedSeekPosition);
if (speed == 0) {
m_consumer->set("refresh", 1);
} else {
m_producer->set_speed(speed);
}
} else {
if (m_producer->get_speed() == 0) {
m_consumer->purge();
} /*else if (m_isZoneMode) {
if (pos >= m_producer->get_int("out") - 1) {
if (m_isLoopMode) {
m_consumer->purge();
m_producer->seek((int)(m_loopStart.frames(m_fps)));
m_producer->set_speed(1.0);
m_consumer->set("refresh", 1);
} else {
if (m_producer->get_speed() == 0) {
return false;
}
}
}
}*/
}
return true;
}
void GLWidget::mousePressEvent(QMouseEvent *event)
{
if (rootObject() && rootObject()->objectName() != QLatin1String("root") && !(event->modifiers() & Qt::ControlModifier) && !(event->buttons() & Qt::MiddleButton)) {
......
......@@ -113,6 +113,8 @@ public:
void setAudioThumb(int channels = 0, const QVariantList &audioCache = QList<QVariant>());
int droppedFrames() const;
void resetDrops();
void seek(int pos);
bool checkFrameNumber(int pos);
protected:
void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
......@@ -150,6 +152,7 @@ signals:
void lockMonitor(bool);
void passKeyEvent(QKeyEvent *);
void panView(const QPoint &diff);
void seekPosition(int);
private:
int m_id;
......@@ -162,6 +165,7 @@ private:
Mlt::Filter *m_glslManager;
Mlt::Consumer *m_consumer;
Mlt::Producer *m_producer;
int m_requestedSeekPosition;
QSemaphore m_initSem;
QSemaphore m_analyseSem;
bool m_isInitialized;
......
......@@ -153,6 +153,7 @@ 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);
m_videoWidget = QWidget::createWindowContainer(qobject_cast<QWindow *>(m_glMonitor));
m_videoWidget->setAcceptDrops(true);
QuickEventEater *leventEater = new QuickEventEater(this);
......@@ -1740,7 +1741,7 @@ void Monitor::onFrameDisplayed(const SharedFrame &frame)
m_monitorManager->frameDisplayed(frame);
int position = frame.get_position();
seekCursor(position);
if (!render->checkFrameNumber(position)) {
if (!m_glMonitor->checkFrameNumber(position)) {
m_playAction->setActive(false);
} else if (position >= m_length) {
m_playAction->setActive(false);
......@@ -2213,4 +2214,13 @@ void Monitor::panView(QPoint diff)
}
}
void Monitor::requestSeek(int pos)
{
m_glMonitor->seek(pos);
}
void Monitor::setProducer(Mlt::Producer *producer)
{
m_glMonitor->setProducer(producer);
}
......@@ -152,6 +152,7 @@ public:
void clearDisplay();
/** @brief Seeks timeline without refreshing if monitor is not active **/
void silentSeek(int pos);
void setProducer(Mlt::Producer *producer);
protected:
void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
......@@ -325,9 +326,12 @@ public slots:
void slotGetCurrentImage(bool request);
/** @brief Enable/disable display of monitor's audio levels widget */
void slotSwitchAudioMonitor();
/** @brief Request seeking */
void requestSeek(int pos);
signals:
void renderPosition(int);
void seekPosition(int);
void durationChanged(int);
void refreshClipThumbnail(const QString &);
void zoneUpdated(const QPoint &);
......
......@@ -108,6 +108,9 @@ void ProjectManager::slotLoadOnOpen()
m_loadClipsOnOpen.clear();
TimelineWidget *timelineWidget = new TimelineWidget(pCore->binController(), m_project->commandStack(), pCore->window());
pCore->addTimeline(timelineWidget, m_project->url().fileName());
connect(timelineWidget, &TimelineWidget::seeked, pCore->monitorManager()->projectMonitor(), &Monitor::requestSeek, Qt::DirectConnection);
connect(pCore->monitorManager()->projectMonitor(), &Monitor::seekPosition, timelineWidget, &TimelineWidget::onSeeked, Qt::DirectConnection);
pCore->monitorManager()->projectMonitor()->setProducer(timelineWidget->producer());
}
void ProjectManager::init(const QUrl &projectUrl, const QString &clipList)
......
......@@ -509,7 +509,7 @@ int Render::setSceneList(QString playlist, int position)
QString retain = QStringLiteral("xml_retain %1").arg(m_binController->binPlaylistId());
tractor.set(retain.toUtf8().constData(), m_binController->service(), 0);
//if (!m_binController->hasClip("black")) m_binController->addClipToBin("black", *m_blackClip);
m_qmlView->setProducer(m_mltProducer);
//m_qmlView->setProducer(m_mltProducer);
m_mltConsumer = m_qmlView->consumer();
}
......
......@@ -119,6 +119,7 @@ public:
@param logUndo if set to false, no undo object is stored
*/
bool requestClipMove(int cid, int tid, int position, bool updateView = true, bool logUndo = true);
protected:
/* Same function, but accumulates undo and redo, and doesn't check for group*/
bool requestClipMove(int cid, int tid, int position, bool updateView, Fun &undo, Fun &redo);
......
......@@ -37,6 +37,7 @@ Rectangle {
property color selectedTrackColor: activePalette.highlight //.rgba(0.8, 0.8, 0, 0.3);
property alias trackCount: tracksRepeater.count
property bool stopScrolling: false
property int seekPos: 0
property color shotcutBlue: Qt.rgba(23/255, 92/255, 118/255, 1.0)
//property alias ripple: toolbar.ripple
......@@ -146,14 +147,16 @@ Rectangle {
hoverEnabled: true
onClicked: {
console.log("Position changed: ",timeline.position)
timeline.position = (scrollView.flickableItem.contentX + mouse.x) / timeline.scaleFactor
root.seekPos = (scrollView.flickableItem.contentX + mouse.x) / timeline.scaleFactor
timeline.position = root.seekPos
}
property bool scim: false
onReleased: scim = false
onExited: scim = false
onPositionChanged: {
if (mouse.modifiers === Qt.ShiftModifier || mouse.buttons === Qt.LeftButton) {
timeline.position = (scrollView.flickableItem.contentX + mouse.x) / timeline.scaleFactor
root.seekPos = (scrollView.flickableItem.contentX + mouse.x) / timeline.scaleFactor
timeline.position = root.seekPos
scim = true
}
else
......@@ -168,9 +171,10 @@ Rectangle {
&& (timeline.position * timeline.scaleFactor >= 50)
onTriggered: {
if (parent.mouseX < 50)
timeline.position -= 10
root.seekPos = timeline.position - 10
else
timeline.position += 10
root.seekPos = timeline.position + 10
timeline.position = root.seekPos
}
}
......@@ -184,7 +188,7 @@ Rectangle {
Ruler {
id: ruler
width: tracksContainer.width
width: parent.width
index: index
timeScale: timeline.scaleFactor
}
......@@ -244,6 +248,16 @@ Rectangle {
x: timeline.position * timeline.scaleFactor - scrollView.flickableItem.contentX
y: 0
}
Rectangle {
id: seekCursor
visible: timeline.position != root.seekPos
color: activePalette.highlight
width: 4
height: ruler.height
opacity: 0.5
x: root.seekPos * timeline.scaleFactor - scrollView.flickableItem.contentX
y: 0
}
TimelinePlayhead {
id: playhead
visible: timeline.position > -1
......
......@@ -38,9 +38,20 @@ TimelineWidget::TimelineWidget(BinController *binController, std::weak_ptr<DocUn
rootContext()->setContextProperty("multitrack", &*m_model);
rootContext()->setContextProperty("timeline", this);
setSource(QUrl(QStringLiteral("qrc:/qml/timeline.qml")));
//m_model->tractor()->multitrack()->listen("producer-changed", this, (mlt_listener) TimelineWidget::onTractorChange);
m_model->tractor()->refresh();
Mlt::Producer service(m_model->tractor()->parent().get_producer());
qDebug()<<"TL SERVIE: "<<service.get("mlt_type")<<" / "<<service.get("mlt_service");
qDebug()<<"*** BUILDING TIMELINE LENGTH: "<<service.get("length");
//connect(&*m_model, SIGNAL(seeked(int)), this, SLOT(onSeeked(int)));
}
void TimelineWidget::onTractorChange(mlt_multitrack, TimelineWidget *self)
{
qDebug()<<" * * ** * *DURATUION CHANGED";
self->updateDuration();
}
void TimelineWidget::setSelection(QList<int> newSelection, int trackIndex, bool isMultitrack)
{
if (newSelection != selection()
......@@ -75,6 +86,10 @@ int TimelineWidget::duration() const
return m_model->duration();
}
void TimelineWidget::updateDuration()
{
rootObject()->setProperty("duration", m_model->duration());
}
QList<int> TimelineWidget::selection() const
{
......@@ -174,18 +189,7 @@ QString TimelineWidget::timecode(int frames)
void TimelineWidget::setPosition(int position)
{
if (!m_model->tractor()) return;
// Testing puspose only
m_position = position;
emit positionChanged();
return;
if (position <= m_model->tractor()->get_length()) {
//emit seeked(position);
} else {
m_position = m_model->tractor()->get_length();
emit positionChanged();
}
emit seeked(position);
}
void TimelineWidget::onSeeked(int position)
......@@ -194,3 +198,11 @@ void TimelineWidget::onSeeked(int position)
emit positionChanged();
}
Mlt::Producer *TimelineWidget::producer()
{
Mlt::Producer *prod = new Mlt::Producer(m_model->tractor()->get_producer());
qDebug()<<"*** TIMELINE LENGTH: "<<prod->get_playtime()<<" / "<<m_model->tractor()->get_length();
return prod;
}
......@@ -60,11 +60,16 @@ public:
Q_INVOKABLE bool scrub();
Q_INVOKABLE QString timecode(int frames);
Q_INVOKABLE void insertClip(int track, int position, QString xml);
static void onTractorChange(mlt_multitrack, TimelineWidget *self);
Mlt::Producer *producer();
public slots:
void selectMultitrack();
void onSeeked(int position);
private slots:
void updateDuration();
private:
std::shared_ptr<TimelineItemModel> m_model;
BinController *m_binController;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment