[Multiple] Moved to Slots + Signals instead of calling JS functions or manually changing object values.
This commit is contained in:
parent
8c71f0b341
commit
5f0d602041
|
@ -27,6 +27,7 @@ set(SOURCES
|
||||||
src/main.cpp
|
src/main.cpp
|
||||||
src/MpvPlayerBackend.cpp
|
src/MpvPlayerBackend.cpp
|
||||||
src/utils.cpp
|
src/utils.cpp
|
||||||
|
src/enums.hpp
|
||||||
)
|
)
|
||||||
|
|
||||||
find_program(CCACHE_FOUND ccache)
|
find_program(CCACHE_FOUND ccache)
|
||||||
|
|
|
@ -16,20 +16,23 @@
|
||||||
#include "discord_rpc.h"
|
#include "discord_rpc.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
namespace {
|
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);
|
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)
|
Q_UNUSED(ctx)
|
||||||
|
|
||||||
|
@ -59,10 +62,15 @@ public:
|
||||||
{
|
{
|
||||||
// init mpv_gl:
|
// init mpv_gl:
|
||||||
if (!obj->mpv_gl) {
|
if (!obj->mpv_gl) {
|
||||||
mpv_opengl_init_params gl_init_params{ get_proc_address_mpv, nullptr, nullptr };
|
mpv_opengl_init_params gl_init_params{ get_proc_address_mpv,
|
||||||
mpv_render_param params[]{ { MPV_RENDER_PARAM_API_TYPE, const_cast<char*>(MPV_RENDER_API_TYPE_OPENGL) },
|
nullptr,
|
||||||
|
nullptr };
|
||||||
|
mpv_render_param params[]{
|
||||||
|
{ MPV_RENDER_PARAM_API_TYPE,
|
||||||
|
const_cast<char*>(MPV_RENDER_API_TYPE_OPENGL) },
|
||||||
{ MPV_RENDER_PARAM_OPENGL_INIT_PARAMS, &gl_init_params },
|
{ 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)
|
if (mpv_render_context_create(&obj->mpv_gl, obj->mpv, params) < 0)
|
||||||
throw std::runtime_error("failed to initialize mpv GL context");
|
throw std::runtime_error("failed to initialize mpv GL context");
|
||||||
mpv_render_context_set_update_callback(obj->mpv_gl, on_mpv_redraw, obj);
|
mpv_render_context_set_update_callback(obj->mpv_gl, on_mpv_redraw, obj);
|
||||||
|
@ -77,12 +85,14 @@ public:
|
||||||
obj->window()->resetOpenGLState();
|
obj->window()->resetOpenGLState();
|
||||||
|
|
||||||
QOpenGLFramebufferObject* fbo = framebufferObject();
|
QOpenGLFramebufferObject* fbo = framebufferObject();
|
||||||
mpv_opengl_fbo mpfbo{
|
mpv_opengl_fbo mpfbo{ .fbo = static_cast<int>(fbo->handle()),
|
||||||
.fbo = static_cast<int>(fbo->handle()), .w = fbo->width(), .h = fbo->height(), .internal_format = 0
|
.w = fbo->width(),
|
||||||
};
|
.h = fbo->height(),
|
||||||
|
.internal_format = 0 };
|
||||||
int flip_y{ 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
|
// render onto the entire screen. If you want to show the video
|
||||||
// in a smaller rectangle or apply fancy transformations, you'll
|
// in a smaller rectangle or apply fancy transformations, you'll
|
||||||
// need to render into a separate FBO and draw it manually.
|
// need to render into a separate FBO and draw it manually.
|
||||||
|
@ -106,11 +116,11 @@ MpvPlayerBackend::MpvPlayerBackend(QQuickItem* parent)
|
||||||
if (!mpv)
|
if (!mpv)
|
||||||
throw std::runtime_error("could not create mpv context");
|
throw std::runtime_error("could not create mpv context");
|
||||||
|
|
||||||
#ifdef DISCORD
|
#ifdef DISCORD
|
||||||
DiscordEventHandlers handlers;
|
DiscordEventHandlers handlers;
|
||||||
memset(&handlers, 0, sizeof(handlers));
|
memset(&handlers, 0, sizeof(handlers));
|
||||||
Discord_Initialize("511220330996432896", &handlers, 1, NULL);
|
Discord_Initialize("511220330996432896", &handlers, 1, NULL);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
mpv_set_option_string(mpv, "terminal", "yes");
|
mpv_set_option_string(mpv, "terminal", "yes");
|
||||||
mpv_set_option_string(mpv, "msg-level", "all=v");
|
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, "track-list", MPV_FORMAT_NODE);
|
||||||
mpv_observe_property(mpv, 0, "audio-device-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, "playlist-pos", MPV_FORMAT_DOUBLE);
|
||||||
mpv_observe_property(mpv, 0, "volume", MPV_FORMAT_DOUBLE);
|
mpv_observe_property(mpv, 0, "volume", MPV_FORMAT_NONE);
|
||||||
mpv_observe_property(mpv, 0, "muted", 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, "duration", MPV_FORMAT_DOUBLE);
|
||||||
mpv_observe_property(mpv, 0, "media-title", MPV_FORMAT_STRING);
|
mpv_observe_property(mpv, 0, "media-title", MPV_FORMAT_STRING);
|
||||||
mpv_observe_property(mpv, 0, "sub-text", 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)
|
if (mpv_initialize(mpv) < 0)
|
||||||
throw std::runtime_error("could not initialize mpv context");
|
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()
|
MpvPlayerBackend::~MpvPlayerBackend()
|
||||||
|
@ -155,60 +175,73 @@ MpvPlayerBackend::~MpvPlayerBackend()
|
||||||
printf("MPV terminated.\n");
|
printf("MPV terminated.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void MpvPlayerBackend::on_update(void* ctx)
|
void
|
||||||
|
MpvPlayerBackend::on_update(void* ctx)
|
||||||
{
|
{
|
||||||
MpvPlayerBackend* self = (MpvPlayerBackend*)ctx;
|
MpvPlayerBackend* self = (MpvPlayerBackend*)ctx;
|
||||||
emit self->onUpdate();
|
emit self->onUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MpvPlayerBackend::doUpdate()
|
void
|
||||||
|
MpvPlayerBackend::doUpdate()
|
||||||
{
|
{
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant MpvPlayerBackend::getProperty(const QString& name) const
|
QVariant
|
||||||
|
MpvPlayerBackend::getProperty(const QString& name) const
|
||||||
{
|
{
|
||||||
return mpv::qt::get_property_variant(mpv, name);
|
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);
|
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);
|
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);
|
mpv::qt::set_option_variant(mpv, name, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MpvPlayerBackend::launchAboutQt()
|
void
|
||||||
|
MpvPlayerBackend::launchAboutQt()
|
||||||
{
|
{
|
||||||
QApplication* qapp = qobject_cast<QApplication*>(QCoreApplication::instance());
|
QApplication* qapp =
|
||||||
|
qobject_cast<QApplication*>(QCoreApplication::instance());
|
||||||
qapp->aboutQt();
|
qapp->aboutQt();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DISCORD
|
#ifdef DISCORD
|
||||||
void MpvPlayerBackend::updateDiscord()
|
void
|
||||||
|
MpvPlayerBackend::updateDiscord()
|
||||||
{
|
{
|
||||||
char buffer[256];
|
char buffer[256];
|
||||||
DiscordRichPresence discordPresence;
|
DiscordRichPresence discordPresence;
|
||||||
memset(&discordPresence, 0, sizeof(discordPresence));
|
memset(&discordPresence, 0, sizeof(discordPresence));
|
||||||
discordPresence.state = getProperty("pause").toBool() ? "Paused" : "Playing";
|
discordPresence.state = getProperty("pause").toBool() ? "Paused" : "Playing";
|
||||||
sprintf(buffer, "Currently Playing: Video %s", getProperty("media-title").toString().toUtf8().constData());
|
sprintf(buffer,
|
||||||
discordPresence.details = buffer;
|
"Currently Playing: Video %s",
|
||||||
discordPresence.startTimestamp = time(0);
|
getProperty("media-title").toString().toUtf8().constData());
|
||||||
discordPresence.endTimestamp = time(0) + (getProperty("duration").toFloat() - getProperty("time-pos").toFloat());
|
discordPresence.details = buffer;
|
||||||
discordPresence.instance = 0;
|
discordPresence.startTimestamp = time(0);
|
||||||
Discord_UpdatePresence(&discordPresence);
|
discordPresence.endTimestamp = time(0) + (getProperty("duration").toFloat() -
|
||||||
|
getProperty("time-pos").toFloat());
|
||||||
|
discordPresence.instance = 0;
|
||||||
|
Discord_UpdatePresence(&discordPresence);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
QVariant MpvPlayerBackend::getaudioDevices() const
|
QVariant
|
||||||
|
MpvPlayerBackend::getaudioDevices() const
|
||||||
{
|
{
|
||||||
QVariant drivers = getProperty("audio-device-list");
|
QVariant drivers = getProperty("audio-device-list");
|
||||||
QVariant currentDevice = getProperty("audio-device");
|
QVariant currentDevice = getProperty("audio-device");
|
||||||
|
@ -229,99 +262,117 @@ QVariant MpvPlayerBackend::getaudioDevices() const
|
||||||
return QVariant(newDrivers);
|
return QVariant(newDrivers);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MpvPlayerBackend::setAudioDevice(const QString& name)
|
void
|
||||||
|
MpvPlayerBackend::setAudioDevice(const QString& name)
|
||||||
{
|
{
|
||||||
setProperty("audio-device", name);
|
setProperty("audio-device", name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MpvPlayerBackend::togglePlayPause()
|
void
|
||||||
|
MpvPlayerBackend::togglePlayPause()
|
||||||
{
|
{
|
||||||
command(QVariantList() << "cycle"
|
command(QVariantList() << "cycle"
|
||||||
<< "pause");
|
<< "pause");
|
||||||
}
|
}
|
||||||
|
|
||||||
void MpvPlayerBackend::toggleMute()
|
void
|
||||||
|
MpvPlayerBackend::toggleMute()
|
||||||
{
|
{
|
||||||
command(QVariantList() << "cycle"
|
command(QVariantList() << "cycle"
|
||||||
<< "mute");
|
<< "mute");
|
||||||
}
|
}
|
||||||
|
|
||||||
void MpvPlayerBackend::nextAudioTrack()
|
void
|
||||||
|
MpvPlayerBackend::nextAudioTrack()
|
||||||
{
|
{
|
||||||
command(QVariantList() << "cycle"
|
command(QVariantList() << "cycle"
|
||||||
<< "audio");
|
<< "audio");
|
||||||
}
|
}
|
||||||
void MpvPlayerBackend::nextSubtitleTrack()
|
void
|
||||||
|
MpvPlayerBackend::nextSubtitleTrack()
|
||||||
{
|
{
|
||||||
command(QVariantList() << "cycle"
|
command(QVariantList() << "cycle"
|
||||||
<< "sub");
|
<< "sub");
|
||||||
}
|
}
|
||||||
|
|
||||||
void MpvPlayerBackend::nextVideoTrack()
|
void
|
||||||
|
MpvPlayerBackend::nextVideoTrack()
|
||||||
{
|
{
|
||||||
command(QVariantList() << "cycle"
|
command(QVariantList() << "cycle"
|
||||||
<< "video");
|
<< "video");
|
||||||
}
|
}
|
||||||
|
|
||||||
void MpvPlayerBackend::prevPlaylistItem()
|
void
|
||||||
|
MpvPlayerBackend::prevPlaylistItem()
|
||||||
{
|
{
|
||||||
command(QVariantList() << "playlist-prev");
|
command(QVariantList() << "playlist-prev");
|
||||||
}
|
}
|
||||||
|
|
||||||
void MpvPlayerBackend::nextPlaylistItem()
|
void
|
||||||
|
MpvPlayerBackend::nextPlaylistItem()
|
||||||
{
|
{
|
||||||
command(QVariantList() << "playlist-next"
|
command(QVariantList() << "playlist-next"
|
||||||
<< "force");
|
<< "force");
|
||||||
}
|
}
|
||||||
|
|
||||||
void MpvPlayerBackend::loadFile(const QVariant& filename)
|
void
|
||||||
|
MpvPlayerBackend::loadFile(const QVariant& filename)
|
||||||
{
|
{
|
||||||
command(QVariantList() << "loadfile" << filename);
|
command(QVariantList() << "loadfile" << filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MpvPlayerBackend::appendFile(const QVariant& filename)
|
void
|
||||||
|
MpvPlayerBackend::appendFile(const QVariant& filename)
|
||||||
{
|
{
|
||||||
command(QVariantList() << "loadfile" << filename << "append-play");
|
command(QVariantList() << "loadfile" << filename << "append-play");
|
||||||
}
|
}
|
||||||
|
|
||||||
void MpvPlayerBackend::setVolume(const QVariant& volume)
|
void
|
||||||
|
MpvPlayerBackend::setVolume(const QVariant& volume)
|
||||||
{
|
{
|
||||||
command(QVariantList() << "set"
|
command(QVariantList() << "set"
|
||||||
<< "volume" << volume);
|
<< "volume" << volume);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MpvPlayerBackend::addVolume(const QVariant& volume)
|
void
|
||||||
|
MpvPlayerBackend::addVolume(const QVariant& volume)
|
||||||
{
|
{
|
||||||
command(QVariantList() << "add"
|
command(QVariantList() << "add"
|
||||||
<< "volume" << volume);
|
<< "volume" << volume);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MpvPlayerBackend::seekAbsolute(const QVariant& seekTime)
|
void
|
||||||
|
MpvPlayerBackend::seekAbsolute(const QVariant& seekTime)
|
||||||
{
|
{
|
||||||
command(QVariantList() << "seek" << seekTime << "absolute");
|
command(QVariantList() << "seek" << seekTime << "absolute");
|
||||||
}
|
}
|
||||||
|
|
||||||
void MpvPlayerBackend::seek(const QVariant& seekTime)
|
void
|
||||||
|
MpvPlayerBackend::seek(const QVariant& seekTime)
|
||||||
{
|
{
|
||||||
command(QVariantList() << "seek" << seekTime);
|
command(QVariantList() << "seek" << seekTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant MpvPlayerBackend::getTracks() const
|
QVariant
|
||||||
|
MpvPlayerBackend::getTracks() const
|
||||||
{
|
{
|
||||||
return mpv::qt::get_property_variant(mpv, "track-list");
|
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);
|
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);
|
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();
|
int d = seconds.toInt();
|
||||||
double h = floor(d / 3600);
|
double h = floor(d / 3600);
|
||||||
|
@ -329,50 +380,60 @@ QVariant MpvPlayerBackend::createTimestamp(const QVariant& seconds) const
|
||||||
double s = floor(d % 3600 % 60);
|
double s = floor(d % 3600 % 60);
|
||||||
|
|
||||||
QString hour = h > 0 ? QString::number(h) + ":" : "";
|
QString hour = h > 0 ? QString::number(h) + ":" : "";
|
||||||
QString minute =
|
QString minute = h < 1 ? QString::number(m) + ":"
|
||||||
h < 1 ? QString::number(m) + ":" : (m < 10 ? "0" + QString::number(m) + ":" : QString::number(m) + ":");
|
: (m < 10 ? "0" + QString::number(m) + ":"
|
||||||
|
: QString::number(m) + ":");
|
||||||
QString second = s < 10 ? "0" + QString::number(s) : QString::number(s);
|
QString second = s < 10 ? "0" + QString::number(s) : QString::number(s);
|
||||||
return hour + minute + second;
|
return hour + minute + second;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MpvPlayerBackend::toggleOnTop()
|
void
|
||||||
|
MpvPlayerBackend::toggleOnTop()
|
||||||
{
|
{
|
||||||
onTop = !onTop;
|
onTop = !onTop;
|
||||||
AlwaysOnTop(window()->winId(), onTop);
|
AlwaysOnTop(window()->winId(), onTop);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MpvPlayerBackend::toggleStats()
|
void
|
||||||
|
MpvPlayerBackend::toggleStats()
|
||||||
{
|
{
|
||||||
command(QVariantList() << "script-binding"
|
command(QVariantList() << "script-binding"
|
||||||
<< "stats/display-stats-toggle");
|
<< "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);
|
speedString = speedString.left(speedString.lastIndexOf('.') + 2);
|
||||||
setSpeed(QVariant(speedString));
|
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);
|
speedString = speedString.left(speedString.lastIndexOf('.') + 2);
|
||||||
setSpeed(QVariant(speedString));
|
setSpeed(QVariant(speedString));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MpvPlayerBackend::changeSpeed(const QVariant& speedFactor)
|
void
|
||||||
|
MpvPlayerBackend::changeSpeed(const QVariant& speedFactor)
|
||||||
{
|
{
|
||||||
setSpeed(QVariant(getProperty("speed").toDouble() * speedFactor.toDouble()));
|
setSpeed(QVariant(getProperty("speed").toDouble() * speedFactor.toDouble()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MpvPlayerBackend::setSpeed(const QVariant& speed)
|
void
|
||||||
|
MpvPlayerBackend::setSpeed(const QVariant& speed)
|
||||||
{
|
{
|
||||||
command(QVariantList() << "set"
|
command(QVariantList() << "set"
|
||||||
<< "speed" << speed.toString());
|
<< "speed" << speed.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
void MpvPlayerBackend::on_mpv_events()
|
void
|
||||||
|
MpvPlayerBackend::on_mpv_events()
|
||||||
{
|
{
|
||||||
while (mpv) {
|
while (mpv) {
|
||||||
mpv_event* event = mpv_wait_event(mpv, 0);
|
mpv_event* event = mpv_wait_event(mpv, 0);
|
||||||
|
@ -383,48 +444,18 @@ void MpvPlayerBackend::on_mpv_events()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MpvPlayerBackend::updateDurationStringText()
|
void
|
||||||
|
MpvPlayerBackend::updateDurationString()
|
||||||
{
|
{
|
||||||
findChild<QObject*>("timeLabel")
|
emit durationStringChanged(
|
||||||
->setProperty("text",
|
|
||||||
QString("%1 / %2 (%3x)")
|
QString("%1 / %2 (%3x)")
|
||||||
.arg(createTimestamp(getProperty("time-pos")).toString(),
|
.arg(createTimestamp(getProperty("time-pos")).toString(),
|
||||||
createTimestamp(getProperty("duration")).toString(),
|
createTimestamp(getProperty("duration")).toString(),
|
||||||
getProperty("speed").toString()));
|
getProperty("speed").toString()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MpvPlayerBackend::updatePrev(const QVariant& val)
|
void
|
||||||
{
|
MpvPlayerBackend::handle_mpv_event(mpv_event* event)
|
||||||
if (val.toDouble() != 0) {
|
|
||||||
findChild<QObject*>("playlistPrevButton")->setProperty("visible", true);
|
|
||||||
} else {
|
|
||||||
findChild<QObject*>("playlistPrevButton")->setProperty("visible", false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MpvPlayerBackend::updateVolume(const QVariant& val)
|
|
||||||
{
|
|
||||||
if (getProperty("mute").toBool() || (val.toDouble() == 0)) {
|
|
||||||
findChild<QObject*>("volumeButton")->setProperty("iconSource", "qrc:/player/icons/volume-mute.svg");
|
|
||||||
} else {
|
|
||||||
if (val.toDouble() < 25) {
|
|
||||||
findChild<QObject*>("volumeButton")->setProperty("iconSource", "qrc:/player/icons/volume-down.svg");
|
|
||||||
} else {
|
|
||||||
findChild<QObject*>("volumeButton")->setProperty("iconSource", "qrc:/player/icons/volume-up.svg");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MpvPlayerBackend::updatePlayPause(const QVariant& val)
|
|
||||||
{
|
|
||||||
if (val.toBool()) {
|
|
||||||
findChild<QObject*>("playPauseButton")->setProperty("iconSource", "qrc:/player/icons/play.svg");
|
|
||||||
} else {
|
|
||||||
findChild<QObject*>("playPauseButton")->setProperty("iconSource", "qrc:/player/icons/pause.svg");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MpvPlayerBackend::handle_mpv_event(mpv_event* event)
|
|
||||||
{
|
{
|
||||||
switch (event->event_id) {
|
switch (event->event_id) {
|
||||||
case MPV_EVENT_PROPERTY_CHANGE: {
|
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 (strcmp(prop->name, "time-pos") == 0) {
|
||||||
if (prop->format == MPV_FORMAT_DOUBLE) {
|
if (prop->format == MPV_FORMAT_DOUBLE) {
|
||||||
double time = *(double*)prop->data;
|
double time = *(double*)prop->data;
|
||||||
updateDurationStringText();
|
emit positionChanged(time);
|
||||||
findChild<QObject*>("progressBar")->setProperty("value", time);
|
|
||||||
}
|
}
|
||||||
} else if (strcmp(prop->name, "duration") == 0) {
|
} else if (strcmp(prop->name, "duration") == 0) {
|
||||||
if (prop->format == MPV_FORMAT_DOUBLE) {
|
if (prop->format == MPV_FORMAT_DOUBLE) {
|
||||||
double time = *(double*)prop->data;
|
double time = *(double*)prop->data;
|
||||||
updateDurationStringText();
|
emit durationChanged(time);
|
||||||
findChild<QObject*>("progressBar")->setProperty("to", time);
|
|
||||||
}
|
}
|
||||||
} else if (strcmp(prop->name, "volume") == 0) {
|
} else if (strcmp(prop->name, "mute") == 0 ||
|
||||||
if (prop->format == MPV_FORMAT_DOUBLE) {
|
strcmp(prop->name, "volume") == 0) {
|
||||||
double volume = *(double*)prop->data;
|
double volume = getProperty("volume").toDouble();
|
||||||
updateVolume(QVariant(volume));
|
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) {
|
// emit volumeChanged(volume);
|
||||||
updateVolume(getProperty("volume"));
|
|
||||||
} else if (strcmp(prop->name, "media-title") == 0) {
|
} else if (strcmp(prop->name, "media-title") == 0) {
|
||||||
if (prop->format == MPV_FORMAT_STRING) {
|
if (prop->format == MPV_FORMAT_STRING) {
|
||||||
char* title = *(char**)prop->data;
|
char* title = *(char**)prop->data;
|
||||||
findChild<QObject*>("titleLabel")->setProperty("text", title);
|
emit titleChanged(QString(title));
|
||||||
#ifdef DISCORD
|
|
||||||
updateDiscord();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
} else if (strcmp(prop->name, "sub-text") == 0) {
|
} else if (strcmp(prop->name, "sub-text") == 0) {
|
||||||
if (prop->format == MPV_FORMAT_STRING) {
|
if (prop->format == MPV_FORMAT_STRING) {
|
||||||
char* subs = *(char**)prop->data;
|
char* subs = *(char**)prop->data;
|
||||||
findChild<QObject*>("nativeSubs")->setProperty("text", subs);
|
emit subtitlesChanged(QString(subs));
|
||||||
}
|
}
|
||||||
} else if (strcmp(prop->name, "demuxer-cache-duration") == 0) {
|
} else if (strcmp(prop->name, "demuxer-cache-duration") == 0) {
|
||||||
if (prop->format == MPV_FORMAT_DOUBLE) {
|
if (prop->format == MPV_FORMAT_DOUBLE) {
|
||||||
double duration = *(double*)prop->data;
|
double duration = *(double*)prop->data;
|
||||||
QMetaObject::invokeMethod(findChild<QObject*>("progressBar"), "setCachedDuration", Q_ARG(QVariant, duration));
|
emit cachedDurationChanged(duration);
|
||||||
}
|
}
|
||||||
} else if (strcmp(prop->name, "playlist-pos") == 0) {
|
} else if (strcmp(prop->name, "playlist-pos") == 0) {
|
||||||
if (prop->format == MPV_FORMAT_DOUBLE) {
|
if (prop->format == MPV_FORMAT_DOUBLE) {
|
||||||
double pos = *(double*)prop->data;
|
double pos = *(double*)prop->data;
|
||||||
updatePrev(QVariant(pos));
|
emit playlistPositionChanged(pos);
|
||||||
}
|
}
|
||||||
} else if (strcmp(prop->name, "pause") == 0) {
|
} else if (strcmp(prop->name, "pause") == 0) {
|
||||||
qDebug() << prop->data;
|
if (getProperty("pause").toBool()) {
|
||||||
updatePlayPause(getProperty("pause"));
|
emit playStatusChanged(Enums::PlayStatus::Paused);
|
||||||
#ifdef DISCORD
|
} else {
|
||||||
updateDiscord();
|
emit playStatusChanged(Enums::PlayStatus::Playing);
|
||||||
#endif
|
}
|
||||||
} else if (strcmp(prop->name, "tracks-menu") == 0) {
|
} else if (strcmp(prop->name, "tracks-menu") == 0) {
|
||||||
QMetaObject::invokeMethod(findChild<QObject*>("menuBar"), "updateTracks");
|
emit tracksChanged();
|
||||||
} else if (strcmp(prop->name, "audio-device-list") == 0) {
|
} else if (strcmp(prop->name, "audio-device-list") == 0) {
|
||||||
QMetaObject::invokeMethod(findChild<QObject*>("audioDeviceMenu"), "update");
|
emit audioDevicesChanged();
|
||||||
}
|
}
|
||||||
|
#ifdef DISCORD
|
||||||
|
updateDiscord();
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MPV_EVENT_SHUTDOWN: {
|
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()->setPersistentOpenGLContext(true);
|
||||||
window()->setPersistentSceneGraph(true);
|
window()->setPersistentSceneGraph(true);
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
#include <QOpenGLContext>
|
#include <QOpenGLContext>
|
||||||
#include <QQuickFramebufferObject>
|
#include <QQuickFramebufferObject>
|
||||||
|
|
||||||
|
#include "enums.hpp"
|
||||||
|
|
||||||
class MpvRenderer;
|
class MpvRenderer;
|
||||||
|
|
||||||
class MpvPlayerBackend : public QQuickFramebufferObject
|
class MpvPlayerBackend : public QQuickFramebufferObject
|
||||||
|
@ -41,13 +43,9 @@ public slots:
|
||||||
void nextPlaylistItem();
|
void nextPlaylistItem();
|
||||||
void toggleOnTop();
|
void toggleOnTop();
|
||||||
void toggleStats();
|
void toggleStats();
|
||||||
void updateDurationStringText();
|
|
||||||
QVariant getTracks() const;
|
QVariant getTracks() const;
|
||||||
QVariant getaudioDevices() const;
|
QVariant getaudioDevices() const;
|
||||||
void setAudioDevice(const QString& name);
|
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 addSpeed(const QVariant& speed);
|
||||||
void subtractSpeed(const QVariant& speed);
|
void subtractSpeed(const QVariant& speed);
|
||||||
void changeSpeed(const QVariant& speedFactor);
|
void changeSpeed(const QVariant& speedFactor);
|
||||||
|
@ -68,12 +66,24 @@ public slots:
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void onUpdate();
|
void onUpdate();
|
||||||
void positionChanged(int value);
|
|
||||||
void mpv_events();
|
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:
|
private slots:
|
||||||
void doUpdate();
|
void doUpdate();
|
||||||
void on_mpv_events();
|
void on_mpv_events();
|
||||||
|
void updateDurationString();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void handle_mpv_event(mpv_event* event);
|
void handle_mpv_event(mpv_event* event);
|
||||||
|
|
24
src/enums.hpp
Normal file
24
src/enums.hpp
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
#ifndef ENUMS_HPP
|
||||||
|
#define ENUMS_HPP
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QtGlobal>
|
||||||
|
|
||||||
|
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
|
13
src/main.cpp
13
src/main.cpp
|
@ -6,6 +6,7 @@
|
||||||
#include "utils.hpp"
|
#include "utils.hpp"
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
||||||
|
#include "enums.hpp"
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QProcessEnvironment>
|
#include <QProcessEnvironment>
|
||||||
#include <QQmlApplicationEngine>
|
#include <QQmlApplicationEngine>
|
||||||
|
@ -110,6 +111,18 @@ main(int argc, char* argv[])
|
||||||
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||||
QApplication::setAttribute(Qt::AA_NativeWindows);
|
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>("Enums.PlayStatus");
|
||||||
|
qRegisterMetaType<Enums::VolumeStatus>("Enums.VolumeStatus");
|
||||||
|
|
||||||
qmlRegisterType<MpvPlayerBackend>("player", 1, 0, "PlayerBackend");
|
qmlRegisterType<MpvPlayerBackend>("player", 1, 0, "PlayerBackend");
|
||||||
std::setlocale(LC_NUMERIC, "C");
|
std::setlocale(LC_NUMERIC, "C");
|
||||||
|
|
||||||
|
|
|
@ -69,6 +69,11 @@ Item {
|
||||||
width: subsContainer.childrenRect.width
|
width: subsContainer.childrenRect.width
|
||||||
height: subsContainer.childrenRect.height
|
height: subsContainer.childrenRect.height
|
||||||
}
|
}
|
||||||
|
Component.onCompleted: {
|
||||||
|
player.subtitlesChanged.connect(function(subtitles) {
|
||||||
|
text = subtitles
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -111,12 +116,18 @@ Item {
|
||||||
anchors.bottomMargin: 0
|
anchors.bottomMargin: 0
|
||||||
anchors.topMargin: progressBackground.height
|
anchors.topMargin: progressBackground.height
|
||||||
bottomPadding: 0
|
bottomPadding: 0
|
||||||
|
Component.onCompleted: {
|
||||||
function setCachedDuration(val) {
|
player.positionChanged.connect(function(position) {
|
||||||
cachedLength.width = ((progressBar.width / progressBar.to)
|
if (! pressed) {progressBar.value = position}
|
||||||
* val) - progressLength.width
|
})
|
||||||
|
player.durationChanged.connect(function(duration) {
|
||||||
|
progressBar.to = duration
|
||||||
|
})
|
||||||
|
player.cachedDurationChanged.connect(function(duration) {
|
||||||
|
cachedLength.width = ((progressBar.width / progressBar.to)
|
||||||
|
* duration) - progressLength.width
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
onMoved: {
|
onMoved: {
|
||||||
player.seekAbsolute(progressBar.value)
|
player.seekAbsolute(progressBar.value)
|
||||||
}
|
}
|
||||||
|
@ -208,7 +219,6 @@ Item {
|
||||||
Button {
|
Button {
|
||||||
id: playlistPrevButton
|
id: playlistPrevButton
|
||||||
objectName: "playlistPrevButton"
|
objectName: "playlistPrevButton"
|
||||||
//icon.name: "prev"
|
|
||||||
icon.source: "icons/prev.svg"
|
icon.source: "icons/prev.svg"
|
||||||
icon.color: "white"
|
icon.color: "white"
|
||||||
display: AbstractButton.IconOnly
|
display: AbstractButton.IconOnly
|
||||||
|
@ -222,14 +232,20 @@ Item {
|
||||||
background: Rectangle {
|
background: Rectangle {
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
}
|
}
|
||||||
|
Component.onCompleted: {
|
||||||
|
player.playlistPositionChanged.connect(function(position) {
|
||||||
|
if (position != 0 ) {
|
||||||
|
visible = true
|
||||||
|
} else {
|
||||||
|
visible = false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Button {
|
Button {
|
||||||
id: playPauseButton
|
id: playPauseButton
|
||||||
//icon.name: "pause"
|
icon.source: "icons/pause.svg"
|
||||||
objectName: "playPauseButton"
|
|
||||||
property string iconSource: "icons/pause.svg"
|
|
||||||
icon.source: iconSource
|
|
||||||
icon.color: "white"
|
icon.color: "white"
|
||||||
display: AbstractButton.IconOnly
|
display: AbstractButton.IconOnly
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
|
@ -241,6 +257,15 @@ Item {
|
||||||
background: Rectangle {
|
background: Rectangle {
|
||||||
color: "transparent"
|
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 {
|
Button {
|
||||||
|
@ -263,8 +288,7 @@ Item {
|
||||||
Button {
|
Button {
|
||||||
id: volumeButton
|
id: volumeButton
|
||||||
objectName: "volumeButton"
|
objectName: "volumeButton"
|
||||||
property string iconSource: "icons/volume-up.svg"
|
icon.source: "icons/volume-up.svg"
|
||||||
icon.source: iconSource
|
|
||||||
icon.color: "white"
|
icon.color: "white"
|
||||||
display: AbstractButton.IconOnly
|
display: AbstractButton.IconOnly
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
|
@ -272,11 +296,21 @@ Item {
|
||||||
anchors.left: playlistNextButton.right
|
anchors.left: playlistNextButton.right
|
||||||
onClicked: {
|
onClicked: {
|
||||||
player.toggleMute()
|
player.toggleMute()
|
||||||
player.updateVolume(player.getProperty("volume"))
|
|
||||||
}
|
}
|
||||||
background: Rectangle {
|
background: Rectangle {
|
||||||
color: "transparent"
|
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 {
|
Slider {
|
||||||
id: volumeBar
|
id: volumeBar
|
||||||
|
@ -299,7 +333,11 @@ Item {
|
||||||
onMoved: {
|
onMoved: {
|
||||||
player.setVolume(Math.round(volumeBar.value).toString())
|
player.setVolume(Math.round(volumeBar.value).toString())
|
||||||
}
|
}
|
||||||
|
Component.onCompleted: {
|
||||||
|
player.volumeChanged.connect(function(volume) {
|
||||||
|
volumeBar.value = volume
|
||||||
|
})
|
||||||
|
}
|
||||||
handle: Rectangle {
|
handle: Rectangle {
|
||||||
x: volumeBar.leftPadding + volumeBar.visualPosition
|
x: volumeBar.leftPadding + volumeBar.visualPosition
|
||||||
* (volumeBar.availableWidth - width)
|
* (volumeBar.availableWidth - width)
|
||||||
|
@ -340,6 +378,11 @@ Item {
|
||||||
font.pixelSize: 14
|
font.pixelSize: 14
|
||||||
verticalAlignment: Text.AlignVCenter
|
verticalAlignment: Text.AlignVCenter
|
||||||
renderType: Text.NativeRendering
|
renderType: Text.NativeRendering
|
||||||
|
Component.onCompleted: {
|
||||||
|
player.durationStringChanged.connect(function(durationString) {
|
||||||
|
text = durationString
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Button {
|
Button {
|
||||||
|
|
|
@ -20,7 +20,10 @@ MenuBar {
|
||||||
|| subsMenuBarItem.opened
|
|| subsMenuBarItem.opened
|
||||||
|| aboutMenuBarItem.opened
|
|| aboutMenuBarItem.opened
|
||||||
|
|
||||||
objectName: "menuBar"
|
Component.onCompleted: {
|
||||||
|
player.tracksChanged.connect(updateTracks)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function updateTracks() {
|
function updateTracks() {
|
||||||
for (var i = 0, len = audioMenu.count; i < len; i++) {
|
for (var i = 0, len = audioMenu.count; i < len; i++) {
|
||||||
|
@ -30,7 +33,7 @@ MenuBar {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (var i = 0, len = videoMenu.count; i < len; i++) {
|
for (var i = 0, len = videoMenu.count; i < len; i++) {
|
||||||
var videoAction = audioMenu.actionAt(i)
|
var videoAction = videoMenu.actionAt(i)
|
||||||
if (videoAction.trackID != "no") {
|
if (videoAction.trackID != "no") {
|
||||||
videoMenu.removeAction(videoAction)
|
videoMenu.removeAction(videoAction)
|
||||||
}
|
}
|
||||||
|
@ -340,7 +343,10 @@ MenuBar {
|
||||||
id: audioDeviceMenu
|
id: audioDeviceMenu
|
||||||
objectName: "audioDeviceMenu"
|
objectName: "audioDeviceMenu"
|
||||||
|
|
||||||
function update() {
|
Component.onCompleted: {
|
||||||
|
player.audioDevicesChanged.connect(updateAudioDevices)
|
||||||
|
}
|
||||||
|
function updateAudioDevices() {
|
||||||
var audioDevices = player.getaudioDevices()
|
var audioDevices = player.getaudioDevices()
|
||||||
|
|
||||||
for (var i = 0, len = audioDeviceMenu.count; i < len; i++) {
|
for (var i = 0, len = audioDeviceMenu.count; i < len; i++) {
|
||||||
|
|
|
@ -305,6 +305,11 @@ ApplicationWindow {
|
||||||
font.pixelSize: 14
|
font.pixelSize: 14
|
||||||
font.bold: true
|
font.bold: true
|
||||||
opacity: 1
|
opacity: 1
|
||||||
|
Component.onCompleted: {
|
||||||
|
player.titleChanged.connect(function(title) {
|
||||||
|
text = title
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,8 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
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;
|
/* Core implementation for both setenv() and unsetenv() functions;
|
||||||
* at the outset, assume that the requested operation may fail.
|
* at the outset, assume that the requested operation may fail.
|
||||||
|
|
|
@ -4,9 +4,11 @@
|
||||||
#include <QGuiApplication>
|
#include <QGuiApplication>
|
||||||
#include <QtCore>
|
#include <QtCore>
|
||||||
|
|
||||||
QString getPlatformName()
|
QString
|
||||||
|
getPlatformName()
|
||||||
{
|
{
|
||||||
QGuiApplication* qapp = qobject_cast<QGuiApplication*>(QCoreApplication::instance());
|
QGuiApplication* qapp =
|
||||||
|
qobject_cast<QGuiApplication*>(QCoreApplication::instance());
|
||||||
return qapp->platformName();
|
return qapp->platformName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,7 +20,8 @@ QString getPlatformName()
|
||||||
#include <X11/extensions/dpms.h>
|
#include <X11/extensions/dpms.h>
|
||||||
#include <X11/keysym.h>
|
#include <X11/keysym.h>
|
||||||
|
|
||||||
void SetDPMS(bool on)
|
void
|
||||||
|
SetDPMS(bool on)
|
||||||
{
|
{
|
||||||
qDebug() << getPlatformName();
|
qDebug() << getPlatformName();
|
||||||
if (getPlatformName() != "xcb") {
|
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;
|
qDebug() << "On Top:" << on;
|
||||||
Display* display = QX11Info::display();
|
Display* display = QX11Info::display();
|
||||||
|
@ -53,17 +57,23 @@ void AlwaysOnTop(WId wid, bool on)
|
||||||
event.xclient.data.l[3] = 0;
|
event.xclient.data.l[3] = 0;
|
||||||
event.xclient.data.l[4] = 0;
|
event.xclient.data.l[4] = 0;
|
||||||
|
|
||||||
XSendEvent(display, DefaultRootWindow(display), False, SubstructureRedirectMask | SubstructureNotifyMask, &event);
|
XSendEvent(display,
|
||||||
|
DefaultRootWindow(display),
|
||||||
|
False,
|
||||||
|
SubstructureRedirectMask | SubstructureNotifyMask,
|
||||||
|
&event);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
void AlwaysOnTop(WId wid, bool on)
|
void
|
||||||
|
AlwaysOnTop(WId wid, bool on)
|
||||||
{
|
{
|
||||||
qDebug() << "Can't set on top for platform: " << getPlatformName();
|
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();
|
qDebug() << "Can't set DPMS for platform: " << getPlatformName();
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,9 @@
|
||||||
#include <QWindow>
|
#include <QWindow>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
void SetDPMS(bool on);
|
void
|
||||||
void AlwaysOnTop(WId wid, bool on);
|
SetDPMS(bool on);
|
||||||
|
void
|
||||||
|
AlwaysOnTop(WId wid, bool on);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue