diff --git a/src/UI/DocumentViews/MpvContainer.cc b/src/UI/DocumentViews/MpvContainer.cc index 2ac832af0aa040ebacd0054baa7516e66a85bd3c..326f8c2bdfae10857279de32a68d9c9c182b3eb0 100644 --- a/src/UI/DocumentViews/MpvContainer.cc +++ b/src/UI/DocumentViews/MpvContainer.cc @@ -12,8 +12,9 @@ MpvContainer::mpvEventWakeUpCB(void *user) noexcept emit container->mpvEvent(); } -MpvContainer::MpvContainer() - : mpv(mpv_create()) +MpvContainer::MpvContainer(QWidget *parent) + : QWidget(parent) + , mpv(mpv_create()) { if (mpv == nullptr) throw std::runtime_error("Failed to create the MPV context"); @@ -40,20 +41,18 @@ MpvContainer::MpvContainer() } void -MpvContainer::registerMpvTimeCallback(void (*callback)(double)) noexcept +MpvContainer::registerMpvTimeCallback(std::function<void(double)> callback) noexcept { if (mpvTimeCallback) - qWarning() << "Override a previous mpv callback, was" << mpvTimeCallback - << "and now will be" << callback; + qWarning() << "Override a previous mpv callback!"; mpvTimeCallback = callback; } void -MpvContainer::registerMpvDurationCallback(void (*callback)(double)) noexcept +MpvContainer::registerMpvDurationCallback(std::function<void(double)> callback) noexcept { if (mpvDurationCallback) - qWarning() << "Override a previous mpv callback, was" << mpvDurationCallback - << "and now will be" << callback; + qWarning() << "Override a previous mpv callback!"; mpvDurationCallback = callback; } diff --git a/src/UI/DocumentViews/MpvContainer.hh b/src/UI/DocumentViews/MpvContainer.hh index df1fe1505f8a284b2bda7dd8b6496dbe31f4902d..e8ac2cac4fe1207fa6535d337b7117a9d9c5eb07 100644 --- a/src/UI/DocumentViews/MpvContainer.hh +++ b/src/UI/DocumentViews/MpvContainer.hh @@ -6,6 +6,8 @@ #include "../../Lib/Utils.hh" +#include <functional> + extern "C" { struct mpv_handle; struct mpv_event; @@ -13,25 +15,26 @@ struct mpv_event; namespace Vivy { -class MpvContainer : public QWidget { +class MpvContainer final : public QWidget { Q_OBJECT VIVY_UNMOVABLE_OBJECT(MpvContainer) private: bool isPlaybackPaused{ true }; mpv_handle *mpv{ nullptr }; - void (*mpvTimeCallback)(double){ nullptr }; - void (*mpvDurationCallback)(double){ nullptr }; + std::function<void(double)> mpvTimeCallback{ nullptr }; + std::function<void(double)> mpvDurationCallback{ nullptr }; public: - explicit MpvContainer(); + explicit MpvContainer(QWidget *parent); ~MpvContainer() noexcept override; void loadFile(const QString &) noexcept; // Register a callback for time change, don't use Qt's signals for that. - void registerMpvTimeCallback(void (*)(double)) noexcept; - void registerMpvDurationCallback(void (*)(double)) noexcept; + // Here the function will likely be moved if necessary (I hope...). + void registerMpvTimeCallback(std::function<void(double)>) noexcept; + void registerMpvDurationCallback(std::function<void(double)>) noexcept; private: void handleMpvEvent(mpv_event *) noexcept; diff --git a/src/UI/DocumentViews/MpvControls.cc b/src/UI/DocumentViews/MpvControls.cc new file mode 100644 index 0000000000000000000000000000000000000000..b129142b17b78f33a1f84ec0c684b12d43d11677 --- /dev/null +++ b/src/UI/DocumentViews/MpvControls.cc @@ -0,0 +1,26 @@ +#include "MpvControls.hh" +#include "MpvContainer.hh" + +#include <QProgressBar> +#include <QVBoxLayout> + +using namespace Vivy; + +MpvControls::MpvControls(MpvContainer *passedContainer, QWidget *parent) noexcept + : QWidget(parent) + , mpv(passedContainer) +{ + QProgressBar *progressBar = new QProgressBar(this); + + mpv->registerMpvDurationCallback([progressBar](double time) noexcept -> void { + progressBar->setMaximum(static_cast<int>(time)); + progressBar->setValue(0); + }); + mpv->registerMpvTimeCallback([progressBar](double time) noexcept -> void { + progressBar->setValue(static_cast<int>(time)); + }); + + auto *centralLayout = new QVBoxLayout(this); + centralLayout->addWidget(progressBar); + setLayout(centralLayout); +} diff --git a/src/UI/DocumentViews/MpvControls.hh b/src/UI/DocumentViews/MpvControls.hh new file mode 100644 index 0000000000000000000000000000000000000000..acb53d11362bf6f3d78629a64020fb87285a513c --- /dev/null +++ b/src/UI/DocumentViews/MpvControls.hh @@ -0,0 +1,21 @@ +#pragma once + +#ifndef __cplusplus +#error "This is a C++ header" +#endif + +namespace Vivy +{ +class MpvContainer; + +class MpvControls final : public QWidget { + Q_OBJECT + VIVY_UNMOVABLE_OBJECT(MpvControls) + +private: + MpvContainer *mpv{ nullptr }; + +public: + explicit MpvControls(MpvContainer *mpv, QWidget *parent) noexcept; +}; +} diff --git a/src/UI/DocumentViews/VideoView.cc b/src/UI/DocumentViews/VideoView.cc new file mode 100644 index 0000000000000000000000000000000000000000..bc73922e714944733f788251d866f26441bba4e0 --- /dev/null +++ b/src/UI/DocumentViews/VideoView.cc @@ -0,0 +1,31 @@ +#include "VideoView.hh" +#include "MpvContainer.hh" +#include "MpvControls.hh" + +#include <QVBoxLayout> + +using namespace Vivy; + +VideoView::VideoView(QWidget *parent) noexcept + : QWidget(parent) + , mpv(new MpvContainer(this)) +{ + auto *centralLayout = new QVBoxLayout(this); + + centralLayout->addWidget(mpv, 1); + centralLayout->addWidget(new MpvControls(mpv, this)); + + setLayout(centralLayout); +} + +void +VideoView::loadFile(const QString &filename) noexcept +{ + mpv->loadFile(filename); +} + +void +VideoView::forceStopPlayback() noexcept +{ + mpv->mpvPause(); +} diff --git a/src/UI/DocumentViews/VideoView.hh b/src/UI/DocumentViews/VideoView.hh new file mode 100644 index 0000000000000000000000000000000000000000..20a97b8d6c519cd28d0b1d96e670161303582a9c --- /dev/null +++ b/src/UI/DocumentViews/VideoView.hh @@ -0,0 +1,26 @@ +#pragma once + +#ifndef __cplusplus +#error "This is a C++ header" +#endif + +#include "../../Lib/Utils.hh" + +namespace Vivy +{ +class MpvContainer; + +class VideoView final : public QWidget { + Q_OBJECT + VIVY_UNMOVABLE_OBJECT(VideoView) + + MpvContainer *mpv{ nullptr }; + +public: + explicit VideoView(QWidget *parent) noexcept; + +public slots: + void loadFile(const QString &) noexcept; + void forceStopPlayback() noexcept; +}; +}