1
0
Fork 0

[UI] Improved Menu Bar, Custom Components, Better Keybinds.

This commit is contained in:
Kitteh 2018-10-24 14:24:32 +01:00
parent 33d616ca88
commit 75798b1c42
4 changed files with 362 additions and 148 deletions

View file

@ -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
}
}
}

View file

@ -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"
}
}

View file

@ -19,7 +19,6 @@ ApplicationWindow {
source: "fonts/NotoSans.ttf" source: "fonts/NotoSans.ttf"
} }
property int lastScreenVisibility property int lastScreenVisibility
function toggleFullscreen() { function toggleFullscreen() {
@ -67,7 +66,6 @@ ApplicationWindow {
} }
function updateControls() { function updateControls() {
keybinds.focus = true
updatePrev() updatePrev()
updatePlayPauseIcon() updatePlayPauseIcon()
updateVolume() updateVolume()
@ -78,10 +76,6 @@ ApplicationWindow {
updatePlayPauseIcon() updatePlayPauseIcon()
} }
function setSubtitle(sub) {
console.log(sub)
}
function tracksMenuUpdate() { function tracksMenuUpdate() {
var tracks = player.getProperty("track-list/count") var tracks = player.getProperty("track-list/count")
var track = 0 var track = 0
@ -135,14 +129,16 @@ ApplicationWindow {
MpvObject { MpvObject {
id: player id: player
anchors.fill: parent anchors.fill: parent
width: parent.width
height: parent.height
Timer { Timer {
id: initTimer id: initTimer
interval: 2000 interval: 1000
running: false running: false
repeat: false repeat: false
onTriggered: { onTriggered: {
player.startPlayer() player.startPlayer()
} }
} }
Component.onCompleted: { initTimer.start() } Component.onCompleted: { initTimer.start() }
@ -199,6 +195,16 @@ ApplicationWindow {
progressBar.value = val 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() { function setTitle() {
titleLabel.text = player.getProperty("media-title") titleLabel.text = player.getProperty("media-title")
} }
@ -208,7 +214,7 @@ ApplicationWindow {
} }
function hideControls() { function hideControls() {
if ( ! (subtitlesMenu.visible || settingsMenu.visible) ) { if ( ! (subtitlesMenu.visible || settingsMenu.visible || fileMenuBarItem.opened) ) {
player.setOption("sub-margin-y", "22") player.setOption("sub-margin-y", "22")
controlsBar.visible = false controlsBar.visible = false
controlsBackground.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 { MenuBar {
id: menuBar id: menuBar
contentWidth: parent.width //width: parent.width
height: Screen.height / 24
delegate: MenuBarItem { delegate: MenuBarItem {
id: menuBarItem id: menuBarItem
contentItem: Text { contentItem: Text {
text: menuBarItem.text text: menuBarItem.text
font.family: notoFont.name font.family: notoFont.name
font.pixelSize: 12 font.pixelSize: 14
renderType: Text.NativeRendering renderType: Text.NativeRendering
opacity: 1 opacity: 1
color: menuBarItem.highlighted ? "#5a50da" : "white" color: menuBarItem.highlighted ? "#5a50da" : "white"
@ -338,36 +363,228 @@ ApplicationWindow {
} }
Menu { Menu {
id: fileMenuBarItem
title: "File" title: "File"
MenuItem { width: 100
background: Rectangle {
implicitWidth: parent.width
implicitHeight: 10
color: "black"
opacity: 0.6
}
delegate: CustomMenuItem {}
Action {
text: "Open File" text: "Open File"
onTriggered: fileDialog.open() onTriggered: fileDialog.open()
shortcut: "Ctrl+O"
} }
MenuItem { Action {
text: "Open URI/URL" text: "Open URI/URL"
onTriggered: loadDialog.open() onTriggered: loadDialog.open()
shortcut: "Ctrl+Shift+O"
} }
MenuItem { Action {
text: "Exit" text: "Exit"
onTriggered: Qt.quit() 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"
} }
} Action {
/*Menu { text: "Fullscreen"
title: "Help" onTriggered: {
MenuItem { toggleFullscreen()
text: "About" }
onTriggered: aboutDialog.open() 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 { Rectangle {
id: titleBackground id: titleBackground
height: titleBar.height height: titleBar.height
anchors.top: titleBar.top anchors.top: titleBar.top
anchors.left: parent.left anchors.left: titleBar.left
anchors.right: parent.right anchors.right: titleBar.right
Layout.fillWidth: true Layout.fillWidth: true
Layout.fillHeight: true Layout.fillHeight: true
color: "black" color: "black"
@ -376,12 +593,10 @@ ApplicationWindow {
Rectangle { Rectangle {
id: titleBar id: titleBar
height: Screen.height / 24 height: menuBar.height
anchors.right: parent.right anchors.right: parent.right
anchors.rightMargin: parent.width / 128 anchors.left: menuBar.right
anchors.left: parent.left anchors.top: parent.top
anchors.leftMargin: parent.width / 128
anchors.top: menuBar.bottom
visible: true visible: true
color: "transparent" color: "transparent"
@ -393,6 +608,7 @@ ApplicationWindow {
width: parent.width width: parent.width
height: parent.height height: parent.height
anchors.left: parent.left anchors.left: parent.left
anchors.leftMargin: 10
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
anchors.bottomMargin: 4 anchors.bottomMargin: 4
anchors.topMargin: 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 { Slider {
id: progressBar id: progressBar
to: 1 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()
}
}
} }
} }

View file

@ -1,6 +1,8 @@
<RCC> <RCC>
<qresource prefix="/player"> <qresource prefix="/player">
<file>main.qml</file> <file>main.qml</file>
<file>CustomComboBox.qml</file>
<file>CustomMenuItem.qml</file>
<file>icons/play.svg</file> <file>icons/play.svg</file>
<file>icons/pause.svg</file> <file>icons/pause.svg</file>
<file>icons/forward.svg</file> <file>icons/forward.svg</file>