mirror of
https://github.com/end-4/dots-hyprland.git
synced 2026-06-07 07:49:28 -05:00
132 lines
4.0 KiB
QML
132 lines
4.0 KiB
QML
import qs.modules.common
|
|
import qs.modules.common.widgets
|
|
import qs.services
|
|
import qs.modules.common.functions
|
|
import Qt5Compat.GraphicalEffects
|
|
import QtQuick
|
|
import Quickshell
|
|
import Quickshell.Io
|
|
|
|
Rectangle {
|
|
id: root
|
|
property string entry
|
|
property real maxWidth
|
|
property real maxHeight
|
|
property bool blur: false
|
|
property string blurText: "Image hidden"
|
|
|
|
property string imageDecodePath: Directories.cliphistDecode
|
|
property string imageDecodeFileName: `${entryNumber}`
|
|
property string imageDecodeFilePath: `${imageDecodePath}/${imageDecodeFileName}`
|
|
property string source
|
|
|
|
property int entryNumber: {
|
|
if (!root.entry)
|
|
return 0;
|
|
const match = root.entry.match(/^(\d+)\t/);
|
|
return match ? parseInt(match[1]) : 0;
|
|
}
|
|
property int imageWidth: {
|
|
if (!root.entry)
|
|
return 0;
|
|
const match = root.entry.match(/(\d+)x(\d+)/);
|
|
return match ? parseInt(match[1]) : 0;
|
|
}
|
|
property int imageHeight: {
|
|
if (!root.entry)
|
|
return 0;
|
|
const match = root.entry.match(/(\d+)x(\d+)/);
|
|
return match ? parseInt(match[2]) : 0;
|
|
}
|
|
property real scale: {
|
|
return Math.min(root.maxWidth / imageWidth, root.maxHeight / imageHeight, 1);
|
|
}
|
|
|
|
color: Appearance.colors.colLayer1
|
|
radius: Appearance.rounding.small
|
|
implicitHeight: imageHeight * scale
|
|
implicitWidth: imageWidth * scale
|
|
|
|
Component.onCompleted: {
|
|
decodeImageProcess.running = true;
|
|
}
|
|
|
|
Process {
|
|
id: decodeImageProcess
|
|
command: ["bash", "-c", `[ -f ${imageDecodeFilePath} ] || echo '${StringUtils.shellSingleQuoteEscape(root.entry)}' | ${Cliphist.cliphistBinary} decode > '${imageDecodeFilePath}'`]
|
|
onExited: (exitCode, exitStatus) => {
|
|
if (exitCode === 0) {
|
|
root.source = imageDecodeFilePath;
|
|
} else {
|
|
console.error("[CliphistImage] Failed to decode image for entry:", root.entry);
|
|
root.source = "";
|
|
}
|
|
}
|
|
}
|
|
|
|
Component.onDestruction: {
|
|
Quickshell.execDetached(["bash", "-c", `[ -f '${imageDecodeFilePath}' ] && rm -f '${imageDecodeFilePath}'`]);
|
|
}
|
|
|
|
layer.enabled: true
|
|
layer.effect: OpacityMask {
|
|
maskSource: Rectangle {
|
|
width: image.width
|
|
height: image.height
|
|
radius: root.radius
|
|
}
|
|
}
|
|
|
|
StyledImage {
|
|
id: image
|
|
anchors.fill: parent
|
|
|
|
source: Qt.resolvedUrl(root.source)
|
|
fillMode: Image.PreserveAspectFit
|
|
antialiasing: true
|
|
asynchronous: true
|
|
|
|
width: root.imageWidth * root.scale
|
|
height: root.imageHeight * root.scale
|
|
sourceSize.width: width
|
|
sourceSize.height: height
|
|
}
|
|
|
|
Loader {
|
|
id: blurLoader
|
|
active: root.blur
|
|
anchors.fill: image
|
|
sourceComponent: GaussianBlur {
|
|
source: image
|
|
radius: 35
|
|
samples: radius * 2 + 1
|
|
|
|
Rectangle {
|
|
anchors.fill: parent
|
|
color: ColorUtils.transparentize(Appearance.colors.colLayer0, 0.5)
|
|
|
|
Column {
|
|
anchors {
|
|
left: parent.left
|
|
right: parent.right
|
|
verticalCenter: parent.verticalCenter
|
|
}
|
|
MaterialSymbol {
|
|
visible: width <= image.width
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
text: "visibility_off"
|
|
font.pixelSize: 28
|
|
}
|
|
StyledText {
|
|
visible: width <= image.width
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
text: root.blurText
|
|
color: Appearance.colors.colOnSurface
|
|
font.pixelSize: Appearance.font.pixelSize.smallie
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|