Warning, /multimedia/audiotube/src/contents/ui/MaximizedPlayerPage.qml is written in an unsupported language. File is not indexed.
0001 // SPDX-FileCopyrightText: 2020-2022 Devin Lin <devin@kde.org> 0002 // 0003 // SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0004 0005 import QtQuick 2.15 0006 import QtQuick.Effects 0007 import QtQuick.Controls 2.15 0008 import QtQuick.Layouts 1.15 0009 0010 import QtMultimedia 0011 0012 import org.kde.kirigami 2.19 as Kirigami 0013 import org.kde.kirigamiaddons.components 1.0 as Components 0014 import org.kde.ytmusic 1.0 0015 0016 import "dialogs" 0017 0018 Item { 0019 id: root 0020 0021 required property var info // VideoInfoExtractor object 0022 required property var audio // Audio object 0023 required property string thumbnail 0024 readonly property bool isWidescreen: width >= Kirigami.Units.gridUnit * 50 0025 0026 signal requestClose() 0027 0028 onWidthChanged: {sideDrawer.Layout.minimumWidth = -1} 0029 0030 // background image 0031 0032 Item { 0033 id: bg 0034 anchors.fill: parent 0035 clip: true 0036 0037 Rectangle { 0038 anchors.fill: parent 0039 color: Qt.rgba(25, 25, 30, 1) 0040 } 0041 0042 Image { 0043 scale: 1.8 0044 anchors.fill: parent 0045 asynchronous: true 0046 0047 source: root.thumbnail 0048 fillMode: Image.PreserveAspectCrop 0049 0050 sourceSize.width: 512 0051 sourceSize.height: 512 0052 } 0053 } 0054 MultiEffect { 0055 source: bg 0056 anchors.fill: bg 0057 0058 brightness: -0.25 0059 saturation: 0.5 0060 0061 blurEnabled: true 0062 autoPaddingEnabled: false 0063 blur: 1.0 0064 blurMax: 40 0065 blurMultiplier: 3.0 0066 } 0067 0068 Rectangle { 0069 anchors.fill: parent 0070 gradient: Gradient{ 0071 GradientStop { position: 0.0; color: "transparent" } 0072 GradientStop { position: 1.1; color: "black" } 0073 } 0074 } 0075 0076 // content 0077 RowLayout { 0078 anchors.fill: parent 0079 0080 ColumnLayout { 0081 id: mainContent 0082 Layout.fillWidth: true 0083 // hide arrow button 0084 ToolButton { 0085 id: closeButton 0086 0087 Layout.alignment: Qt.AlignHCenter | Qt.AlignTop 0088 Layout.maximumHeight: parent.height 0089 Layout.preferredHeight: Kirigami.Units.gridUnit * 3 0090 Layout.maximumWidth: parent.height 0091 Layout.preferredWidth: Kirigami.Units.gridUnit * 3 0092 Layout.topMargin: Kirigami.Units.smallSpacing 0093 0094 icon.name: "arrow-down" 0095 icon.color: "white" 0096 Kirigami.Theme.colorSet: Kirigami.Theme.Complementary 0097 Kirigami.Theme.inherit: false 0098 onClicked: root.requestClose() 0099 text: i18n("Close Maximized Player") 0100 display: ToolButton.IconOnly 0101 0102 ToolTip.text: text 0103 ToolTip.delay: Kirigami.Units.toolTipDelay 0104 ToolTip.visible: Kirigami.Settings.isMobile ? pressed : hovered 0105 } 0106 0107 SwipeView { 0108 interactive: false 0109 Layout.fillHeight: true 0110 Layout.fillWidth: true 0111 clip:true 0112 id: swipeView 0113 property double specWidth: { 0114 let allowedWidth = root.width - Kirigami.Units.largeSpacing * 4; 0115 let allowedHeight = root.height - Kirigami.Units.largeSpacing * 16 - (closeButton.height + bottomPlayerControls.height); 0116 if (allowedWidth > allowedHeight) { 0117 return allowedHeight; 0118 } else { 0119 return allowedWidth; 0120 } 0121 } 0122 Layout.alignment: Qt.AlignHCenter | Qt.AlignTop 0123 Layout.preferredHeight: specWidth 0124 0125 // music art 0126 Flickable { 0127 flickableDirection: Flickable.HorizontalFlick 0128 clip: true 0129 contentWidth: coverArt.width 0130 contentHeight: coverArt.height 0131 height: swipeView.height 0132 width: applicationWindow().width-sideDrawer.width 0133 onFlickEnded:{ 0134 0135 if(horizontalVelocity<0){ 0136 UserPlaylistModel.next() 0137 } 0138 else{ 0139 if(UserPlaylistModel.canSkipBack){ 0140 UserPlaylistModel.previous() 0141 } 0142 } 0143 } 0144 Item { 0145 height: swipeView.height 0146 width: applicationWindow().width-sideDrawer.width 0147 Kirigami.ShadowedRectangle { 0148 id: coverArt 0149 x: 4 0150 anchors.centerIn: parent 0151 width: swipeView.specWidth 0152 height: swipeView.specWidth 0153 0154 visible: root.thumbnail.toString() !== "" 0155 0156 color: "transparent" 0157 radius: 10 0158 shadow.size: 15 0159 shadow.xOffset: 5 0160 shadow.yOffset: 5 0161 shadow.color: Qt.rgba(0, 0, 0, 0.2) 0162 RoundedImage { 0163 source: root.thumbnail 0164 height: parent.height 0165 width: height 0166 radius: 10 0167 } 0168 } 0169 } 0170 } 0171 0172 ColumnLayout { 0173 width: swipeView.width 0174 height: swipeView.height 0175 ScrollView { 0176 Layout.maximumWidth: 900 0177 contentWidth: -1 0178 contentHeight: lyrics.implicitHeight 0179 Layout.fillWidth: true 0180 Layout.fillHeight: true 0181 Layout.alignment: Qt.AlignHCenter 0182 clip: true 0183 0184 //contentY: audio.position / audio.duration 0185 0186 Label { 0187 id: lyrics 0188 padding: 20 0189 text: UserPlaylistModel.lyrics 0190 color: "white" 0191 } 0192 } 0193 } 0194 } 0195 0196 ColumnLayout { 0197 id: bottomPlayerControls 0198 Layout.topMargin: Kirigami.Units.largeSpacing 0199 Layout.leftMargin: Kirigami.Units.gridUnit * 2 0200 Layout.rightMargin: Kirigami.Units.gridUnit * 2 0201 Layout.bottomMargin: Kirigami.Units.gridUnit * 0.5 0202 0203 // song name 0204 Label { 0205 id: mainLabel 0206 text: info.title ? info.title : i18n("No media playing") 0207 0208 Layout.fillWidth: true 0209 0210 horizontalAlignment: Text.AlignHCenter 0211 elide: Text.ElideRight 0212 maximumLineCount: 1 0213 // Hardcoded because the footerbar blur always makes a dark-ish 0214 // background, so we don't want to use a color scheme color that 0215 // might also be dark 0216 color: "white" 0217 font.pointSize: Kirigami.Theme.defaultFont.pointSize * 1.5 0218 font.weight: Font.Bold 0219 font.bold: true 0220 } 0221 0222 // song artist 0223 Kirigami.Heading { 0224 id: authorLabel 0225 text: info.artist ? info.artist : info.channel 0226 color: Kirigami.Theme.disabledTextColor 0227 0228 Layout.fillWidth: true 0229 Layout.maximumWidth:600 0230 Layout.alignment: Qt.AlignHCenter 0231 horizontalAlignment: Text.AlignHCenter 0232 elide: Text.ElideRight 0233 maximumLineCount: 1 0234 // Hardcoded because the footerbar blur always makes a dark-ish 0235 // background, so we don't want to use a color scheme color that 0236 // might also be dark 0237 opacity: 0.9 0238 font.pointSize: Kirigami.Theme.defaultFont.pointSize * 1.3 0239 font.bold: true 0240 Layout.bottomMargin: Kirigami.Units.gridUnit 0241 } 0242 RowLayout { 0243 Layout.topMargin: Kirigami.Units.gridUnit 0244 0245 id: controlButtonBox 0246 Layout.alignment: Qt.AlignHCenter 0247 Layout.fillHeight: true 0248 spacing: 2 0249 0250 0251 Button { 0252 id: skipBackwardButton 0253 focusPolicy: Qt.TabFocus 0254 implicitHeight: 40 0255 implicitWidth: 40 0256 0257 Kirigami.Theme.colorSet: Kirigami.Theme.Complementary 0258 Kirigami.Theme.inherit: false 0259 0260 enabled: UserPlaylistModel.canSkipBack 0261 onClicked: UserPlaylistModel.previous() 0262 contentItem: Item{ 0263 Kirigami.Icon { 0264 anchors.centerIn:parent 0265 source:"media-skip-backward" 0266 color: "white" 0267 width: Kirigami.Units.gridUnit 0268 height: Kirigami.Units.gridUnit 0269 0270 } 0271 } 0272 background: Kirigami.ShadowedRectangle{ 0273 border.color: Kirigami.Theme.hoverColor 0274 border.width: skipBackwardButton.activeFocus? 1 :0 0275 corners.topLeftRadius: 7 0276 corners.bottomLeftRadius: 7 0277 0278 0279 color: if (parent.down){ 0280 Kirigami.ColorUtils.linearInterpolation(Kirigami.Theme.hoverColor, "transparent", 0.3) 0281 }else if(parent.hovered){ 0282 Kirigami.ColorUtils.linearInterpolation(Kirigami.Theme.hoverColor, "transparent", 0.7) 0283 }else{ 0284 Qt.rgba(1, 1, 1, 0.2) 0285 } 0286 } 0287 } 0288 0289 Button { 0290 id: playPauseButton 0291 focusPolicy: Qt.TabFocus 0292 implicitHeight: 40 0293 implicitWidth: 60 0294 enabled: info.title 0295 onClicked: audio.playbackState === MediaPlayer.PlayingState ? audio.pause() : audio.play() 0296 contentItem: Item{ 0297 Kirigami.Icon { 0298 anchors.centerIn:parent 0299 source: audio.playbackState === MediaPlayer.PlayingState ? "media-playback-pause" : "media-playback-start" 0300 color: "white" 0301 width: Kirigami.Units.gridUnit 0302 height: Kirigami.Units.gridUnit 0303 } 0304 } 0305 background: Kirigami.ShadowedRectangle{ 0306 border.color: Kirigami.Theme.hoverColor 0307 border.width: playPauseButton.activeFocus? 1 :0 0308 color: if (parent.down){ 0309 Kirigami.ColorUtils.linearInterpolation(Kirigami.Theme.hoverColor, "transparent", 0.3) 0310 }else if(parent.hovered){ 0311 Kirigami.ColorUtils.linearInterpolation(Kirigami.Theme.hoverColor, "transparent", 0.7) 0312 }else{ 0313 Qt.rgba(1, 1, 1, 0.2) 0314 } 0315 } 0316 } 0317 0318 Button { 0319 id: skipForwardButton 0320 focusPolicy: Qt.TabFocus 0321 implicitHeight: 40 0322 implicitWidth: 40 0323 Layout.rightMargin:isWidescreen?0:10 0324 0325 Kirigami.Theme.colorSet: Kirigami.Theme.Complementary 0326 Kirigami.Theme.inherit: false 0327 0328 enabled: UserPlaylistModel.canSkip 0329 onClicked: UserPlaylistModel.next() 0330 contentItem: Item{ 0331 Kirigami.Icon { 0332 anchors.centerIn:parent 0333 source:"media-skip-forward" 0334 color: "white" 0335 width: Kirigami.Units.gridUnit 0336 height: Kirigami.Units.gridUnit 0337 0338 } 0339 } 0340 background: Kirigami.ShadowedRectangle{ 0341 border.color: Kirigami.Theme.hoverColor 0342 border.width: skipForwardButton.activeFocus? 1 :0 0343 corners.topRightRadius: 7 0344 corners.bottomRightRadius: 7 0345 color: if (parent.down){ 0346 Kirigami.ColorUtils.linearInterpolation(Kirigami.Theme.hoverColor, "transparent", 0.3) 0347 }else if(parent.hovered){ 0348 Kirigami.ColorUtils.linearInterpolation(Kirigami.Theme.hoverColor, "transparent", 0.7) 0349 }else{ 0350 Qt.rgba(1, 1, 1, 0.2) 0351 } 0352 } 0353 } 0354 } 0355 // slider row 0356 RowLayout { 0357 Layout.topMargin: Kirigami.Units.gridUnit 0358 spacing: Kirigami.Units.smallSpacing 0359 0360 Label { 0361 Layout.alignment: Qt.AlignVCenter 0362 color: "white" 0363 visible: info.title 0364 text: PlayerUtils.formatTimestamp(audio.position) 0365 } 0366 0367 Slider { 0368 Layout.alignment: Qt.AlignVCenter 0369 Layout.fillWidth: true 0370 from: 0 0371 to: audio.duration 0372 value: audio.position 0373 enabled: audio.seekable 0374 onMoved: { 0375 console.log("Value:", value); 0376 audio.position = Math.floor(value); 0377 } 0378 0379 Behavior on value { 0380 NumberAnimation { 0381 duration: 1000 0382 } 0383 } 0384 } 0385 0386 Label { 0387 Layout.alignment: Qt.AlignVCenter 0388 color: "white" 0389 visible: info.title 0390 text: PlayerUtils.formatTimestamp(audio.duration) 0391 } 0392 } 0393 0394 RowLayout { 0395 Layout.topMargin: Kirigami.Units.largeSpacing 0396 Layout.fillWidth: true 0397 // ensure white icons 0398 Kirigami.Theme.colorSet: Kirigami.Theme.Complementary 0399 Kirigami.Theme.inherit: false 0400 Item { 0401 width: queueButton.width 0402 visible: wideScreen 0403 } 0404 0405 Item { Layout.fillWidth: true} 0406 0407 ToolButton { 0408 id: favouriteButton 0409 readonly property QtObject favouriteWatcher: Library.favouriteWatcher(info.videoId) 0410 Layout.alignment: Qt.AlignRight | Qt.AlignVCenter 0411 Layout.preferredHeight: Kirigami.Units.gridUnit * 2.5 0412 Layout.maximumWidth: height 0413 Layout.preferredWidth: height 0414 onClicked: { 0415 if (favouriteWatcher) { 0416 if (favouriteWatcher.isFavourite) { 0417 Library.removeFavourite(info.videoId) 0418 // This would insert slightly ugly data into the database, but let's hope the song is already saved 0419 } else { 0420 let index = UserPlaylistModel.index(UserPlaylistModel.currentIndex, 0) 0421 let videoId = UserPlaylistModel.data(index, UserPlaylistModel.VideoId) 0422 let title = UserPlaylistModel.data(index, UserPlaylistModel.Title) 0423 let artist = UserPlaylistModel.data(index, UserPlaylistModel.Artists) 0424 let album = UserPlaylistModel.data(index, UserPlaylistModel.Album) 0425 Library.addFavourite(videoId, title, artist, album) 0426 } 0427 } 0428 } 0429 text: favouriteWatcher ? (favouriteWatcher.isFavourite ? i18n("Remove from Favourites") : i18n("Add to Favourites")) : i18n("Add to Favourites") 0430 icon.name: favouriteWatcher ? (favouriteWatcher.isFavourite ? "starred-symbolic" : "non-starred-symbolic") : "non-starred-symbolic" 0431 enabled: favouriteWatcher 0432 icon.color: "white" 0433 display: AbstractButton.IconOnly 0434 0435 ToolTip.text: text 0436 ToolTip.delay: Kirigami.Units.toolTipDelay 0437 ToolTip.visible: Kirigami.Settings.isMobile ? pressed : hovered 0438 0439 Kirigami.Theme.colorSet: Kirigami.Theme.Complementary 0440 Kirigami.Theme.inherit: false 0441 } 0442 0443 ToolButton { 0444 id: volumeButtonSmallScreen 0445 Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter 0446 Layout.preferredHeight: Kirigami.Units.gridUnit * 2.5 0447 Layout.maximumWidth: height 0448 Layout.preferredWidth: height 0449 visible: !isWidescreen 0450 enabled: !isWidescreen 0451 0452 icon.name: muteButton.icon.name 0453 0454 text: i18n("Open Volume Drawer") 0455 display: AbstractButton.IconOnly 0456 ToolTip.text: text 0457 ToolTip.delay: Kirigami.Units.toolTipDelay 0458 ToolTip.visible: Kirigami.Settings.isMobile ? pressed : hovered 0459 0460 onClicked:{ 0461 if(!volumeDrawer.opened){ 0462 volumeDrawer.open() 0463 } 0464 else{ 0465 volumeDrawer.close() 0466 } 0467 } 0468 Components.BottomDrawer { 0469 id: volumeDrawer 0470 0471 parent: applicationWindow().overlay 0472 0473 drawerContentItem: RowLayout { 0474 ToolButton { 0475 Layout.preferredHeight: Kirigami.Units.gridUnit * 2.5 0476 Layout.maximumWidth: height 0477 Layout.preferredWidth: height 0478 0479 icon.name: muteButton.icon.name 0480 checkable: true 0481 checked: muteButton.checked 0482 text: muteButton.text 0483 display: muteButton.display 0484 0485 ToolTip.text: text 0486 ToolTip.delay: Kirigami.Units.toolTipDelay 0487 ToolTip.visible: Kirigami.Settings.isMobile ? pressed : hovered 0488 0489 onClicked: { 0490 if(audio.muted) 0491 { 0492 muteButton.unmuteAudio() 0493 } 0494 else 0495 { 0496 muteButton.muteAudio() 0497 } 0498 } 0499 } 0500 0501 Slider { 0502 id: slider 0503 value: volumeSlider.value 0504 opacity: volumeSlider.opacity 0505 wheelEnabled: true 0506 0507 Layout.fillWidth: true 0508 Layout.preferredHeight: Kirigami.Units.gridUnit * 2.5 0509 0510 onMoved: { 0511 volumeSlider.value = value 0512 volumeSlider.valueChanged() 0513 } 0514 } 0515 0516 Label { 0517 Layout.preferredHeight: slider.height 0518 Layout.preferredWidth: Kirigami.Units.gridUnit * 2.5 0519 0520 text: volumeLabel.text 0521 } 0522 } 0523 } 0524 } 0525 0526 ToolButton { 0527 id: muteButton 0528 0529 function muteAudio() { 0530 audioOutput.muted = true 0531 volumeSlider.opacity = 0.5 0532 checked = true 0533 } 0534 function unmuteAudio() { 0535 audioOutput.muted = false 0536 volumeSlider.opacity = 1 0537 checked = false 0538 } 0539 0540 Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter 0541 Layout.preferredHeight: Kirigami.Units.gridUnit * 2.5 0542 Layout.maximumWidth: height 0543 Layout.preferredWidth: height 0544 0545 onClicked: { 0546 if(audioOutput.muted) { 0547 unmuteAudio() 0548 } 0549 else { 0550 muteAudio() 0551 } 0552 } 0553 0554 icon.name: audioOutput.muted ? "audio-volume-muted" : (volumeSlider.value < .33 ? "audio-volume-low" : (volumeSlider.value < .66 ? "audio-volume-medium" : "audio-volume-high")) 0555 icon.color: "white" 0556 0557 Kirigami.Theme.colorSet: Kirigami.Theme.Complementary 0558 Kirigami.Theme.inherit: false 0559 0560 checkable: true 0561 visible: isWidescreen 0562 enabled: isWidescreen 0563 text: audioOutput.muted ? i18n("Unmute Audio") : i18n("Mute Audio") 0564 display: AbstractButton.IconOnly 0565 0566 ToolTip.text: text 0567 ToolTip.delay: Kirigami.Units.toolTipDelay 0568 ToolTip.visible: Kirigami.Settings.isMobile ? pressed : hovered 0569 } 0570 0571 Slider { 0572 id: volumeSlider 0573 enabled: isWidescreen 0574 visible: isWidescreen 0575 0576 property real volume: PlayerUtils.convertVolume(value) 0577 0578 Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter 0579 Layout.preferredHeight: Kirigami.Units.gridUnit * 2.5 0580 Layout.preferredWidth: 2*Layout.preferredHeight 0581 0582 value: 1.0 0583 from: 0.0 0584 to: 1.0 0585 wheelEnabled: true 0586 0587 onMoved: { 0588 audioOutput.volume = volumeSlider.volume 0589 if (volumeSlider.value === 0) { 0590 muteButton.muteAudio() 0591 } else { 0592 muteButton.unmuteAudio() 0593 } 0594 } 0595 } 0596 0597 Label { 0598 id: volumeLabel 0599 0600 enabled: isWidescreen 0601 visible: isWidescreen 0602 text: i18n("%1%", Math.round(volumeSlider.value*100)) 0603 0604 Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter 0605 Layout.preferredWidth: Kirigami.Units.gridUnit * 2.5 0606 } 0607 0608 ToolButton { 0609 property bool lyricsShown: false 0610 id: lyricsButton 0611 Layout.preferredHeight: Kirigami.Units.gridUnit * 2.5 0612 Layout.maximumWidth: height 0613 Layout.preferredWidth: height 0614 checked: lyricsShown 0615 onClicked: { 0616 if (!lyricsShown) 0617 swipeView.setCurrentIndex(1) 0618 else{ 0619 swipeView.setCurrentIndex(0) 0620 } 0621 lyricsShown = !lyricsShown 0622 } 0623 Connections { 0624 target: UserPlaylistModel 0625 function onNoLyrics() { 0626 if(lyricsButton.lyricsShown) { 0627 lyricsButton.clicked() 0628 } 0629 } 0630 } 0631 enabled: UserPlaylistModel.lyrics 0632 text: lyricsShown ? i18n("Hide Lyrics") : i18n("Show Lyrics") 0633 icon.name: "view-media-lyrics" 0634 icon.color: "white" 0635 display: AbstractButton.IconOnly 0636 0637 ToolTip.text: text 0638 ToolTip.delay: Kirigami.Units.toolTipDelay 0639 ToolTip.visible: Kirigami.Settings.isMobile ? pressed : hovered 0640 0641 Kirigami.Theme.colorSet: Kirigami.Theme.Complementary 0642 Kirigami.Theme.inherit: false 0643 } 0644 ToolButton { 0645 0646 id: shareButton 0647 Layout.preferredHeight: Kirigami.Units.gridUnit * 2.5 0648 Layout.maximumWidth: height 0649 Layout.preferredWidth: height 0650 onClicked: openShareMenu(info.title, UserPlaylistModel.webUrl) 0651 0652 text: i18n("Share Song") 0653 icon.name: "emblem-shared-symbolic" 0654 icon.color: "white" 0655 display: AbstractButton.IconOnly 0656 0657 ToolTip.text: text 0658 ToolTip.delay: Kirigami.Units.toolTipDelay 0659 ToolTip.visible: Kirigami.Settings.isMobile ? pressed : hovered 0660 0661 enabled: info.title 0662 0663 Kirigami.Theme.colorSet: Kirigami.Theme.Complementary 0664 Kirigami.Theme.inherit: false 0665 } 0666 0667 PlaylistDialog { 0668 id: playlistsDialog 0669 } 0670 ToolButton { 0671 id: addToPlaylistButton 0672 Layout.preferredHeight: Kirigami.Units.gridUnit * 2.5 0673 Layout.maximumWidth: height 0674 Layout.preferredWidth: height 0675 enabled: info.videoId 0676 0677 onClicked: { 0678 let index = UserPlaylistModel.index(UserPlaylistModel.currentIndex, 0) 0679 let videoId = UserPlaylistModel.data(index, UserPlaylistModel.VideoId) 0680 let title = UserPlaylistModel.data(index, UserPlaylistModel.Title) 0681 let artist = UserPlaylistModel.data(index, UserPlaylistModel.Artists) 0682 let album = UserPlaylistModel.data(index, UserPlaylistModel.Album) 0683 playlistsDialog.videoId = videoId 0684 playlistsDialog.songTitle = title 0685 playlistsDialog.artists = artist 0686 playlistsDialog.album = album 0687 0688 playlistsDialog.open() 0689 } 0690 0691 icon.name: "media-playlist-append" 0692 icon.color: "white" 0693 text: i18n("Add to a local playlist") 0694 display: AbstractButton.IconOnly 0695 0696 ToolTip.text: text 0697 ToolTip.delay: Kirigami.Units.toolTipDelay 0698 ToolTip.visible: Kirigami.Settings.isMobile ? pressed : hovered 0699 0700 Kirigami.Theme.colorSet: Kirigami.Theme.Complementary 0701 Kirigami.Theme.inherit: false 0702 } 0703 Item { 0704 Layout.fillWidth: true 0705 visible: wideScreen 0706 } 0707 0708 ToolButton { 0709 id: queueButton 0710 Layout.alignment: Qt.AlignRight 0711 Layout.preferredHeight: Kirigami.Units.gridUnit * 2.5 0712 Layout.maximumWidth: height 0713 Layout.preferredWidth: height 0714 checked: !sideDrawer.collapsed && wideScreen 0715 enabled: playListView.count != 0 || !sideDrawer.collapsed 0716 0717 onClicked: { 0718 if (wideScreen) { 0719 if (!sideDrawer.collapsed) 0720 collapse.running = true 0721 else{ 0722 sideDrawer.visible=true 0723 show.running = true 0724 } 0725 sideDrawer.collapsed = !sideDrawer.collapsed 0726 }else{queueDrawer.open()} 0727 checked = !sideDrawer.collapsed && wideScreen 0728 } 0729 0730 text: checked ? i18n("Hide Queue") : i18n("Show Queue") 0731 display: AbstractButton.IconOnly 0732 0733 ToolTip.text: text 0734 ToolTip.delay: Kirigami.Units.toolTipDelay 0735 ToolTip.visible: Kirigami.Settings.isMobile ? pressed : hovered 0736 0737 icon.name: "amarok_playlist" 0738 icon.color: "white" 0739 0740 Kirigami.Theme.colorSet: Kirigami.Theme.Complementary 0741 Kirigami.Theme.inherit: false 0742 } 0743 0744 Item { 0745 Layout.fillWidth: true 0746 visible: !wideScreen 0747 } 0748 0749 } 0750 } 0751 } 0752 0753 Item { 0754 onWidthChanged: if(!wideScreen) {collapse.running=true; collapsed=true; queueButton.checked=false} 0755 property bool collapsed: true 0756 id: sideDrawer 0757 Layout.fillWidth: true 0758 Layout.maximumWidth: -1 0759 Layout.preferredWidth: Math.max(350, root.width/3) 0760 0761 Layout.fillHeight: true 0762 visible: false 0763 NumberAnimation on Layout.maximumWidth { 0764 id: collapse 0765 easing.type: Easing.OutCubic 0766 running: false 0767 from: Math.min(sideDrawer.Layout.preferredWidth, sideDrawer.Layout.maximumWidth); to: 0 0768 onFinished: { sideDrawer.visible=false} 0769 } 0770 NumberAnimation on Layout.maximumWidth { 0771 id: show 0772 easing.type: Easing.OutCubic 0773 running: false 0774 from: 0; to: Math.min(sideDrawer.Layout.preferredWidth, root.width - mainContent.Layout.minimumWidth) 0775 //onFinished: { sideDrawer.visible=false} 0776 } 0777 Kirigami.Separator{ 0778 color: "white" 0779 opacity: 0.3 0780 height: parent.height 0781 anchors.left: parent.left 0782 0783 } 0784 Rectangle{ 0785 anchors.fill: parent 0786 color: "white" 0787 opacity: 0.2 0788 } 0789 0790 MouseArea { 0791 id: queueResizer 0792 0793 anchors.horizontalCenter: parent.left 0794 anchors.top: parent.top 0795 anchors.bottom: parent.bottom 0796 width: Kirigami.Units.gridUnit 0797 0798 cursorShape: Qt.SplitHCursor 0799 onPositionChanged: { 0800 if(Math.max(sideDrawer.width - (mouse.x - width/2), queueFooter.Layout.minimumWidth) + mainContent.Layout.minimumWidth < root.width){ 0801 sideDrawer.Layout.preferredWidth = sideDrawer.Layout.minimumWidth = sideDrawer.Layout.maximumWidth = Math.max(sideDrawer.width - (mouse.x - width/2), queueFooter.Layout.minimumWidth) 0802 } 0803 } 0804 } 0805 0806 ColumnLayout { 0807 spacing: 0 0808 anchors.fill: parent 0809 ScrollView { 0810 id: playListScrollView 0811 0812 contentWidth: availableWidth 0813 0814 Layout.fillWidth: true 0815 Layout.fillHeight: true 0816 Layout.leftMargin:10 0817 ListView { 0818 id: playListView 0819 0820 reuseItems: true 0821 0822 spacing: 5 0823 rightMargin: 10 0824 topMargin:10 0825 bottomMargin: 10 0826 clip: true 0827 contentWidth: playListScrollView.contentWidth - rightMargin - leftMargin 0828 0829 Kirigami.Theme.colorSet: Kirigami.Theme.Complementary 0830 Kirigami.Theme.inherit: false 0831 0832 BusyIndicator { 0833 anchors.centerIn: parent 0834 visible: UserPlaylistModel.loading || UserPlaylistModel.loading 0835 } 0836 0837 model: UserPlaylistModel 0838 0839 moveDisplaced: Transition { 0840 YAnimator { 0841 duration: Kirigami.Units.mediumDuration 0842 easing.type: Easing.InOutQuad 0843 } 0844 } 0845 0846 delegate: Item{ 0847 //listItemDragHandle requires queueEntry to be a child of the delegate, and not the delegate itself 0848 id: delegateItem 0849 0850 required property string title 0851 required property string videoId 0852 required property string artists 0853 required property bool isCurrent 0854 required property int index 0855 width: queueEntry.implicitWidth 0856 height: queueEntry.implicitHeight 0857 0858 ItemDelegate { 0859 id: queueEntry 0860 0861 width: playListView.contentWidth 0862 0863 background: Rectangle{ 0864 radius: 7 0865 color: 0866 if (parent.down){ 0867 Kirigami.ColorUtils.linearInterpolation(Kirigami.Theme.hoverColor, "transparent", 0.3) 0868 }else if(parent.hovered){ 0869 Kirigami.ColorUtils.linearInterpolation(Kirigami.Theme.hoverColor, "transparent", 0.7) 0870 }else if(parent.highlighted){ 0871 Kirigami.ColorUtils.linearInterpolation(Kirigami.Theme.hoverColor, "transparent", 0.7) 0872 }else{ 0873 Qt.rgba(0, 0, 0, 0.4) 0874 } 0875 0876 border.color: 0877 if (parent.down){ 0878 Kirigami.Theme.hoverColor 0879 }else if(parent.hovered){ 0880 Kirigami.Theme.hoverColor 0881 }else{ 0882 Qt.rgba(1, 1, 1, 0) 0883 } 0884 0885 border.width: 1 0886 } 0887 highlighted: isCurrent 0888 onClicked: UserPlaylistModel.skipTo(videoId) 0889 contentItem: RowLayout { 0890 id: contentLayout 0891 0892 Item { 0893 width: handle.width 0894 height: handle.height 0895 Kirigami.ListItemDragHandle { 0896 id: handle 0897 Layout.fillHeight: true 0898 listItem: queueEntry 0899 listView: playListView 0900 onMoveRequested: UserPlaylistModel.moveRow(oldIndex, newIndex) 0901 } 0902 Rectangle { 0903 anchors.fill: handle 0904 layer.enabled: true 0905 layer.effect: MultiEffect { 0906 maskSource: handle 0907 maskEnabled: true 0908 } 0909 } 0910 } 0911 ThumbnailSource { 0912 id: delegateThumbnailSource 0913 videoId: delegateItem.videoId 0914 } 0915 RoundedImage { 0916 source: delegateThumbnailSource.cachedPath 0917 Layout.margins: 2.5 0918 height: column.implicitHeight 0919 width: column.implicitHeight 0920 radius: 5 0921 } 0922 0923 ColumnLayout { 0924 id: column 0925 Layout.margins: 5 0926 0927 Layout.fillWidth: true 0928 Layout.fillHeight: true 0929 0930 Kirigami.Heading { 0931 elide: Text.ElideRight 0932 Layout.fillWidth: true 0933 level: 2 0934 text: title 0935 0936 MouseArea { 0937 anchors.fill: parent 0938 hoverEnabled: true 0939 ToolTip.text: parent.text 0940 ToolTip.delay: Kirigami.Units.toolTipDelay 0941 ToolTip.visible: parent.truncated ? (Kirigami.Settings.isMobile ? containsPress : containsMouse) : false 0942 } 0943 } 0944 0945 Label { 0946 elide: Text.ElideRight 0947 Layout.fillWidth: true 0948 color: Kirigami.Theme.disabledTextColor 0949 text: artists 0950 } 0951 0952 } 0953 ToolButton { 0954 text: i18n("Remove Track") 0955 icon.name: "list-remove" 0956 icon.color: "white" 0957 display: AbstractButton.IconOnly 0958 onClicked: UserPlaylistModel.remove(delegateItem.videoId) 0959 } 0960 } 0961 } 0962 } 0963 } 0964 } 0965 0966 0967 Kirigami.Separator { 0968 color: "white" 0969 opacity: 0.3 0970 Layout.fillWidth: true 0971 } 0972 0973 RowLayout { 0974 id: queueFooter 0975 0976 Layout.margins: Kirigami.Units.gridUnit * 0.5 0977 enabled: playListView.count != 0 0978 Item { 0979 Layout.fillWidth: true 0980 } 0981 0982 ToolButton { 0983 id: clearPlaylistButton 0984 0985 Layout.preferredHeight: Kirigami.Units.gridUnit * 2.5 0986 Layout.maximumWidth: height 0987 Layout.preferredWidth: height 0988 0989 text: i18n("Clear Queue") 0990 icon { 0991 name: "edit-clear-all" 0992 color: "white" 0993 } 0994 display: AbstractButton.IconOnly 0995 0996 ToolTip.text: text 0997 ToolTip.delay: Kirigami.Units.toolTipDelay 0998 ToolTip.visible: Kirigami.Settings.isMobile ? pressed : hovered 0999 1000 onClicked: UserPlaylistModel.clearExceptCurrent() 1001 1002 Kirigami.Theme.colorSet: Kirigami.Theme.Complementary 1003 Kirigami.Theme.inherit: false 1004 } 1005 1006 ToolButton { 1007 id: shuffleButton 1008 Layout.preferredHeight: Math.round(Kirigami.Units.gridUnit * 2.5) 1009 Layout.maximumWidth: height 1010 Layout.preferredWidth: height 1011 1012 onClicked: UserPlaylistModel.shufflePlaylist() 1013 1014 text: i18n("Shuffle Queue") 1015 1016 ToolTip.text: text 1017 ToolTip.delay: Kirigami.Units.toolTipDelay 1018 ToolTip.visible: Kirigami.Settings.isMobile ? pressed : hovered 1019 1020 icon { 1021 name: "media-playlist-shuffle" 1022 color: "white" 1023 } 1024 display: AbstractButton.IconOnly 1025 Kirigami.Theme.colorSet: Kirigami.Theme.Complementary 1026 Kirigami.Theme.inherit: false 1027 } 1028 1029 Item { 1030 Layout.fillWidth: true 1031 } 1032 } 1033 } 1034 } 1035 1036 Components.BottomDrawer { 1037 id: queueDrawer 1038 1039 parent: applicationWindow().overlay 1040 1041 onClosed:{sideDrawer.collapsed=true} 1042 height: applicationWindow().height-50 1043 interactive: true 1044 1045 headerContentItem: RowLayout { 1046 Kirigami.Heading { 1047 text: i18n("Upcoming Songs") 1048 elide: Qt.ElideRight 1049 Layout.margins: 0 1050 Layout.fillWidth: true 1051 } 1052 Item { 1053 Layout.fillWidth: true 1054 } 1055 ToolButton { 1056 Layout.topMargin: 0 1057 Layout.bottomMargin: 0 1058 Layout.maximumWidth: height 1059 Layout.preferredWidth: height 1060 text: clearPlaylistButton.text 1061 1062 ToolTip.text: text 1063 ToolTip.delay: Kirigami.Units.toolTipDelay 1064 ToolTip.visible: Kirigami.Settings.isMobile ? pressed : hovered 1065 1066 icon.name: "edit-clear-all" 1067 display: clearPlaylistButton.display 1068 onClicked: { 1069 UserPlaylistModel.clearExceptCurrent() 1070 } 1071 enabled: playListView.count != 0 1072 } 1073 1074 ToolButton { 1075 Layout.topMargin: 0 1076 Layout.bottomMargin: 0 1077 Layout.maximumWidth: height 1078 Layout.preferredWidth: height 1079 icon.name: "media-playlist-shuffle" 1080 text: shuffleButton.text 1081 display: shuffleButton.display 1082 1083 ToolTip.text: text 1084 ToolTip.delay: Kirigami.Units.toolTipDelay 1085 ToolTip.visible: Kirigami.Settings.isMobile ? pressed : hovered 1086 1087 onClicked: { 1088 UserPlaylistModel.shufflePlaylist() 1089 } 1090 enabled: playListView.count != 0 1091 } 1092 } 1093 1094 drawerContentItem: ScrollView { 1095 ListView { 1096 id: drawerListView 1097 topMargin: 10 1098 clip: true 1099 1100 reuseItems: true 1101 1102 BusyIndicator { 1103 anchors.centerIn: parent 1104 visible: UserPlaylistModel.loading || UserPlaylistModel.loading 1105 } 1106 1107 model: UserPlaylistModel 1108 1109 moveDisplaced: Transition { 1110 YAnimator { 1111 duration: Kirigami.Units.mediumDuration 1112 easing.type: Easing.InOutQuad 1113 } 1114 } 1115 1116 delegate: Item { 1117 id: drawerDelegateItem 1118 required property string title 1119 required property string videoId 1120 required property string artists 1121 required property bool isCurrent 1122 required property int index 1123 1124 width: drawerListView.width 1125 height: drawerQueueEntry.height 1126 1127 ItemDelegate { 1128 id: drawerQueueEntry 1129 1130 width: parent.width 1131 1132 highlighted: drawerDelegateItem.isCurrent 1133 onClicked: { 1134 queueDrawer.close() 1135 UserPlaylistModel.skipTo(drawerDelegateItem.videoId) 1136 } 1137 contentItem: RowLayout { 1138 Layout.fillWidth: true 1139 Item { 1140 width: drawerHandle.width 1141 height: drawerHandle.height 1142 Kirigami.ListItemDragHandle { 1143 id: drawerHandle 1144 Layout.fillHeight: true 1145 listItem: drawerQueueEntry 1146 listView: drawerListView 1147 onMoveRequested: UserPlaylistModel.moveRow(oldIndex, newIndex) 1148 } 1149 1150 Rectangle { 1151 anchors.fill: drawerHandle 1152 layer.enabled: true 1153 layer.effect: MultiEffect { 1154 maskSource: drawerHandle 1155 maskEnabled: true 1156 } 1157 } 1158 } 1159 ThumbnailSource { 1160 id: drawerDelegateThumbnailSource 1161 videoId: drawerDelegateItem.videoId 1162 } 1163 RoundedImage { 1164 source: drawerDelegateThumbnailSource.cachedPath 1165 1166 height: 50 1167 width: height 1168 radius: 5 1169 } 1170 1171 ColumnLayout { 1172 Layout.margins: 5 1173 Layout.fillWidth: true 1174 Kirigami.Heading { 1175 elide: Text.ElideRight 1176 Layout.fillWidth: true 1177 level: 2 1178 text: drawerDelegateItem.title 1179 1180 MouseArea { 1181 anchors.fill: parent 1182 hoverEnabled: true 1183 ToolTip.text: parent.text 1184 ToolTip.delay: Kirigami.Units.toolTipDelay 1185 ToolTip.visible: parent.truncated ? (Kirigami.Settings.isMobile ? containsPress : containsMouse) : false 1186 } 1187 } 1188 1189 Label { 1190 elide: Text.ElideRight 1191 Layout.fillWidth: true 1192 color: Kirigami.Theme.disabledTextColor 1193 text: drawerDelegateItem.artists 1194 } 1195 } 1196 1197 ToolButton { 1198 text: i18n("Remove Track") 1199 icon.name: "list-remove" 1200 display: AbstractButton.IconOnly 1201 onClicked: UserPlaylistModel.remove(drawerDelegateItem.videoId) 1202 } 1203 } 1204 } 1205 } 1206 } 1207 } 1208 } 1209 } 1210 }