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 }