[UI+Backend] Major refactor. Added niconico theme and made components more split up. Used Connections for signals.
|
@ -14,7 +14,11 @@ find_package(Qt5Gui REQUIRED)
|
|||
find_package(Qt5 CONFIG REQUIRED COMPONENTS Qml Quick Gui Widgets Core X11Extras)
|
||||
|
||||
find_package(Qt5QuickCompiler)
|
||||
if(DEVELOP)
|
||||
qt5_add_resources(QT_RESOURCES qml.qrc)
|
||||
else()
|
||||
qtquick_compiler_add_resources(qml_QRC src/qml/qml.qrc)
|
||||
endif()
|
||||
|
||||
find_package(PkgConfig)
|
||||
pkg_check_modules(MPV REQUIRED mpv)
|
||||
|
|
|
@ -581,4 +581,3 @@ MpvPlayerBackend::createRenderer() const
|
|||
window()->setPersistentSceneGraph(true);
|
||||
return new MpvRenderer(const_cast<MpvPlayerBackend*>(this));
|
||||
}
|
||||
|
||||
|
|
40
src/main.cpp
|
@ -106,23 +106,22 @@ main(int argc, char* argv[])
|
|||
QSettings settings;
|
||||
QString backendSetting = settings.value("Backend/backend", "").toString();
|
||||
if (backendSetting.length() == 0) {
|
||||
#ifndef DISABLE_MpvPlayerBackend
|
||||
settings.setValue("Backend/backend", "mpv");
|
||||
#else
|
||||
settings.setValue("Backend/backend", "direct-mpv");
|
||||
#endif
|
||||
#ifndef DISABLE_MpvPlayerBackend
|
||||
settings.setValue("Backend/backend", "mpv");
|
||||
#else
|
||||
settings.setValue("Backend/backend", "direct-mpv");
|
||||
#endif
|
||||
}
|
||||
|
||||
qDebug() << backendSetting;
|
||||
qDebug() << backendSetting;
|
||||
|
||||
for (int i = 1; i < argc; ++i) {
|
||||
if (!qstrcmp(argv[i], "--update")) {
|
||||
Utils::updateAppImage();
|
||||
}
|
||||
else if (!qstrcmp(argv[i], "--backend=mpv") || backendSetting == "mpv") {
|
||||
} else if (!qstrcmp(argv[i], "--backend=mpv") || backendSetting == "mpv") {
|
||||
backend = Enums::Backends::MpvBackend;
|
||||
}
|
||||
else if (!qstrcmp(argv[i], "--backend=direct-mpv") || backendSetting == "direct-mpv") {
|
||||
} else if (!qstrcmp(argv[i], "--backend=direct-mpv") ||
|
||||
backendSetting == "direct-mpv") {
|
||||
backend = Enums::Backends::DirectMpvBackend;
|
||||
}
|
||||
}
|
||||
|
@ -141,19 +140,20 @@ main(int argc, char* argv[])
|
|||
qRegisterMetaType<Enums::Backends>("Enums.Backends");
|
||||
|
||||
qRegisterMetaType<Enums::Commands>("Enums.Commands");
|
||||
|
||||
|
||||
qmlRegisterType<UtilsClass>("player", 1, 0, "Utils");
|
||||
|
||||
switch (backend) {
|
||||
case Enums::Backends::MpvBackend: {
|
||||
#ifndef DISABLE_MpvPlayerBackend
|
||||
qmlRegisterType<MpvPlayerBackend>("player", 1, 0, "PlayerBackend");
|
||||
#else
|
||||
qDebug() << "Normal MPV backend not available, resetting backend option to blank.";
|
||||
settings.setValue("Backend/backend", "direct-mpv");
|
||||
app.exit();
|
||||
#endif
|
||||
break;
|
||||
#ifndef DISABLE_MpvPlayerBackend
|
||||
qmlRegisterType<MpvPlayerBackend>("player", 1, 0, "PlayerBackend");
|
||||
#else
|
||||
qDebug() << "Normal MPV backend not available, resetting backend option "
|
||||
"to blank.";
|
||||
settings.setValue("Backend/backend", "direct-mpv");
|
||||
app.exit();
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case Enums::Backends::DirectMpvBackend: {
|
||||
qmlRegisterType<DirectMpvPlayerBackend>("player", 1, 0, "PlayerBackend");
|
||||
|
@ -171,7 +171,7 @@ main(int argc, char* argv[])
|
|||
rt->setMainQmlFilename("main.qml");
|
||||
rt->reload();
|
||||
#else
|
||||
engine.load(QUrl(QStringLiteral("qrc:///player/main.qml")));
|
||||
engine.load(QUrl(QStringLiteral("qrc:///main.qml")));
|
||||
#endif
|
||||
|
||||
return app.exec();
|
||||
|
|
|
@ -8,6 +8,7 @@ import Qt.labs.platform 1.0 as LabsPlatform
|
|||
import player 1.0
|
||||
|
||||
Item {
|
||||
id: controlsBarItem
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
@ -17,6 +18,23 @@ Item {
|
|||
property var controls: controlsBar
|
||||
property var duration: progressBar.to
|
||||
|
||||
Component.onCompleted: {
|
||||
setControlsTheme(appearance.themeName)
|
||||
}
|
||||
|
||||
function setControlsTheme(themeName) {
|
||||
for (var i = 0; i < controlsBar.children.length; ++i) {
|
||||
if (controlsBar.children[i].objectName == "buttonLayout") {
|
||||
controlsBar.children[i].destroy()
|
||||
}
|
||||
}
|
||||
|
||||
var component = Qt.createComponent(themeName + "ButtonLayout.qml")
|
||||
component.createObject(controlsBar, {
|
||||
anchors.fill: controlsBar
|
||||
})
|
||||
}
|
||||
|
||||
Item {
|
||||
id: subtitlesBar
|
||||
visible: !appearance.useMpvSubs
|
||||
|
@ -67,10 +85,12 @@ Item {
|
|||
width: subsContainer.childrenRect.width
|
||||
height: subsContainer.childrenRect.height
|
||||
}
|
||||
Component.onCompleted: {
|
||||
player.subtitlesChanged.connect(function (subtitles) {
|
||||
text = subtitles
|
||||
})
|
||||
Connections {
|
||||
target: player
|
||||
enabled: true
|
||||
onSubtitlesChanged: function (subtitles) {
|
||||
nativeSubs.text = subtitles
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -79,9 +99,8 @@ Item {
|
|||
|
||||
Rectangle {
|
||||
id: controlsBackground
|
||||
height: controlsBar.visible ? controlsBar.height
|
||||
+ (fun.nyanCat ? progressBackground.height
|
||||
* 0.3 : progressBackground.height * 2) : 0
|
||||
height: controlsBar.visible ? controlsBar.height + progressBar.topPadding
|
||||
+ (fun.nyanCat ? 0 : 1) : 0
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
@ -100,353 +119,13 @@ Item {
|
|||
anchors.bottom: parent.bottom
|
||||
anchors.bottomMargin: 2
|
||||
visible: true
|
||||
|
||||
Slider {
|
||||
VideoProgress {
|
||||
id: progressBar
|
||||
objectName: "progressBar"
|
||||
to: 1
|
||||
value: 0.0
|
||||
anchors.bottom: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.bottomMargin: 0
|
||||
anchors.topMargin: progressBackground.height
|
||||
bottomPadding: 0
|
||||
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.duration = duration
|
||||
})
|
||||
}
|
||||
onMoved: {
|
||||
player.playerCommand(Enums.Commands.SeekAbsolute, value)
|
||||
}
|
||||
|
||||
function getProgressBarHeight(nyan, isMouse) {
|
||||
var x = Math.max(Screen.height / 256, fun.nyanCat ? 12 : 2)
|
||||
return isMouse & !fun.nyanCat ? x * 2 : x
|
||||
}
|
||||
MouseArea {
|
||||
id: mouseAreaProgressBar
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
anchors.fill: parent
|
||||
y: parent.y
|
||||
x: parent.x
|
||||
hoverEnabled: true
|
||||
propagateComposedEvents: false
|
||||
acceptedButtons: Qt.NoButton
|
||||
z: 1
|
||||
onPositionChanged: {
|
||||
var a = (progressBar.to / progressBar.width ) * mouseAreaProgressBar.mouseX
|
||||
hoverProgressLabel.text = utils.createTimestamp(a)
|
||||
}
|
||||
}
|
||||
|
||||
background: Rectangle {
|
||||
id: progressBackground
|
||||
x: progressBar.leftPadding
|
||||
y: progressBar.topPadding + progressBar.availableHeight / 2 - height / 2
|
||||
width: progressBar.availableWidth
|
||||
height: progressBar.getProgressBarHeight(
|
||||
fun.nyanCat, mouseAreaProgressBar.containsMouse)
|
||||
color: appearance.progressBackgroundColor
|
||||
|
||||
|
||||
Rectangle {
|
||||
x: (mouseAreaProgressBar.mouseX - width / 2) + progressBar.leftPadding
|
||||
y: progressBackground.y - 20 - height
|
||||
visible: mouseAreaProgressBar.containsMouse
|
||||
color: appearance.mainBackground
|
||||
height: 20
|
||||
width: 50
|
||||
z: 80
|
||||
Text {
|
||||
id: hoverProgressLabel
|
||||
text: "0:00"
|
||||
color: "white"
|
||||
padding: 2
|
||||
font.family: appearance.fontName
|
||||
font.pixelSize: 14
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
renderType: Text.NativeRendering
|
||||
}
|
||||
}
|
||||
|
||||
ProgressBar {
|
||||
id: cachedLength
|
||||
background: Item {
|
||||
}
|
||||
contentItem: Item {
|
||||
Rectangle {
|
||||
width: cachedLength.visualPosition * parent.width
|
||||
height: parent.height
|
||||
color: appearance.progressCachedColor
|
||||
}
|
||||
}
|
||||
z: 40
|
||||
to: progressBar.to
|
||||
property int duration
|
||||
value: progressBar.value + duration
|
||||
anchors.fill: parent
|
||||
}
|
||||
|
||||
Item {
|
||||
anchors.fill: parent
|
||||
id: chapterMarkers
|
||||
Component.onCompleted: {
|
||||
player.chaptersChanged.connect(chaptersChanged)
|
||||
}
|
||||
function chaptersChanged(chapters) {
|
||||
for (var i = 0, len = chapters.length; i < len; i++) {
|
||||
var chapter = chapters[i]
|
||||
var component = Qt.createComponent(
|
||||
"ChapterMarker.qml")
|
||||
|
||||
var marker = component.createObject(chapterMarkers,
|
||||
{
|
||||
time: chapter["time"]
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: progressLength
|
||||
z: 50
|
||||
anchors.left: progressBackground.left
|
||||
width: progressBar.visualPosition * parent.width
|
||||
height: parent.height
|
||||
color: appearance.progressSliderColor
|
||||
Image {
|
||||
visible: fun.nyanCat
|
||||
id: rainbow
|
||||
anchors.fill: parent
|
||||
height: parent.height
|
||||
width: parent.width
|
||||
source: "qrc:/player/icons/rainbow.png"
|
||||
fillMode: Image.TileHorizontally
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
handle: Rectangle {
|
||||
z: 70
|
||||
id: handleRect
|
||||
x: progressBar.leftPadding + progressBar.visualPosition
|
||||
* (progressBar.availableWidth - width)
|
||||
y: progressBar.topPadding + progressBar.availableHeight / 2 - height / 2
|
||||
implicitHeight: radius
|
||||
implicitWidth: radius
|
||||
radius: 12 + (progressBackground.height / 2)
|
||||
color: fun.nyanCat ? "transparent" : appearance.progressSliderColor
|
||||
AnimatedImage {
|
||||
z: 80
|
||||
visible: fun.nyanCat
|
||||
paused: progressBar.pressed
|
||||
height: 30
|
||||
id: nyanimation
|
||||
anchors.centerIn: parent
|
||||
source: "qrc:/player/icons/nyancat.gif"
|
||||
fillMode: Image.PreserveAspectFit
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
id: layout
|
||||
anchors.fill: parent
|
||||
spacing: 2
|
||||
|
||||
Button {
|
||||
id: playlistPrevButton
|
||||
objectName: "playlistPrevButton"
|
||||
icon.source: "icons/prev.svg"
|
||||
icon.color: appearance.buttonColor
|
||||
display: AbstractButton.IconOnly
|
||||
visible: false
|
||||
width: visible ? playPauseButton.width : 0
|
||||
onClicked: {
|
||||
player.playerCommand(Enums.Commands.PreviousPlaylistItem)
|
||||
}
|
||||
background: Item {
|
||||
}
|
||||
Component.onCompleted: {
|
||||
player.playlistPositionChanged.connect(function (position) {
|
||||
if (position != 0) {
|
||||
visible = true
|
||||
} else {
|
||||
visible = false
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
id: playPauseButton
|
||||
icon.source: "icons/pause.svg"
|
||||
icon.color: appearance.buttonColor
|
||||
display: AbstractButton.IconOnly
|
||||
onClicked: {
|
||||
player.playerCommand(Enums.Commands.TogglePlayPause)
|
||||
}
|
||||
background: Item {
|
||||
}
|
||||
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 {
|
||||
id: playlistNextButton
|
||||
//icon.name: "next"
|
||||
icon.source: "icons/next.svg"
|
||||
icon.color: appearance.buttonColor
|
||||
display: AbstractButton.IconOnly
|
||||
onClicked: {
|
||||
player.playerCommand(Enums.Commands.NextPlaylistItem)
|
||||
}
|
||||
background: Item {
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
id: volumeButton
|
||||
objectName: "volumeButton"
|
||||
icon.source: "icons/volume-up.svg"
|
||||
icon.color: appearance.buttonColor
|
||||
display: AbstractButton.IconOnly
|
||||
onClicked: {
|
||||
player.playerCommand(Enums.Commands.ToggleMute)
|
||||
}
|
||||
background: Item {
|
||||
}
|
||||
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
|
||||
to: 100
|
||||
value: 100
|
||||
palette.dark: "#f00"
|
||||
|
||||
implicitWidth: Math.max(
|
||||
background ? background.implicitWidth : 0,
|
||||
(handle ? handle.implicitWidth : 0)
|
||||
+ leftPadding + rightPadding)
|
||||
implicitHeight: Math.max(
|
||||
background ? background.implicitHeight : 0,
|
||||
(handle ? handle.implicitHeight : 0)
|
||||
+ topPadding + bottomPadding)
|
||||
onMoved: {
|
||||
player.playerCommand(Enums.Commands.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)
|
||||
y: volumeBar.topPadding + volumeBar.availableHeight / 2 - height / 2
|
||||
implicitWidth: 12
|
||||
implicitHeight: 12
|
||||
radius: 12
|
||||
color: "#f6f6f6"
|
||||
border.color: "#f6f6f6"
|
||||
}
|
||||
|
||||
background: Rectangle {
|
||||
x: volumeBar.leftPadding
|
||||
y: volumeBar.topPadding + volumeBar.availableHeight / 2 - height / 2
|
||||
implicitWidth: 60
|
||||
implicitHeight: 3
|
||||
width: volumeBar.availableWidth
|
||||
height: implicitHeight
|
||||
color: "#33333311"
|
||||
Rectangle {
|
||||
width: volumeBar.visualPosition * parent.width
|
||||
height: parent.height
|
||||
color: "white"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
id: timeLabel
|
||||
objectName: "timeLabel"
|
||||
text: "0:00 / 0:00"
|
||||
color: "white"
|
||||
padding: 2
|
||||
font.family: appearance.fontName
|
||||
font.pixelSize: 14
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
renderType: Text.NativeRendering
|
||||
Component.onCompleted: {
|
||||
player.durationStringChanged.connect(
|
||||
function (durationString) {
|
||||
text = durationString
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
Button {
|
||||
id: settingsButton
|
||||
//icon.name: "settings"
|
||||
icon.source: "icons/settings.svg"
|
||||
icon.color: appearance.buttonColor
|
||||
Layout.alignment: Qt.AlignVCenter | Qt.AlignRight
|
||||
display: AbstractButton.IconOnly
|
||||
onClicked: {
|
||||
console.log("Settings Menu Not Yet Implemented.")
|
||||
}
|
||||
background: Item {
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
id: fullscreenButton
|
||||
//icon.name: "fullscreen"
|
||||
icon.source: "icons/fullscreen.svg"
|
||||
icon.color: appearance.buttonColor
|
||||
Layout.alignment: Qt.AlignVCenter | Qt.AlignRight
|
||||
|
||||
display: AbstractButton.IconOnly
|
||||
onClicked: {
|
||||
toggleFullscreen()
|
||||
}
|
||||
|
||||
background: Item {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,75 +0,0 @@
|
|||
import QtQuick 2.11
|
||||
import QtQuick.Controls 2.4
|
||||
import Qt.labs.settings 1.0
|
||||
|
||||
ComboBox {
|
||||
id: control
|
||||
width: parent.width
|
||||
height: 10
|
||||
|
||||
indicator: Canvas {
|
||||
id: canvas
|
||||
x: control.width - width - control.rightPadding
|
||||
y: control.topPadding + (control.availableHeight - height) / 2
|
||||
width: 12
|
||||
height: 8
|
||||
contextType: "2d"
|
||||
|
||||
Connections {
|
||||
target: control
|
||||
onPressedChanged: canvas.requestPaint()
|
||||
}
|
||||
|
||||
onPaint: {
|
||||
context.reset()
|
||||
context.moveTo(0, 0)
|
||||
context.lineTo(width, 0)
|
||||
context.lineTo(width / 2, height)
|
||||
context.closePath()
|
||||
context.fillStyle = control.pressed ? "#17a81a" : "#21be2b"
|
||||
context.fill()
|
||||
}
|
||||
}
|
||||
|
||||
contentItem: Text {
|
||||
leftPadding: 2
|
||||
rightPadding: control.indicator.width + control.spacing
|
||||
text: control.displayText
|
||||
font.family: appearance.fontName
|
||||
color: control.pressed ? "#5a50da" : "white"
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
|
||||
background: Rectangle {
|
||||
implicitWidth: 120
|
||||
implicitHeight: 40
|
||||
color: "transparent"
|
||||
}
|
||||
|
||||
popup: Popup {
|
||||
y: control.height - 1
|
||||
width: control.width
|
||||
implicitHeight: contentItem.implicitHeight
|
||||
padding: 1
|
||||
|
||||
contentItem: ListView {
|
||||
clip: true
|
||||
implicitHeight: contentHeight
|
||||
model: control.popup.visible ? control.delegateModel : null
|
||||
currentIndex: control.highlightedIndex
|
||||
highlight: Rectangle {
|
||||
color: "white"
|
||||
opacity: 1
|
||||
}
|
||||
|
||||
ScrollIndicator.vertical: ScrollIndicator {
|
||||
}
|
||||
}
|
||||
|
||||
background: Rectangle {
|
||||
opacity: 0.6
|
||||
color: "orange"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -12,19 +12,20 @@ Dialog {
|
|||
height: Math.max(480, childrenRect.height * playlistListView.count)
|
||||
width: 720
|
||||
modality: Qt.NonModal
|
||||
Component.onCompleted: {
|
||||
player.playlistChanged.connect(updatePlaylistMenu)
|
||||
}
|
||||
function updatePlaylistMenu(playlist) {
|
||||
playlistModel.clear()
|
||||
for (var thing in playlist) {
|
||||
var item = playlist[thing]
|
||||
playlistModel.append({
|
||||
playlistItemTitle: item["title"],
|
||||
playlistItemFilename: item["filename"],
|
||||
current: item["current"],
|
||||
playlistPos: thing
|
||||
})
|
||||
Connections {
|
||||
target: player
|
||||
enabled: true
|
||||
onPlaylistChanged: function(playlist) {
|
||||
playlistModel.clear()
|
||||
for (var thing in playlist) {
|
||||
var item = playlist[thing]
|
||||
playlistModel.append({
|
||||
playlistItemTitle: item["title"],
|
||||
playlistItemFilename: item["filename"],
|
||||
current: item["current"],
|
||||
playlistPos: thing
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -7,8 +7,10 @@ Rectangle {
|
|||
id: chapterMarker
|
||||
property int time: 0
|
||||
color: appearance.chapterMarkerColor
|
||||
Component.onCompleted: {
|
||||
player.chaptersChanged.connect(chapterMarker.destroy)
|
||||
Connections {
|
||||
target: player
|
||||
enabled: true
|
||||
onChaptersChanged: {chapterMarker.destroy()}
|
||||
}
|
||||
|
||||
width: 4
|
|
@ -20,8 +20,12 @@ MenuBar {
|
|||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
player.tracksChanged.connect(updateTracks)
|
||||
Connections {
|
||||
target: player
|
||||
enabled: true
|
||||
onTracksChanged: function (tracks) {
|
||||
menuBar.updateTracks(tracks)
|
||||
}
|
||||
}
|
||||
|
||||
function updateTracks(tracks) {
|
||||
|
@ -340,8 +344,12 @@ MenuBar {
|
|||
id: audioDeviceMenu
|
||||
objectName: "audioDeviceMenu"
|
||||
|
||||
Component.onCompleted: {
|
||||
player.audioDevicesChanged.connect(updateAudioDevices)
|
||||
Connections {
|
||||
target: player
|
||||
enabled: true
|
||||
onAudioDevicesChanged: function (ad) {
|
||||
audioDeviceMenu.updateAudioDevices(ad)
|
||||
}
|
||||
}
|
||||
function updateAudioDevices(audioDevices) {
|
||||
for (var i = 0, len = audioDeviceMenu.count; i < len; i++) {
|
||||
|
|
76
src/qml/NiconicoButtonLayout.qml
Normal file
|
@ -0,0 +1,76 @@
|
|||
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
|
||||
|
||||
PlayPauseButton {
|
||||
id: playPauseButton
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
height: 16
|
||||
width: 26
|
||||
icon.height: 16
|
||||
icon.width: 26
|
||||
}
|
||||
VolumeButton {
|
||||
id: volumeButton
|
||||
anchors.left: playPauseButton.right
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
icon.height: 16
|
||||
icon.width: 16
|
||||
}
|
||||
VolumeSlider {
|
||||
anchors.left: volumeButton.right
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
}
|
||||
|
||||
PlaylistPrevButton {
|
||||
id: playlistPrevButton
|
||||
anchors.right: timeLabel.left
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
icon.height: 16
|
||||
icon.width: 16
|
||||
}
|
||||
TimeLabel {
|
||||
id: timeLabel
|
||||
anchors.centerIn: parent
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
}
|
||||
PlaylistNextButton {
|
||||
id: playlistNextButton
|
||||
anchors.left: timeLabel.right
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
icon.height: 16
|
||||
icon.width: 16
|
||||
}
|
||||
|
||||
FullscreenButton {
|
||||
id: fullscreenButton
|
||||
anchors.right: settingsButton.left
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
icon.height: 16
|
||||
icon.width: 16
|
||||
}
|
||||
SettingsButton {
|
||||
id: settingsButton
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
icon.height: 16
|
||||
icon.width: 16
|
||||
}
|
||||
}
|
24
src/qml/UIComponents/FullscreenButton.qml
Normal file
|
@ -0,0 +1,24 @@
|
|||
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
|
||||
|
||||
Button {
|
||||
id: fullscreenButton
|
||||
//icon.name: "fullscreen"
|
||||
icon.source: "icons/" + appearance.themeName + "/fullscreen.svg"
|
||||
icon.color: appearance.buttonColor
|
||||
Layout.alignment: Qt.AlignVCenter | Qt.AlignRight
|
||||
|
||||
display: AbstractButton.IconOnly
|
||||
onClicked: {
|
||||
toggleFullscreen()
|
||||
}
|
||||
|
||||
background: Item {
|
||||
}
|
||||
}
|
32
src/qml/UIComponents/PlayPauseButton.qml
Normal file
|
@ -0,0 +1,32 @@
|
|||
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
|
||||
|
||||
Button {
|
||||
id: playPauseButton
|
||||
icon.source: "icons/" + appearance.themeName + "/pause.svg"
|
||||
icon.color: appearance.buttonColor
|
||||
display: AbstractButton.IconOnly
|
||||
onClicked: {
|
||||
player.playerCommand(Enums.Commands.TogglePlayPause)
|
||||
}
|
||||
background: Item {
|
||||
}
|
||||
Connections {
|
||||
target: player
|
||||
enabled: true
|
||||
onPlayStatusChanged: function (status) {
|
||||
console.log(icon.height)
|
||||
if (status == Enums.PlayStatus.Playing) {
|
||||
icon.source = "qrc:/icons/" + appearance.themeName + "/pause.svg"
|
||||
} else if (status == Enums.PlayStatus.Paused) {
|
||||
icon.source = "qrc:/icons/" + appearance.themeName + "/play.svg"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
23
src/qml/UIComponents/PlaylistNextButton.qml
Normal file
|
@ -0,0 +1,23 @@
|
|||
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
|
||||
|
||||
|
||||
Button {
|
||||
id: playlistNextButton
|
||||
//icon.name: "next"
|
||||
icon.source: "icons/" + appearance.themeName + "/next.svg"
|
||||
icon.color: appearance.buttonColor
|
||||
display: AbstractButton.IconOnly
|
||||
onClicked: {
|
||||
player.playerCommand(Enums.Commands.NextPlaylistItem)
|
||||
}
|
||||
background: Item {
|
||||
}
|
||||
}
|
||||
|
37
src/qml/UIComponents/PlaylistPrevButton.qml
Normal file
|
@ -0,0 +1,37 @@
|
|||
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
|
||||
|
||||
|
||||
Button {
|
||||
id: playlistPrevButton
|
||||
objectName: "playlistPrevButton"
|
||||
icon.source: "icons/" + appearance.themeName + "/prev.svg"
|
||||
icon.color: appearance.buttonColor
|
||||
display: AbstractButton.IconOnly
|
||||
visible: appearance.themeName == "Youtube" ? false : true
|
||||
onClicked: {
|
||||
player.playerCommand(Enums.Commands.PreviousPlaylistItem)
|
||||
}
|
||||
background: Item {
|
||||
}
|
||||
Connections {
|
||||
target: player
|
||||
enabled: true
|
||||
onPlaylistPositionChanged: function (position) {
|
||||
if (appearance.themeName == "YouTube") {
|
||||
if (position != 0) {
|
||||
visible = true
|
||||
|
||||
} else {
|
||||
visible = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
24
src/qml/UIComponents/SettingsButton.qml
Normal file
|
@ -0,0 +1,24 @@
|
|||
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
|
||||
|
||||
Button {
|
||||
id: settingsButton
|
||||
//icon.name: "settings"
|
||||
icon.source: "icons/" + appearance.themeName + "/settings.svg"
|
||||
icon.color: appearance.buttonColor
|
||||
Layout.alignment: Qt.AlignVCenter | Qt.AlignRight
|
||||
display: AbstractButton.IconOnly
|
||||
onClicked: {
|
||||
appearance.themeName = appearance.themeName == "YouTube" ? "Niconico" : "YouTube"
|
||||
controlsBarItem.setControlsTheme(appearance.themeName)
|
||||
console.log("Settings Menu Not Yet Implemented.")
|
||||
}
|
||||
background: Item {
|
||||
}
|
||||
}
|
27
src/qml/UIComponents/TimeLabel.qml
Normal file
|
@ -0,0 +1,27 @@
|
|||
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: timeLabel
|
||||
objectName: "timeLabel"
|
||||
text: "0:00 / 0:00"
|
||||
color: "white"
|
||||
padding: 2
|
||||
font.family: appearance.fontName
|
||||
font.pixelSize: 14
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
renderType: Text.NativeRendering
|
||||
Connections {
|
||||
target: player
|
||||
enabled: true
|
||||
onDurationStringChanged: function (durationString) {
|
||||
timeLabel.text = durationString
|
||||
}
|
||||
}
|
||||
}
|
181
src/qml/UIComponents/VideoProgress.qml
Normal file
|
@ -0,0 +1,181 @@
|
|||
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
|
||||
|
||||
Slider {
|
||||
id: progressBar
|
||||
objectName: "progressBar"
|
||||
to: 1
|
||||
value: 0.0
|
||||
Connections {
|
||||
target: player
|
||||
enabled: true
|
||||
onPositionChanged: function (position) {
|
||||
if (!pressed) {
|
||||
progressBar.value = position
|
||||
}
|
||||
}
|
||||
onDurationChanged: function (duration) {
|
||||
progressBar.to = duration
|
||||
}
|
||||
onCachedDurationChanged: function (duration) {
|
||||
cachedLength.duration = duration
|
||||
}
|
||||
}
|
||||
onMoved: {
|
||||
player.playerCommand(Enums.Commands.SeekAbsolute, value)
|
||||
}
|
||||
|
||||
function getProgressBarHeight(nyan, isMouse) {
|
||||
var x = Math.max(Screen.height / 256, fun.nyanCat ? 12 : 2)
|
||||
if (appearance.themeName == "Niconico" && !fun.nyanCat) {
|
||||
return x * 2
|
||||
} else if (isMouse & !fun.nyanCat) {
|
||||
return x * 2
|
||||
} else {
|
||||
return x
|
||||
}
|
||||
}
|
||||
function getHandleVisibility(themeName, isMouse) {
|
||||
if (appearance.themeName == "Niconico" && isMouse) {
|
||||
return true
|
||||
} else if (appearance.themeName == "Niconico") {
|
||||
return false
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
}
|
||||
MouseArea {
|
||||
id: mouseAreaProgressBar
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
anchors.fill: parent
|
||||
y: parent.y
|
||||
x: parent.x
|
||||
hoverEnabled: true
|
||||
propagateComposedEvents: false
|
||||
acceptedButtons: Qt.NoButton
|
||||
z: 1
|
||||
|
||||
onPositionChanged: {
|
||||
var a = (progressBar.to / progressBar.width ) * mouseAreaProgressBar.mouseX
|
||||
hoverProgressLabel.text = utils.createTimestamp(a)
|
||||
}
|
||||
}
|
||||
|
||||
background: Rectangle {
|
||||
id: progressBackground
|
||||
x: progressBar.leftPadding
|
||||
y: progressBar.topPadding + progressBar.availableHeight / 2 - height / 2
|
||||
width: progressBar.availableWidth
|
||||
height: progressBar.getProgressBarHeight(
|
||||
fun.nyanCat, mouseAreaProgressBar.containsMouse)
|
||||
color: appearance.progressBackgroundColor
|
||||
|
||||
|
||||
Rectangle {
|
||||
x: (mouseAreaProgressBar.mouseX - width / 2) + progressBar.leftPadding
|
||||
y: progressBackground.y - 20 - height
|
||||
visible: mouseAreaProgressBar.containsMouse
|
||||
color: appearance.mainBackground
|
||||
height: 20
|
||||
width: 50
|
||||
z: 80
|
||||
Text {
|
||||
id: hoverProgressLabel
|
||||
text: "0:00"
|
||||
color: "white"
|
||||
padding: 2
|
||||
font.family: appearance.fontName
|
||||
font.pixelSize: 14
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
renderType: Text.NativeRendering
|
||||
}
|
||||
}
|
||||
|
||||
ProgressBar {
|
||||
id: cachedLength
|
||||
background: Item {
|
||||
}
|
||||
contentItem: Item {
|
||||
Rectangle {
|
||||
width: cachedLength.visualPosition * parent.width
|
||||
height: parent.height
|
||||
color: appearance.progressCachedColor
|
||||
}
|
||||
}
|
||||
z: 40
|
||||
to: progressBar.to
|
||||
property int duration
|
||||
value: progressBar.value + duration
|
||||
anchors.fill: parent
|
||||
}
|
||||
|
||||
Item {
|
||||
anchors.fill: parent
|
||||
id: chapterMarkers
|
||||
Connections {
|
||||
target: player
|
||||
enabled: true
|
||||
onChaptersChanged: function(chapters) {
|
||||
for (var i = 0, len = chapters.length; i < len; i++) {
|
||||
var component = Qt.createComponent(
|
||||
"ChapterMarker.qml")
|
||||
|
||||
var marker = component.createObject(chapterMarkers,
|
||||
{
|
||||
time: chapters[i]["time"]
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: progressLength
|
||||
z: 50
|
||||
anchors.left: progressBackground.left
|
||||
width: progressBar.visualPosition * parent.width
|
||||
height: parent.height
|
||||
color: appearance.progressSliderColor
|
||||
Image {
|
||||
visible: fun.nyanCat
|
||||
id: rainbow
|
||||
anchors.fill: parent
|
||||
height: parent.height
|
||||
width: parent.width
|
||||
source: "qrc:/icons/rainbow.png"
|
||||
fillMode: Image.TileHorizontally
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
handle: Rectangle {
|
||||
z: 70
|
||||
id: handleRect
|
||||
x: progressBar.leftPadding + progressBar.visualPosition
|
||||
* (progressBar.availableWidth - width)
|
||||
y: progressBar.topPadding + progressBar.availableHeight / 2 - height / 2
|
||||
implicitHeight: radius
|
||||
implicitWidth: radius
|
||||
radius: 12 + (progressBackground.height / 2)
|
||||
color: fun.nyanCat ? "transparent" : appearance.progressSliderColor
|
||||
visible: getHandleVisibility(appearance.themeName, mouseAreaProgressBar.containsMouse)
|
||||
AnimatedImage {
|
||||
z: 80
|
||||
visible: fun.nyanCat
|
||||
paused: progressBar.pressed
|
||||
height: 30
|
||||
id: nyanimation
|
||||
anchors.centerIn: parent
|
||||
source: "qrc:/icons/nyancat.gif"
|
||||
fillMode: Image.PreserveAspectFit
|
||||
}
|
||||
}
|
||||
}
|
38
src/qml/UIComponents/VolumeButton.qml
Normal file
|
@ -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
|
||||
|
||||
|
||||
Button {
|
||||
id: volumeButton
|
||||
objectName: "volumeButton"
|
||||
icon.source: "icons/" + appearance.themeName + "/volume-up.svg"
|
||||
icon.color: appearance.buttonColor
|
||||
display: AbstractButton.IconOnly
|
||||
onClicked: {
|
||||
player.playerCommand(Enums.Commands.ToggleMute)
|
||||
}
|
||||
background: Item {
|
||||
}
|
||||
Connections {
|
||||
target: player
|
||||
enabled: true
|
||||
onVolumeStatusChanged: function (status){
|
||||
if (volumeButton == null)
|
||||
console.log("OwO");
|
||||
|
||||
if (status == Enums.VolumeStatus.Muted) {
|
||||
volumeButton.icon.source = "qrc:/icons/" + appearance.themeName + "/volume-mute.svg"
|
||||
} else if (status == Enums.VolumeStatus.Low) {
|
||||
volumeButton.icon.source = "qrc:/icons/" + appearance.themeName + "/volume-down.svg"
|
||||
} else if (status == Enums.VolumeStatus.Normal) {
|
||||
volumeButton.icon.source = "qrc:/icons/" + appearance.themeName + "/volume-up.svg"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
63
src/qml/UIComponents/VolumeSlider.qml
Normal file
|
@ -0,0 +1,63 @@
|
|||
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
|
||||
|
||||
|
||||
Slider {
|
||||
id: volumeBar
|
||||
to: 100
|
||||
value: 100
|
||||
palette.dark: "#f00"
|
||||
|
||||
implicitWidth: Math.max(
|
||||
background ? background.implicitWidth : 0,
|
||||
(handle ? handle.implicitWidth : 0)
|
||||
+ leftPadding + rightPadding)
|
||||
implicitHeight: Math.max(
|
||||
background ? background.implicitHeight : 0,
|
||||
(handle ? handle.implicitHeight : 0)
|
||||
+ topPadding + bottomPadding)
|
||||
onMoved: {
|
||||
player.playerCommand(Enums.Commands.SetVolume,
|
||||
Math.round(volumeBar.value).toString())
|
||||
}
|
||||
Connections {
|
||||
target: player
|
||||
enabled: true
|
||||
onVolumeChanged: function (volume){
|
||||
volumeBar.value = volume
|
||||
}
|
||||
}
|
||||
handle: Rectangle {
|
||||
x: volumeBar.leftPadding + volumeBar.visualPosition
|
||||
* (volumeBar.availableWidth - width)
|
||||
y: volumeBar.topPadding + volumeBar.availableHeight / 2 - height / 2
|
||||
implicitWidth: 12
|
||||
implicitHeight: 12
|
||||
radius: 12
|
||||
visible: appearance.themeName == "Niconico" ? false : true
|
||||
color: "#f6f6f6"
|
||||
border.color: "#f6f6f6"
|
||||
}
|
||||
|
||||
background: Rectangle {
|
||||
x: volumeBar.leftPadding
|
||||
y: volumeBar.topPadding + volumeBar.availableHeight / 2 - height / 2
|
||||
implicitWidth: appearance.themeName == "Niconico" ? 80 : 60
|
||||
implicitHeight: appearance.themeName == "Niconico" ? 4 : 3
|
||||
width: volumeBar.availableWidth
|
||||
height: implicitHeight
|
||||
color: appearance.progressBackgroundColor
|
||||
Rectangle {
|
||||
width: volumeBar.visualPosition * parent.width
|
||||
height: parent.height
|
||||
color: appearance.volumeSliderBackground
|
||||
}
|
||||
}
|
||||
}
|
||||
|
64
src/qml/YouTubeButtonLayout.qml
Normal file
|
@ -0,0 +1,64 @@
|
|||
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
|
||||
|
||||
PlaylistPrevButton {
|
||||
id: playlistPrevButton
|
||||
anchors.left: parent.left
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
width: visible ? playlistNextButton.width : 0
|
||||
}
|
||||
PlayPauseButton {
|
||||
id: playPauseButton
|
||||
anchors.left: playlistPrevButton.right
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
}
|
||||
PlaylistNextButton {
|
||||
id: playlistNextButton
|
||||
anchors.left: playPauseButton.right
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
}
|
||||
|
||||
VolumeButton {
|
||||
id: volumeButton
|
||||
anchors.left: playlistNextButton.right
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
}
|
||||
VolumeSlider {
|
||||
id: volumeSlider
|
||||
anchors.left: volumeButton.right
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
}
|
||||
TimeLabel {
|
||||
anchors.left: volumeSlider.right
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
}
|
||||
|
||||
SettingsButton {
|
||||
id: settingsButton
|
||||
anchors.right: fullscreenButton.left
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
}
|
||||
FullscreenButton {
|
||||
id: fullscreenButton
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
}
|
||||
}
|
1
src/qml/icons/Niconico/fullscreen.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.4" class="EnableFullScreenButton-icon"><path d="M60 92a4 4 0 0 1 4-4h15.5L59 67.5a4 4 0 0 1 0-5.7l2.8-2.8a4 4 0 0 1 5.7 0L88 79.5V64a4 4 0 0 1 4-4h4a4 4 0 0 1 4 4v32a4 4 0 0 1-4 4H64a4 4 0 0 1-4-4v-4zM40 8a4 4 0 0 1-4 4H20.5L41 32.5a4 4 0 0 1 0 5.7L38.2 41a4 4 0 0 1-5.7 0L12 20.5V36a4 4 0 0 1-4 4H4a4 4 0 0 1-4-4V4a4 4 0 0 1 4-4h32a4 4 0 0 1 4 4v4z"></path></svg>
|
After Width: | Height: | Size: 512 B |
1
src/qml/icons/Niconico/next.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.4" class="PlayerSkipNextButton-icon"><path d="M34.6 46.6a4 4 0 0 1 0 6.8L6 71.2A4 4 0 0 1 0 67.8V32.2a4 4 0 0 1 6.1-3.4l28.5 17.8zM74.6 46.6a4 4 0 0 1 0 6.8L46 71.2a4 4 0 0 1-6.1-3.4V32.2a4 4 0 0 1 6.1-3.4l28.5 17.8zM100 4a4 4 0 0 0-4-4h-8a4 4 0 0 0-4 4v92a4 4 0 0 0 4 4h8a4 4 0 0 0 4-4V4z"></path></svg>
|
After Width: | Height: | Size: 452 B |
1
src/qml/icons/Niconico/pause.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg viewBox="0 0 88 100" xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.4" class="PlayerPauseButton-icon"><path d="M32 4a4 4 0 0 0-4-4H4a4 4 0 0 0-4 4v92a4 4 0 0 0 4 4h24a4 4 0 0 0 4-4V4zM88 4a4 4 0 0 0-4-4H60a4 4 0 0 0-4 4v92a4 4 0 0 0 4 4h24a4 4 0 0 0 4-4V4z"></path></svg>
|
After Width: | Height: | Size: 350 B |
1
src/qml/icons/Niconico/play.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.4" class="PlayerPlayButton-icon"><path d="M95 42a8.9 8.9 0 0 1 0 16L12.9 99A8.9 8.9 0 0 1 0 91.2V9a8.9 8.9 0 0 1 12.8-8C33.2 11.1 73 31 95.1 42.1z"></path></svg>
|
After Width: | Height: | Size: 309 B |
1
src/qml/icons/Niconico/prev.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.4" class="SeekToHeadButton-icon"><path d="M65.4 46.6a4 4 0 0 0 0 6.8L94 71.2a4 4 0 0 0 6.1-3.4V32.2a4 4 0 0 0-6.1-3.4L65.4 46.6zM25.4 46.6a4 4 0 0 0 0 6.8L54 71.2a4 4 0 0 0 6.1-3.4V32.2a4 4 0 0 0-6.1-3.4L25.4 46.6zM0 4a4 4 0 0 1 4-4h8a4 4 0 0 1 4 4v92a4 4 0 0 1-4 4H4a4 4 0 0 1-4-4V4z"></path></svg>
|
After Width: | Height: | Size: 447 B |
1
src/qml/icons/Niconico/settings.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.4" class="PlayerOptionButton-icon"><path d="M56.5 3.2A4 4 0 0 0 53 0H47a4 4 0 0 0-3.6 3L41 14a4 4 0 0 1-2.6 2.9c-1.3.4-2.5 1-3.7 1.5a4 4 0 0 1-3.9-.2l-9.3-5.8a4 4 0 0 0-4.8.4 52.2 52.2 0 0 0-4 4 4 4 0 0 0-.4 4.8l5.8 9.3a4 4 0 0 1 .2 4c-.6 1.1-1 2.3-1.5 3.6a4 4 0 0 1-2.9 2.6L3.2 43.5A4 4 0 0 0 0 47V53a4 4 0 0 0 3 3.6L14 59a4 4 0 0 1 2.9 2.6c.4 1.3 1 2.5 1.5 3.7a4 4 0 0 1-.2 3.9l-5.8 9.3a4 4 0 0 0 .4 4.8c1.2 1.4 2.6 2.8 4 4a4 4 0 0 0 4.8.4l9.3-5.8a4 4 0 0 1 4-.2c1.1.6 2.3 1 3.6 1.5a4 4 0 0 1 2.6 3l2.5 10.6A4 4 0 0 0 47 100H53a4 4 0 0 0 3.6-3L59 86a4 4 0 0 1 2.6-2.9c1.3-.4 2.5-1 3.7-1.5a4 4 0 0 1 3.9.2l9.3 5.8a4 4 0 0 0 4.8-.4c1.4-1.2 2.8-2.6 4-4a4 4 0 0 0 .4-4.8L82 69.2a4 4 0 0 1-.2-4c.6-1.1 1-2.3 1.5-3.6a4 4 0 0 1 3-2.6l10.6-2.5A4 4 0 0 0 100 53V47a4 4 0 0 0-3-3.6L86 41a4 4 0 0 1-2.9-2.6c-.4-1.3-1-2.5-1.5-3.7a4 4 0 0 1 .2-3.9l5.8-9.3a4 4 0 0 0-.4-4.8 52.2 52.2 0 0 0-4-4 4 4 0 0 0-4.8-.4L69.2 18a4 4 0 0 1-4 .2c-1.1-.6-2.3-1-3.6-1.5a4 4 0 0 1-2.6-2.9L56.5 3.2zm-6.5 27a19.9 19.9 0 0 1 0 39.7 19.9 19.9 0 1 1 0-39.7z"></path></svg>
|
After Width: | Height: | Size: 1.2 KiB |
1
src/qml/icons/Niconico/volume-down.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.4" class="MuteVideoButton-icon"><path d="M24.1 24L45.2 1.3a3.7 3.7 0 0 1 4.4-1C51 1.2 52 2.8 52 4.6v91c0 1.8-1 3.4-2.4 4.1-1.5.7-3.2.4-4.4-.9L24.2 76H8a8 8 0 0 1-8-8V32a8 8 0 0 1 8-8h16.1zm51.4-9.3l.5-.7 1.5-1.5a4 4 0 0 1 5.4-.2 49.9 49.9 0 0 1 0 75.3 4 4 0 0 1-5.4-.2A75 75 0 0 1 76 86a4 4 0 0 1 .2-5.8 40 40 0 0 0 9-11.1V69l.1-.2a39.3 39.3 0 0 0 4.4-14v-.3L90 50c0-10.6-4.1-20.2-10.8-27.3l-.1-.2a44 44 0 0 0-1-1H78l-.1-.2a35 35 0 0 0-2-1.8 4 4 0 0 1-.6-.8v-.3a4 4 0 0 1 .1-3.6v-.1zM62.2 27.8l1-1a4 4 0 0 1 5.4-.4l2.5 2.2a30 30 0 0 1-2.7 45v.1a4 4 0 0 1-2.2.7c-1.1 0-2.1-.4-3-1.1l-.9-1-.5-.5a4 4 0 0 1-.6-.8l-.1-.2a4 4 0 0 1 1-5A20 20 0 0 0 70 50a20 20 0 0 0-7.8-15.8A4 4 0 0 1 62 28l.2-.2z"></path></svg>
|
After Width: | Height: | Size: 854 B |
1
src/qml/icons/Niconico/volume-mute.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.4" class="UnMuteVideoButton-icon"><path d="M24.1 24L45.2 1.3a3.7 3.7 0 0 1 4.4-1C51 1.2 52 2.8 52 4.6v91c0 1.8-1 3.4-2.4 4.1-1.5.7-3.2.4-4.4-.9L24.2 76H8a8 8 0 0 1-8-8V32a8 8 0 0 1 8-8h16.1zM80 42.7l11.5-11.4a4.4 4.4 0 0 1 6.1 0l1.1 1a4.4 4.4 0 0 1 0 6.2L87.3 50l11.4 11.5a4.4 4.4 0 0 1 0 6.1l-1 1.1a4.4 4.4 0 0 1-6.2 0L80 57.3 68.5 68.7a4.4 4.4 0 0 1-6.1 0l-1.1-1a4.4 4.4 0 0 1 0-6.2L72.7 50 61.3 38.5a4.4 4.4 0 0 1 0-6.1l1-1.1a4.4 4.4 0 0 1 6.2 0L80 42.7z"></path></svg>
|
After Width: | Height: | Size: 620 B |
1
src/qml/icons/Niconico/volume-up.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.4" class="MuteVideoButton-icon"><path d="M24.1 24L45.2 1.3a3.7 3.7 0 0 1 4.4-1C51 1.2 52 2.8 52 4.6v91c0 1.8-1 3.4-2.4 4.1-1.5.7-3.2.4-4.4-.9L24.2 76H8a8 8 0 0 1-8-8V32a8 8 0 0 1 8-8h16.1zm51.4-9.3l.5-.7 1.5-1.5a4 4 0 0 1 5.4-.2 49.9 49.9 0 0 1 0 75.3 4 4 0 0 1-5.4-.2A75 75 0 0 1 76 86a4 4 0 0 1 .2-5.8 40 40 0 0 0 9-11.1V69l.1-.2a39.3 39.3 0 0 0 4.4-14v-.3L90 50c0-10.6-4.1-20.2-10.8-27.3l-.1-.2a44 44 0 0 0-1-1H78l-.1-.2a35 35 0 0 0-2-1.8 4 4 0 0 1-.6-.8v-.3a4 4 0 0 1 .1-3.6v-.1zM62.2 27.8l1-1a4 4 0 0 1 5.4-.4l2.5 2.2a30 30 0 0 1-2.7 45v.1a4 4 0 0 1-2.2.7c-1.1 0-2.1-.4-3-1.1l-.9-1-.5-.5a4 4 0 0 1-.6-.8l-.1-.2a4 4 0 0 1 1-5A20 20 0 0 0 70 50a20 20 0 0 0-7.8-15.8A4 4 0 0 1 62 28l.2-.2z"></path></svg>
|
After Width: | Height: | Size: 854 B |
|
@ -1,3 +0,0 @@
|
|||
# Icons
|
||||
- Icons where all from https://material.io/tools/icons/?style=baseline
|
||||
- Exceptions: nyancat.gif
|
Before Width: | Height: | Size: 640 B After Width: | Height: | Size: 640 B |
Before Width: | Height: | Size: 642 B After Width: | Height: | Size: 642 B |
Before Width: | Height: | Size: 172 B After Width: | Height: | Size: 172 B |
Before Width: | Height: | Size: 121 B After Width: | Height: | Size: 121 B |
Before Width: | Height: | Size: 117 B After Width: | Height: | Size: 117 B |
Before Width: | Height: | Size: 97 B After Width: | Height: | Size: 97 B |
Before Width: | Height: | Size: 174 B After Width: | Height: | Size: 174 B |
Before Width: | Height: | Size: 111 B After Width: | Height: | Size: 111 B |
Before Width: | Height: | Size: 754 B After Width: | Height: | Size: 754 B |
Before Width: | Height: | Size: 235 B After Width: | Height: | Size: 235 B |
Before Width: | Height: | Size: 171 B After Width: | Height: | Size: 171 B |
Before Width: | Height: | Size: 451 B After Width: | Height: | Size: 451 B |
Before Width: | Height: | Size: 281 B After Width: | Height: | Size: 281 B |
|
@ -17,7 +17,7 @@ Window {
|
|||
height: 480
|
||||
|
||||
property bool onTop: false
|
||||
|
||||
|
||||
Translator {
|
||||
id: translate
|
||||
}
|
||||
|
@ -34,6 +34,7 @@ Window {
|
|||
property bool titleOnlyOnFullscreen: true
|
||||
property bool clickToPause: true
|
||||
property bool useMpvSubs: false
|
||||
property string themeName: "YouTube"
|
||||
property string fontName: "Roboto"
|
||||
property string mainBackground: "#9C000000"
|
||||
property string progressBackgroundColor: "#3CFFFFFF"
|
||||
|
@ -41,7 +42,9 @@ Window {
|
|||
property string buttonColor: "white"
|
||||
property string progressSliderColor: "red"
|
||||
property string chapterMarkerColor: "#fc0"
|
||||
property string volumeSliderBackground: "white"
|
||||
}
|
||||
|
||||
Settings {
|
||||
id: i18n
|
||||
category: "I18N"
|
||||
|
@ -118,11 +121,11 @@ Window {
|
|||
mainWindow.visibility = lastScreenVisibility
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Utils {
|
||||
id: utils
|
||||
}
|
||||
|
||||
|
||||
PlayerBackend {
|
||||
id: player
|
||||
anchors.fill: parent
|
||||
|
@ -196,7 +199,7 @@ Window {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Item {
|
||||
id: controlsOverlay
|
||||
anchors.centerIn: player
|
||||
|
@ -218,7 +221,7 @@ Window {
|
|||
mouseAreaPlayer.cursorShape = Qt.ArrowCursor
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
MouseArea {
|
||||
id: mouseAreaBar
|
||||
|
||||
|
@ -322,10 +325,12 @@ Window {
|
|||
visible: controlsOverlay.controlsShowing
|
||||
&& ((!appearance.titleOnlyOnFullscreen)
|
||||
|| (mainWindow.visibility == Window.FullScreen))
|
||||
Component.onCompleted: {
|
||||
player.titleChanged.connect(function (title) {
|
||||
text = title
|
||||
})
|
||||
Connections {
|
||||
target: player
|
||||
enabled: true
|
||||
onTitleChanged: function (title) {
|
||||
titleLabel.text = title
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,32 +1,51 @@
|
|||
<RCC>
|
||||
<qresource prefix="/player">
|
||||
<qresource prefix="/">
|
||||
<file>main.qml</file>
|
||||
<file>ChapterMarker.qml</file>
|
||||
<file>PlaylistDialog.qml</file>
|
||||
<file>CustomComboBox.qml</file>
|
||||
<file>CustomMenuItem.qml</file>
|
||||
<file>CustomMenu.qml</file>
|
||||
<file>ControlsBar.qml</file>
|
||||
<file>MainMenu.qml</file>
|
||||
<file>TrackItem.qml</file>
|
||||
<file>AudioDeviceItem.qml</file>
|
||||
<file>Translator.qml</file>
|
||||
<file>translations.js</file>
|
||||
<file>icons/play.svg</file>
|
||||
<file>icons/pause.svg</file>
|
||||
<file>icons/forward.svg</file>
|
||||
<file>icons/backward.svg</file>
|
||||
<file>icons/settings.svg</file>
|
||||
<file>icons/fullscreen.svg</file>
|
||||
<file>icons/volume-up.svg</file>
|
||||
<file>icons/volume-mute.svg</file>
|
||||
<file>icons/volume-down.svg</file>
|
||||
<file>icons/next.svg</file>
|
||||
<file>icons/prev.svg</file>
|
||||
<file>icons/subtitles.svg</file>
|
||||
<file>YouTubeButtonLayout.qml</file>
|
||||
<file>NiconicoButtonLayout.qml</file>
|
||||
<file alias="PlaylistPrevButton.qml">UIComponents/PlaylistPrevButton.qml</file>
|
||||
<file alias="PlayPauseButton.qml">UIComponents/PlayPauseButton.qml</file>
|
||||
<file alias="VideoProgress.qml">UIComponents/VideoProgress.qml</file>
|
||||
<file alias="VolumeButton.qml">UIComponents/VolumeButton.qml</file>
|
||||
<file alias="VolumeSlider.qml">UIComponents/VolumeSlider.qml</file>
|
||||
<file alias="TimeLabel.qml">UIComponents/TimeLabel.qml</file>
|
||||
<file alias="SettingsButton.qml">UIComponents/SettingsButton.qml</file>
|
||||
<file alias="FullscreenButton.qml">UIComponents/FullscreenButton.qml</file>
|
||||
<file alias="PlaylistNextButton.qml">UIComponents/PlaylistNextButton.qml</file>
|
||||
<file alias="codes.js">Utils/codes.js</file>
|
||||
<file alias="Translator.qml">Utils/Translator.qml</file>
|
||||
<file alias="translations.js">Utils/translations.js</file>
|
||||
<file alias="ChapterMarkerItem.qml">Items/ChapterMarkerItem.qml</file>
|
||||
<file alias="TrackItem.qml">Items/TrackItem.qml</file>
|
||||
<file alias="AudioDeviceItem.qml">Items/AudioDeviceItem.qml</file>
|
||||
<file alias="CustomMenuItem.qml">Items/CustomMenuItem.qml</file>
|
||||
<file alias="PlaylistDialog.qml">Dialogs/PlaylistDialog.qml</file>
|
||||
<file>icons/YouTube/play.svg</file>
|
||||
<file>icons/YouTube/pause.svg</file>
|
||||
<file>icons/YouTube/forward.svg</file>
|
||||
<file>icons/YouTube/backward.svg</file>
|
||||
<file>icons/YouTube/settings.svg</file>
|
||||
<file>icons/YouTube/fullscreen.svg</file>
|
||||
<file>icons/YouTube/volume-up.svg</file>
|
||||
<file>icons/YouTube/volume-mute.svg</file>
|
||||
<file>icons/YouTube/volume-down.svg</file>
|
||||
<file>icons/YouTube/next.svg</file>
|
||||
<file>icons/YouTube/prev.svg</file>
|
||||
<file>icons/YouTube/subtitles.svg</file>
|
||||
<file>icons/YouTube/playlist.svg</file>
|
||||
<file>icons/Niconico/play.svg</file>
|
||||
<file>icons/Niconico/pause.svg</file>
|
||||
<file>icons/Niconico/settings.svg</file>
|
||||
<file>icons/Niconico/volume-up.svg</file>
|
||||
<file>icons/Niconico/volume-down.svg</file>
|
||||
<file>icons/Niconico/volume-mute.svg</file>
|
||||
<file>icons/Niconico/prev.svg</file>
|
||||
<file>icons/Niconico/next.svg</file>
|
||||
<file>icons/Niconico/fullscreen.svg</file>
|
||||
<file>icons/nyancat.gif</file>
|
||||
<file>icons/rainbow.png</file>
|
||||
<file>icons/playlist.svg</file>
|
||||
<file>codes.js</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
|