104 lines
2.7 KiB
QML
104 lines
2.7 KiB
QML
import QtQuick
|
|
import QtQuick.Effects
|
|
import Quickshell
|
|
import Quickshell.Widgets
|
|
import qs.Constants
|
|
import qs.Noctalia
|
|
|
|
Rectangle {
|
|
id: root
|
|
|
|
property string imagePath: ""
|
|
property color borderColor: Color.transparent
|
|
property real borderWidth: 0
|
|
property real imageRadius: width * 0.5
|
|
property string fallbackIcon: ""
|
|
property real fallbackIconSize: Style.fontSizeXXL
|
|
property real scaledRadius: imageRadius
|
|
|
|
signal statusChanged(int status)
|
|
|
|
color: Color.transparent
|
|
radius: scaledRadius
|
|
anchors.margins: Style.marginXXS
|
|
|
|
Rectangle {
|
|
color: Color.transparent
|
|
anchors.fill: parent
|
|
|
|
Image {
|
|
id: img
|
|
|
|
anchors.fill: parent
|
|
source: imagePath
|
|
visible: false // Hide since we're using it as shader source
|
|
mipmap: true
|
|
smooth: true
|
|
asynchronous: true
|
|
antialiasing: true
|
|
fillMode: Image.PreserveAspectCrop
|
|
onStatusChanged: root.statusChanged(status)
|
|
}
|
|
|
|
ShaderEffect {
|
|
property var source
|
|
// Use custom property names to avoid conflicts with final properties
|
|
property real itemWidth: root.width
|
|
property real itemHeight: root.height
|
|
property real cornerRadius: root.radius
|
|
property real imageOpacity: root.opacity
|
|
|
|
anchors.fill: parent
|
|
fragmentShader: Qt.resolvedUrl(Quickshell.shellDir + "/Shaders/qsb/rounded_image.frag.qsb")
|
|
// Qt6 specific properties - ensure proper blending
|
|
supportsAtlasTextures: false
|
|
blending: true
|
|
|
|
// Make sure the background is transparent
|
|
Rectangle {
|
|
id: background
|
|
|
|
anchors.fill: parent
|
|
color: Color.transparent
|
|
z: -1
|
|
}
|
|
|
|
source: ShaderEffectSource {
|
|
sourceItem: img
|
|
hideSource: true
|
|
live: true
|
|
recursive: false
|
|
format: ShaderEffectSource.RGBA
|
|
}
|
|
|
|
}
|
|
|
|
// Fallback icon
|
|
Loader {
|
|
active: fallbackIcon !== undefined && fallbackIcon !== "" && (imagePath === undefined || imagePath === "")
|
|
anchors.centerIn: parent
|
|
|
|
sourceComponent: NIcon {
|
|
anchors.centerIn: parent
|
|
icon: fallbackIcon
|
|
pointSize: fallbackIconSize
|
|
z: 0
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Border
|
|
Rectangle {
|
|
anchors.fill: parent
|
|
radius: parent.radius
|
|
color: Color.transparent
|
|
border.color: parent.borderColor
|
|
border.width: parent.borderWidth
|
|
antialiasing: true
|
|
z: 10
|
|
}
|
|
|
|
}
|