diff --git a/CMakeLists.txt b/CMakeLists.txt index 462edc5..47982c6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,6 +27,7 @@ set(SOURCES src/main.cpp src/MpvPlayerBackend.cpp src/utils.cpp + src/enums.hpp ) find_program(CCACHE_FOUND ccache) diff --git a/src/MpvPlayerBackend.cpp b/src/MpvPlayerBackend.cpp index cc13ced..bdfc798 100644 --- a/src/MpvPlayerBackend.cpp +++ b/src/MpvPlayerBackend.cpp @@ -16,20 +16,23 @@ #include "discord_rpc.h" #endif - namespace { -void wakeup(void* ctx) +void +wakeup(void* ctx) { - QMetaObject::invokeMethod((MpvPlayerBackend*)ctx, "on_mpv_events", Qt::QueuedConnection); + QMetaObject::invokeMethod( + (MpvPlayerBackend*)ctx, "on_mpv_events", Qt::QueuedConnection); } -void on_mpv_redraw(void* ctx) +void +on_mpv_redraw(void* ctx) { MpvPlayerBackend::on_update(ctx); } -static void* get_proc_address_mpv(void* ctx, const char* name) +static void* +get_proc_address_mpv(void* ctx, const char* name) { Q_UNUSED(ctx) @@ -59,10 +62,15 @@ public: { // init mpv_gl: if (!obj->mpv_gl) { - mpv_opengl_init_params gl_init_params{ get_proc_address_mpv, nullptr, nullptr }; - mpv_render_param params[]{ { MPV_RENDER_PARAM_API_TYPE, const_cast(MPV_RENDER_API_TYPE_OPENGL) }, + mpv_opengl_init_params gl_init_params{ get_proc_address_mpv, + nullptr, + nullptr }; + mpv_render_param params[]{ + { MPV_RENDER_PARAM_API_TYPE, + const_cast(MPV_RENDER_API_TYPE_OPENGL) }, { MPV_RENDER_PARAM_OPENGL_INIT_PARAMS, &gl_init_params }, - { MPV_RENDER_PARAM_INVALID, nullptr } }; + { MPV_RENDER_PARAM_INVALID, nullptr } + }; if (mpv_render_context_create(&obj->mpv_gl, obj->mpv, params) < 0) throw std::runtime_error("failed to initialize mpv GL context"); mpv_render_context_set_update_callback(obj->mpv_gl, on_mpv_redraw, obj); @@ -77,12 +85,14 @@ public: obj->window()->resetOpenGLState(); QOpenGLFramebufferObject* fbo = framebufferObject(); - mpv_opengl_fbo mpfbo{ - .fbo = static_cast(fbo->handle()), .w = fbo->width(), .h = fbo->height(), .internal_format = 0 - }; + mpv_opengl_fbo mpfbo{ .fbo = static_cast(fbo->handle()), + .w = fbo->width(), + .h = fbo->height(), + .internal_format = 0 }; int flip_y{ 0 }; - mpv_render_param params[] = { // Specify the default framebuffer (0) as target. This will + mpv_render_param params[] = { + // Specify the default framebuffer (0) as target. This will // render onto the entire screen. If you want to show the video // in a smaller rectangle or apply fancy transformations, you'll // need to render into a separate FBO and draw it manually. @@ -106,12 +116,12 @@ MpvPlayerBackend::MpvPlayerBackend(QQuickItem* parent) if (!mpv) throw std::runtime_error("could not create mpv context"); - #ifdef DISCORD - DiscordEventHandlers handlers; - memset(&handlers, 0, sizeof(handlers)); - Discord_Initialize("511220330996432896", &handlers, 1, NULL); - #endif - +#ifdef DISCORD + DiscordEventHandlers handlers; + memset(&handlers, 0, sizeof(handlers)); + Discord_Initialize("511220330996432896", &handlers, 1, NULL); +#endif + mpv_set_option_string(mpv, "terminal", "yes"); mpv_set_option_string(mpv, "msg-level", "all=v"); @@ -130,8 +140,8 @@ MpvPlayerBackend::MpvPlayerBackend(QQuickItem* parent) mpv_observe_property(mpv, 0, "track-list", MPV_FORMAT_NODE); mpv_observe_property(mpv, 0, "audio-device-list", MPV_FORMAT_NODE); mpv_observe_property(mpv, 0, "playlist-pos", MPV_FORMAT_DOUBLE); - mpv_observe_property(mpv, 0, "volume", MPV_FORMAT_DOUBLE); - mpv_observe_property(mpv, 0, "muted", MPV_FORMAT_NONE); + mpv_observe_property(mpv, 0, "volume", MPV_FORMAT_NONE); + mpv_observe_property(mpv, 0, "mute", MPV_FORMAT_NONE); mpv_observe_property(mpv, 0, "duration", MPV_FORMAT_DOUBLE); mpv_observe_property(mpv, 0, "media-title", MPV_FORMAT_STRING); mpv_observe_property(mpv, 0, "sub-text", MPV_FORMAT_STRING); @@ -143,7 +153,17 @@ MpvPlayerBackend::MpvPlayerBackend(QQuickItem* parent) if (mpv_initialize(mpv) < 0) throw std::runtime_error("could not initialize mpv context"); - connect(this, &MpvPlayerBackend::onUpdate, this, &MpvPlayerBackend::doUpdate, Qt::QueuedConnection); + connect(this, + &MpvPlayerBackend::onUpdate, + this, + &MpvPlayerBackend::doUpdate, + Qt::QueuedConnection); + connect(this, + &MpvPlayerBackend::positionChanged, + &MpvPlayerBackend::updateDurationString); + connect(this, + &MpvPlayerBackend::durationChanged, + &MpvPlayerBackend::updateDurationString); } MpvPlayerBackend::~MpvPlayerBackend() @@ -155,60 +175,73 @@ MpvPlayerBackend::~MpvPlayerBackend() printf("MPV terminated.\n"); } -void MpvPlayerBackend::on_update(void* ctx) +void +MpvPlayerBackend::on_update(void* ctx) { MpvPlayerBackend* self = (MpvPlayerBackend*)ctx; emit self->onUpdate(); } -void MpvPlayerBackend::doUpdate() +void +MpvPlayerBackend::doUpdate() { update(); } -QVariant MpvPlayerBackend::getProperty(const QString& name) const +QVariant +MpvPlayerBackend::getProperty(const QString& name) const { return mpv::qt::get_property_variant(mpv, name); } -void MpvPlayerBackend::command(const QVariant& params) +void +MpvPlayerBackend::command(const QVariant& params) { mpv::qt::command_variant(mpv, params); } -void MpvPlayerBackend::setProperty(const QString& name, const QVariant& value) +void +MpvPlayerBackend::setProperty(const QString& name, const QVariant& value) { mpv::qt::set_property_variant(mpv, name, value); } -void MpvPlayerBackend::setOption(const QString& name, const QVariant& value) +void +MpvPlayerBackend::setOption(const QString& name, const QVariant& value) { mpv::qt::set_option_variant(mpv, name, value); } -void MpvPlayerBackend::launchAboutQt() +void +MpvPlayerBackend::launchAboutQt() { - QApplication* qapp = qobject_cast(QCoreApplication::instance()); + QApplication* qapp = + qobject_cast(QCoreApplication::instance()); qapp->aboutQt(); } #ifdef DISCORD -void MpvPlayerBackend::updateDiscord() +void +MpvPlayerBackend::updateDiscord() { - char buffer[256]; - DiscordRichPresence discordPresence; - memset(&discordPresence, 0, sizeof(discordPresence)); - discordPresence.state = getProperty("pause").toBool() ? "Paused" : "Playing"; - sprintf(buffer, "Currently Playing: Video %s", getProperty("media-title").toString().toUtf8().constData()); - discordPresence.details = buffer; - discordPresence.startTimestamp = time(0); - discordPresence.endTimestamp = time(0) + (getProperty("duration").toFloat() - getProperty("time-pos").toFloat()); - discordPresence.instance = 0; - Discord_UpdatePresence(&discordPresence); + char buffer[256]; + DiscordRichPresence discordPresence; + memset(&discordPresence, 0, sizeof(discordPresence)); + discordPresence.state = getProperty("pause").toBool() ? "Paused" : "Playing"; + sprintf(buffer, + "Currently Playing: Video %s", + getProperty("media-title").toString().toUtf8().constData()); + discordPresence.details = buffer; + discordPresence.startTimestamp = time(0); + discordPresence.endTimestamp = time(0) + (getProperty("duration").toFloat() - + getProperty("time-pos").toFloat()); + discordPresence.instance = 0; + Discord_UpdatePresence(&discordPresence); } #endif -QVariant MpvPlayerBackend::getaudioDevices() const +QVariant +MpvPlayerBackend::getaudioDevices() const { QVariant drivers = getProperty("audio-device-list"); QVariant currentDevice = getProperty("audio-device"); @@ -229,99 +262,117 @@ QVariant MpvPlayerBackend::getaudioDevices() const return QVariant(newDrivers); } -void MpvPlayerBackend::setAudioDevice(const QString& name) +void +MpvPlayerBackend::setAudioDevice(const QString& name) { setProperty("audio-device", name); } -void MpvPlayerBackend::togglePlayPause() +void +MpvPlayerBackend::togglePlayPause() { command(QVariantList() << "cycle" << "pause"); } -void MpvPlayerBackend::toggleMute() +void +MpvPlayerBackend::toggleMute() { command(QVariantList() << "cycle" << "mute"); } -void MpvPlayerBackend::nextAudioTrack() +void +MpvPlayerBackend::nextAudioTrack() { command(QVariantList() << "cycle" << "audio"); } -void MpvPlayerBackend::nextSubtitleTrack() +void +MpvPlayerBackend::nextSubtitleTrack() { command(QVariantList() << "cycle" << "sub"); } -void MpvPlayerBackend::nextVideoTrack() +void +MpvPlayerBackend::nextVideoTrack() { command(QVariantList() << "cycle" << "video"); } -void MpvPlayerBackend::prevPlaylistItem() +void +MpvPlayerBackend::prevPlaylistItem() { command(QVariantList() << "playlist-prev"); } -void MpvPlayerBackend::nextPlaylistItem() +void +MpvPlayerBackend::nextPlaylistItem() { command(QVariantList() << "playlist-next" << "force"); } -void MpvPlayerBackend::loadFile(const QVariant& filename) +void +MpvPlayerBackend::loadFile(const QVariant& filename) { command(QVariantList() << "loadfile" << filename); } -void MpvPlayerBackend::appendFile(const QVariant& filename) +void +MpvPlayerBackend::appendFile(const QVariant& filename) { command(QVariantList() << "loadfile" << filename << "append-play"); } -void MpvPlayerBackend::setVolume(const QVariant& volume) +void +MpvPlayerBackend::setVolume(const QVariant& volume) { command(QVariantList() << "set" << "volume" << volume); } -void MpvPlayerBackend::addVolume(const QVariant& volume) +void +MpvPlayerBackend::addVolume(const QVariant& volume) { command(QVariantList() << "add" << "volume" << volume); } -void MpvPlayerBackend::seekAbsolute(const QVariant& seekTime) +void +MpvPlayerBackend::seekAbsolute(const QVariant& seekTime) { command(QVariantList() << "seek" << seekTime << "absolute"); } -void MpvPlayerBackend::seek(const QVariant& seekTime) +void +MpvPlayerBackend::seek(const QVariant& seekTime) { command(QVariantList() << "seek" << seekTime); } -QVariant MpvPlayerBackend::getTracks() const +QVariant +MpvPlayerBackend::getTracks() const { return mpv::qt::get_property_variant(mpv, "track-list"); } -void MpvPlayerBackend::setTrack(const QVariant& track, const QVariant& id) +void +MpvPlayerBackend::setTrack(const QVariant& track, const QVariant& id) { command(QVariantList() << "set" << track << id); } -QVariant MpvPlayerBackend::getTrack(const QString& track) +QVariant +MpvPlayerBackend::getTrack(const QString& track) { return mpv::qt::get_property_variant(mpv, track); } -QVariant MpvPlayerBackend::createTimestamp(const QVariant& seconds) const +QVariant +MpvPlayerBackend::createTimestamp(const QVariant& seconds) const { int d = seconds.toInt(); double h = floor(d / 3600); @@ -329,50 +380,60 @@ QVariant MpvPlayerBackend::createTimestamp(const QVariant& seconds) const double s = floor(d % 3600 % 60); QString hour = h > 0 ? QString::number(h) + ":" : ""; - QString minute = - h < 1 ? QString::number(m) + ":" : (m < 10 ? "0" + QString::number(m) + ":" : QString::number(m) + ":"); + QString minute = h < 1 ? QString::number(m) + ":" + : (m < 10 ? "0" + QString::number(m) + ":" + : QString::number(m) + ":"); QString second = s < 10 ? "0" + QString::number(s) : QString::number(s); return hour + minute + second; } -void MpvPlayerBackend::toggleOnTop() +void +MpvPlayerBackend::toggleOnTop() { onTop = !onTop; AlwaysOnTop(window()->winId(), onTop); } -void MpvPlayerBackend::toggleStats() +void +MpvPlayerBackend::toggleStats() { command(QVariantList() << "script-binding" << "stats/display-stats-toggle"); } -void MpvPlayerBackend::addSpeed(const QVariant& speed) +void +MpvPlayerBackend::addSpeed(const QVariant& speed) { - QString speedString = QString::number(getProperty("speed").toDouble() + speed.toDouble()); + QString speedString = + QString::number(getProperty("speed").toDouble() + speed.toDouble()); speedString = speedString.left(speedString.lastIndexOf('.') + 2); setSpeed(QVariant(speedString)); } -void MpvPlayerBackend::subtractSpeed(const QVariant& speed) +void +MpvPlayerBackend::subtractSpeed(const QVariant& speed) { - QString speedString = QString::number(getProperty("speed").toDouble() - speed.toDouble()); + QString speedString = + QString::number(getProperty("speed").toDouble() - speed.toDouble()); speedString = speedString.left(speedString.lastIndexOf('.') + 2); setSpeed(QVariant(speedString)); } -void MpvPlayerBackend::changeSpeed(const QVariant& speedFactor) +void +MpvPlayerBackend::changeSpeed(const QVariant& speedFactor) { setSpeed(QVariant(getProperty("speed").toDouble() * speedFactor.toDouble())); } -void MpvPlayerBackend::setSpeed(const QVariant& speed) +void +MpvPlayerBackend::setSpeed(const QVariant& speed) { command(QVariantList() << "set" << "speed" << speed.toString()); } -void MpvPlayerBackend::on_mpv_events() +void +MpvPlayerBackend::on_mpv_events() { while (mpv) { mpv_event* event = mpv_wait_event(mpv, 0); @@ -383,48 +444,18 @@ void MpvPlayerBackend::on_mpv_events() } } -void MpvPlayerBackend::updateDurationStringText() +void +MpvPlayerBackend::updateDurationString() { - findChild("timeLabel") - ->setProperty("text", + emit durationStringChanged( QString("%1 / %2 (%3x)") - .arg(createTimestamp(getProperty("time-pos")).toString(), - createTimestamp(getProperty("duration")).toString(), - getProperty("speed").toString())); + .arg(createTimestamp(getProperty("time-pos")).toString(), + createTimestamp(getProperty("duration")).toString(), + getProperty("speed").toString())); } -void MpvPlayerBackend::updatePrev(const QVariant& val) -{ - if (val.toDouble() != 0) { - findChild("playlistPrevButton")->setProperty("visible", true); - } else { - findChild("playlistPrevButton")->setProperty("visible", false); - } -} - -void MpvPlayerBackend::updateVolume(const QVariant& val) -{ - if (getProperty("mute").toBool() || (val.toDouble() == 0)) { - findChild("volumeButton")->setProperty("iconSource", "qrc:/player/icons/volume-mute.svg"); - } else { - if (val.toDouble() < 25) { - findChild("volumeButton")->setProperty("iconSource", "qrc:/player/icons/volume-down.svg"); - } else { - findChild("volumeButton")->setProperty("iconSource", "qrc:/player/icons/volume-up.svg"); - } - } -} - -void MpvPlayerBackend::updatePlayPause(const QVariant& val) -{ - if (val.toBool()) { - findChild("playPauseButton")->setProperty("iconSource", "qrc:/player/icons/play.svg"); - } else { - findChild("playPauseButton")->setProperty("iconSource", "qrc:/player/icons/pause.svg"); - } -} - -void MpvPlayerBackend::handle_mpv_event(mpv_event* event) +void +MpvPlayerBackend::handle_mpv_event(mpv_event* event) { switch (event->event_id) { case MPV_EVENT_PROPERTY_CHANGE: { @@ -432,56 +463,61 @@ void MpvPlayerBackend::handle_mpv_event(mpv_event* event) if (strcmp(prop->name, "time-pos") == 0) { if (prop->format == MPV_FORMAT_DOUBLE) { double time = *(double*)prop->data; - updateDurationStringText(); - findChild("progressBar")->setProperty("value", time); + emit positionChanged(time); } } else if (strcmp(prop->name, "duration") == 0) { if (prop->format == MPV_FORMAT_DOUBLE) { double time = *(double*)prop->data; - updateDurationStringText(); - findChild("progressBar")->setProperty("to", time); + emit durationChanged(time); } - } else if (strcmp(prop->name, "volume") == 0) { - if (prop->format == MPV_FORMAT_DOUBLE) { - double volume = *(double*)prop->data; - updateVolume(QVariant(volume)); + } else if (strcmp(prop->name, "mute") == 0 || + strcmp(prop->name, "volume") == 0) { + double volume = getProperty("volume").toDouble(); + bool mute = getProperty("mute").toBool(); + if (mute || volume == 0) { + emit volumeStatusChanged(Enums::VolumeStatus::Muted); + } else { + if (volume < 25) { + emit volumeStatusChanged(Enums::VolumeStatus::Low); + } else { + emit volumeStatusChanged(Enums::VolumeStatus::Normal); + } } - } else if (strcmp(prop->name, "muted") == 0) { - updateVolume(getProperty("volume")); + // emit volumeChanged(volume); } else if (strcmp(prop->name, "media-title") == 0) { if (prop->format == MPV_FORMAT_STRING) { char* title = *(char**)prop->data; - findChild("titleLabel")->setProperty("text", title); - #ifdef DISCORD - updateDiscord(); - #endif + emit titleChanged(QString(title)); } } else if (strcmp(prop->name, "sub-text") == 0) { if (prop->format == MPV_FORMAT_STRING) { char* subs = *(char**)prop->data; - findChild("nativeSubs")->setProperty("text", subs); + emit subtitlesChanged(QString(subs)); } } else if (strcmp(prop->name, "demuxer-cache-duration") == 0) { if (prop->format == MPV_FORMAT_DOUBLE) { double duration = *(double*)prop->data; - QMetaObject::invokeMethod(findChild("progressBar"), "setCachedDuration", Q_ARG(QVariant, duration)); + emit cachedDurationChanged(duration); } } else if (strcmp(prop->name, "playlist-pos") == 0) { if (prop->format == MPV_FORMAT_DOUBLE) { double pos = *(double*)prop->data; - updatePrev(QVariant(pos)); + emit playlistPositionChanged(pos); } } else if (strcmp(prop->name, "pause") == 0) { - qDebug() << prop->data; - updatePlayPause(getProperty("pause")); - #ifdef DISCORD - updateDiscord(); - #endif + if (getProperty("pause").toBool()) { + emit playStatusChanged(Enums::PlayStatus::Paused); + } else { + emit playStatusChanged(Enums::PlayStatus::Playing); + } } else if (strcmp(prop->name, "tracks-menu") == 0) { - QMetaObject::invokeMethod(findChild("menuBar"), "updateTracks"); + emit tracksChanged(); } else if (strcmp(prop->name, "audio-device-list") == 0) { - QMetaObject::invokeMethod(findChild("audioDeviceMenu"), "update"); + emit audioDevicesChanged(); } +#ifdef DISCORD + updateDiscord(); +#endif break; } case MPV_EVENT_SHUTDOWN: { @@ -494,7 +530,8 @@ void MpvPlayerBackend::handle_mpv_event(mpv_event* event) } } -QQuickFramebufferObject::Renderer* MpvPlayerBackend::createRenderer() const +QQuickFramebufferObject::Renderer* +MpvPlayerBackend::createRenderer() const { window()->setPersistentOpenGLContext(true); window()->setPersistentSceneGraph(true); diff --git a/src/MpvPlayerBackend.h b/src/MpvPlayerBackend.h index 1acc9fd..42d6aa1 100644 --- a/src/MpvPlayerBackend.h +++ b/src/MpvPlayerBackend.h @@ -9,6 +9,8 @@ #include #include +#include "enums.hpp" + class MpvRenderer; class MpvPlayerBackend : public QQuickFramebufferObject @@ -41,13 +43,9 @@ public slots: void nextPlaylistItem(); void toggleOnTop(); void toggleStats(); - void updateDurationStringText(); QVariant getTracks() const; QVariant getaudioDevices() const; void setAudioDevice(const QString& name); - void updatePrev(const QVariant& val); - void updateVolume(const QVariant& val); - void updatePlayPause(const QVariant& val); void addSpeed(const QVariant& speed); void subtractSpeed(const QVariant& speed); void changeSpeed(const QVariant& speedFactor); @@ -68,12 +66,24 @@ public slots: signals: void onUpdate(); - void positionChanged(int value); void mpv_events(); + void playStatusChanged(const Enums::PlayStatus& status); + void volumeStatusChanged(const Enums::VolumeStatus& status); + void volumeChanged(const int& volume); + void durationChanged(const double& duration); + void positionChanged(const double& position); + void cachedDurationChanged(const double& duration); + void playlistPositionChanged(const double& position); + void titleChanged(const QString& title); + void subtitlesChanged(const QString& subtitles); + void durationStringChanged(const QString& string); + void tracksChanged(); + void audioDevicesChanged(); private slots: void doUpdate(); void on_mpv_events(); + void updateDurationString(); private: void handle_mpv_event(mpv_event* event); diff --git a/src/enums.hpp b/src/enums.hpp new file mode 100644 index 0000000..aec7d52 --- /dev/null +++ b/src/enums.hpp @@ -0,0 +1,24 @@ +#ifndef ENUMS_HPP +#define ENUMS_HPP + +#include +#include + +namespace Enums { +Q_NAMESPACE +enum class PlayStatus : int +{ + Playing = 0, + Paused = 1 +}; +Q_ENUM_NS(PlayStatus) +enum class VolumeStatus : int +{ + Muted = 0, + Low = 1, + Normal = 2 +}; +Q_ENUM_NS(VolumeStatus) +} + +#endif diff --git a/src/main.cpp b/src/main.cpp index affee7e..dfb9189 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -6,6 +6,7 @@ #include "utils.hpp" #include +#include "enums.hpp" #include #include #include @@ -110,6 +111,18 @@ main(int argc, char* argv[]) QApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QApplication::setAttribute(Qt::AA_NativeWindows); + qmlRegisterUncreatableMetaObject( + Enums::staticMetaObject, // static meta object + "player", // import statement (can be any string) + 1, + 0, // major and minor version of the import + "Enums", // name in QML (does not have to match C++ name) + "Error: only enums" // error in case someone tries to create a MyNamespace + // object + ); + qRegisterMetaType("Enums.PlayStatus"); + qRegisterMetaType("Enums.VolumeStatus"); + qmlRegisterType("player", 1, 0, "PlayerBackend"); std::setlocale(LC_NUMERIC, "C"); diff --git a/src/qml/ControlsBar.qml b/src/qml/ControlsBar.qml index 35278f0..bef1bd8 100644 --- a/src/qml/ControlsBar.qml +++ b/src/qml/ControlsBar.qml @@ -69,6 +69,11 @@ Item { width: subsContainer.childrenRect.width height: subsContainer.childrenRect.height } + Component.onCompleted: { + player.subtitlesChanged.connect(function(subtitles) { + text = subtitles + }) + } } } } @@ -111,12 +116,18 @@ Item { anchors.bottomMargin: 0 anchors.topMargin: progressBackground.height bottomPadding: 0 - - function setCachedDuration(val) { - cachedLength.width = ((progressBar.width / progressBar.to) - * val) - progressLength.width + Component.onCompleted: { + player.positionChanged.connect(function(position) { + if (! pressed) {progressBar.value = position} + }) + player.durationChanged.connect(function(duration) { + progressBar.to = duration + }) + player.cachedDurationChanged.connect(function(duration) { + cachedLength.width = ((progressBar.width / progressBar.to) + * duration) - progressLength.width + }) } - onMoved: { player.seekAbsolute(progressBar.value) } @@ -208,7 +219,6 @@ Item { Button { id: playlistPrevButton objectName: "playlistPrevButton" - //icon.name: "prev" icon.source: "icons/prev.svg" icon.color: "white" display: AbstractButton.IconOnly @@ -222,14 +232,20 @@ Item { background: Rectangle { color: "transparent" } + Component.onCompleted: { + player.playlistPositionChanged.connect(function(position) { + if (position != 0 ) { + visible = true + } else { + visible = false + } + }) + } } Button { id: playPauseButton - //icon.name: "pause" - objectName: "playPauseButton" - property string iconSource: "icons/pause.svg" - icon.source: iconSource + icon.source: "icons/pause.svg" icon.color: "white" display: AbstractButton.IconOnly anchors.top: parent.top @@ -241,6 +257,15 @@ Item { background: Rectangle { color: "transparent" } + Component.onCompleted: { + player.playStatusChanged.connect(function(status) { + if (status == Enums.PlayStatus.Playing) { + icon.source = "qrc:/player/icons/pause.svg" + } else if (status == Enums.PlayStatus.Paused) { + icon.source = "qrc:/player/icons/play.svg" + } + }) + } } Button { @@ -263,8 +288,7 @@ Item { Button { id: volumeButton objectName: "volumeButton" - property string iconSource: "icons/volume-up.svg" - icon.source: iconSource + icon.source: "icons/volume-up.svg" icon.color: "white" display: AbstractButton.IconOnly anchors.top: parent.top @@ -272,11 +296,21 @@ Item { anchors.left: playlistNextButton.right onClicked: { player.toggleMute() - player.updateVolume(player.getProperty("volume")) } background: Rectangle { color: "transparent" } + Component.onCompleted: { + player.volumeStatusChanged.connect(function(status) { + if (status == Enums.VolumeStatus.Muted) { + volumeButton.icon.source = "qrc:/player/icons/volume-mute.svg" + } else if (status == Enums.VolumeStatus.Low) { + volumeButton.icon.source = "qrc:/player/icons/volume-down.svg" + } else if (status == Enums.VolumeStatus.Normal) { + volumeButton.icon.source = "qrc:/player/icons/volume-up.svg" + } + }) + } } Slider { id: volumeBar @@ -299,7 +333,11 @@ Item { onMoved: { player.setVolume(Math.round(volumeBar.value).toString()) } - + Component.onCompleted: { + player.volumeChanged.connect(function(volume) { + volumeBar.value = volume + }) + } handle: Rectangle { x: volumeBar.leftPadding + volumeBar.visualPosition * (volumeBar.availableWidth - width) @@ -340,6 +378,11 @@ Item { font.pixelSize: 14 verticalAlignment: Text.AlignVCenter renderType: Text.NativeRendering + Component.onCompleted: { + player.durationStringChanged.connect(function(durationString) { + text = durationString + }) + } } Button { diff --git a/src/qml/MainMenu.qml b/src/qml/MainMenu.qml index 60d8d78..272c3f2 100644 --- a/src/qml/MainMenu.qml +++ b/src/qml/MainMenu.qml @@ -20,8 +20,11 @@ MenuBar { || subsMenuBarItem.opened || aboutMenuBarItem.opened - objectName: "menuBar" - + Component.onCompleted: { + player.tracksChanged.connect(updateTracks) + } + + function updateTracks() { for (var i = 0, len = audioMenu.count; i < len; i++) { var audioAction = audioMenu.actionAt(i) @@ -30,7 +33,7 @@ MenuBar { } } for (var i = 0, len = videoMenu.count; i < len; i++) { - var videoAction = audioMenu.actionAt(i) + var videoAction = videoMenu.actionAt(i) if (videoAction.trackID != "no") { videoMenu.removeAction(videoAction) } @@ -340,7 +343,10 @@ MenuBar { id: audioDeviceMenu objectName: "audioDeviceMenu" - function update() { + Component.onCompleted: { + player.audioDevicesChanged.connect(updateAudioDevices) + } + function updateAudioDevices() { var audioDevices = player.getaudioDevices() for (var i = 0, len = audioDeviceMenu.count; i < len; i++) { diff --git a/src/qml/main.qml b/src/qml/main.qml index 84b91e4..81926b1 100644 --- a/src/qml/main.qml +++ b/src/qml/main.qml @@ -55,7 +55,7 @@ ApplicationWindow { category: "Fun" property bool nyanCat: false } - + function startPlayer() { var args = Qt.application.arguments var len = Qt.application.arguments.length @@ -305,6 +305,11 @@ ApplicationWindow { font.pixelSize: 14 font.bold: true opacity: 1 + Component.onCompleted: { + player.titleChanged.connect(function(title) { + text = title + }) + } } } diff --git a/src/setenv_mingw.hpp b/src/setenv_mingw.hpp index a5c2ed5..b547c64 100644 --- a/src/setenv_mingw.hpp +++ b/src/setenv_mingw.hpp @@ -36,7 +36,8 @@ #include #include -int setenv(const char* var, const char* value, int overwrite) +int +setenv(const char* var, const char* value, int overwrite) { /* Core implementation for both setenv() and unsetenv() functions; * at the outset, assume that the requested operation may fail. diff --git a/src/utils.cpp b/src/utils.cpp index 9ba4856..b2d92e0 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -4,9 +4,11 @@ #include #include -QString getPlatformName() +QString +getPlatformName() { - QGuiApplication* qapp = qobject_cast(QCoreApplication::instance()); + QGuiApplication* qapp = + qobject_cast(QCoreApplication::instance()); return qapp->platformName(); } @@ -18,7 +20,8 @@ QString getPlatformName() #include #include -void SetDPMS(bool on) +void +SetDPMS(bool on) { qDebug() << getPlatformName(); if (getPlatformName() != "xcb") { @@ -34,7 +37,8 @@ void SetDPMS(bool on) } } -void AlwaysOnTop(WId wid, bool on) +void +AlwaysOnTop(WId wid, bool on) { qDebug() << "On Top:" << on; Display* display = QX11Info::display(); @@ -53,17 +57,23 @@ void AlwaysOnTop(WId wid, bool on) event.xclient.data.l[3] = 0; event.xclient.data.l[4] = 0; - XSendEvent(display, DefaultRootWindow(display), False, SubstructureRedirectMask | SubstructureNotifyMask, &event); + XSendEvent(display, + DefaultRootWindow(display), + False, + SubstructureRedirectMask | SubstructureNotifyMask, + &event); } #else -void AlwaysOnTop(WId wid, bool on) +void +AlwaysOnTop(WId wid, bool on) { qDebug() << "Can't set on top for platform: " << getPlatformName(); } -void SetDPMS(bool on) +void +SetDPMS(bool on) { qDebug() << "Can't set DPMS for platform: " << getPlatformName(); } diff --git a/src/utils.hpp b/src/utils.hpp index 7082c90..8af9fff 100644 --- a/src/utils.hpp +++ b/src/utils.hpp @@ -3,7 +3,9 @@ #include #include -void SetDPMS(bool on); -void AlwaysOnTop(WId wid, bool on); +void +SetDPMS(bool on); +void +AlwaysOnTop(WId wid, bool on); #endif