Warning, /multimedia/elisa/src/qml/mobile/MobileFooterBar.qml is written in an unsupported language. File is not indexed.
0001 /* 0002 SPDX-FileCopyrightText: 2016 (c) Matthieu Gallien <matthieu_gallien@yahoo.fr> 0003 SPDX-FileCopyrightText: 2020 (c) Devin Lin <espidev@gmail.com> 0004 0005 SPDX-License-Identifier: LGPL-3.0-or-later 0006 */ 0007 0008 import QtQuick 2.7 0009 import QtQuick.Layouts 1.2 0010 import QtQuick.Controls 2.3 0011 import QtQuick.Window 2.2 0012 import Qt5Compat.GraphicalEffects 0013 import org.kde.kirigami 2.5 as Kirigami 0014 import org.kde.elisa 1.0 0015 import ".." 0016 0017 Flickable { 0018 id: footerBar 0019 0020 property string title 0021 property string artist 0022 property string albumArtist 0023 property string album 0024 property string image 0025 property string newImage 0026 property string oldImage 0027 property int trackRating 0028 property int albumID 0029 property bool ratingVisible 0030 property alias trackControl: playControlItem 0031 property alias playerControl: mobileTrackPlayer 0032 property int imageSourceSize: 512 0033 0034 property bool portrait: (contentZone.height/contentZone.width) > 0.7 0035 0036 signal openArtist() 0037 signal openAlbum() 0038 signal openNowPlaying() 0039 0040 property bool isMaximized: contentY == contentHeight / 2 0041 0042 boundsBehavior: Flickable.StopAtBounds 0043 0044 onOpenArtist: toClose.restart() 0045 onOpenAlbum: toClose.restart() 0046 onOpenNowPlaying: toClose.restart() 0047 0048 NumberAnimation on contentY { 0049 id: toOpen 0050 from: contentY 0051 to: contentHeight / 2 0052 duration: Kirigami.Units.longDuration * 2 0053 easing.type: Easing.OutCubic 0054 running: false 0055 } 0056 NumberAnimation on contentY { 0057 id: toClose 0058 from: contentY 0059 to: 0 0060 duration: Kirigami.Units.longDuration * 2 0061 easing.type: Easing.OutCubic 0062 running: false 0063 } 0064 0065 // snap to end 0066 MouseArea { 0067 anchors.fill: contentZone 0068 propagateComposedEvents: true 0069 onPressed: { 0070 toOpen.stop(); 0071 toClose.stop(); 0072 propagateComposedEvents = true; 0073 } 0074 onReleased: footerBar.resetToBoundsOnFlick() 0075 } 0076 0077 function resetToBoundsOnFlick() { 0078 if (!atYBeginning || !atYEnd) { 0079 if (footerBar.verticalVelocity > 0) { 0080 toOpen.restart(); 0081 } else if (footerBar.verticalVelocity < 0) { 0082 toClose.restart(); 0083 } else { // i.e. when verticalVelocity === 0 0084 if (contentY > contentHeight / 4) { 0085 toOpen.restart(); 0086 } else { 0087 toClose.restart(); 0088 } 0089 } 0090 } 0091 } 0092 0093 function resetToBoundsOnResize() { 0094 if (contentY > contentHeight / 4) { 0095 contentY = contentHeight / 2; 0096 } else { 0097 contentY = 0; 0098 } 0099 } 0100 0101 onMovementStarted: { 0102 toOpen.stop(); 0103 toClose.stop(); 0104 } 0105 onFlickStarted: resetToBoundsOnFlick() 0106 onMovementEnded: resetToBoundsOnFlick() 0107 onHeightChanged: resetToBoundsOnResize() 0108 0109 onImageChanged: { 0110 if (changeBackgroundTransition.running) { 0111 changeBackgroundTransition.complete() 0112 } 0113 0114 newImage = image 0115 changeBackgroundTransition.start() 0116 } 0117 0118 Item { 0119 id: background 0120 anchors.fill: contentZone 0121 0122 // a cover for content underneath the panel 0123 Rectangle { 0124 id: coverUnderneath 0125 color: "#424242" // since background blurs have a dark hue, it doesn't make sense to theme 0126 anchors.fill: parent 0127 } 0128 0129 ImageWithFallback { 0130 id: oldBackground 0131 0132 source: oldImage 0133 fallback: elisaTheme.defaultBackgroundImage 0134 asynchronous: true 0135 0136 anchors.fill: parent 0137 fillMode: Image.PreserveAspectCrop 0138 0139 sourceSize.width: imageSourceSize 0140 sourceSize.height: imageSourceSize 0141 0142 opacity: 1 0143 0144 layer.enabled: true 0145 layer.effect: HueSaturation { 0146 cached: true 0147 0148 lightness: -0.4 0149 saturation: 0.9 0150 0151 layer.enabled: true 0152 layer.effect: FastBlur { 0153 cached: true 0154 radius: 100 0155 } 0156 } 0157 } 0158 0159 ImageWithFallback { 0160 id: newBackground 0161 0162 source: newImage 0163 fallback: Qt.resolvedUrl(elisaTheme.defaultBackgroundImage) 0164 0165 asynchronous: true 0166 0167 anchors.fill: parent 0168 fillMode: Image.PreserveAspectCrop 0169 0170 sourceSize.width: imageSourceSize 0171 sourceSize.height: imageSourceSize 0172 0173 visible: false 0174 opacity: 0 0175 0176 layer.enabled: true 0177 layer.effect: HueSaturation { 0178 cached: true 0179 0180 lightness: -0.5 0181 saturation: 0.9 0182 0183 layer.enabled: true 0184 layer.effect: FastBlur { 0185 cached: true 0186 radius: 100 0187 } 0188 } 0189 } 0190 } 0191 0192 ColumnLayout { 0193 id: contentZone 0194 0195 anchors.bottom: parent.bottom 0196 anchors.left: parent.left 0197 anchors.right: parent.right 0198 height: mainWindow.height + elisaTheme.mediaPlayerControlHeight 0199 spacing: 0 0200 0201 MobileMinimizedPlayerControl { 0202 id: playControlItem 0203 0204 Layout.fillWidth: true 0205 Layout.minimumHeight: elisaTheme.mediaPlayerControlHeight 0206 Layout.alignment: Qt.AlignTop 0207 focus: true 0208 0209 image: newImage 0210 title: footerBar.title 0211 artist: footerBar.artist 0212 } 0213 0214 MobileTrackPlayer { 0215 id: mobileTrackPlayer 0216 Layout.fillWidth: true 0217 Layout.fillHeight: true 0218 Layout.margins: Kirigami.Units.largeSpacing * 2 0219 0220 image: newImage 0221 title: footerBar.title 0222 artist: footerBar.artist 0223 album: footerBar.album 0224 albumArtist: footerBar.albumArtist 0225 0226 portrait: footerBar.portrait 0227 } 0228 } 0229 0230 ParallelAnimation { 0231 id: changeBackgroundTransition 0232 0233 onStarted: { 0234 newBackground.opacity = 0; 0235 newBackground.visible = true; 0236 newBackground.source = (newImage ? newImage : Qt.resolvedUrl(elisaTheme.defaultBackgroundImage)); 0237 } 0238 0239 onStopped: { 0240 footerBar.oldImage = image; 0241 oldBackground.source = (footerBar.oldImage ? footerBar.oldImage : Qt.resolvedUrl(elisaTheme.defaultBackgroundImage)); 0242 oldBackground.opacity = 1; 0243 newBackground.visible = false; 0244 oldImage = newImage; 0245 } 0246 0247 NumberAnimation { 0248 targets: [newBackground] 0249 property: 'opacity' 0250 from: 0 0251 to: 1 0252 duration: Kirigami.Units.longDuration 0253 easing.type: Easing.Linear 0254 } 0255 0256 NumberAnimation { 0257 targets: [oldBackground] 0258 property: 'opacity' 0259 from: 1 0260 to: 0 0261 duration: Kirigami.Units.longDuration 0262 easing.type: Easing.Linear 0263 } 0264 } 0265 } 0266