From f5581ab89581305a2035893bfb1be0b4e463e61e Mon Sep 17 00:00:00 2001 From: NamedKitten Date: Mon, 3 Dec 2018 08:17:57 +0000 Subject: [PATCH] [Backend+UI] Made alot of appearance changes and added RoosterTeeth theme. --- src/DirectMpvPlayerBackend.cpp | 9 +- src/DirectMpvPlayerBackend.h | 3 + src/MpvPlayerBackend.cpp | 65 +++++++----- src/MpvPlayerBackend.h | 5 +- src/backendinterface.hpp | 1 + src/main.cpp | 2 +- src/qml/ControlsBar.qml | 7 +- src/qml/Items/AudioDeviceItem.qml | 2 +- src/qml/MainMenu.qml | 15 ++- src/qml/NiconicoButtonLayout.qml | 1 + src/qml/RoosterTeethButtonLayout.qml | 111 ++++++++++++++++++++ src/qml/UIComponents/BackwardButton.qml | 7 +- src/qml/UIComponents/ForwardButton.qml | 6 +- src/qml/UIComponents/FullscreenButton.qml | 6 +- src/qml/UIComponents/PlayPauseButton.qml | 6 +- src/qml/UIComponents/PlaylistNextButton.qml | 6 +- src/qml/UIComponents/PlaylistPrevButton.qml | 6 +- src/qml/UIComponents/SettingsButton.qml | 10 +- src/qml/UIComponents/SpeedText.qml | 38 +++++++ src/qml/UIComponents/VerticalVolume.qml | 78 ++++++++++++++ src/qml/UIComponents/VideoProgress.qml | 6 +- src/qml/UIComponents/VolumeButton.qml | 6 +- src/qml/icons/RoosterTeeth/backward.svg | 1 + src/qml/icons/RoosterTeeth/forward.svg | 1 + src/qml/icons/RoosterTeeth/fullscreen.svg | 1 + src/qml/icons/RoosterTeeth/next.svg | 1 + src/qml/icons/RoosterTeeth/pause.svg | 1 + src/qml/icons/RoosterTeeth/play.svg | 1 + src/qml/icons/RoosterTeeth/playlist.svg | 1 + src/qml/icons/RoosterTeeth/prev.svg | 1 + src/qml/icons/RoosterTeeth/settings.svg | 1 + src/qml/icons/RoosterTeeth/subtitles.svg | 1 + src/qml/icons/RoosterTeeth/volume-down.svg | 1 + src/qml/icons/RoosterTeeth/volume-mute.svg | 1 + src/qml/icons/RoosterTeeth/volume-up.svg | 1 + src/qml/main.qml | 17 +++ src/qml/qml.qrc | 18 ++++ 37 files changed, 390 insertions(+), 54 deletions(-) create mode 100644 src/qml/RoosterTeethButtonLayout.qml create mode 100644 src/qml/UIComponents/SpeedText.qml create mode 100644 src/qml/UIComponents/VerticalVolume.qml create mode 100644 src/qml/icons/RoosterTeeth/backward.svg create mode 100644 src/qml/icons/RoosterTeeth/forward.svg create mode 100644 src/qml/icons/RoosterTeeth/fullscreen.svg create mode 100644 src/qml/icons/RoosterTeeth/next.svg create mode 100644 src/qml/icons/RoosterTeeth/pause.svg create mode 100755 src/qml/icons/RoosterTeeth/play.svg create mode 100644 src/qml/icons/RoosterTeeth/playlist.svg create mode 100644 src/qml/icons/RoosterTeeth/prev.svg create mode 100644 src/qml/icons/RoosterTeeth/settings.svg create mode 100644 src/qml/icons/RoosterTeeth/subtitles.svg create mode 100644 src/qml/icons/RoosterTeeth/volume-down.svg create mode 100644 src/qml/icons/RoosterTeeth/volume-mute.svg create mode 100644 src/qml/icons/RoosterTeeth/volume-up.svg diff --git a/src/DirectMpvPlayerBackend.cpp b/src/DirectMpvPlayerBackend.cpp index 7622a43..d0bf002 100644 --- a/src/DirectMpvPlayerBackend.cpp +++ b/src/DirectMpvPlayerBackend.cpp @@ -111,6 +111,7 @@ DirectMpvPlayerBackend::DirectMpvPlayerBackend(QQuickItem* parent) mpv_observe_property(mpv, 0, "demuxer-cache-duration", MPV_FORMAT_DOUBLE); mpv_observe_property(mpv, 0, "pause", MPV_FORMAT_NODE); mpv_observe_property(mpv, 0, "playlist", MPV_FORMAT_NODE); + mpv_observe_property(mpv, 0, "speed", MPV_FORMAT_DOUBLE); mpv_set_wakeup_callback(mpv, wakeup, this); if (mpv_initialize(mpv) < 0) @@ -494,7 +495,10 @@ DirectMpvPlayerBackend::updateDurationString(int numTime) durationString += " / "; durationString += totalDurationString; if (lastSpeed != 1) { - durationString += " (" + speed.toString() + "x)"; + if (settings.value("Appearance/themeName", "").toString() != + "RoosterTeeth") { + durationString += " (" + speed.toString() + "x)"; + } } emit durationStringChanged(durationString); } @@ -598,6 +602,9 @@ DirectMpvPlayerBackend::handle_mpv_event(mpv_event* event) } else if (strcmp(prop->name, "chapter-list") == 0) { mpv_node* nod = (mpv_node*)prop->data; emit chaptersChanged(mpv::qt::node_to_variant(nod).toList()); + } else if (strcmp(prop->name, "speed") == 0) { + double speed = *(double*)prop->data; + emit speedChanged(speed); } #ifdef DISCORD updateDiscord(); diff --git a/src/DirectMpvPlayerBackend.h b/src/DirectMpvPlayerBackend.h index 889ff26..b04b74e 100644 --- a/src/DirectMpvPlayerBackend.h +++ b/src/DirectMpvPlayerBackend.h @@ -8,6 +8,7 @@ #include #include #include +#include #include #include "backendinterface.hpp" @@ -46,6 +47,7 @@ class DirectMpvPlayerBackend double lastSpeed = 0; QString totalDurationString; QString lastPositionString; + QSettings settings; public: static void on_update(void* ctx); @@ -91,6 +93,7 @@ signals: void audioDevicesChanged(const QVariantMap& devices); void playlistChanged(const QVariantList& devices); void chaptersChanged(const QVariantList& devices); + void speedChanged(const double& speed); private slots: void doUpdate(); diff --git a/src/MpvPlayerBackend.cpp b/src/MpvPlayerBackend.cpp index 4259583..d8294e8 100644 --- a/src/MpvPlayerBackend.cpp +++ b/src/MpvPlayerBackend.cpp @@ -1,10 +1,11 @@ +#include "MpvPlayerBackend.h" #include #include #include -#include "MpvPlayerBackend.h" #include "utils.hpp" #include +#include #include #include #include @@ -17,9 +18,9 @@ #ifdef __linux__ #include +#include #include #include -#include #include #endif @@ -34,7 +35,8 @@ wakeup(void* ctx) void on_mpv_redraw(void* ctx) { - QMetaObject::invokeMethod(reinterpret_cast(ctx), "update"); + QMetaObject::invokeMethod( + reinterpret_cast(ctx), "update", Qt::QueuedConnection); } static void* @@ -79,18 +81,19 @@ public: { MPV_RENDER_PARAM_INVALID, nullptr } }; #if __linux__ - if (QGuiApplication::platformName().contains("xcb")) { + if (QGuiApplication::platformName().contains("xcb")) { params[2].type = MPV_RENDER_PARAM_X11_DISPLAY; params[2].data = QX11Info::display(); qDebug() << "On Xorg."; - } else if (QGuiApplication::platformName().contains("wayland")) { - QPlatformNativeInterface *native = QGuiApplication::platformNativeInterface(); + } else if (QGuiApplication::platformName().contains("wayland")) { + QPlatformNativeInterface* native = + QGuiApplication::platformNativeInterface(); params[2].type = MPV_RENDER_PARAM_WL_DISPLAY; params[2].data = native->nativeResourceForWindow("display", nullptr); qDebug() << "On wayland."; - } + } #endif - + 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); @@ -118,7 +121,6 @@ public: { MPV_RENDER_PARAM_INVALID, nullptr } }; - // See render_gl.h on what OpenGL environment mpv expects, and // other API details. mpv_render_context_render(obj->mpv_gl, params); @@ -157,7 +159,7 @@ MpvPlayerBackend::MpvPlayerBackend(QQuickItem* parent) mpv_observe_property(mpv, 0, "playback-abort", MPV_FORMAT_NONE); mpv_observe_property(mpv, 0, "chapter-list", MPV_FORMAT_NODE); mpv_observe_property(mpv, 0, "track-list", MPV_FORMAT_NODE); - mpv_observe_property(mpv, 0, "audio-device-list", MPV_FORMAT_NONE); + 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_NONE); mpv_observe_property(mpv, 0, "mute", MPV_FORMAT_NONE); @@ -168,6 +170,7 @@ MpvPlayerBackend::MpvPlayerBackend(QQuickItem* parent) mpv_observe_property(mpv, 0, "demuxer-cache-duration", MPV_FORMAT_DOUBLE); mpv_observe_property(mpv, 0, "pause", MPV_FORMAT_NODE); mpv_observe_property(mpv, 0, "playlist", MPV_FORMAT_NODE); + mpv_observe_property(mpv, 0, "speed", MPV_FORMAT_DOUBLE); mpv_set_wakeup_callback(mpv, wakeup, this); if (mpv_initialize(mpv) < 0) @@ -180,10 +183,14 @@ MpvPlayerBackend::MpvPlayerBackend(QQuickItem* parent) Qt::QueuedConnection); connect(this, &MpvPlayerBackend::positionChanged, - &MpvPlayerBackend::updateDurationString); + this, + &MpvPlayerBackend::updateDurationString, + Qt::QueuedConnection); connect(this, &MpvPlayerBackend::durationChanged, - &MpvPlayerBackend::updateDurationString); + this, + &MpvPlayerBackend::updateDurationString, + Qt::QueuedConnection); } MpvPlayerBackend::~MpvPlayerBackend() @@ -218,13 +225,16 @@ MpvPlayerBackend::getProperty(const QString& name) const void MpvPlayerBackend::command(const QVariant& params) { - mpv::qt::command_variant(mpv, params); + mpv::qt::node_builder node(params); + mpv_command_node(mpv, node.node(), nullptr); } void MpvPlayerBackend::setProperty(const QString& name, const QVariant& value) { - mpv::qt::set_property_variant(mpv, name, value); + mpv::qt::node_builder node(value); + qDebug() << "Setting property" << name << "to" << value; + mpv_set_property(mpv, name.toUtf8().data(), MPV_FORMAT_NODE, node.node()); } void @@ -478,7 +488,10 @@ MpvPlayerBackend::updateDurationString(int numTime) durationString += " / "; durationString += totalDurationString; if (lastSpeed != 1) { - durationString += " (" + speed.toString() + "x)"; + if (settings.value("Appearance/themeName", "").toString() != + "RoosterTeeth") { + durationString += " (" + speed.toString() + "x)"; + } } emit durationStringChanged(durationString); } @@ -490,24 +503,15 @@ MpvPlayerBackend::updateAppImage() } QVariantMap -MpvPlayerBackend::getAudioDevices() const +MpvPlayerBackend::getAudioDevices(const QVariant& drivers) const { - QVariant drivers = getProperty("audio-device-list"); - QVariant currentDevice = getProperty("audio-device"); - QVariantMap newDrivers; QSequentialIterable iterable = drivers.value(); foreach (const QVariant& v, iterable) { QVariantMap item = v.toMap(); - item["selected"] = currentDevice == item["name"]; newDrivers[item["description"].toString()] = item; } - QMap pulseItem; - pulseItem["name"] = "pulse"; - pulseItem["description"] = "Default (pulseaudio)"; - pulseItem["selected"] = currentDevice == "pulse"; - newDrivers[pulseItem["description"].toString()] = pulseItem; return newDrivers; } @@ -566,22 +570,27 @@ MpvPlayerBackend::handle_mpv_event(mpv_event* event) mpv_node* nod = (mpv_node*)prop->data; if (mpv::qt::node_to_variant(nod).toBool()) { emit playStatusChanged(Enums::PlayStatus::Paused); - Utils::SetScreensaver(window()->winId(), true); + // Utils::SetScreensaver(window()->winId(), true); } else { emit playStatusChanged(Enums::PlayStatus::Playing); - Utils::SetScreensaver(window()->winId(), false); + // Utils::SetScreensaver(window()->winId(), false); } } else if (strcmp(prop->name, "track-list") == 0) { mpv_node* nod = (mpv_node*)prop->data; emit tracksChanged(mpv::qt::node_to_variant(nod).toList()); } else if (strcmp(prop->name, "audio-device-list") == 0) { - emit audioDevicesChanged(getAudioDevices()); + mpv_node* nod = (mpv_node*)prop->data; + emit audioDevicesChanged( + getAudioDevices(mpv::qt::node_to_variant(nod))); } else if (strcmp(prop->name, "playlist") == 0) { mpv_node* nod = (mpv_node*)prop->data; emit playlistChanged(mpv::qt::node_to_variant(nod).toList()); } else if (strcmp(prop->name, "chapter-list") == 0) { mpv_node* nod = (mpv_node*)prop->data; emit chaptersChanged(mpv::qt::node_to_variant(nod).toList()); + } else if (strcmp(prop->name, "speed") == 0) { + double speed = *(double*)prop->data; + emit speedChanged(speed); } #ifdef DISCORD updateDiscord(); diff --git a/src/MpvPlayerBackend.h b/src/MpvPlayerBackend.h index a1501b0..d676150 100644 --- a/src/MpvPlayerBackend.h +++ b/src/MpvPlayerBackend.h @@ -9,6 +9,7 @@ #include #include #include +#include #include "backendinterface.hpp" #include "enums.hpp" @@ -26,6 +27,7 @@ class MpvPlayerBackend mpv_handle* mpv; mpv_render_context* mpv_gl; + QSettings settings; bool onTop = false; int lastTime = 0; double lastSpeed = 0; @@ -53,7 +55,7 @@ public slots: void setOption(const QString& name, const QVariant& value); QVariant getProperty(const QString& name) const; // Just used for adding missing audio devices to list. - QVariantMap getAudioDevices() const; + QVariantMap getAudioDevices(const QVariant& drivers) const; bool event(QEvent* event); signals: @@ -76,6 +78,7 @@ signals: void audioDevicesChanged(const QVariantMap& devices); void playlistChanged(const QVariantList& devices); void chaptersChanged(const QVariantList& devices); + void speedChanged(const double& speed); private slots: void doUpdate(); diff --git a/src/backendinterface.hpp b/src/backendinterface.hpp index 96fb014..1db4bf4 100644 --- a/src/backendinterface.hpp +++ b/src/backendinterface.hpp @@ -42,6 +42,7 @@ signals: virtual void audioDevicesChanged(const QVariantMap& devices) = 0; virtual void playlistChanged(const QVariantList& devices) = 0; virtual void chaptersChanged(const QVariantList& devices) = 0; + virtual void speedChanged(const double& speed) = 0; }; Q_DECLARE_INTERFACE(BackendInterface, "NamedKitten.BackendInterface"); diff --git a/src/main.cpp b/src/main.cpp index fa8eb71..400b6be 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -102,7 +102,7 @@ main(int argc, char* argv[]) app.setOrganizationName("KittehPlayer"); app.setOrganizationDomain("namedkitten.pw"); app.setApplicationName("KittehPlayer"); - + QSettings settings; QString backendSetting = settings.value("Backend/backend", "").toString(); if (backendSetting.length() == 0) { diff --git a/src/qml/ControlsBar.qml b/src/qml/ControlsBar.qml index 8af4df6..cd50b1e 100644 --- a/src/qml/ControlsBar.qml +++ b/src/qml/ControlsBar.qml @@ -30,6 +30,9 @@ Item { } var component = Qt.createComponent(themeName + "ButtonLayout.qml") + if (component.status == Component.Error) { + console.log("Error loading component:", component.errorString()) + } component.createObject(controlsBar, { }) @@ -100,8 +103,7 @@ Item { Rectangle { id: controlsBackground - height: controlsBar.visible ? controlsBar.height + progressBar.topPadding - + (fun.nyanCat ? 0 : 1) : 0 + height: controlsBar.visible ? controlsBar.height + (appearance.themeName == "RoosterTeeth" ? 0 : progressBar.topPadding + (fun.nyanCat ? 0 : 1)) : 0 anchors.bottom: parent.bottom anchors.left: parent.left anchors.right: parent.right @@ -124,6 +126,7 @@ Item { visible: controlsOverlay.controlsShowing VideoProgress { id: progressBar + visible: appearance.themeName == "RoosterTeeth" ? false : true anchors.bottom: parent.top anchors.left: parent.left anchors.right: parent.right diff --git a/src/qml/Items/AudioDeviceItem.qml b/src/qml/Items/AudioDeviceItem.qml index 3bb4076..cff6a93 100644 --- a/src/qml/Items/AudioDeviceItem.qml +++ b/src/qml/Items/AudioDeviceItem.qml @@ -6,7 +6,7 @@ import player 1.0 Action { id: audioDeviceItem property string deviceID: "none" - checkable: true + checkable: false checked: false onTriggered: { diff --git a/src/qml/MainMenu.qml b/src/qml/MainMenu.qml index 5227c94..992380a 100644 --- a/src/qml/MainMenu.qml +++ b/src/qml/MainMenu.qml @@ -47,7 +47,8 @@ MenuBar { var trackType = track["type"] var trackLang = LanguageCodes.localeCodeToEnglish( String(track["lang"])) - var trackTitle = track["title"] + trackLang = trackLang == undefined ? "" : trackLang + var trackTitle = track["title"] == undefined ? "" : track["title"] + " " var component = Qt.createComponent("TrackItem.qml") if (trackType == "sub") { var action = component.createObject(subMenu, { @@ -61,7 +62,7 @@ MenuBar { subMenu.addAction(action) } else if (trackType == "audio") { var action = component.createObject(audioMenu, { - text: (trackTitle == undefined ? "" : trackTitle + " ") + (trackLang == "undefined" ? "" : trackLang), + text: trackTitle + trackLang, trackID: String( trackID), trackType: "aid", @@ -71,7 +72,7 @@ MenuBar { audioMenu.addAction(action) } else if (trackType == "video") { var action = component.createObject(videoMenu, { - text: "Video " + trackID, + text: "Video " + trackID + trackTitle, trackID: String( trackID), trackType: "vid", @@ -358,15 +359,11 @@ MenuBar { } for (var thing in audioDevices) { var audioDevice = audioDevices[thing] - var name = audioDevice["name"] - var description = audioDevice["description"] - var selected = audioDevice["selected"] var component = Qt.createComponent("AudioDeviceItem.qml") var action = component.createObject(audioDeviceMenu, { - text: description, + text: audioDevices[thing]["description"], deviceID: String( - name), - checked: audioDevice["selected"] + audioDevices[thing]["name"]) }) action.ActionGroup.group = audioDeviceMenuGroup audioDeviceMenu.addAction(action) diff --git a/src/qml/NiconicoButtonLayout.qml b/src/qml/NiconicoButtonLayout.qml index 3aeba28..3784f7f 100644 --- a/src/qml/NiconicoButtonLayout.qml +++ b/src/qml/NiconicoButtonLayout.qml @@ -14,6 +14,7 @@ Item { PlayPauseButton { id: playPauseButton + anchors.left: owo.right anchors.top: parent.top anchors.bottom: parent.bottom icon.height: parent.height / 2 diff --git a/src/qml/RoosterTeethButtonLayout.qml b/src/qml/RoosterTeethButtonLayout.qml new file mode 100644 index 0000000..85c5dc8 --- /dev/null +++ b/src/qml/RoosterTeethButtonLayout.qml @@ -0,0 +1,111 @@ +import QtQuick 2.11 +import QtQuick.Controls 2.4 +import QtQuick.Dialogs 1.3 +import QtQuick.Layouts 1.11 +import QtQuick.Window 2.11 +import Qt.labs.settings 1.0 +import Qt.labs.platform 1.0 as LabsPlatform +import player 1.0 + +Item { + objectName: "buttonLayout" + id: layout + anchors.fill: controlsBar + + PlayPauseButton { + id: playPauseButton + anchors.top: parent.top + anchors.bottom: parent.bottom + icon.height: parent.height / 2 + icon.width: parent.height / 2 + } + + MouseArea { + id: mouseAreaVolumeArea + anchors.bottom: volumeButton.bottom + anchors.left: volumeSliderArea.left + anchors.right: volumeSliderArea.right + anchors.top: volumeSliderArea.top + height: layout.height + volumeButton.height + + (volumeSliderArea.visible ? volumeSliderArea.height : 0) + hoverEnabled: true + propagateComposedEvents: true + acceptedButtons: Qt.NoButton + + onEntered: { + volumeSliderArea.visible = true + mouseAreaPlayerTimer.stop() + } + + onExited: { + volumeSliderArea.visible = false + mouseAreaPlayerTimer.restart() + } + } + + VolumeButton { + id: volumeButton + anchors.left: playPauseButton.right + anchors.top: parent.top + anchors.bottom: parent.bottom + icon.height: parent.height / 2 + icon.width: parent.height / 2 + icon.color: hovered + || mouseAreaVolumeArea.containsMouse ? getAppearanceValueForTheme( + appearance.themeName, + "buttonHoverColor") : getAppearanceValueForTheme( + appearance.themeName, + "buttonColor") + } + + VerticalVolume { + id: volumeSliderArea + anchors.bottom: volumeButton.top + anchors.left: volumeButton.left + anchors.right: volumeButton.right + width: volumeButton.width + visible: mouseAreaVolumeArea.containsMouse || volumeButton.hovered + } + + TimeLabel { + id: timeLabel + anchors.left: volumeButton.right + anchors.top: parent.top + anchors.bottom: parent.bottom + } + + VideoProgress { + id: videoProgressRoosterTeeth + anchors.left: timeLabel.right + anchors.right: speedText.left + anchors.top: parent.top + anchors.bottom: parent.bottom + height: parent.height + to: progressBar.to + value: progressBar.value + } + + SpeedText { + id: speedText + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.right: fullscreenButton.left + } + + FullscreenButton { + id: fullscreenButton + anchors.right: settingsButton.left + anchors.top: parent.top + anchors.bottom: parent.bottom + icon.height: parent.height / 2 + icon.width: parent.height / 2 + } + SettingsButton { + id: settingsButton + anchors.right: parent.right + anchors.top: parent.top + anchors.bottom: parent.bottom + icon.height: parent.height / 2 + icon.width: parent.height / 2 + } +} diff --git a/src/qml/UIComponents/BackwardButton.qml b/src/qml/UIComponents/BackwardButton.qml index d37638b..9886112 100644 --- a/src/qml/UIComponents/BackwardButton.qml +++ b/src/qml/UIComponents/BackwardButton.qml @@ -10,7 +10,12 @@ import player 1.0 Button { id: backwardButton icon.source: "icons/" + appearance.themeName + "/backward.svg" - icon.color: getAppearanceValueForTheme(appearance.themeName, "buttonColor") + + hoverEnabled: true + icon.color: hovered ? getAppearanceValueForTheme( + appearance.themeName, + "buttonHoverColor") : getAppearanceValueForTheme( + appearance.themeName, "buttonColor") display: AbstractButton.IconOnly onClicked: { player.playerCommand(Enums.Commands.Seek, "-10") diff --git a/src/qml/UIComponents/ForwardButton.qml b/src/qml/UIComponents/ForwardButton.qml index f3e3071..78daf51 100644 --- a/src/qml/UIComponents/ForwardButton.qml +++ b/src/qml/UIComponents/ForwardButton.qml @@ -10,7 +10,11 @@ import player 1.0 Button { id: forwardButton icon.source: "icons/" + appearance.themeName + "/forward.svg" - icon.color: getAppearanceValueForTheme(appearance.themeName, "buttonColor") + hoverEnabled: true + icon.color: hovered ? getAppearanceValueForTheme( + appearance.themeName, + "buttonHoverColor") : getAppearanceValueForTheme( + appearance.themeName, "buttonColor") display: AbstractButton.IconOnly onClicked: { player.playerCommand(Enums.Commands.Seek, "10") diff --git a/src/qml/UIComponents/FullscreenButton.qml b/src/qml/UIComponents/FullscreenButton.qml index 7f25dac..2d838bd 100644 --- a/src/qml/UIComponents/FullscreenButton.qml +++ b/src/qml/UIComponents/FullscreenButton.qml @@ -10,7 +10,11 @@ import player 1.0 Button { id: fullscreenButton icon.source: "icons/" + appearance.themeName + "/fullscreen.svg" - icon.color: getAppearanceValueForTheme(appearance.themeName, "buttonColor") + hoverEnabled: true + icon.color: hovered ? getAppearanceValueForTheme( + appearance.themeName, + "buttonHoverColor") : getAppearanceValueForTheme( + appearance.themeName, "buttonColor") Layout.alignment: Qt.AlignVCenter | Qt.AlignRight display: AbstractButton.IconOnly diff --git a/src/qml/UIComponents/PlayPauseButton.qml b/src/qml/UIComponents/PlayPauseButton.qml index 2c06378..c092694 100644 --- a/src/qml/UIComponents/PlayPauseButton.qml +++ b/src/qml/UIComponents/PlayPauseButton.qml @@ -10,7 +10,11 @@ import player 1.0 Button { id: playPauseButton icon.source: "icons/" + appearance.themeName + "/pause.svg" - icon.color: getAppearanceValueForTheme(appearance.themeName, "buttonColor") + hoverEnabled: true + icon.color: hovered ? getAppearanceValueForTheme( + appearance.themeName, + "buttonHoverColor") : getAppearanceValueForTheme( + appearance.themeName, "buttonColor") display: AbstractButton.IconOnly onClicked: { player.playerCommand(Enums.Commands.TogglePlayPause) diff --git a/src/qml/UIComponents/PlaylistNextButton.qml b/src/qml/UIComponents/PlaylistNextButton.qml index 860b252..809218b 100644 --- a/src/qml/UIComponents/PlaylistNextButton.qml +++ b/src/qml/UIComponents/PlaylistNextButton.qml @@ -11,7 +11,11 @@ Button { id: playlistNextButton //icon.name: "next" icon.source: "icons/" + appearance.themeName + "/next.svg" - icon.color: getAppearanceValueForTheme(appearance.themeName, "buttonColor") + hoverEnabled: true + icon.color: hovered ? getAppearanceValueForTheme( + appearance.themeName, + "buttonHoverColor") : getAppearanceValueForTheme( + appearance.themeName, "buttonColor") display: AbstractButton.IconOnly onClicked: { player.playerCommand(Enums.Commands.NextPlaylistItem) diff --git a/src/qml/UIComponents/PlaylistPrevButton.qml b/src/qml/UIComponents/PlaylistPrevButton.qml index 820284e..3d5e4e5 100644 --- a/src/qml/UIComponents/PlaylistPrevButton.qml +++ b/src/qml/UIComponents/PlaylistPrevButton.qml @@ -11,7 +11,11 @@ Button { id: playlistPrevButton objectName: "playlistPrevButton" icon.source: "icons/" + appearance.themeName + "/prev.svg" - icon.color: getAppearanceValueForTheme(appearance.themeName, "buttonColor") + hoverEnabled: true + icon.color: hovered ? getAppearanceValueForTheme( + appearance.themeName, + "buttonHoverColor") : getAppearanceValueForTheme( + appearance.themeName, "buttonColor") display: AbstractButton.IconOnly visible: appearance.themeName == "Youtube" ? false : true onClicked: { diff --git a/src/qml/UIComponents/SettingsButton.qml b/src/qml/UIComponents/SettingsButton.qml index 6e0664b..ec3fc01 100644 --- a/src/qml/UIComponents/SettingsButton.qml +++ b/src/qml/UIComponents/SettingsButton.qml @@ -11,11 +11,17 @@ Button { id: settingsButton //icon.name: "settings" icon.source: "icons/" + appearance.themeName + "/settings.svg" - icon.color: getAppearanceValueForTheme(appearance.themeName, "buttonColor") + hoverEnabled: true + icon.color: hovered ? getAppearanceValueForTheme( + appearance.themeName, + "buttonHoverColor") : getAppearanceValueForTheme( + appearance.themeName, "buttonColor") Layout.alignment: Qt.AlignVCenter | Qt.AlignRight display: AbstractButton.IconOnly onClicked: { - appearance.themeName = appearance.themeName == "YouTube" ? "Niconico" : "YouTube" + var aptn = appearance.themeName + appearance.themeName = aptn == "YouTube" ? "RoosterTeeth" : aptn + == "RoosterTeeth" ? "Niconico" : "YouTube" controlsBarItem.setControlsTheme(appearance.themeName) console.log("Settings Menu Not Yet Implemented.") } diff --git a/src/qml/UIComponents/SpeedText.qml b/src/qml/UIComponents/SpeedText.qml new file mode 100644 index 0000000..b1e4bcd --- /dev/null +++ b/src/qml/UIComponents/SpeedText.qml @@ -0,0 +1,38 @@ +import QtQuick 2.11 +import QtQuick.Controls 2.4 +import QtQuick.Dialogs 1.3 +import QtQuick.Layouts 1.11 +import QtQuick.Window 2.11 +import Qt.labs.settings 1.0 +import Qt.labs.platform 1.0 as LabsPlatform +import player 1.0 + +Text { + id: speedText + leftPadding: 0 + rightPadding: 0 + text: "1x" + font.family: appearance.fontName + font.pixelSize: layout.height / 2.5 + color: speedStatusMouseArea.containsMouse ? getAppearanceValueForTheme( + appearance.themeName, + "buttonHoverColor") : getAppearanceValueForTheme( + appearance.themeName, + "buttonColor") + verticalAlignment: Text.AlignVCenter + Connections { + target: player + enabled: true + onSpeedChanged: function (speed) { + speedText.text = String(speed) + "x" + } + } + MouseArea { + id: speedStatusMouseArea + anchors.fill: parent + height: parent.height + hoverEnabled: true + propagateComposedEvents: false + acceptedButtons: Qt.NoButton + } +} diff --git a/src/qml/UIComponents/VerticalVolume.qml b/src/qml/UIComponents/VerticalVolume.qml new file mode 100644 index 0000000..b31c12e --- /dev/null +++ b/src/qml/UIComponents/VerticalVolume.qml @@ -0,0 +1,78 @@ +import QtQuick 2.11 +import QtQuick.Controls 2.4 +import QtQuick.Dialogs 1.3 +import QtQuick.Layouts 1.11 +import QtQuick.Window 2.11 +import Qt.labs.settings 1.0 +import Qt.labs.platform 1.0 as LabsPlatform +import player 1.0 + +Rectangle { + id: volumeSliderArea + height: 70 + color: getAppearanceValueForTheme(appearance.themeName, "mainBackground") + visible: false + Slider { + id: volumeSlider + anchors.fill: parent + to: 100 + value: 100 + + orientation: Qt.Vertical + + implicitWidth: Math.max(background ? background.implicitWidth : 0, + (handle ? handle.implicitWidth : 0) + + leftPadding + rightPadding) + implicitHeight: Math.max( + background.implicitHeight, + handle.implicitHeight + topPadding + bottomPadding) + + padding: 6 + + Connections { + target: player + enabled: true + onVolumeChanged: function (volume) { + volumeSlider.value = volume + } + } + + onMoved: { + player.playerCommand(Enums.Commands.SetVolume, + Math.round(volumeSlider.value).toString()) + } + + handle: Rectangle { + x: volumeSlider.leftPadding + ((volumeSlider.availableWidth - width) / 2) + y: volumeSlider.topPadding + (volumeSlider.visualPosition + * (volumeSlider.availableHeight - height)) + implicitWidth: 10 + implicitHeight: 10 + radius: width / 2 + color: "white" + border.width: 0 + } + + background: Rectangle { + x: volumeSlider.leftPadding + ((volumeSlider.availableWidth - width) / 2) + y: volumeSlider.topPadding + implicitWidth: 4 + implicitHeight: 70 + width: implicitWidth + height: volumeSlider.availableHeight + radius: 3 + color: getAppearanceValueForTheme(appearance.themeName, + "progressBackgroundColor") + + Rectangle { + y: volumeSlider.visualPosition * parent.height + width: 4 + height: volumeSlider.position * parent.height + + radius: 3 + color: getAppearanceValueForTheme(appearance.themeName, + "volumeSliderBackground") + } + } + } +} diff --git a/src/qml/UIComponents/VideoProgress.qml b/src/qml/UIComponents/VideoProgress.qml index 5d43d26..e9aded4 100644 --- a/src/qml/UIComponents/VideoProgress.qml +++ b/src/qml/UIComponents/VideoProgress.qml @@ -164,8 +164,10 @@ Slider { implicitHeight: radius implicitWidth: radius radius: 12 + (progressBackground.height / 2) - color: fun.nyanCat ? "transparent" : getAppearanceValueForTheme( - appearance.themeName, "progressSliderColor") + color: appearance.themeName + == "RoosterTeeth" ? "white" : fun.nyanCat ? "transparent" : getAppearanceValueForTheme( + appearance.themeName, + "progressSliderColor") visible: getHandleVisibility(appearance.themeName, mouseAreaProgressBar.containsMouse) AnimatedImage { diff --git a/src/qml/UIComponents/VolumeButton.qml b/src/qml/UIComponents/VolumeButton.qml index 69fa485..179c5b8 100644 --- a/src/qml/UIComponents/VolumeButton.qml +++ b/src/qml/UIComponents/VolumeButton.qml @@ -11,7 +11,11 @@ Button { id: volumeButton objectName: "volumeButton" icon.source: "icons/" + appearance.themeName + "/volume-up.svg" - icon.color: getAppearanceValueForTheme(appearance.themeName, "buttonColor") + hoverEnabled: true + icon.color: hovered ? getAppearanceValueForTheme( + appearance.themeName, + "buttonHoverColor") : getAppearanceValueForTheme( + appearance.themeName, "buttonColor") display: AbstractButton.IconOnly onClicked: { player.playerCommand(Enums.Commands.ToggleMute) diff --git a/src/qml/icons/RoosterTeeth/backward.svg b/src/qml/icons/RoosterTeeth/backward.svg new file mode 100644 index 0000000..633505a --- /dev/null +++ b/src/qml/icons/RoosterTeeth/backward.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/qml/icons/RoosterTeeth/forward.svg b/src/qml/icons/RoosterTeeth/forward.svg new file mode 100644 index 0000000..3b31b1b --- /dev/null +++ b/src/qml/icons/RoosterTeeth/forward.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/qml/icons/RoosterTeeth/fullscreen.svg b/src/qml/icons/RoosterTeeth/fullscreen.svg new file mode 100644 index 0000000..1b18f46 --- /dev/null +++ b/src/qml/icons/RoosterTeeth/fullscreen.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/qml/icons/RoosterTeeth/next.svg b/src/qml/icons/RoosterTeeth/next.svg new file mode 100644 index 0000000..091d846 --- /dev/null +++ b/src/qml/icons/RoosterTeeth/next.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/qml/icons/RoosterTeeth/pause.svg b/src/qml/icons/RoosterTeeth/pause.svg new file mode 100644 index 0000000..f251bc1 --- /dev/null +++ b/src/qml/icons/RoosterTeeth/pause.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/qml/icons/RoosterTeeth/play.svg b/src/qml/icons/RoosterTeeth/play.svg new file mode 100755 index 0000000..98cc016 --- /dev/null +++ b/src/qml/icons/RoosterTeeth/play.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/qml/icons/RoosterTeeth/playlist.svg b/src/qml/icons/RoosterTeeth/playlist.svg new file mode 100644 index 0000000..58726ee --- /dev/null +++ b/src/qml/icons/RoosterTeeth/playlist.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/qml/icons/RoosterTeeth/prev.svg b/src/qml/icons/RoosterTeeth/prev.svg new file mode 100644 index 0000000..7281c18 --- /dev/null +++ b/src/qml/icons/RoosterTeeth/prev.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/qml/icons/RoosterTeeth/settings.svg b/src/qml/icons/RoosterTeeth/settings.svg new file mode 100644 index 0000000..050d257 --- /dev/null +++ b/src/qml/icons/RoosterTeeth/settings.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/qml/icons/RoosterTeeth/subtitles.svg b/src/qml/icons/RoosterTeeth/subtitles.svg new file mode 100644 index 0000000..2377483 --- /dev/null +++ b/src/qml/icons/RoosterTeeth/subtitles.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/qml/icons/RoosterTeeth/volume-down.svg b/src/qml/icons/RoosterTeeth/volume-down.svg new file mode 100644 index 0000000..ba28a46 --- /dev/null +++ b/src/qml/icons/RoosterTeeth/volume-down.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/qml/icons/RoosterTeeth/volume-mute.svg b/src/qml/icons/RoosterTeeth/volume-mute.svg new file mode 100644 index 0000000..f0e2bbc --- /dev/null +++ b/src/qml/icons/RoosterTeeth/volume-mute.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/qml/icons/RoosterTeeth/volume-up.svg b/src/qml/icons/RoosterTeeth/volume-up.svg new file mode 100644 index 0000000..dfd49ab --- /dev/null +++ b/src/qml/icons/RoosterTeeth/volume-up.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/qml/main.qml b/src/qml/main.qml index aaaf056..dafa4b6 100644 --- a/src/qml/main.qml +++ b/src/qml/main.qml @@ -25,6 +25,8 @@ Window { return youTubeAppearance[name] } else if (themeName == "Niconico") { return nicoNicoAppearance[name] + } else if (themeName == "RoosterTeeth") { + return roosterTeethAppearance[name] } } @@ -56,6 +58,7 @@ Window { property string progressBackgroundColor: "#3CFFFFFF" property string progressCachedColor: "white" property string buttonColor: "white" + property string buttonHoverColor: "white" property string progressSliderColor: "red" property string chapterMarkerColor: "#fc0" property string volumeSliderBackground: "white" @@ -68,11 +71,25 @@ Window { property string progressBackgroundColor: "#444" property string progressCachedColor: "white" property string buttonColor: "white" + property string buttonHoverColor: "white" property string progressSliderColor: "#007cff" property string chapterMarkerColor: "#fc0" property string volumeSliderBackground: "#007cff" } + Settings { + id: roosterTeethAppearance + category: "RoosterTeethAppearance" + property string mainBackground: "#CC2B333F" + property string progressBackgroundColor: "#444" + property string progressCachedColor: "white" + property string buttonColor: "white" + property string buttonHoverColor: "#c9373f" + property string progressSliderColor: "#c9373f" + property string chapterMarkerColor: "#fc0" + property string volumeSliderBackground: "#c9373f" + } + Settings { id: i18n category: "I18N" diff --git a/src/qml/qml.qrc b/src/qml/qml.qrc index 92b6c26..1d7e451 100644 --- a/src/qml/qml.qrc +++ b/src/qml/qml.qrc @@ -7,6 +7,9 @@ MainMenu.qml YouTubeButtonLayout.qml NiconicoButtonLayout.qml + RoosterTeethButtonLayout.qml + UIComponents/VerticalVolume.qml + UIComponents/SpeedText.qml UIComponents/ForwardButton.qml UIComponents/BackwardButton.qml UIComponents/PlaylistPrevButton.qml @@ -39,6 +42,21 @@ icons/YouTube/prev.svg icons/YouTube/subtitles.svg icons/YouTube/playlist.svg + + icons/RoosterTeeth/play.svg + icons/RoosterTeeth/pause.svg + icons/RoosterTeeth/forward.svg + icons/RoosterTeeth/backward.svg + icons/RoosterTeeth/settings.svg + icons/RoosterTeeth/fullscreen.svg + icons/RoosterTeeth/volume-up.svg + icons/RoosterTeeth/volume-mute.svg + icons/RoosterTeeth/volume-down.svg + icons/RoosterTeeth/next.svg + icons/RoosterTeeth/prev.svg + icons/RoosterTeeth/subtitles.svg + icons/RoosterTeeth/playlist.svg + icons/Niconico/play.svg icons/Niconico/pause.svg icons/Niconico/settings.svg