From 23b97051124400cc52ec2b3dfc579d1033d73907 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Mardelle Date: Sat, 16 Oct 2010 00:55:08 +0000 Subject: [PATCH] Full screen video playback: http://www.kdenlive.org/mantis/view.php?id=1683 svn path=/trunk/kdenlive/; revision=5009 --- src/CMakeLists.txt | 1 - src/mainwindow.cpp | 7 +- src/monitor.cpp | 206 ++++++++++++++++++++++++++++++++++++--------- src/monitor.h | 39 ++++++++- 4 files changed, 204 insertions(+), 49 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 27e5e965..1f492cdc 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -45,7 +45,6 @@ ${optional_libs} kde4_add_ui_files(kdenlive_UI widgets/timeline_ui.ui - widgets/monitor_ui.ui widgets/recmonitor_ui.ui widgets/colorclip_ui.ui widgets/slideshowclip_ui.ui diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index c4ce5d22..6da2caca 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -533,6 +533,9 @@ MainWindow::MainWindow(const QString &MltPath, const KUrl & Url, const QString & activateShuttleDevice(); #endif /* NO_JOGSHUTTLE */ m_projectListDock->raise(); + + actionCollection()->addAssociatedWidget(m_clipMonitor->container()); + actionCollection()->addAssociatedWidget(m_projectMonitor->container()); } MainWindow::~MainWindow() @@ -3857,8 +3860,8 @@ void MainWindow::slotSwitchMonitors() void MainWindow::slotSwitchFullscreen() { - /*if (m_projectMonitor->isActive()) m_projectMonitor->slotSwitchFullScreen(); - else m_clipMonitor->slotSwitchFullScreen();*/ + if (m_projectMonitor->isActive()) m_projectMonitor->slotSwitchFullScreen(); + else m_clipMonitor->slotSwitchFullScreen(); } void MainWindow::slotInsertZoneToTree() diff --git a/src/monitor.cpp b/src/monitor.cpp index 60a72c47..98a2c371 100644 --- a/src/monitor.cpp +++ b/src/monitor.cpp @@ -64,13 +64,20 @@ Monitor::Monitor(QString name, MonitorManager *manager, QString profile, QWidget m_loopClipTransition(true) { - m_ui.setupUi(this); QVBoxLayout *layout = new QVBoxLayout; layout->setContentsMargins(0, 0, 0, 0); + + // Video widget holder + m_videoBox = new VideoContainer(this); + m_videoBox->setContentsMargins(0, 0, 0, 0); + m_videoBox->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); + layout->addWidget(m_videoBox, 10); + layout->addStretch(); + + // Monitor ruler layout->addWidget(m_ruler); - m_ui.ruler_frame->setLayout(layout); - setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - setMinimumHeight(200); + + // Tool bar buttons QToolBar *toolbar = new QToolBar(name, this); QVBoxLayout *layout2 = new QVBoxLayout; layout2->setContentsMargins(0, 0, 0, 0); @@ -91,7 +98,7 @@ Monitor::Monitor(QString name, MonitorManager *manager, QString profile, QWidget QToolButton *playButton = new QToolButton(toolbar); m_playMenu = new QMenu(i18n("Play..."), this); m_playAction = m_playMenu->addAction(m_playIcon, i18n("Play")); - m_playAction->setCheckable(true); + //m_playAction->setCheckable(true); connect(m_playAction, SIGNAL(triggered()), this, SLOT(slotPlay())); playButton->setMenu(m_playMenu); @@ -127,31 +134,30 @@ Monitor::Monitor(QString name, MonitorManager *manager, QString profile, QWidget m_timePos = new TimecodeDisplay(m_monitorManager->timecode(), this); toolbar->addWidget(m_timePos); connect(m_timePos, SIGNAL(editingFinished()), this, SLOT(slotSeek())); + layout->addWidget(toolbar); - layout2->addWidget(toolbar); - m_ui.button_frame->setLayout(layout2); - const int toolHeight = toolbar->height(); - m_ui.button_frame->setMinimumHeight(toolHeight); - - //m_ruler->setPixelPerMark(3); + setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + setLayout(layout); + setMinimumHeight(200); if (profile.isEmpty()) profile = KdenliveSettings::current_profile(); - QVBoxLayout *rendererBox = new QVBoxLayout(m_ui.video_frame); - rendererBox->setContentsMargins(0, 0, 0, 0); bool monitorCreated = false; #ifdef Q_WS_MAC - createOpenGlWidget(rendererBox, profile); + createOpenGlWidget(videoBox, profile); monitorCreated = true; //m_glWidget->setFixedSize(width, height); #elif defined (USE_OPEN_GL) if (KdenliveSettings::openglmonitors()) { - monitorCreated = createOpenGlWidget(rendererBox, profile); + monitorCreated = createOpenGlWidget(m_videoBox, profile); } #endif + QVBoxLayout *lay = new QVBoxLayout; + lay->setContentsMargins(0, 0, 0, 0); if (!monitorCreated) { - m_monitorRefresh = new MonitorRefresh(m_ui.video_frame); - rendererBox->addWidget(m_monitorRefresh); + m_monitorRefresh = new MonitorRefresh; + lay->addWidget(m_monitorRefresh); + m_videoBox->setLayout(lay); render = new Render(m_name, (int) m_monitorRefresh->winId(), profile, this); m_monitorRefresh->setRenderer(render); } @@ -174,10 +180,10 @@ Monitor::Monitor(QString name, MonitorManager *manager, QString profile, QWidget if (name == "project") { m_effectScene = new MonitorScene(render); - m_effectView = new QGraphicsView(m_effectScene, m_ui.video_frame); + m_effectView = new QGraphicsView(m_effectScene, m_videoBox); + lay->addWidget(m_effectView); m_effectView->setRenderHints(QFlags()); m_effectView->scale(((double) render->renderWidth()) / render->frameRenderWidth(), 1.0); - rendererBox->addWidget(m_effectView); m_effectView->setMouseTracking(true); m_effectScene->setUp(); m_effectView->hide(); @@ -197,21 +203,25 @@ Monitor::~Monitor() delete render; } +QWidget *Monitor::container() +{ + return m_videoBox; +} + QString Monitor::name() const { return m_name; } #if defined(Q_WS_MAC) || defined(USE_OPEN_GL) -bool Monitor::createOpenGlWidget(QVBoxLayout *rendererBox, const QString profile) +bool Monitor::createOpenGlWidget(QWidget *parent, const QString profile) { render = new Render(m_name, 0, profile, this); - m_glWidget = new VideoGLWidget(m_ui.video_frame); + m_glWidget = new VideoGLWidget(parent); if (m_glWidget == NULL) { // Creation failed, we are in trouble... return false; } - rendererBox->addWidget(m_glWidget); m_glWidget->setImageAspectRatio(render->dar()); m_glWidget->setBackgroundColor(KdenliveSettings::window_background()); connect(render, SIGNAL(showImageSignal(QImage)), m_glWidget, SLOT(showImage(QImage))); @@ -286,7 +296,7 @@ void Monitor::slotSetSizeOneToOne() height = height * 0.8; } kDebug() << "// MONITOR; set SIZE: " << width << ", " << height; - m_ui.video_frame->setFixedSize(width, height); + m_videoBox->setFixedSize(width, height); updateGeometry(); adjustSize(); //m_ui.video_frame->setMinimumSize(0, 0); @@ -306,7 +316,7 @@ void Monitor::slotSetSizeOneToTwo() height = height * 0.8; } kDebug() << "// MONITOR; set SIZE: " << width << ", " << height; - m_ui.video_frame->setFixedSize(width, height); + m_videoBox->setFixedSize(width, height); updateGeometry(); adjustSize(); //m_ui.video_frame->setMinimumSize(0, 0); @@ -315,7 +325,7 @@ void Monitor::slotSetSizeOneToTwo() void Monitor::resetSize() { - m_ui.video_frame->setMinimumSize(0, 0); + m_videoBox->setMinimumSize(0, 0); } DocClipBase *Monitor::activeClip() @@ -412,18 +422,23 @@ void Monitor::slotSetZoneEnd() void Monitor::mousePressEvent(QMouseEvent * event) { if (event->button() != Qt::RightButton) { - if (m_ui.video_frame->underMouse()) { + if (m_videoBox->underMouse()) { m_dragStarted = true; m_DragStartPosition = event->pos(); } } else m_contextMenu->popup(event->globalPos()); } +void Monitor::slotSwitchFullScreen() +{ + m_videoBox->switchFullScreen(); +} + // virtual void Monitor::mouseReleaseEvent(QMouseEvent * event) { if (m_dragStarted) { - if (m_ui.video_frame->underMouse() && (!m_effectView || !m_effectView->isVisible())) { + if (m_videoBox->underMouse() && (!m_effectView || !m_effectView->isVisible())) { if (isActive()) slotPlay(); else activateMonitor(); } else QWidget::mouseReleaseEvent(event); @@ -492,12 +507,18 @@ QStringList Monitor::mimeTypes() const // virtual void Monitor::wheelEvent(QWheelEvent * event) { - if (event->modifiers() == Qt::ControlModifier) { + slotMouseSeek(event->delta(), event->modifiers() == Qt::ControlModifier); + event->accept(); +} + +void Monitor::slotMouseSeek(int eventDelta, bool fast) +{ + if (fast) { int delta = m_monitorManager->timecode().fps(); - if (event->delta() > 0) delta = 0 - delta; + if (eventDelta > 0) delta = 0 - delta; slotSeek(render->seekFramePosition() - delta); } else { - if (event->delta() >= 0) slotForwardOneFrame(); + if (eventDelta >= 0) slotForwardOneFrame(); else slotRewindOneFrame(); } } @@ -615,7 +636,7 @@ void Monitor::slotRewind(double speed) if (currentspeed >= 0) render->play(-2); else render->play(currentspeed * 2); } else render->play(speed); - m_playAction->setChecked(true); + //m_playAction->setChecked(true); m_playAction->setIcon(m_pauseIcon); } @@ -627,7 +648,7 @@ void Monitor::slotForward(double speed) if (currentspeed <= 1) render->play(2); else render->play(currentspeed * 2); } else render->play(speed); - m_playAction->setChecked(true); + //m_playAction->setChecked(true); m_playAction->setIcon(m_pauseIcon); } @@ -661,7 +682,7 @@ void Monitor::rendererStopped(int pos) m_timePos->setValue(pos); } disconnect(m_playAction, SIGNAL(triggered()), this, SLOT(slotPlay())); - m_playAction->setChecked(false); + //m_playAction->setChecked(false); connect(m_playAction, SIGNAL(triggered()), this, SLOT(slotPlay())); m_playAction->setIcon(m_playIcon); } @@ -711,7 +732,7 @@ void Monitor::pause() activateMonitor(); render->pause(); //m_playAction->setChecked(true); - //m_playAction->setIcon(m_pauseIcon); + m_playAction->setIcon(m_playIcon); } void Monitor::slotPlay() @@ -719,10 +740,10 @@ void Monitor::slotPlay() if (render == NULL) return; activateMonitor(); if (render->playSpeed() == 0) { - m_playAction->setChecked(true); + //m_playAction->setChecked(true); m_playAction->setIcon(m_pauseIcon); } else { - m_playAction->setChecked(false); + //m_playAction->setChecked(false); m_playAction->setIcon(m_playIcon); } render->switchPlay(); @@ -734,7 +755,7 @@ void Monitor::slotPlayZone() activateMonitor(); QPoint p = m_ruler->zone(); render->playZone(GenTime(p.x(), m_monitorManager->timecode().fps()), GenTime(p.y(), m_monitorManager->timecode().fps())); - m_playAction->setChecked(true); + //m_playAction->setChecked(true); m_playAction->setIcon(m_pauseIcon); } @@ -744,7 +765,7 @@ void Monitor::slotLoopZone() activateMonitor(); QPoint p = m_ruler->zone(); render->loopZone(GenTime(p.x(), m_monitorManager->timecode().fps()), GenTime(p.y(), m_monitorManager->timecode().fps())); - m_playAction->setChecked(true); + //m_playAction->setChecked(true); m_playAction->setIcon(m_pauseIcon); } @@ -754,7 +775,7 @@ void Monitor::slotLoopClip() return; activateMonitor(); render->loopZone(m_selectedClip->startPos(), m_selectedClip->endPos()); - m_playAction->setChecked(true); + //m_playAction->setChecked(true); m_playAction->setIcon(m_pauseIcon); } @@ -931,9 +952,10 @@ bool Monitor::effectSceneDisplayed() } MonitorRefresh::MonitorRefresh(QWidget* parent) : - QWidget(parent), - m_renderer(NULL) + QWidget(parent) + , m_renderer(NULL) { + // MonitorRefresh is used as container for the SDL display (it's window id is passed to SDL) setAttribute(Qt::WA_PaintOnScreen); setAttribute(Qt::WA_OpaquePaintEvent); //setAttribute(Qt::WA_NoSystemBackground); @@ -950,7 +972,6 @@ void MonitorRefresh::paintEvent(QPaintEvent *event) if (m_renderer) m_renderer->doRefresh(); } - Overlay::Overlay(QWidget* parent) : QLabel(parent) { @@ -975,4 +996,105 @@ void Overlay::setOverlayText(const QString &text, bool isZone) update(); } +VideoContainer::VideoContainer(Monitor* parent) : + QFrame() + , m_monitor(parent) +{ + setFrameShape(QFrame::NoFrame); + setFocusPolicy(Qt::ClickFocus); + setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); +} + +// virtual +void VideoContainer::mousePressEvent(QMouseEvent * event) +{ + if (m_monitor->underMouse()) event->setAccepted(false); +} + +// virtual +void VideoContainer::mouseReleaseEvent(QMouseEvent * event) +{ + if (m_monitor->underMouse()) event->setAccepted(false); + else { + if (m_monitor->isActive()) { + m_monitor->slotPlay(); + event->accept(); + } + } +} + +// virtual +void VideoContainer::mouseMoveEvent(QMouseEvent *event) +{ + if (m_monitor->underMouse()) event->setAccepted(false); +} + +// virtual +void VideoContainer::wheelEvent(QWheelEvent * event) +{ + if (m_monitor->underMouse()) event->setAccepted(false); + else { + m_monitor->slotMouseSeek(event->delta(), event->modifiers() == Qt::ControlModifier); + event->accept(); + } +} + +void VideoContainer::mouseDoubleClickEvent(QMouseEvent * event) +{ + if (!KdenliveSettings::openglmonitors()) + switchFullScreen(); +} + +void VideoContainer::switchFullScreen() +{ + // TODO: disable screensaver? + Qt::WindowFlags flags = windowFlags(); + if (!isFullScreen()) { + // Check if we ahave a multiple monitor setup + setUpdatesEnabled(false); +#if QT_VERSION >= 0x040600 + int monitors = QApplication::desktop()->screenCount(); +#else + int monitors = QApplication::desktop()->numScreens(); +#endif + if (monitors > 1) { + QRect screenres; + // Move monitor widget to the second screen (one screen for Kdenlive, the other one for the Monitor widget + int currentScreen = QApplication::desktop()->screenNumber(this); + if (currentScreen < monitors - 1) + screenres = QApplication::desktop()->screenGeometry(currentScreen + 1); + else + screenres = QApplication::desktop()->screenGeometry(currentScreen - 1); + move(QPoint(screenres.x(), screenres.y())); + resize(screenres.width(), screenres.height()); + } + + m_baseFlags = flags & (Qt::Window | Qt::SubWindow); + flags |= Qt::Window; + flags ^= Qt::SubWindow; + setWindowFlags(flags); +#ifdef Q_WS_X11 + // This works around a bug with Compiz + // as the window must be visible before we can set the state + show(); + raise(); + setWindowState(windowState() | Qt::WindowFullScreen); // set +#else + setWindowState(windowState() | Qt::WindowFullScreen); // set + setUpdatesEnabled(true); + show(); +#endif + } else { + setUpdatesEnabled(false); + flags ^= (Qt::Window | Qt::SubWindow); //clear the flags... + flags |= m_baseFlags; //then we reset the flags (window and subwindow) + setWindowFlags(flags); + setWindowState(windowState() ^ Qt::WindowFullScreen); // reset + setUpdatesEnabled(true); + show(); + } + m_monitor->pause(); +} + + #include "monitor.moc" diff --git a/src/monitor.h b/src/monitor.h index 0ee47787..31a56ccb 100644 --- a/src/monitor.h +++ b/src/monitor.h @@ -28,7 +28,6 @@ #include #include "gentime.h" -#include "ui_monitor_ui.h" #include "timecodedisplay.h" #if defined(Q_WS_MAC) || defined(USE_OPEN_GL) #include "videoglwidget.h" @@ -45,16 +44,44 @@ class ClipItem; class QGraphicsView; class QGraphicsPixmapItem; +class Monitor; + +class VideoContainer : public QFrame +{ + Q_OBJECT +public: + VideoContainer(Monitor *parent = 0); + void switchFullScreen(); + +protected: + virtual void mouseDoubleClickEvent(QMouseEvent * event); + virtual void mousePressEvent(QMouseEvent * event); + virtual void mouseReleaseEvent(QMouseEvent *event); + virtual void mouseMoveEvent(QMouseEvent *event); + virtual void wheelEvent(QWheelEvent * event); + +private: + Qt::WindowFlags m_baseFlags; + Monitor *m_monitor; +}; + class MonitorRefresh : public QWidget { Q_OBJECT public: MonitorRefresh(QWidget *parent = 0); - virtual void paintEvent(QPaintEvent *event); void setRenderer(Render* render); +protected: + virtual void paintEvent(QPaintEvent *event); + private: Render *m_renderer; + +signals: + void switchFullScreen(); + void switchPlay(); + void mouseSeek(int, bool); }; class Overlay : public QLabel @@ -89,6 +116,7 @@ public: void updateTimecodeFormat(); void updateMarkers(DocClipBase *source); MonitorScene *getEffectScene(); + QWidget *container(); protected: virtual void mousePressEvent(QMouseEvent * event); @@ -109,7 +137,6 @@ protected: //virtual void paintEvent(QPaintEvent * event); private: - Ui::Monitor_UI m_ui; QString m_name; MonitorManager *m_monitorManager; DocClipBase *m_currentClip; @@ -133,6 +160,7 @@ private: QPoint m_DragStartPosition; MonitorScene *m_effectScene; QGraphicsView *m_effectView; + VideoContainer *m_videoBox; /** Selected clip/transition in timeline. Used for looping it. */ AbstractClipItem *m_selectedClip; /** true if selected clip is transition, false = selected clip is clip. @@ -140,10 +168,11 @@ private: bool m_loopClipTransition; #if defined(Q_WS_MAC) || defined(USE_OPEN_GL) VideoGLWidget *m_glWidget; - bool createOpenGlWidget(QVBoxLayout *rendererBox, const QString profile); + bool createOpenGlWidget(QWidget *parent, const QString profile); #endif GenTime getSnapForPos(bool previous); + Qt::WindowFlags m_baseFlags; private slots: void seekCursor(int pos); @@ -197,6 +226,8 @@ public slots: void slotSetSelectedClip(AbstractClipItem *item); void slotSetSelectedClip(ClipItem *item); void slotSetSelectedClip(Transition *item); + void slotMouseSeek(int eventDelta, bool fast); + void slotSwitchFullScreen(); signals: void renderPosition(int); -- 2.39.2