101 lines
2.9 KiB
QML
101 lines
2.9 KiB
QML
import "root:/modules/common"
|
|
import "root:/modules/common/widgets"
|
|
import "root:/services"
|
|
import "root:/modules/common/functions/string_utils.js" as StringUtils
|
|
import "root:/modules/common/functions/file_utils.js" as FileUtils
|
|
import Qt5Compat.GraphicalEffects
|
|
import Qt.labs.platform
|
|
import QtQuick
|
|
import QtQuick.Controls
|
|
import QtQuick.Layouts
|
|
import Quickshell.Io
|
|
import Quickshell.Widgets
|
|
import Quickshell.Hyprland
|
|
|
|
Rectangle {
|
|
id: root
|
|
property string entry
|
|
property real maxWidth
|
|
property real maxHeight
|
|
|
|
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 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: {
|
|
Hyprland.dispatch(`exec bash -c "[ -f '${imageDecodeFilePath}' ] && rm -f '${imageDecodeFilePath}'"`)
|
|
}
|
|
|
|
Image {
|
|
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
|
|
|
|
layer.enabled: true
|
|
layer.effect: OpacityMask {
|
|
maskSource: Rectangle {
|
|
width: image.width
|
|
height: image.height
|
|
radius: root.radius
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|