Warning, /plasma/plasma-workspace/wallpapers/image/imagepackage/contents/ui/ImageStackView.qml is written in an unsupported language. File is not indexed.
0001 /* 0002 SPDX-FileCopyrightText: 2013 Marco Martin <mart@kde.org> 0003 SPDX-FileCopyrightText: 2014 Sebastian Kügler <sebas@kde.org> 0004 SPDX-FileCopyrightText: 2014 Kai Uwe Broulik <kde@privat.broulik.de> 0005 0006 SPDX-License-Identifier: GPL-2.0-or-later 0007 */ 0008 0009 import QtQuick 0010 import QtQuick.Controls as QQC2 0011 import org.kde.plasma.wallpapers.image as Wallpaper 0012 import org.kde.kirigami as Kirigami 0013 0014 QQC2.StackView { 0015 id: view 0016 0017 required property int fillMode 0018 required property string configColor 0019 required property bool blur 0020 property alias source: mediaProxy.source 0021 required property size sourceSize 0022 required property QtObject wallpaperInterface 0023 0024 readonly property alias mediaProxy: mediaProxy 0025 readonly property url modelImage: mediaProxy.modelImage 0026 0027 /** 0028 * Stores pending image here to avoid the default image overriding the true image. 0029 * 0030 * @see BUG 456189 0031 */ 0032 property Item pendingImage 0033 0034 property bool doesSkipAnimation: true 0035 0036 property Component staticImageComponent 0037 property Component animatedImageComponent 0038 0039 onFillModeChanged: Qt.callLater(loadImage); 0040 onModelImageChanged: Qt.callLater(loadImage); 0041 onConfigColorChanged: Qt.callLater(loadImage); 0042 onBlurChanged: Qt.callLater(loadImage); 0043 0044 function createBackgroundComponent() { 0045 switch (mediaProxy.backgroundType) { 0046 case Wallpaper.BackgroundType.Image: { 0047 if (!staticImageComponent) { 0048 staticImageComponent = Qt.createComponent("mediacomponent/StaticImageComponent.qml"); 0049 } 0050 return staticImageComponent; 0051 } 0052 case Wallpaper.BackgroundType.AnimatedImage: { 0053 if (!animatedImageComponent) { 0054 animatedImageComponent = Qt.createComponent("mediacomponent/AnimatedImageComponent.qml"); 0055 } 0056 return animatedImageComponent; 0057 } 0058 } 0059 } 0060 0061 function loadImageImmediately() { 0062 loadImage(true); 0063 } 0064 0065 function loadImage(skipAnimation) { 0066 if (pendingImage) { 0067 pendingImage.statusChanged.disconnect(replaceWhenLoaded); 0068 pendingImage.destroy(); 0069 pendingImage = null; 0070 } 0071 0072 if (mediaProxy.providerType == Wallpaper.Provider.Unknown) { 0073 console.error("The backend got an unknown wallpaper provider type. The wallpaper will now fall back to the default. Please check your wallpaper configuration!"); 0074 mediaProxy.useSingleImageDefaults(); 0075 return; 0076 } 0077 0078 doesSkipAnimation = view.currentItem == undefined || view.currentItem.sourceSize !== view.sourceSize || !!skipAnimation; 0079 const baseImage = createBackgroundComponent(); 0080 pendingImage = baseImage.createObject(view, { 0081 // Use mediaProxy instead of view because colorSchemeChanged needs immediately update the wallpaper 0082 "source": mediaProxy.modelImage, 0083 "fillMode": view.fillMode, 0084 "sourceSize": view.sourceSize, 0085 "color": view.configColor, 0086 "blur": view.blur, 0087 "opacity": 0, 0088 "width": view.width, 0089 "height": view.height, 0090 }); 0091 0092 pendingImage.statusChanged.connect(replaceWhenLoaded); 0093 replaceWhenLoaded(); 0094 } 0095 0096 function replaceWhenLoaded() { 0097 if (pendingImage.status === Image.Loading) { 0098 return; 0099 } 0100 0101 pendingImage.statusChanged.disconnect(replaceWhenLoaded); 0102 // BUG 454908: Update accent color 0103 pendingImage.QQC2.StackView.onActivated.connect(() => { 0104 if (Qt.colorEqual(mediaProxy.customColor, "transparent") && Qt.colorEqual(wallpaperInterface.accentColor, "transparent")) { 0105 wallpaperInterface.accentColorChanged(); 0106 } else { 0107 wallpaperInterface.accentColor = mediaProxy.customColor; 0108 } 0109 }); 0110 0111 // onRemoved only fires when all transitions end. If a user switches wallpaper quickly this adds up 0112 // Given it's such a heavy item, try to cleanup as early as possible 0113 pendingImage.QQC2.StackView.onDeactivated.connect(pendingImage.destroy); 0114 pendingImage.QQC2.StackView.onRemoved.connect(pendingImage.destroy); 0115 view.replace(pendingImage, {}, QQC2.StackView.Transition); 0116 0117 wallpaperInterface.loading = false; 0118 0119 if (pendingImage.status !== Image.Ready) { 0120 mediaProxy.useSingleImageDefaults(); 0121 } 0122 0123 pendingImage = null; 0124 } 0125 0126 replaceEnter: Transition { 0127 OpacityAnimator { 0128 id: replaceEnterOpacityAnimator 0129 from: 0 0130 to: 1 0131 // The value is to keep compatible with the old feeling defined by "TransitionAnimationDuration" (default: 1000) 0132 // 1 is HACK for https://bugreports.qt.io/browse/QTBUG-106797 to avoid flickering 0133 duration: view.doesSkipAnimation ? 1 : Math.round(Kirigami.Units.veryLongDuration * 2.5) 0134 } 0135 } 0136 // Keep the old image around till the new one is fully faded in 0137 // If we fade both at the same time you can see the background behind glimpse through 0138 replaceExit: Transition{ 0139 PauseAnimation { 0140 // 500: The exit transition starts first and can be completed earlier than the enter transition 0141 duration: replaceEnterOpacityAnimator.duration + 500 0142 } 0143 } 0144 0145 Wallpaper.MediaProxy { 0146 id: mediaProxy 0147 0148 targetSize: view.sourceSize 0149 0150 onActualSizeChanged: Qt.callLater(loadImageImmediately); 0151 onColorSchemeChanged: loadImageImmediately(); 0152 onSourceFileUpdated: loadImageImmediately() 0153 } 0154 }