Introducing fragment shaders for image rounding.

This commit is contained in:
LemmyCook 2025-08-22 13:59:49 -04:00
parent 8f951946ea
commit b6379da96c
12 changed files with 193 additions and 31 deletions

73
Widgets/NImageCircled.qml Normal file
View file

@ -0,0 +1,73 @@
import QtQuick
import QtQuick.Effects
import Quickshell
import Quickshell.Widgets
import qs.Commons
import qs.Services
Rectangle {
id: root
property string imagePath: ""
property string fallbackIcon: ""
property color borderColor: Color.transparent
property real borderWidth: 0
color: Color.transparent
radius: parent.width * 0.5
anchors.margins: Style.marginXXS * scaling
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
}
ShaderEffect {
anchors.fill: parent
property var source: ShaderEffectSource {
sourceItem: img
hideSource: true
live: true
recursive: false
format: ShaderEffectSource.RGBA
}
property real imageOpacity: root.opacity
fragmentShader: "file:Shaders/qsb/circled_image.frag.qsb"
supportsAtlasTextures: false
blending: true
}
// Fallback icon
NIcon {
anchors.centerIn: parent
text: fallbackIcon
font.pointSize: Style.fontSizeXXL * scaling
visible: fallbackIcon !== undefined && fallbackIcon !== "" && (imagePath === undefined || imagePath === "")
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
}
}

View file

@ -23,13 +23,12 @@ Rectangle {
Rectangle {
color: Color.transparent
anchors.fill: parent
anchors.margins: borderWidth
Image {
id: img
anchors.fill: parent
source: imagePath
visible: false
visible: false // Hide since we're using it as shader source
mipmap: true
smooth: true
asynchronous: true
@ -37,24 +36,33 @@ Rectangle {
fillMode: Image.PreserveAspectCrop
}
MultiEffect {
ShaderEffect {
anchors.fill: parent
source: img
maskEnabled: true
maskSource: mask
maskSpreadAtMax: 0.75
visible: imagePath !== ""
}
Item {
id: mask
anchors.fill: parent
layer.enabled: true
visible: false
property var source: ShaderEffectSource {
sourceItem: img
hideSource: true
live: true
recursive: false
format: ShaderEffectSource.RGBA
}
// 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
fragmentShader: "file: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
radius: scaledRadius
antialiasing: true
color: "transparent"
z: -1
}
}