You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

227 lines
6.8 KiB
QML

/*
* SPDX-FileCopyrightText: 2020 George Florea Bănuș <georgefb899@gmail.com>
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
import QtQml 2.12
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12
import QtQuick.Shapes 1.12
import QtGraphicalEffects 1.0
import FishUI 1.0 as FishUI
Slider {
id: root
property alias loopIndicator: loopIndicator
property var chapters
property bool seekStarted: false
from: 0
to: mpv.duration
implicitWidth: 200
implicitHeight: 7
leftPadding: 0
rightPadding: 0
handle: Item { visible: false }
background: Rectangle {
id: progressBarBackground
color: FishUI.Theme.darkMode ? "#3E3E40" : "#E6E6E6"
Rectangle {
id: loopIndicator
property double startPosition: -1
property double endPosition: -1
width: endPosition === -1 ? 1 : (endPosition / mpv.duration * progressBarBackground.width) - x
height: parent.height
color: Qt.hsla(0, 0, 0, 0.4)
visible: startPosition !== -1
x: startPosition / mpv.duration * progressBarBackground.width
z: 110
}
Rectangle {
width: visualPosition * parent.width
height: parent.height
color: FishUI.Theme.highlightColor
}
ToolTip {
id: progressBarToolTip
visible: progressBarMouseArea.containsMouse
timeout: -1
delay: 0
}
MouseArea {
id: progressBarMouseArea
anchors.fill: parent
hoverEnabled: true
acceptedButtons: Qt.MiddleButton | Qt.RightButton
onClicked: {
if (mouse.button === Qt.MiddleButton) {
if (!GeneralSettings.showChapterMarkers) {
return
}
const time = mouseX * 100 / progressBarBackground.width * root.to / 100
const chapters = mpv.getProperty("chapter-list")
const nextChapter = chapters.findIndex(chapter => chapter.time > time)
mpv.chapter = nextChapter
}
if (mouse.button === Qt.RightButton && root.chapters.length > 0) {
const menuX = mouse.x-chaptersMenu.width * 0.5
const menuY = -((chaptersMenu.count - 1) * chaptersMenu.menuItemHeight + 15)
chaptersMenu.popup(root, menuX, menuY)
}
}
onMouseXChanged: {
progressBarToolTip.x = mouseX - (progressBarToolTip.width * 0.5)
const time = mouseX * 100 / progressBarBackground.width * root.to / 100
progressBarToolTip.text = app.formatTime(time)
}
// onEntered: {
// progressBarToolTip.x = mouseX - (progressBarToolTip.width * 0.5)
// progressBarToolTip.y = root.height
// }
onWheel: {
if (wheel.angleDelta.y > 0) {
actions["seekForwardMediumAction"].trigger()
} else if (wheel.angleDelta.y) {
actions["seekBackwardMediumAction"].trigger()
}
}
}
}
// create markers for the chapters
Repeater {
id: chaptersInstantiator
// model: GeneralSettings.showChapterMarkers ? chapters : 0
model: 0
delegate: Shape {
id: chapterMarkerShape
// where the chapter marker shoud be positioned on the progress bar
property int position: modelData.time / mpv.duration * progressBarBackground.width
antialiasing: true
ShapePath {
id: shape
strokeWidth: 1
strokeColor: FishUI.Theme.textColor
startX: chapterMarkerShape.position
startY: root.height
fillColor: FishUI.Theme.textColor
PathLine { x: shape.startX; y: -1 }
PathLine { x: shape.startX + 6; y: -7 }
PathLine { x: shape.startX - 7; y: -7 }
PathLine { x: shape.startX - 1; y: -1 }
}
Rectangle {
x: chapterMarkerShape.position - 8
y: -11
width: 15
height: 11
color: "transparent"
ToolTip {
id: chapterTitleToolTip
text: modelData.title
visible: false
delay: 0
timeout: 10000
}
MouseArea {
anchors.fill: parent
hoverEnabled: true
onEntered: chapterTitleToolTip.visible = true
onExited: chapterTitleToolTip.visible = false
onClicked: mpv.setProperty("chapter", index)
}
}
}
}
onToChanged: value = mpv.position
onPressedChanged: {
if (pressed) {
seekStarted = true
} else {
mpv.command(["seek", value, "absolute"])
seekStarted = false
}
}
Menu {
id: chaptersMenu
property int menuItemHeight
property var checkedItem
width: 0
modal: true
MenuSeparator {}
MenuItem {
id: skipChaptersMenuItem
// text: qsTr("Skip Chapters")
checkable: true
// checked: PlaybackSettings.skipChapters
onCheckedChanged: {
PlaybackSettings.skipChapters = checked
PlaybackSettings.save()
}
}
Instantiator {
model: root.chapters
delegate: MenuItem {
id: menuitem
checkable: true
checked: index === chaptersMenu.checkedItem
text: `${app.formatTime(modelData.time)} - ${modelData.title}`
Component.onCompleted: {
chaptersMenu.width = menuitem.width > chaptersMenu.width
? menuitem.width
: chaptersMenu.width
chaptersMenu.menuItemHeight = height
}
onClicked: mpv.chapter = index
}
onObjectAdded: chaptersMenu.insertItem(index, object)
onObjectRemoved: chaptersMenu.removeItem(object)
}
}
Connections {
target: mpv
function onFileLoaded() {
chapters = mpv.getProperty("chapter-list")
}
function onChapterChanged() {
chaptersMenu.checkedItem = mpv.chapter
}
function onPositionChanged() {
if (!root.seekStarted) {
root.value = mpv.position
}
}
}
}