@ -8,7 +8,9 @@
* /
import QtQuick 2.15
import QtQuick . Controls 2.15 as QQC2
import QtQuick . Layouts 1.1
import org . kde . plasma . plasmoid 2.0
import org . kde . plasma . core 2.0 as PlasmaCore
import org . kde . plasma . components 3.0 as PlasmaComponents3
@ -148,10 +150,13 @@ PlasmaExtras.Representation {
ShaderEffect {
id: backgroundImage
property real scaleFactor: 1.0
property Image source: albumArt
property ShaderEffectSource source: ShaderEffectSource {
id: shaderEffectSource
sourceItem: albumArt
}
anchors.centerIn: parent
visible: ! ! root . track && source . status === Image . Ready && ! softwareRendering
visible: ( exitTransition . running || albumArt . hasImage ) && ! softwareRendering
layer.enabled: ! softwareRendering
layer.effect: HueSaturation {
@ -174,12 +179,20 @@ PlasmaExtras.Representation {
/ / u s e S t a t e t o a v o i d u n n e c e s s a r y r e e v a l u a t i o n o f w i d t h a n d h e i g h t
states: State {
name: "albumArtReady"
when: Plasmoid . expanded && backgroundImage . visible && albumArt . paintedWidth > 0
when: Plasmoid . expanded && backgroundImage . visible && albumArt . currentItem . paintedWidth > 0
PropertyChanges {
target: backgroundImage
scaleFactor: Math . max ( parent . width / source . paintedWidth , parent . height / source . paintedHeight )
width: Math . round ( source . paintedWidth * scaleFactor )
height: Math . round ( source . paintedHeight * scaleFactor )
scaleFactor: Math . max ( parent . width / albumArt . currentItem . paintedWidth , parent . height / albumArt . currentItem . paintedHeight )
width: Math . round ( albumArt . currentItem . paintedWidth * scaleFactor )
height: Math . round ( albumArt . currentItem . paintedHeight * scaleFactor )
}
PropertyChanges {
target: shaderEffectSource
/ / H A C K : F i x b a c k g r o u n d r a t i o w h e n D P I > 1
sourceRect: Qt . rect ( albumArt . width - albumArt . currentItem . paintedWidth ,
Math . round ( ( albumArt . height - albumArt . currentItem . paintedHeight ) / 2 ) ,
albumArt . currentItem . paintedWidth ,
albumArt . currentItem . paintedHeight )
}
}
}
@ -199,26 +212,121 @@ PlasmaExtras.Representation {
Layout.fillHeight: true
Layout.preferredWidth: 50
Image { / / A l b u m A r t
QQC2 . StackView {
id: albumArt
anchors.fill: parent
visible: ! ! root . track && status === Image . Ready
readonly property bool hasImage: currentItem instanceof Image
&& ( currentItem . status === Image . Ready || currentItem . status === Image . Loading )
replaceEnter: Transition {
ParallelAnimation {
OpacityAnimator {
from: 0
to: 1
duration: PlasmaCore . Units . longDuration
}
PropertyAction {
target: fallbackIconLoader
property: "opacity"
value: 0
}
}
}
replaceExit: Transition {
id: exitTransition
ParallelAnimation {
OpacityAnimator {
from: 1
to: 0
duration: PlasmaCore . Units . longDuration
}
OpacityAnimator {
target: fallbackIconLoader
to: 1
duration: PlasmaCore . Units . longDuration
}
}
}
Connections {
enabled: Plasmoid . expanded
target: root
function onAlbumArtChanged ( ) {
albumArt . loadAlbumArt ( ) ;
}
}
Connections {
target: plasmoid
function onExpandedChanged ( ) {
/ / N O T E : D o n ' t u s e s t r i c t e q u a l i t y
if ( ! Plasmoid . expanded || ( albumArt . currentItem instanceof Image && albumArt . currentItem . source == root . albumArt ) ) {
return ;
}
albumArt . loadAlbumArt ( ) ;
}
}
function loadAlbumArt ( ) {
if ( ! root . albumArt ) {
albumArt . clear ( QQC2 . StackView . ReplaceTransition ) ;
return ;
}
const pendingImage = albumArtComponent . createObject ( albumArt , {
"source" : root . albumArt ,
"opacity" : 0 ,
} ) ;
function replaceWhenLoaded ( ) {
if ( pendingImage . status === Image . Loading ) {
return ;
}
if ( pendingImage . status === Image . Null || pendingImage . status === Image . Error ) {
pendingImage . destroy ( ) ;
return ;
}
albumArt . replace ( pendingImage , { } , QQC2 . StackView . ReplaceTransition ) ;
pendingImage . statusChanged . disconnect ( replaceWhenLoaded ) ;
}
pendingImage . statusChanged . connect ( replaceWhenLoaded ) ;
replaceWhenLoaded ( ) ;
}
Component {
id: albumArtComponent
asynchronous: true
Image { / / A l b u m A r t
horizontalAlignment: Image . AlignRight
verticalAlignment: Image . AlignVCenter
fillMode: Image . PreserveAspectFit
horizontalAlignment: Image . AlignRight
verticalAlignment: Image . AlignVCenter
fillMode: Image . PreserveAspectFit
asynchronous: true
cache: false
source: root . albumArt
QQC2.StackView.onRemoved: {
source = "" ; / / H A C K : R e d u c e m e m o r y u s a g e
destroy ( ) ;
}
}
}
}
Loader {
id: fallbackIconLoader
/ / W h e n a l b u m A r t i s s h o w n , t h e i c o n i s u n l o a d e d t o r e d u c e m e m o r y u s a g e .
readonly property string icon: ( mpris2Source . currentData && mpris2Source . currentData [ "Desktop Icon Name" ] ) || "media-album-cover"
active: ! albumArt . visible
active: Plasmoid . expanded && ! albumArt . hasImag e
anchors.fill: parent
sourceComponent: root . track ? fallbackIconItem : placeholderMessage
@ -237,6 +345,7 @@ PlasmaExtras.Representation {
Component {
id: placeholderMessage
Item { / / P u t P l a c e h o l d e r M e s s a g e i n I t e m s o P l a c e h o l d e r M e s s a g e w i l l n o t f i l l i t s p a r e n t .
anchors.fill: parent
@ -266,7 +375,7 @@ PlasmaExtras.Representation {
id: songTitle
level: 1
color: ( softwareRendering || ! albumArt . visibl e) ? PlasmaCore.ColorScope.textColor : "white"
color: ( softwareRendering || ! albumArt . hasImag e) ? PlasmaCore.ColorScope.textColor : "white"
textFormat: Text . PlainText
wrapMode: Text . Wrap
@ -283,7 +392,7 @@ PlasmaExtras.Representation {
visible: root . artist
level: 2
color: ( softwareRendering || ! albumArt . visibl e) ? PlasmaCore.ColorScope.textColor : "white"
color: ( softwareRendering || ! albumArt . hasImag e) ? PlasmaCore.ColorScope.textColor : "white"
textFormat: Text . PlainText
wrapMode: Text . Wrap
@ -295,7 +404,7 @@ PlasmaExtras.Representation {
Layout.maximumHeight: PlasmaCore . Units . gridUnit * 2
}
Kirigami . Heading { / / S o n g A l b u m
color: ( softwareRendering || ! albumArt . visibl e) ? PlasmaCore.ColorScope.textColor : "white"
color: ( softwareRendering || ! albumArt . hasImag e) ? PlasmaCore.ColorScope.textColor : "white"
level: 3
opacity: 0.6