Warning, /multimedia/haruna/src/qml/HProgressBar.qml is written in an unsupported language. File is not indexed.
0001 /* 0002 * SPDX-FileCopyrightText: 2020 George Florea Bănuș <georgefb899@gmail.com> 0003 * 0004 * SPDX-License-Identifier: GPL-3.0-or-later 0005 */ 0006 0007 import QtQml 0008 import QtQuick 0009 import QtQuick.Controls 0010 import QtQuick.Layouts 0011 import QtQuick.Shapes 0012 0013 import org.kde.kirigami as Kirigami 0014 import org.kde.haruna 0015 import org.kde.haruna.mpvproperties 0016 import org.kde.haruna.settings 0017 0018 Slider { 0019 id: root 0020 0021 property alias loopIndicator: loopIndicator 0022 property bool seekStarted: false 0023 0024 from: 0 0025 to: mpv.duration 0026 implicitWidth: 200 0027 implicitHeight: 25 0028 leftPadding: 0 0029 rightPadding: 0 0030 0031 handle: Item { visible: false } 0032 0033 background: Rectangle { 0034 id: progressBarBG 0035 color: Kirigami.Theme.alternateBackgroundColor 0036 scale: root.mirrored ? -1 : 1 0037 0038 Rectangle { 0039 id: loopIndicator 0040 property double startPosition: -1 0041 property double endPosition: -1 0042 width: endPosition === -1 ? 1 : (endPosition / mpv.duration * progressBarBG.width) - x 0043 height: parent.height 0044 color: Qt.hsla(0, 0, 0, 0.4) 0045 visible: startPosition !== -1 0046 x: startPosition / mpv.duration * progressBarBG.width 0047 z: 110 0048 } 0049 0050 Rectangle { 0051 width: root.position * parent.width 0052 height: parent.height 0053 color: Kirigami.Theme.highlightColor 0054 } 0055 0056 ToolTip { 0057 id: progressBarToolTip 0058 0059 z: 10 0060 visible: progressBarMouseArea.containsMouse && mpv.duration > 0 0061 timeout: -1 0062 delay: 0 0063 contentItem: ColumnLayout { 0064 0065 Loader { 0066 id: previewMpvLoader 0067 0068 property string file: "" 0069 property double position: 0 0070 property double aspectRatio: 1 0071 0072 active: GeneralSettings.showPreviewThumbnail && previewMpvLoader.file !== "" 0073 visible: false 0074 sourceComponent: MpvPreview { 0075 anchors.fill: parent 0076 accuratePreview: GeneralSettings.accuratePreviewThumbnail 0077 position: previewMpvLoader.position 0078 file: previewMpvLoader.file 0079 0080 onIsLocalFileChanged: { 0081 previewMpvLoader.visible = isLocalFile 0082 } 0083 onAspectRatioChanged: previewMpvLoader.aspectRatio = aspectRatio || 1 0084 } 0085 0086 Layout.preferredWidth: GeneralSettings.previewThumbnailWidth 0087 Layout.preferredHeight: Math.ceil(Layout.preferredWidth / previewMpvLoader.aspectRatio) 0088 Layout.alignment: Qt.AlignCenter 0089 0090 } 0091 0092 Label { 0093 text: progressBarToolTip.text 0094 Kirigami.Theme.colorSet: Kirigami.Theme.Tooltip 0095 Layout.alignment: Qt.AlignCenter 0096 } 0097 } 0098 0099 } 0100 0101 MouseArea { 0102 id: progressBarMouseArea 0103 0104 anchors.fill: parent 0105 hoverEnabled: true 0106 acceptedButtons: Qt.MiddleButton | Qt.RightButton 0107 0108 onClicked: function(mouse) { 0109 if (mouse.button === Qt.MiddleButton) { 0110 if (!GeneralSettings.showChapterMarkers) { 0111 return 0112 } 0113 0114 const time = mouseX / progressBarBG.width * root.to 0115 const chapters = mpv.getProperty(MpvProperties.ChapterList) 0116 const nextChapter = chapters.findIndex(chapter => chapter.time > time) 0117 mpv.chapter = nextChapter 0118 } 0119 if (mouse.button === Qt.RightButton && mpv.chaptersModel.rowCount() > 0) { 0120 chaptersPopup.x = mouseX - chaptersPopup.width * 0.5 0121 chaptersPopup.open() 0122 } 0123 } 0124 0125 onMouseXChanged: { 0126 progressBarToolTip.x = mouseX - (progressBarToolTip.width * 0.5) 0127 0128 const time = mouseX / progressBarBG.width * root.to 0129 previewMpvLoader.position = time 0130 progressBarToolTip.text = app.formatTime(time) 0131 } 0132 0133 onEntered: { 0134 progressBarToolTip.x = mouseX - (progressBarToolTip.width * 0.5) 0135 progressBarToolTip.y = root.height + Kirigami.Units.largeSpacing 0136 } 0137 0138 onWheel: function(wheel) { 0139 if (wheel.angleDelta.y > 0) { 0140 appActions.seekForwardMediumAction.trigger() 0141 } else if (wheel.angleDelta.y) { 0142 appActions.seekBackwardMediumAction.trigger() 0143 } 0144 } 0145 } 0146 } 0147 0148 onToChanged: value = mpv.position 0149 onPressedChanged: { 0150 if (pressed) { 0151 seekStarted = true 0152 } else { 0153 mpv.command(["seek", value, "absolute"]) 0154 seekStarted = false 0155 } 0156 } 0157 0158 // create markers for the chapters 0159 Repeater { 0160 id: chaptersInstantiator 0161 model: GeneralSettings.showChapterMarkers ? mpv.chaptersModel : 0 0162 delegate: Shape { 0163 id: chapterMarkerShape 0164 0165 // where the chapter marker shoud be positioned on the progress bar 0166 property int position: root.mirrored 0167 ? progressBarBG.width - (model.startTime / mpv.duration * progressBarBG.width) 0168 : model.startTime / mpv.duration * progressBarBG.width 0169 0170 antialiasing: true 0171 ShapePath { 0172 id: shape 0173 strokeWidth: 1 0174 strokeColor: Kirigami.Theme.textColor 0175 startX: chapterMarkerShape.position 0176 startY: root.height 0177 fillColor: Kirigami.Theme.textColor 0178 PathLine { x: shape.startX; y: -1 } 0179 PathLine { x: shape.startX + 6; y: -7 } 0180 PathLine { x: shape.startX - 7; y: -7 } 0181 PathLine { x: shape.startX - 1; y: -1 } 0182 } 0183 Rectangle { 0184 x: chapterMarkerShape.position - 8 0185 y: -11 0186 width: 15 0187 height: 11 0188 color: "transparent" 0189 ToolTip { 0190 id: chapterTitleToolTip 0191 text: model.title 0192 visible: false 0193 delay: 0 0194 timeout: 10000 0195 } 0196 MouseArea { 0197 anchors.fill: parent 0198 hoverEnabled: true 0199 onEntered: chapterTitleToolTip.visible = true 0200 onExited: chapterTitleToolTip.visible = false 0201 onClicked: mpv.chapter = index 0202 } 0203 } 0204 } 0205 } 0206 0207 Popup { 0208 id: chaptersPopup 0209 0210 property int itemHeight 0211 property int itemBiggestWidth: 1 0212 property var checkedItem 0213 property int maxWidth: window.width * 0.7 > Kirigami.Units.gridUnit * 40 0214 ? Kirigami.Units.gridUnit * 40 0215 : window.width * 0.7 0216 0217 y: -height - root.height 0218 z: 20 0219 width: itemBiggestWidth > maxWidth ? maxWidth : itemBiggestWidth 0220 height: itemHeight * mpv.chaptersModel.rowCount() + listViewPage.footer.height > mpv.height - Kirigami.Units.gridUnit 0221 ? mpv.height - Kirigami.Units.gridUnit 0222 : itemHeight * mpv.chaptersModel.rowCount() + listViewPage.footer.height 0223 padding: 0 0224 onOpened: { 0225 listView.positionViewAtIndex(checkedItem, ListView.Beginning) 0226 } 0227 0228 Kirigami.ScrollablePage { 0229 id: listViewPage 0230 0231 padding: 0 0232 0233 anchors.fill: parent 0234 footer: ToolBar { 0235 z: 100 0236 width: parent.width 0237 CheckBox { 0238 text: i18nc("@action:inmenu", "Skip Chapters") 0239 checked: PlaybackSettings.skipChapters 0240 onCheckedChanged: { 0241 PlaybackSettings.skipChapters = checked 0242 PlaybackSettings.save() 0243 } 0244 0245 ToolTip { 0246 text: i18nc("@info:tooltip", "Automatically skips chapters containing certain words/characters.\nCheck 'Playback' settings for more details") 0247 } 0248 } 0249 } 0250 0251 ListView { 0252 id: listView 0253 0254 model: mpv.chaptersModel 0255 delegate: CheckDelegate { 0256 id: menuitem 0257 0258 text: `${app.formatTime(model.startTime)} - ${model.title}` 0259 checked: index === chaptersPopup.checkedItem 0260 width: listViewPage.width 0261 onClicked: { 0262 chaptersPopup.close() 0263 mpv.chapter = index 0264 } 0265 Component.onCompleted: { 0266 const scrollBarWidth = listViewPage.contentItem.ScrollBar.vertical.width 0267 chaptersPopup.itemBiggestWidth = menuitem.implicitWidth + scrollBarWidth > chaptersPopup.width 0268 ? menuitem.implicitWidth + scrollBarWidth 0269 : chaptersPopup.width 0270 0271 chaptersPopup.itemHeight = height 0272 } 0273 } 0274 } 0275 } 0276 } 0277 0278 Connections { 0279 target: mpv 0280 function onFileLoaded() { 0281 loopIndicator.startPosition = -1 0282 loopIndicator.endPosition = -1 0283 previewMpvLoader.file = mpv.currentUrl 0284 } 0285 function onChapterChanged() { 0286 chaptersPopup.checkedItem = mpv.chapter 0287 } 0288 function onPositionChanged() { 0289 if (!root.seekStarted) { 0290 root.value = mpv.position 0291 } 0292 } 0293 } 0294 }