/** * SPDX-FileCopyrightText: 2021-2023 Bart De Vries * * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL */ import QtQuick import QtQuick.Controls as Controls import QtQuick.Layouts import QtQuick.Effects import QtQuick.Window import org.kde.kirigami as Kirigami import org.kde.kasts import org.kde.kasts.settings Item { id: root property string imageSource: "no-image" property real imageOpacity: 1 property int absoluteRadius: 0 property real fractionalRadius: 0.0 property string imageTitle: "" property bool isLoading: false property int imageFillMode: Image.PreserveAspectCrop property bool imageResize: true Loader { id: imageLoader anchors.fill: parent visible: false sourceComponent: (imageSource === "no-image" || imageSource === "") ? fallbackImg : (imageSource === "fetching" ? loaderSymbol : realImg ) } MultiEffect { anchors.fill: parent source: imageLoader.item opacity: root.imageOpacity maskEnabled: true maskThresholdMin: 0.5 maskSpreadAtMin: 0.5 maskSource: ShaderEffectSource { width: imageLoader.width height: imageLoader.height sourceItem: Rectangle { anchors.centerIn: parent width: imageLoader.adapt ? imageLoader.width : Math.min(imageLoader.width, imageLoader.height) height: imageLoader.adapt ? imageLoader.height : width radius: (absoluteRadius > 0) ? absoluteRadius : ( (fractionalRadius > 0) ? Math.min(width, height)*fractionalRadius : 0 ) } } } Component { id: realImg Image { anchors.fill: parent source: root.imageSource fillMode: root.imageFillMode asynchronous: true // mipmap = smooth image at smaller sizes than original // needs to be a fixed value; bindings will break the behaviour, // see: https://bugreports-test.qt.io/browse/QTBUG-105277 mipmap: true // still resizing images despite mipmap for non-resizable images // since it gives much better (i.e. non-blurry) results sourceSize.width: root.imageResize ? width * Screen.devicePixelRatio : 0 sourceSize.height: root.imageResize ? height * Screen.devicePixelRatio : 0 } } Component { id: fallbackImg Item { anchors.fill: parent // Add white background color in order to use coloroverlay later on Rectangle { anchors.fill: parent color: "white" } Kirigami.Icon { anchors.fill: parent source: "rss" isMask: true color: "black" } } } Component { id: imageText Item { Rectangle { anchors.fill: header opacity: 0.5 color: "black" } Kirigami.Heading { id: header anchors.bottom: parent.bottom anchors.left: parent.left anchors.right: parent.right padding: 10 text: root.imageTitle level: 3 font.bold: true color: "white" wrapMode: Text.Wrap elide: Text.ElideRight } } } Loader { anchors.fill: parent active: root.imageTitle !== "" && (SettingsManager.alwaysShowFeedTitles ? true : (imageSource === "no-image" || imageSource === "fetching")) sourceComponent: imageText } Component { id: loaderSymbol Item { anchors.fill: parent Rectangle { color: "white" opacity: 0.5 anchors.fill: parent } Controls.BusyIndicator { anchors.centerIn: parent width: parent.width / 2 height: parent.height / 2 } } } Loader { active: isLoading sourceComponent: loaderSymbol anchors.fill: parent } }