1
0
Fork 0
VideoPlayer/src/qml/main.qml

1357 lines
49 KiB
QML
Raw Normal View History

2018-10-29 00:35:24 +00:00
import QtQuick 2.11
2018-10-13 15:38:31 +01:00
import QtQuick.Controls 2.4
import QtQuick.Dialogs 1.3
import QtQuick.Layouts 1.11
import QtQuick.Window 2.11
2018-10-24 17:41:41 +01:00
import Qt.labs.settings 1.0
2018-11-04 15:11:50 +00:00
import Qt.labs.platform 1.0 as LabsPlatform
2018-10-13 15:38:31 +01:00
import player 1.0
import "codes.js" as LanguageCodes
2018-10-23 23:19:26 +01:00
ApplicationWindow {
2018-10-13 15:38:31 +01:00
id: mainWindow
title: titleLabel.text
2018-10-13 15:38:31 +01:00
visible: true
width: 720
height: 480
Translator {
id: translate
2018-10-24 19:49:05 +01:00
}
2018-10-23 23:19:26 +01:00
2018-10-13 15:38:31 +01:00
property int lastScreenVisibility
2018-10-16 16:55:25 +01:00
function toggleFullscreen() {
if (mainWindow.visibility != Window.FullScreen) {
lastScreenVisibility = mainWindow.visibility
mainWindow.visibility = Window.FullScreen
} else {
mainWindow.visibility = lastScreenVisibility
}
}
2018-10-13 15:38:31 +01:00
function tracksMenuUpdate() {
subModel.clear()
audioModel.clear()
vidModel.clear()
2018-11-04 13:21:50 +00:00
var newTracks = player.getTracks()
2018-11-06 07:37:05 +00:00
for (var i = 0, len = newTracks.length; i < len; i++) {
2018-11-04 13:21:50 +00:00
var track = newTracks[i]
var trackID = track["id"]
var trackType = track["type"]
2018-11-06 07:37:05 +00:00
var trackLang = LanguageCodes.localeCodeToEnglish(
String(track["lang"]))
2018-11-04 13:21:50 +00:00
var trackTitle = track["title"]
2018-10-13 15:38:31 +01:00
if (trackType == "sub") {
subModel.append({
key: trackLang,
value: trackID
})
2018-11-04 13:21:50 +00:00
if (track["selected"]) {
subList.currentIndex = subList.count - 1
2018-10-13 15:38:31 +01:00
}
} else if (trackType == "audio") {
audioModel.append({
key: (trackTitle === undefined ? "" : trackTitle + " ")
+ trackLang,
value: trackID
})
2018-11-04 13:21:50 +00:00
if (track["selected"]) {
audioList.currentIndex = audioList.count - 1
2018-10-13 15:38:31 +01:00
}
} else if (trackType == "video") {
vidModel.append({
key: "Video " + trackID,
value: trackID
})
2018-11-04 13:21:50 +00:00
if (track["selected"]) {
vidList.currentIndex = vidList.count - 1
2018-10-13 15:38:31 +01:00
}
}
}
}
PlayerBackend {
2018-10-23 15:42:44 +01:00
id: player
2018-10-13 15:38:31 +01:00
anchors.fill: parent
width: parent.width
height: parent.height
2018-10-18 11:07:09 +01:00
2018-10-29 16:12:19 +00:00
Settings {
id: appearance
category: "Appearance"
property bool titleOnlyOnFullscreen: true
property bool clickToPause: true
property bool useMpvSubs: false
property string fontName: "Roboto"
}
Settings {
id: i18n
category: "I18N"
property string language: "english"
2018-10-29 16:12:19 +00:00
}
Settings {
id: fun
category: "Fun"
property bool nyanCat: false
}
2018-10-18 11:07:09 +01:00
function startPlayer() {
2018-10-13 15:38:31 +01:00
var args = Qt.application.arguments
var len = Qt.application.arguments.length
var argNo = 0
2018-10-29 16:12:19 +00:00
if (!appearance.useMpvSubs) {
player.setOption("sub-font", "Noto Sans")
player.setOption("sub-font-size", "24")
player.setOption("sub-ass-override", "force")
player.setOption("sub-ass", "off")
player.setOption("sub-border-size", "0")
player.setOption("sub-bold", "off")
player.setOption("sub-scale-by-window", "on")
player.setOption("sub-scale-with-window", "on")
player.setOption("sub-color", "0.0/0.0/0.0/0.0")
player.setOption("sub-border-color", "0.0/0.0/0.0/0.0")
player.setOption("sub-back-color", "0.0/0.0/0.0/0.0")
}
2018-10-23 15:42:44 +01:00
player.setOption("ytdl-format", "bestvideo[width<=" + Screen.width
2018-10-24 19:49:05 +01:00
+ "][height<=" + Screen.height + "]+bestaudio")
2018-10-13 15:38:31 +01:00
if (len > 1) {
for (argNo = 1; argNo < len; argNo++) {
2018-10-13 15:38:31 +01:00
var argument = args[argNo]
2018-10-24 19:49:05 +01:00
if (argument.indexOf("KittehPlayer") !== -1) {
continue
}
2018-10-21 13:00:25 +01:00
if (argument.startsWith("--")) {
2018-10-13 15:38:31 +01:00
argument = argument.substr(2)
if (argument.length > 0) {
var splitArg = argument.split(/=(.+)/)
if (splitArg[0] == "fullscreen") {
toggleFullscreen()
} else {
if (splitArg[1].length == 0) {
splitArg[1] = "true"
}
2018-10-23 15:42:44 +01:00
player.setOption(splitArg[0], splitArg[1])
}
}
2018-10-24 19:49:05 +01:00
} else {
player.loadFile(argument)
2018-10-21 13:00:25 +01:00
}
2018-10-13 15:38:31 +01:00
}
}
}
function setProgressBarEnd(val) {
progressBar.to = val
2018-10-29 00:35:24 +00:00
}
2018-10-13 15:38:31 +01:00
function setProgressBarValue(val) {
timeLabel.text = player.createTimestamp(val) + " / " + player.createTimestamp(
2018-10-29 00:35:24 +00:00
progressBar.to) + " (" + parseFloat(
player.getProperty("speed").toFixed(2)) + "x)"
2018-10-13 15:38:31 +01:00
progressBar.value = val
}
function skipToNinth(val) {
var skipto = 0
if (val != 0) {
skipto = Math.floor(progressBar.to / 9 * val)
}
player.command(["seek", skipto, "absolute"])
}
2018-10-26 15:13:14 +01:00
function updatePrev(val) {
if (val != 0) {
playlistPrevButton.visible = true
playlistPrevButton.width = playPauseButton.width
} else {
playlistPrevButton.visible = false
playlistPrevButton.width = 0
}
2018-10-13 15:38:31 +01:00
}
2018-10-26 15:13:14 +01:00
function updateVolume(volume) {
var muted = player.getProperty("mute")
if (muted || volume === 0) {
volumeButton.icon.source = "qrc:/player/icons/volume-mute.svg"
} else {
if (volume < 25) {
volumeButton.icon.source = "qrc:/player/icons/volume-down.svg"
} else {
volumeButton.icon.source = "qrc:/player/icons/volume-up.svg"
}
}
}
function updateMuted(muted) {
if (muted) {
volumeButton.icon.source = "qrc:/player/icons/volume-mute.svg"
}
}
function updatePlayPause() {
var paused = player.getProperty("pause")
if (paused) {
playPauseButton.icon.source = "qrc:/player/icons/play.svg"
} else {
playPauseButton.icon.source = "qrc:/player/icons/pause.svg"
}
}
function setTitle(title) {
titleLabel.text = title
}
function setSubtitles(subs) {
nativeSubs.text = subs
}
2018-10-24 15:50:22 +01:00
function isAnyMenuOpen() {
2018-10-24 19:49:05 +01:00
return subtitlesMenu.visible || settingsMenu.visible
|| fileMenuBarItem.opened || playbackMenuBarItem.opened
2018-10-28 12:19:24 +00:00
|| viewMenuBarItem.opened || audioMenuBarItem.opened
2018-10-29 16:12:19 +00:00
|| videoMenuBarItem.opened || subsMenuBarItem.opened
|| aboutMenuBarItem.opened
2018-10-24 15:50:22 +01:00
}
function hideControls(force) {
if (!isAnyMenuOpen() || force) {
2018-10-21 14:32:39 +01:00
controlsBar.visible = false
controlsBackground.visible = false
titleBar.visible = false
titleBackground.visible = false
2018-10-23 23:19:26 +01:00
menuBar.visible = false
2018-10-21 14:32:39 +01:00
}
2018-10-13 15:38:31 +01:00
}
function showControls() {
2018-10-24 19:49:05 +01:00
if (!controlsBar.visible) {
controlsBar.visible = true
controlsBackground.visible = true
if (appearance.titleOnlyOnFullscreen) {
if (mainWindow.visibility == Window.FullScreen) {
titleBar.visible = true
}
} else {
titleBar.visible = true
}
titleBackground.visible = true
2018-10-23 23:19:26 +01:00
menuBar.visible = true
}
2018-10-13 15:38:31 +01:00
}
2018-11-04 15:11:50 +00:00
LabsPlatform.FileDialog {
id: screenshotSaveDialog
title: translate.getTranslation("SAVE_SCREENSHOT", i18n.language)
2018-11-04 15:11:50 +00:00
fileMode: LabsPlatform.FileDialog.SaveFile
defaultSuffix: "png"
nameFilters: ["Images (*.png)", "All files (*)"]
onAccepted: {
player.grabToImage(function (result) {
2018-11-04 15:11:50 +00:00
var filepath = String(screenshotSaveDialog.file).replace(
"file://", '')
result.saveToFile(filepath)
2018-10-29 16:12:19 +00:00
subtitlesBar.visible = appearance.useMpvSubs ? false : true
})
}
}
2018-11-04 15:11:50 +00:00
LabsPlatform.FileDialog {
2018-10-21 15:42:52 +01:00
id: fileDialog
title: translate.getTranslation("OPEN_FILE", i18n.language)
nameFilters: ["All files (*)"]
2018-10-21 15:42:52 +01:00
onAccepted: {
2018-11-04 15:11:50 +00:00
player.loadFile(String(fileDialog.file))
2018-10-21 15:42:52 +01:00
fileDialog.close()
}
onRejected: {
fileDialog.close()
}
}
Dialog {
id: loadDialog
title: translate.getTranslation("URL_FILE_PATH", i18n.language)
2018-10-21 15:42:52 +01:00
standardButtons: StandardButton.Cancel | StandardButton.Open
onAccepted: {
2018-11-04 13:04:26 +00:00
player.loadFile(pathText.text)
2018-10-24 19:49:05 +01:00
pathText.text = ""
}
2018-10-21 15:42:52 +01:00
TextField {
id: pathText
placeholderText: translate.getTranslation("URL_FILE_PATH",
i18n.language)
}
}
2018-10-13 15:38:31 +01:00
MouseArea {
id: mouseAreaBar
x: 0
y: parent.height
2018-10-13 15:38:31 +01:00
width: parent.width
height: (controlsBar.height * 2) + progressBar.height
2018-10-13 15:38:31 +01:00
anchors.bottom: parent.bottom
anchors.bottomMargin: 0
hoverEnabled: true
onEntered: {
mouseAreaPlayerTimer.stop()
}
2018-10-13 15:38:31 +01:00
}
MouseArea {
id: mouseAreaPlayer
2018-10-29 16:12:19 +00:00
z: 1000
focus: true
width: parent.width
anchors.bottom: mouseAreaBar.top
anchors.bottomMargin: 10
anchors.right: parent.right
anchors.rightMargin: 0
anchors.left: parent.left
anchors.leftMargin: 0
anchors.top: titleBar.bottom
anchors.topMargin: 0
hoverEnabled: true
cursorShape: controlsBar.visible ? Qt.ArrowCursor : Qt.BlankCursor
2018-10-21 14:32:39 +01:00
onClicked: {
if (appearance.clickToPause) {
player.togglePlayPause()
}
2018-10-21 14:32:39 +01:00
}
Timer {
id: mouseAreaPlayerTimer
interval: 1000
2018-10-29 16:12:19 +00:00
running: true
repeat: false
onTriggered: {
2018-10-23 15:42:44 +01:00
player.hideControls()
}
}
onPositionChanged: {
2018-10-23 15:42:44 +01:00
player.showControls()
mouseAreaPlayerTimer.restart()
}
}
2018-10-13 15:38:31 +01:00
2018-10-24 17:41:41 +01:00
Settings {
id: keybinds
category: "Keybinds"
property string playPause: "K"
property string forward10: "L"
property string rewind10: "J"
property string forward5: "Right"
property string rewind5: "Left"
property string openFile: "Ctrl+O"
property string openURI: "Ctrl+Shift+O"
property string quit: "Ctrl+Q"
property string fullscreen: "F"
property string tracks: "Ctrl+T"
property string statsForNerds: "I"
2018-10-24 18:02:46 +01:00
property string forwardFrame: "."
property string backwardFrame: ","
property string cycleSub: "Alt+S"
property string cycleSubBackwards: "Alt+Shift+S"
property string cycleAudio: "A"
property string cycleVideo: "V"
property string cycleVideoAspect: "Shift+A"
property string screenshot: "S"
property string screenshotWithoutSubtitles: "Shift+S"
property string fullScreenshot: "Ctrl+S"
2018-10-26 19:11:07 +01:00
property string nyanCat: "Ctrl+N"
2018-10-27 11:34:13 +01:00
property string decreaseSpeedBy10Percent: "["
property string increaseSpeedBy10Percent: "]"
property string halveSpeed: "{"
property string doubleSpeed: "}"
2018-10-28 12:19:24 +00:00
property string increaseVolume: "*"
property string decreaseVolume: "/"
property string mute: "m"
2018-11-06 07:37:05 +00:00
property string customKeybind0: ""
property string customKeybind0Command: ""
2018-11-06 07:37:05 +00:00
property string customKeybind1: ""
property string customKeybind1Command: ""
2018-11-06 07:37:05 +00:00
property string customKeybind2: ""
property string customKeybind2Command: ""
2018-11-06 07:37:05 +00:00
property string customKeybind3: ""
property string customKeybind3Command: ""
2018-11-06 07:37:05 +00:00
property string customKeybind4: ""
property string customKeybind4Command: ""
2018-11-06 07:37:05 +00:00
property string customKeybind5: ""
property string customKeybind5Command: ""
2018-11-06 07:37:05 +00:00
property string customKeybind6: ""
property string customKeybind6Command: ""
2018-11-06 07:37:05 +00:00
property string customKeybind7: ""
property string customKeybind7Command: ""
2018-11-06 07:37:05 +00:00
property string customKeybind8: ""
property string customKeybind8Command: ""
2018-11-06 07:37:05 +00:00
property string customKeybind9: ""
property string customKeybind9Command: ""
2018-10-24 17:41:41 +01:00
}
2018-10-24 19:49:05 +01:00
MenuBar {
id: menuBar
//width: parent.width
2018-11-01 20:32:00 +00:00
height: Math.max(24, Screen.height / 32)
2018-10-24 19:49:05 +01:00
delegate: MenuBarItem {
id: menuBarItem
2018-10-23 23:19:26 +01:00
padding: 4
topPadding: padding
leftPadding: padding
rightPadding: padding
bottomPadding: padding
2018-10-24 19:49:05 +01:00
contentItem: Text {
id: menuBarItemText
2018-10-24 19:49:05 +01:00
text: menuBarItem.text
font.family: appearance.fontName
2018-10-24 19:49:05 +01:00
font.pixelSize: 14
font.bold: menuBarItem.highlighted
2018-10-24 19:49:05 +01:00
opacity: 1
color: menuBarItem.highlighted ? "#5a50da" : "white"
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight
renderType: Text.NativeRendering
2018-10-24 19:49:05 +01:00
}
2018-10-23 23:19:26 +01:00
2018-10-24 19:49:05 +01:00
background: Rectangle {
implicitWidth: 10
implicitHeight: 10
opacity: 1
color: menuBarItem.highlighted ? "#c0c0f0" : "transparent"
}
2018-10-23 23:19:26 +01:00
}
background: Rectangle {
2018-10-27 16:11:29 +01:00
width: parent.width
implicitHeight: 10
color: "black"
opacity: 0.6
}
2018-10-24 19:49:05 +01:00
Menu {
id: fileMenuBarItem
title: translate.getTranslation("FILE_MENU", i18n.language)
font.family: appearance.fontName
width: 300
2018-10-24 19:49:05 +01:00
background: Rectangle {
implicitWidth: parent.width
implicitHeight: 10
color: "black"
opacity: 0.6
}
delegate: CustomMenuItem {
}
2018-10-24 19:49:05 +01:00
Action {
2018-11-02 08:09:18 +00:00
text: translate.getTranslation("OPEN_FILE", i18n.language)
2018-10-24 19:49:05 +01:00
onTriggered: fileDialog.open()
shortcut: keybinds.openFile
}
Action {
text: translate.getTranslation("OPEN_URL", i18n.language)
2018-10-24 19:49:05 +01:00
onTriggered: loadDialog.open()
shortcut: keybinds.openURI
}
Action {
text: translate.getTranslation("SCREENSHOT", i18n.language)
onTriggered: {
player.hideControls(true)
screenshotSaveDialog.open()
}
shortcut: keybinds.screenshot
}
Action {
text: translate.getTranslation(
"SCREENSHOT_WITHOUT_SUBTITLES", i18n.language)
onTriggered: {
player.hideControls(true)
2018-10-29 16:12:19 +00:00
subtitlesBar.visible = false
screenshotSaveDialog.open()
}
shortcut: keybinds.screenshotWithoutSubtitles
}
Action {
text: translate.getTranslation("FULL_SCREENSHOT",
i18n.language)
onTriggered: {
screenshotSaveDialog.open()
}
shortcut: keybinds.fullScreenshot
}
2018-10-24 19:49:05 +01:00
Action {
text: translate.getTranslation("EXIT", i18n.language)
2018-10-24 19:49:05 +01:00
onTriggered: Qt.quit()
shortcut: keybinds.quit
}
2018-10-23 23:19:26 +01:00
}
2018-10-24 19:49:05 +01:00
Menu {
id: playbackMenuBarItem
title: translate.getTranslation("PLAYBACK", i18n.language)
width: 300
2018-10-24 19:49:05 +01:00
background: Rectangle {
implicitWidth: parent.width
implicitHeight: 10
color: "black"
opacity: 0.6
}
delegate: CustomMenuItem {
2018-10-27 16:11:29 +01:00
width: parent.width
2018-10-24 19:49:05 +01:00
}
2018-10-23 23:19:26 +01:00
2018-10-24 19:49:05 +01:00
Action {
text: translate.getTranslation("PLAY_PAUSE", i18n.language)
2018-10-24 19:49:05 +01:00
onTriggered: {
player.togglePlayPause()
2018-10-24 19:49:05 +01:00
}
shortcut: String(keybinds.playPause)
}
2018-10-24 19:49:05 +01:00
Action {
text: translate.getTranslation("REWIND_10S", i18n.language)
2018-10-24 19:49:05 +01:00
onTriggered: {
player.seek("-10")
2018-10-24 19:49:05 +01:00
}
shortcut: keybinds.rewind10
}
2018-10-24 19:49:05 +01:00
Action {
text: translate.getTranslation("FORWARD_10S", i18n.language)
2018-10-24 19:49:05 +01:00
onTriggered: {
player.seek("10")
2018-10-24 19:49:05 +01:00
}
shortcut: keybinds.forward10
}
2018-10-24 19:49:05 +01:00
Action {
text: translate.getTranslation("FORWARD_5S", i18n.language)
2018-10-24 19:49:05 +01:00
onTriggered: {
player.seek("-5")
2018-10-24 19:49:05 +01:00
}
shortcut: keybinds.rewind5
}
2018-10-24 19:49:05 +01:00
Action {
text: translate.getTranslation("FORWARD_5S", i18n.language)
2018-10-24 19:49:05 +01:00
onTriggered: {
player.seek("5")
2018-10-24 19:49:05 +01:00
}
shortcut: keybinds.forward5
}
2018-10-27 11:34:13 +01:00
Action {
text: translate.getTranslation("SPEED_DECREASE_10PERCENT",
i18n.language)
2018-10-27 11:34:13 +01:00
onTriggered: {
player.command(["multiply", "speed", "1/1.1"])
}
shortcut: keybinds.decreaseSpeedBy10Percent
}
Action {
text: translate.getTranslation("SPEED_INCREASE_10PERCENT",
i18n.language)
2018-10-27 11:34:13 +01:00
onTriggered: {
player.command(["multiply", "speed", "1.1"])
}
shortcut: keybinds.increaseSpeedBy10Percent
}
Action {
text: translate.getTranslation("HALVE_SPEED", i18n.language)
2018-10-27 11:34:13 +01:00
onTriggered: {
player.command(["multiply", "speed", "0.5"])
}
shortcut: keybinds.halveSpeed
}
Action {
text: translate.getTranslation("DOUBLE_SPEED",
i18n.language)
2018-10-27 11:34:13 +01:00
onTriggered: {
player.command(["multiply", "speed", "2.0"])
}
shortcut: keybinds.doubleSpeed
}
2018-10-24 19:49:05 +01:00
Action {
text: translate.getTranslation("FORWARD_FRAME",
i18n.language)
2018-10-24 19:49:05 +01:00
onTriggered: {
player.command(["frame-step"])
}
shortcut: keybinds.forwardFrame
}
Action {
text: translate.getTranslation("BACKWARD_FRAME",
i18n.language)
2018-10-24 19:49:05 +01:00
onTriggered: {
player.command(["frame-back-step"])
}
shortcut: keybinds.backwardFrame
}
2018-10-28 12:19:24 +00:00
}
Menu {
id: audioMenuBarItem
title: translate.getTranslation("AUDIO", i18n.language)
width: 300
2018-10-28 12:19:24 +00:00
background: Rectangle {
implicitWidth: parent.width
implicitHeight: 10
color: "black"
opacity: 0.6
}
delegate: CustomMenuItem {
width: parent.width
}
2018-10-24 19:49:05 +01:00
Action {
text: translate.getTranslation("CYCLE_AUDIO_TRACK",
i18n.language)
2018-10-24 19:49:05 +01:00
onTriggered: {
player.nextAudioTrack()
2018-10-24 19:49:05 +01:00
}
2018-10-28 12:19:24 +00:00
shortcut: keybinds.cycleAudio
}
Action {
text: translate.getTranslation("INCREASE_VOLUME",
i18n.language)
2018-10-28 12:19:24 +00:00
onTriggered: {
player.addVolume("2")
2018-10-28 12:19:24 +00:00
}
shortcut: keybinds.increaseVolume
2018-10-28 12:19:24 +00:00
}
Action {
text: translate.getTranslation("DECREASE_VOLUME",
i18n.language)
2018-10-28 12:19:24 +00:00
onTriggered: {
player.addVolume("-2")
2018-10-28 12:19:24 +00:00
}
shortcut: keybinds.decreaseVolume
}
Action {
text: translate.getTranslation("MUTE_VOLUME", i18n.language)
onTriggered: {
player.toggleMute()
}
shortcut: keybinds.mute
}
}
2018-10-24 19:49:05 +01:00
Menu {
2018-10-28 12:19:24 +00:00
id: videoMenuBarItem
title: translate.getTranslation("VIDEO", i18n.language)
width: 300
2018-10-24 19:49:05 +01:00
background: Rectangle {
implicitWidth: parent.width
implicitHeight: 10
color: "black"
opacity: 0.6
}
delegate: CustomMenuItem {
2018-10-27 16:11:29 +01:00
width: parent.width
2018-10-24 19:49:05 +01:00
}
Action {
text: translate.getTranslation("CYCLE_VIDEO", i18n.language)
2018-10-24 19:49:05 +01:00
onTriggered: {
player.nextVideoTrack()
2018-10-24 19:49:05 +01:00
}
2018-10-28 12:19:24 +00:00
shortcut: keybinds.cycleVideo
}
}
Menu {
id: subsMenuBarItem
title: translate.getTranslation("SUBTITLES", i18n.language)
width: 300
2018-10-28 12:19:24 +00:00
background: Rectangle {
implicitWidth: parent.width
implicitHeight: 10
color: "black"
opacity: 0.6
}
delegate: CustomMenuItem {
width: parent.width
2018-10-24 19:49:05 +01:00
}
Action {
text: translate.getTranslation("CYCLE_SUB_TRACK",
i18n.language)
2018-10-24 19:49:05 +01:00
onTriggered: {
player.nextSubtitleTrack()
2018-10-24 19:49:05 +01:00
}
shortcut: keybinds.cycleSub
}
2018-10-29 16:12:19 +00:00
Action {
text: translate.getTranslation("TOGGLE_MPV_SUBS",
i18n.language)
2018-10-29 16:12:19 +00:00
onTriggered: {
appearance.useMpvSubs = !appearance.useMpvSubs
}
shortcut: keybinds.cycleSubBackwards
}
}
2018-10-24 19:49:05 +01:00
Menu {
id: viewMenuBarItem
title: translate.getTranslation("VIEW", i18n.language)
width: 300
2018-10-24 19:49:05 +01:00
background: Rectangle {
implicitWidth: parent.width
implicitHeight: 10
color: "black"
opacity: 0.6
}
delegate: CustomMenuItem {
2018-10-27 16:11:29 +01:00
width: parent.width
2018-10-24 19:49:05 +01:00
}
Action {
text: translate.getTranslation("FULLSCREEN", i18n.language)
2018-10-24 19:49:05 +01:00
onTriggered: {
toggleFullscreen()
}
shortcut: keybinds.fullscreen
}
2018-10-28 12:19:24 +00:00
Action {
text: translate.getTranslation("TRACK_MENU", i18n.language)
2018-10-28 12:19:24 +00:00
onTriggered: {
tracksMenuUpdate()
subtitlesMenu.visible = !subtitlesMenu.visible
subtitlesMenuBackground.visible = !subtitlesMenuBackground.visible
}
shortcut: keybinds.tracks
}
2018-10-24 19:49:05 +01:00
Action {
text: translate.getTranslation("STATS", i18n.language)
2018-10-24 19:49:05 +01:00
onTriggered: {
player.command(
["script-binding", "stats/display-stats-toggle"])
}
shortcut: keybinds.statsForNerds
}
2018-10-26 19:11:07 +01:00
Action {
text: translate.getTranslation("TOGGLE_NYAN_CAT",
i18n.language)
2018-10-26 19:11:07 +01:00
onTriggered: {
2018-10-29 00:35:24 +00:00
fun.nyanCat = !fun.nyanCat
2018-10-26 19:11:07 +01:00
}
shortcut: keybinds.nyanCat
}
}
Menu {
id: aboutMenuBarItem
title: translate.getTranslation("ABOUT", i18n.language)
width: 300
background: Rectangle {
implicitWidth: parent.width
implicitHeight: 10
color: "black"
opacity: 0.6
}
delegate: CustomMenuItem {
width: parent.width
}
Action {
text: translate.getTranslation("ABOUT_QT", i18n.language)
onTriggered: {
player.launchAboutQt()
}
}
}
2018-10-24 19:49:05 +01:00
Action {
onTriggered: player.skipToNinth(parseInt(shortcut))
shortcut: "1"
}
Action {
2018-10-24 19:49:05 +01:00
onTriggered: player.skipToNinth(parseInt(shortcut))
shortcut: "2"
}
Action {
2018-10-24 19:49:05 +01:00
onTriggered: player.skipToNinth(parseInt(shortcut))
shortcut: "3"
}
Action {
2018-10-24 19:49:05 +01:00
onTriggered: player.skipToNinth(parseInt(shortcut))
shortcut: "4"
}
Action {
2018-10-24 19:49:05 +01:00
onTriggered: player.skipToNinth(parseInt(shortcut))
shortcut: "5"
}
Action {
2018-10-24 19:49:05 +01:00
onTriggered: player.skipToNinth(parseInt(shortcut))
shortcut: "6"
}
2018-10-24 19:49:05 +01:00
Action {
onTriggered: player.skipToNinth(parseInt(shortcut))
shortcut: "7"
2018-10-23 23:19:26 +01:00
}
Action {
2018-10-24 19:49:05 +01:00
onTriggered: player.skipToNinth(parseInt(shortcut))
shortcut: "8"
}
2018-10-24 15:50:22 +01:00
Action {
2018-10-24 19:49:05 +01:00
onTriggered: player.skipToNinth(parseInt(shortcut))
shortcut: "9"
}
Action {
onTriggered: player.skipToNinth(parseInt(shortcut))
shortcut: "0"
2018-10-24 15:50:22 +01:00
}
Action {
onTriggered: player.command(keybinds.customKeybind0Command)
shortcut: keybinds.customKeybind0
}
Action {
onTriggered: player.command(keybinds.customKeybind1Command)
shortcut: keybinds.customKeybind1
}
Action {
onTriggered: player.command(keybinds.customKeybind2Command)
shortcut: keybinds.customKeybind2
}
Action {
onTriggered: player.command(keybinds.customKeybind3Command)
shortcut: keybinds.customKeybind3
}
Action {
onTriggered: player.command(keybinds.customKeybind4Command)
shortcut: keybinds.customKeybind4
}
Action {
onTriggered: player.command(keybinds.customKeybind5Command)
shortcut: keybinds.customKeybind5
}
Action {
onTriggered: player.command(keybinds.customKeybind6Command)
shortcut: keybinds.customKeybind6
}
Action {
onTriggered: player.command(keybinds.customKeybind7Command)
shortcut: keybinds.customKeybind7
}
Action {
onTriggered: player.command(keybinds.customKeybind8Command)
shortcut: keybinds.customKeybind8
}
Action {
onTriggered: player.command(keybinds.customKeybind9Command)
shortcut: keybinds.customKeybind9
}
}
2018-10-24 19:49:05 +01:00
Rectangle {
id: subtitlesMenuBackground
anchors.fill: subtitlesMenu
Layout.fillWidth: true
Layout.fillHeight: true
visible: false
color: "black"
opacity: 0.6
}
2018-10-24 19:49:05 +01:00
Rectangle {
id: subtitlesMenu
color: "transparent"
2018-11-04 13:21:50 +00:00
width: controlsBar.width / 2
2018-10-24 19:49:05 +01:00
height: childrenRect.height
visible: false
2018-11-06 07:37:05 +00:00
z: 90000
2018-10-24 19:49:05 +01:00
anchors.centerIn: player
border.color: "black"
border.width: 2
2018-10-23 23:19:26 +01:00
2018-10-24 19:49:05 +01:00
Text {
id: audioLabel
anchors.left: parent.left
anchors.right: parent.right
text: translate.getTranslation("AUDIO", i18n.language)
2018-10-24 19:49:05 +01:00
color: "white"
font.family: appearance.fontName
2018-10-24 19:49:05 +01:00
font.pixelSize: 14
horizontalAlignment: Text.AlignHCenter
opacity: 1
}
2018-10-24 19:49:05 +01:00
ComboBox {
id: audioList
textRole: "key"
2018-11-04 13:21:50 +00:00
width: parent.width
2018-10-24 19:49:05 +01:00
anchors.top: audioLabel.bottom
model: ListModel {
id: audioModel
}
2018-10-24 19:49:05 +01:00
onActivated: {
player.command(["set", "aid", String(audioModel.get(
index).value)])
}
2018-10-24 19:49:05 +01:00
opacity: 1
}
Text {
id: subLabel
anchors.left: parent.left
anchors.right: parent.right
text: translate.getTranslation("SUBTITLES", i18n.language)
2018-10-24 19:49:05 +01:00
color: "white"
font.family: appearance.fontName
2018-10-24 19:49:05 +01:00
font.pixelSize: 14
anchors.top: audioList.bottom
horizontalAlignment: Text.AlignHCenter
opacity: 1
}
ComboBox {
id: subList
textRole: "key"
2018-11-04 13:21:50 +00:00
width: parent.width
2018-10-24 19:49:05 +01:00
anchors.top: subLabel.bottom
model: ListModel {
id: subModel
}
2018-10-24 19:49:05 +01:00
onActivated: {
player.command(["set", "sid", String(subModel.get(
index).value)])
}
2018-10-24 19:49:05 +01:00
opacity: 1
}
Text {
id: vidLabel
anchors.left: parent.left
anchors.right: parent.right
text: translate.getTranslation("VIDEO", i18n.language)
2018-10-24 19:49:05 +01:00
color: "white"
font.family: appearance.fontName
2018-10-24 19:49:05 +01:00
font.pixelSize: 14
anchors.top: subList.bottom
horizontalAlignment: Text.AlignHCenter
opacity: 1
}
ComboBox {
id: vidList
textRole: "key"
2018-11-04 13:21:50 +00:00
width: parent.width
2018-10-24 19:49:05 +01:00
anchors.top: vidLabel.bottom
model: ListModel {
id: vidModel
}
2018-10-24 19:49:05 +01:00
onActivated: {
player.command(["set", "vid", String(vidModel.get(
index).value)])
}
2018-10-24 19:49:05 +01:00
opacity: 1
}
2018-10-24 19:49:05 +01:00
}
2018-10-13 15:38:31 +01:00
Rectangle {
id: titleBackground
height: titleBar.height
2018-10-23 23:19:26 +01:00
anchors.top: titleBar.top
anchors.left: titleBar.left
anchors.right: titleBar.right
2018-10-13 15:38:31 +01:00
Layout.fillWidth: true
Layout.fillHeight: true
color: "black"
opacity: 0.6
}
Rectangle {
id: titleBar
height: menuBar.height
anchors.right: parent.right
anchors.left: menuBar.right
anchors.top: parent.top
2018-10-26 19:11:07 +01:00
visible: !appearance.titleOnlyOnFullscreen
2018-10-13 15:38:31 +01:00
color: "transparent"
Text {
id: titleLabel
text: translate.getTranslation("TITLE", i18n.language)
2018-10-13 15:38:31 +01:00
color: "white"
width: parent.width
height: parent.height
2018-10-13 15:38:31 +01:00
anchors.left: parent.left
anchors.leftMargin: 10
anchors.bottom: parent.bottom
topPadding: 4
bottomPadding: 4
anchors.top: parent.top
font.family: appearance.fontName
font.pixelSize: 14
font.bold: true
2018-10-13 15:38:31 +01:00
opacity: 1
}
}
Rectangle {
id: controlsBackground
2018-10-29 00:35:24 +00:00
height: controlsBar.visible ? controlsBar.height + progressBackground.height
+ (progressBar.topPadding * 2)
- (progressBackground.height * 2) : 0
anchors.bottom: parent.bottom
2018-10-13 15:38:31 +01:00
anchors.left: parent.left
anchors.right: parent.right
Layout.fillWidth: true
Layout.fillHeight: true
color: "black"
opacity: 0.6
}
2018-10-13 15:38:31 +01:00
2018-10-24 19:49:05 +01:00
Rectangle {
2018-10-29 16:12:19 +00:00
id: subtitlesBar
visible: !appearance.useMpvSubs
2018-10-24 19:49:05 +01:00
color: "transparent"
2018-10-29 16:12:19 +00:00
height: player.height / 8
anchors.bottom: controlsBackground.top
anchors.bottomMargin: 5
anchors.right: parent.right
anchors.left: parent.left
2018-10-24 19:49:05 +01:00
2018-10-29 16:12:19 +00:00
RowLayout {
id: nativeSubtitles
visible: true
anchors.left: subtitlesBar.left
anchors.right: subtitlesBar.right
height: childrenRect.height
anchors.bottom: parent.bottom
anchors.bottomMargin: 10
Rectangle {
id: subsContainer
Layout.fillWidth: true
Layout.fillHeight: true
Layout.rightMargin: 0
Layout.leftMargin: 0
Layout.maximumWidth: nativeSubtitles.width
color: "transparent"
height: childrenRect.height
Label {
id: nativeSubs
onWidthChanged: {
if (width > parent.width - 10)
width = parent.width - 10
}
onTextChanged: if (width <= parent.width - 10)
width = undefined
color: "white"
anchors.horizontalCenter: parent.horizontalCenter
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
font.pixelSize: Screen.height / 24
font.family: appearance.fontName
2018-10-29 16:12:19 +00:00
horizontalAlignment: Text.AlignHCenter
opacity: 1
background: Rectangle {
id: subsBackground
color: Qt.rgba(0, 0, 0, 0.6)
width: subsContainer.childrenRect.width
height: subsContainer.childrenRect.height
}
}
2018-10-24 19:49:05 +01:00
}
}
}
function setCachedDuration(val) {
2018-10-29 00:35:24 +00:00
cachedLength.width = ((progressBar.width / progressBar.to) * val) - progressLength.width
}
Rectangle {
id: controlsBar
height: controlsBar.visible ? Screen.height / 24 : 0
anchors.right: parent.right
anchors.rightMargin: parent.width / 128
anchors.left: parent.left
anchors.leftMargin: parent.width / 128
anchors.bottom: parent.bottom
anchors.bottomMargin: 1
visible: true
color: "transparent"
2018-10-23 16:45:44 +01:00
Rectangle {
id: settingsMenuBackground
anchors.fill: settingsMenu
Layout.fillWidth: true
Layout.fillHeight: true
visible: false
color: "black"
opacity: 0.6
radius: 5
}
Rectangle {
id: settingsMenu
color: "transparent"
width: childrenRect.width
height: childrenRect.height
visible: false
anchors.right: settingsButton.right
anchors.bottom: progressBar.top
radius: 5
2018-10-29 00:35:24 +00:00
}
Slider {
id: progressBar
to: 1
value: 0.0
anchors.bottom: parent.top
anchors.left: parent.left
anchors.right: parent.right
anchors.bottomMargin: 0
2018-10-27 11:34:13 +01:00
anchors.topMargin: progressBackground.height
bottomPadding: 0
2018-10-13 15:38:31 +01:00
onMoved: {
2018-10-23 15:42:44 +01:00
player.command(["seek", progressBar.value, "absolute"])
}
2018-10-13 15:38:31 +01:00
background: Rectangle {
id: progressBackground
x: progressBar.leftPadding
y: progressBar.topPadding + progressBar.availableHeight / 2 - height / 2
implicitHeight: Math.max(Screen.height / 256,
fun.nyanCat ? 12 : 2)
width: progressBar.availableWidth
height: implicitHeight
2018-10-26 19:11:07 +01:00
color: Qt.rgba(255, 255, 255, 0.6)
Rectangle {
id: progressLength
width: progressBar.visualPosition * parent.width
height: parent.height
color: "red"
opacity: 1
2018-10-29 00:35:24 +00:00
Image {
2018-10-26 19:11:07 +01:00
visible: fun.nyanCat
2018-10-29 00:35:24 +00:00
id: rainbow
2018-10-26 19:11:07 +01:00
anchors.fill: parent
2018-10-29 00:35:24 +00:00
height: parent.height
width: parent.width
source: "qrc:/player/icons/rainbow.png"
fillMode: Image.TileHorizontally
2018-10-26 19:11:07 +01:00
}
}
Rectangle {
id: cachedLength
z: 10
anchors.left: progressLength.right
2018-10-29 00:35:24 +00:00
anchors.leftMargin: progressBar.handle.width - 2
//anchors.left: progressBar.handle.horizontalCenter
anchors.bottom: progressBar.background.bottom
anchors.top: progressBar.background.top
height: progressBar.background.height
color: "white"
opacity: 0.8
}
}
2018-10-13 15:38:31 +01:00
handle: Rectangle {
2018-10-15 17:39:04 +01:00
id: handleRect
x: progressBar.leftPadding + progressBar.visualPosition
* (progressBar.availableWidth - width)
y: progressBar.topPadding + progressBar.availableHeight / 2 - height / 2
implicitHeight: 12
2018-10-26 19:11:07 +01:00
implicitWidth: 12
radius: 12
2018-10-26 19:11:07 +01:00
color: fun.nyanCat ? "transparent" : "red"
//border.color: "red"
AnimatedImage {
visible: fun.nyanCat
paused: progressBar.pressed
height: 30
2018-10-26 19:11:07 +01:00
id: nyanimation
anchors.centerIn: parent
source: "qrc:/player/icons/nyancat.gif"
fillMode: Image.PreserveAspectFit
}
}
2018-10-13 15:38:31 +01:00
}
Button {
id: playlistPrevButton
//icon.name: "prev"
icon.source: "icons/prev.svg"
icon.color: "white"
display: AbstractButton.IconOnly
2018-10-16 16:55:25 +01:00
anchors.top: parent.top
anchors.bottom: parent.bottom
visible: false
width: 0
onClicked: {
player.prevPlaylistItem()
}
background: Rectangle {
color: "transparent"
}
2018-10-13 15:38:31 +01:00
}
Button {
id: playPauseButton
//icon.name: "pause"
icon.source: "icons/pause.svg"
icon.color: "white"
display: AbstractButton.IconOnly
2018-10-16 16:55:25 +01:00
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.left: playlistPrevButton.right
onClicked: {
player.togglePlayPause()
}
background: Rectangle {
color: "transparent"
}
2018-10-13 15:38:31 +01:00
}
Button {
id: playlistNextButton
//icon.name: "next"
icon.source: "icons/next.svg"
icon.color: "white"
display: AbstractButton.IconOnly
2018-10-16 16:55:25 +01:00
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.left: playPauseButton.right
onClicked: {
player.prevPlaylistItem()
}
background: Rectangle {
color: "transparent"
}
2018-10-13 15:38:31 +01:00
}
Button {
id: volumeButton
//icon.name: "volume-up"
icon.source: "icons/volume-up.svg"
icon.color: "white"
display: AbstractButton.IconOnly
2018-10-16 16:55:25 +01:00
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.left: playlistNextButton.right
onClicked: {
player.toggleMute()
}
background: Rectangle {
color: "transparent"
2018-10-13 15:38:31 +01:00
}
}
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)
anchors.left: volumeButton.right
anchors.top: parent.top
anchors.bottom: parent.bottom
onMoved: {
2018-11-06 07:37:05 +00:00
player.setVolume(Math.round(volumeBar.value).toString())
}
2018-10-13 15:38:31 +01:00
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"
}
2018-10-13 15:38:31 +01:00
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"
}
}
2018-10-13 15:38:31 +01:00
}
Text {
id: timeLabel
text: "0:00 / 0:00"
color: "white"
anchors.left: volumeBar.right
2018-10-16 16:55:25 +01:00
anchors.top: parent.top
anchors.bottom: parent.bottom
2018-10-23 23:56:24 +01:00
padding: 2
font.family: appearance.fontName
2018-10-23 23:56:24 +01:00
font.pixelSize: 14
verticalAlignment: Text.AlignVCenter
renderType: Text.NativeRendering
2018-10-13 15:38:31 +01:00
}
Button {
id: subtitlesButton
//icon.name: "subtitles"
icon.source: "icons/subtitles.svg"
icon.color: "white"
anchors.right: settingsButton.left
2018-10-16 16:55:25 +01:00
anchors.top: parent.top
anchors.bottom: parent.bottom
display: AbstractButton.IconOnly
onClicked: {
tracksMenuUpdate()
subtitlesMenu.visible = !subtitlesMenu.visible
subtitlesMenuBackground.visible = !subtitlesMenuBackground.visible
}
background: Rectangle {
color: "transparent"
}
2018-10-13 15:38:31 +01:00
}
Button {
id: settingsButton
//icon.name: "settings"
icon.source: "icons/settings.svg"
icon.color: "white"
Layout.alignment: Qt.AlignVCenter | Qt.AlignRight
anchors.right: fullscreenButton.left
2018-10-16 16:55:25 +01:00
anchors.top: parent.top
anchors.bottom: parent.bottom
display: AbstractButton.IconOnly
onClicked: {
2018-10-23 16:45:44 +01:00
settingsMenu.visible = !settingsMenu.visible
settingsMenuBackground.visible = !settingsMenuBackground.visible
}
background: Rectangle {
color: "transparent"
2018-10-13 15:38:31 +01:00
}
}
Button {
id: fullscreenButton
//icon.name: "fullscreen"
icon.source: "icons/fullscreen.svg"
icon.color: "white"
Layout.alignment: Qt.AlignVCenter | Qt.AlignRight
anchors.right: parent.right
2018-10-16 16:55:25 +01:00
anchors.top: parent.top
anchors.bottom: parent.bottom
display: AbstractButton.IconOnly
onClicked: {
toggleFullscreen()
}
background: Rectangle {
color: "transparent"
}
2018-10-13 15:38:31 +01:00
}
}
2018-10-13 15:38:31 +01:00
}
}