diff --git a/src/qml/CustomComboBox.qml b/src/qml/CustomComboBox.qml new file mode 100644 index 0000000..fa99df9 --- /dev/null +++ b/src/qml/CustomComboBox.qml @@ -0,0 +1,81 @@ +import QtQuick 2.11 +import QtQuick.Controls 2.4 +import QtQuick.Dialogs 1.3 +import QtQuick.Layouts 1.11 +import QtQuick.Window 2.11 + +ComboBox { + id: control + width: parent.width + + FontLoader { + id: notoFont + source: "fonts/NotoSans.ttf" + } + + 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: notoFont.name + color: "white" + verticalAlignment: Text.AlignVCenter + elide: Text.ElideRight + } + + background: Rectangle { + implicitWidth: 120 + implicitHeight: 40 + color: "transparent" + border.color: "black" + border.width: 2 + } + + 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: "white" + border.color: "black" + border.width: 2 + } + } +} \ No newline at end of file diff --git a/src/qml/CustomMenuItem.qml b/src/qml/CustomMenuItem.qml new file mode 100644 index 0000000..e8e7b93 --- /dev/null +++ b/src/qml/CustomMenuItem.qml @@ -0,0 +1,33 @@ +import QtQuick 2.11 +import QtQuick.Controls 2.4 +import QtQuick.Dialogs 1.3 +import QtQuick.Layouts 1.11 +import QtQuick.Window 2.11 + +MenuItem { + FontLoader { + id: notoFont + source: "fonts/NotoSans.ttf" + } + id: menuItem + implicitWidth: 100 + implicitHeight: 20 + + contentItem: Text { + rightPadding: menuItem.arrow.width + text: menuItem.text + font.family: notoFont.name + opacity: 1 + color: menuItem.highlighted ? "#5a50da" : "white" + horizontalAlignment: Text.AlignLeft + verticalAlignment: Text.AlignVCenter + elide: Text.ElideRight + } + + background: Rectangle { + implicitWidth: 200 + implicitHeight: 20 + opacity: 1 + color: menuItem.highlighted ? "#c0c0f0" : "transparent" + } + } \ No newline at end of file diff --git a/src/qml/main.qml b/src/qml/main.qml index bc0846a..26ee2e6 100644 --- a/src/qml/main.qml +++ b/src/qml/main.qml @@ -17,8 +17,7 @@ ApplicationWindow { FontLoader { id: notoFont source: "fonts/NotoSans.ttf" - } - + } property int lastScreenVisibility @@ -67,7 +66,6 @@ ApplicationWindow { } function updateControls() { - keybinds.focus = true updatePrev() updatePlayPauseIcon() updateVolume() @@ -78,10 +76,6 @@ ApplicationWindow { updatePlayPauseIcon() } - function setSubtitle(sub) { - console.log(sub) - } - function tracksMenuUpdate() { var tracks = player.getProperty("track-list/count") var track = 0 @@ -135,14 +129,16 @@ ApplicationWindow { MpvObject { id: player anchors.fill: parent + width: parent.width + height: parent.height Timer { id: initTimer - interval: 2000 + interval: 1000 running: false - repeat: false + repeat: false onTriggered: { - player.startPlayer() + player.startPlayer() } } Component.onCompleted: { initTimer.start() } @@ -199,6 +195,16 @@ ApplicationWindow { progressBar.value = val } + function skipToNinth(val) { + console.log(val) + var skipto = 0 + if (val != 0) { + skipto = Math.floor(progressBar.to / 9 * val) + } + console.log(skipto) + player.command(["seek", skipto, "absolute"]) + } + function setTitle() { titleLabel.text = player.getProperty("media-title") } @@ -208,7 +214,7 @@ ApplicationWindow { } function hideControls() { - if ( ! (subtitlesMenu.visible || settingsMenu.visible) ) { + if ( ! (subtitlesMenu.visible || settingsMenu.visible || fileMenuBarItem.opened) ) { player.setOption("sub-margin-y", "22") controlsBar.visible = false controlsBackground.visible = false @@ -303,17 +309,36 @@ ApplicationWindow { } } + /*Item { + id: keybinds + anchors.fill: parent + focus: true + Keys.onPressed: { + if (event.key == Qt.Key_K || event.key == Qt.Key_Space) { + player.command(["cycle", "pause"]) + } else if (event.key == Qt.Key_J) { + player.command(["seek", "-10"]) + } else if (event.key == Qt.Key_L) { + player.command(["seek", "10"]) + } else if (event.key == Qt.Key_I) { + player.command(["script-binding", "stats/display-stats-toggle"]) + } + updateControls() + } + }*/ + MenuBar { id: menuBar - contentWidth: parent.width + //width: parent.width + height: Screen.height / 24 delegate: MenuBarItem { id: menuBarItem contentItem: Text { text: menuBarItem.text font.family: notoFont.name - font.pixelSize: 12 + font.pixelSize: 14 renderType: Text.NativeRendering opacity: 1 color: menuBarItem.highlighted ? "#5a50da" : "white" @@ -338,36 +363,228 @@ ApplicationWindow { } Menu { + id: fileMenuBarItem title: "File" - MenuItem { + width: 100 + background: Rectangle { + implicitWidth: parent.width + implicitHeight: 10 + color: "black" + opacity: 0.6 + } + delegate: CustomMenuItem {} + + + Action { text: "Open File" onTriggered: fileDialog.open() + shortcut: "Ctrl+O" } - MenuItem { + Action { text: "Open URI/URL" onTriggered: loadDialog.open() + shortcut: "Ctrl+Shift+O" + } - MenuItem { + Action { text: "Exit" onTriggered: Qt.quit() + shortcut: "Ctrl+Q" + } + } + + Menu { + id: playbackMenuBarItem + title: "Playback" + width: 100 + background: Rectangle { + implicitWidth: parent.width + implicitHeight: 10 + color: "black" + opacity: 0.6 + } + delegate: CustomMenuItem { width: 100 } + + Action { + text: "Play/Pause" + onTriggered: { + player.command(["cycle", "pause"]) + updateControls() + } + shortcut: "K,Space" + } + Action { + text: "Rewind 10s" + onTriggered: { + player.command(["seek", "-10"]) + updateControls() + } + shortcut: "J" + } + Action { + text: "Forward 10s" + onTriggered: { + player.command(["seek", "10"]) + updateControls() + } + shortcut: "L" + } + } + + Menu { + id: viewMenuBarItem + title: "View" + width: 100 + background: Rectangle { + implicitWidth: parent.width + implicitHeight: 10 + color: "black" + opacity: 0.6 + } + delegate: CustomMenuItem {} + + Action { + text: "Tracks" + onTriggered: { + tracksMenuUpdate() + subtitlesMenu.visible = !subtitlesMenu.visible + subtitlesMenuBackground.visible = !subtitlesMenuBackground.visible + } + shortcut: "Ctrl+T" } - } - /*Menu { - title: "Help" - MenuItem { - text: "About" - onTriggered: aboutDialog.open() + Action { + text: "Fullscreen" + onTriggered: { + toggleFullscreen() + } + shortcut: "F" } - }*/ + } + + + Action { onTriggered: player.skipToNinth(parseInt(shortcut)); shortcut: "1";} + Action { onTriggered: player.skipToNinth(parseInt(shortcut)); shortcut: "2";} + Action { onTriggered: player.skipToNinth(parseInt(shortcut)); shortcut: "3";} + Action { onTriggered: player.skipToNinth(parseInt(shortcut)); shortcut: "4";} + Action { onTriggered: player.skipToNinth(parseInt(shortcut)); shortcut: "5";} + Action { onTriggered: player.skipToNinth(parseInt(shortcut)); shortcut: "6";} + Action { onTriggered: player.skipToNinth(parseInt(shortcut)); shortcut: "7";} + Action { onTriggered: player.skipToNinth(parseInt(shortcut)); shortcut: "8";} + Action { onTriggered: player.skipToNinth(parseInt(shortcut)); shortcut: "9";} + Action { onTriggered: player.skipToNinth(parseInt(shortcut)); shortcut: "0";) + } + Rectangle { + id: subtitlesMenuBackground + anchors.fill: subtitlesMenu + Layout.fillWidth: true + Layout.fillHeight: true + visible: false + color: "black" + opacity: 0.6 + } + + + Rectangle { + id: subtitlesMenu + color: "transparent" + width: childrenRect.width + height: childrenRect.height + visible: false + anchors.centerIn: player + anchors.right: player.right + anchors.bottom: progressBar.top + border.color: "black" + border.width: 2 + + + Text { + id: audioLabel + anchors.left: parent.left + anchors.right: parent.right + text: "Audio" + color: "white" + font.family: notoFont.name + font.pixelSize: 14 + renderType: Text.NativeRendering + horizontalAlignment: Text.AlignHCenter + opacity: 1 + } + ComboBox { + id: audioList + textRole: "key" + anchors.top: audioLabel.bottom + model: ListModel { + id: audioModel + } + onActivated: { + player.command(["set", "aid", String( + audioModel.get(index).value)]) + } + opacity: 1 + } + Text { + id: subLabel + anchors.left: parent.left + anchors.right: parent.right + text: "Subtitles" + color: "white" + font.family: notoFont.name + font.pixelSize: 14 + anchors.top: audioList.bottom + renderType: Text.NativeRendering + horizontalAlignment: Text.AlignHCenter + opacity: 1 + } + ComboBox { + id: subList + textRole: "key" + anchors.top: subLabel.bottom + model: ListModel { + id: subModel + } + onActivated: { + player.command(["set", "sid", String( + subModel.get(index).value)]) + } + opacity: 1 + } + Text { + id: vidLabel + anchors.left: parent.left + anchors.right: parent.right + text: "Video" + color: "white" + font.family: notoFont.name + font.pixelSize: 14 + anchors.top: subList.bottom + renderType: Text.NativeRendering + horizontalAlignment: Text.AlignHCenter + opacity: 1 + } + ComboBox { + id: vidList + textRole: "key" + anchors.top: vidLabel.bottom + model: ListModel { + id: vidModel + } + onActivated: { + player.command(["set", "vid", String( + vidModel.get(index).value)]) + } + opacity: 1 + } + } + Rectangle { id: titleBackground height: titleBar.height anchors.top: titleBar.top - anchors.left: parent.left - anchors.right: parent.right + anchors.left: titleBar.left + anchors.right: titleBar.right Layout.fillWidth: true Layout.fillHeight: true color: "black" @@ -376,12 +593,10 @@ ApplicationWindow { Rectangle { id: titleBar - height: Screen.height / 24 + height: menuBar.height anchors.right: parent.right - anchors.rightMargin: parent.width / 128 - anchors.left: parent.left - anchors.leftMargin: parent.width / 128 - anchors.top: menuBar.bottom + anchors.left: menuBar.right + anchors.top: parent.top visible: true color: "transparent" @@ -393,6 +608,7 @@ ApplicationWindow { width: parent.width height: parent.height anchors.left: parent.left + anchors.leftMargin: 10 anchors.bottom: parent.bottom anchors.bottomMargin: 4 anchors.topMargin: 4 @@ -497,107 +713,6 @@ ApplicationWindow { } } - Rectangle { - id: subtitlesMenuBackground - anchors.fill: subtitlesMenu - Layout.fillWidth: true - Layout.fillHeight: true - visible: false - color: "black" - opacity: 0.6 - radius: 5 - } - - - Rectangle { - id: subtitlesMenu - color: "transparent" - width: childrenRect.width - height: childrenRect.height - visible: false - anchors.right: subtitlesButton.right - anchors.bottom: progressBar.top - radius: 5 - - Text { - id: audioLabel - anchors.left: parent.left - anchors.right: parent.right - text: "Audio" - color: "white" - font.family: notoFont.name - font.pixelSize: 14 - renderType: Text.NativeRendering - horizontalAlignment: Text.AlignHCenter - opacity: 1 - } - ComboBox { - id: audioList - textRole: "key" - anchors.top: audioLabel.bottom - model: ListModel { - id: audioModel - } - onActivated: { - player.command(["set", "aid", String( - audioModel.get(index).value)]) - } - opacity: 1 - } - Text { - id: subLabel - anchors.left: parent.left - anchors.right: parent.right - text: "Subtitles" - color: "white" - font.family: notoFont.name - font.pixelSize: 14 - anchors.top: audioList.bottom - renderType: Text.NativeRendering - horizontalAlignment: Text.AlignHCenter - opacity: 1 - } - ComboBox { - id: subList - textRole: "key" - anchors.top: subLabel.bottom - model: ListModel { - id: subModel - } - onActivated: { - player.command(["set", "sid", String( - subModel.get(index).value)]) - } - opacity: 1 - } - Text { - id: vidLabel - anchors.left: parent.left - anchors.right: parent.right - text: "Video" - color: "white" - font.family: notoFont.name - font.pixelSize: 14 - anchors.top: subList.bottom - renderType: Text.NativeRendering - horizontalAlignment: Text.AlignHCenter - opacity: 1 - } - ComboBox { - id: vidList - textRole: "key" - anchors.top: vidLabel.bottom - model: ListModel { - id: vidModel - } - onActivated: { - player.command(["set", "vid", String( - vidModel.get(index).value)]) - } - opacity: 1 - } - } - Slider { id: progressBar to: 1 @@ -838,22 +953,5 @@ ApplicationWindow { } } - Item { - id: keybinds - anchors.fill: parent - focus: true - Keys.onPressed: { - if (event.key == Qt.Key_K || event.key == Qt.Key_Space) { - player.command(["cycle", "pause"]) - } else if (event.key == Qt.Key_J) { - player.command(["seek", "-10"]) - } else if (event.key == Qt.Key_L) { - player.command(["seek", "10"]) - } else if (event.key == Qt.Key_I) { - player.command(["script-binding", "stats/display-stats-toggle"]) - } - updateControls() - } - } } } diff --git a/src/qml/qml.qrc b/src/qml/qml.qrc index 517a557..facae97 100644 --- a/src/qml/qml.qrc +++ b/src/qml/qml.qrc @@ -1,6 +1,8 @@ main.qml + CustomComboBox.qml + CustomMenuItem.qml icons/play.svg icons/pause.svg icons/forward.svg