feat: Add image preview logic

This commit is contained in:
loner
2025-11-19 16:07:07 +08:00
parent ca89a0dc35
commit 79f79e0cff
4 changed files with 72 additions and 41 deletions
+8 -7
View File
@@ -13,12 +13,15 @@ import qs.Widgets
SmartPanel {
id: root
readonly property real clipListRatio: 0.6 // 60% for the list
readonly property real clipPreviewRatio: 0.4 // 40% for the preview
readonly property bool previewActive: activePlugin && activePlugin.name === I18n.tr("plugins.clipboard") && results.length > 0
// Panel configuration
preferredWidth: Math.round(700 * Style.uiScaleRatio) // Base width when both are shown, scaled appropriately
// Panel configuration - use proportional widths
readonly property real clipListRatio: 0.6 // 60% for the list
readonly property real clipPreviewRatio: 0.4 // 40% for the preview
readonly property int totalBaseWidth: Math.round(600 * Style.uiScaleRatio) // Base width when no preview
readonly property int totalExpandedWidth: Math.round(900 * Style.uiScaleRatio) // Width when preview active
preferredWidth: previewActive ? totalExpandedWidth : totalBaseWidth
preferredHeight: Math.round(600 * Style.uiScaleRatio)
preferredWidthRatio: 0.3
preferredHeightRatio: 0.5
@@ -348,10 +351,9 @@ SmartPanel {
ColumnLayout {
id: leftPane
Layout.fillHeight: true
Layout.fillWidth: root.previewActive // Fill width proportionally when preview is active
Layout.preferredWidth: root.previewActive ?
Math.round(root.clipListRatio * (root.preferredWidth - (Style.marginL * 2))) :
(root.preferredWidth - (Style.marginL * 2))
(root.preferredWidth - (Style.marginL * 2)) // Use full width when preview not active
anchors.margins: Style.marginL
spacing: Style.marginM
@@ -659,7 +661,6 @@ SmartPanel {
// --- Right Pane (Preview) ---
Item {
Layout.fillHeight: true
Layout.fillWidth: root.previewActive // Fill width proportionally when preview is active
Layout.preferredWidth: root.previewActive ?
Math.round(root.clipPreviewRatio * (root.preferredWidth - (Style.marginL * 2))) : 0
visible: root.previewActive
@@ -204,12 +204,9 @@ Item {
return results;
}
// Helper: Format image clipboard entry
function formatImageEntry(item) {
const meta = parseImageMeta(item.preview);
// The launcher's delegate will now be responsible for fetching the image data.
// This function's role is to provide the necessary metadata for that request.
return {
"name": meta ? `Image ${meta.w}×${meta.h}` : "Image",
"description": meta ? `${meta.fmt} ${meta.size}` : item.mime || "Image data",
@@ -223,18 +220,15 @@ Item {
};
}
// Helper: Format text clipboard entry with preview
function formatTextEntry(item) {
const preview = (item.preview || "").trim();
const lines = preview.split('\n').filter(l => l.trim());
// Use first line as title, limit length
let title = lines[0] || "Empty text";
if (title.length > 60) {
title = title.substring(0, 57) + "...";
}
// Use second line or character count as description
let description = "";
if (lines.length > 1) {
description = lines[1];
@@ -257,7 +251,6 @@ Item {
};
}
// Helper: Parse image metadata from preview string
function parseImageMeta(preview) {
const re = /\[\[\s*binary data\s+([\d\.]+\s*(?:KiB|MiB|GiB|B))\s+(\w+)\s+(\d+)x(\d+)\s*\]\]/i;
const match = (preview || "").match(re);
@@ -274,8 +267,6 @@ Item {
};
}
// Public method to get image data for a clipboard item
// This can be called by the launcher when rendering
function getImageForItem(clipboardId) {
return ClipboardService.getImageData ? ClipboardService.getImageData(clipboardId) : null;
}