Release v0.3.4 #133
+1
-1
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "iccery",
|
||||
"private": true,
|
||||
"version": "0.4.0",
|
||||
"version": "0.3.4",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"fetch-argyll": "node scripts/fetch-argyll.mjs",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "iccery"
|
||||
version = "0.4.0"
|
||||
version = "0.3.4"
|
||||
description = "Modern Printer Profiling UI frontend for ArgyllCMS"
|
||||
authors = ["Gordon"]
|
||||
edition = "2021"
|
||||
|
||||
@@ -319,6 +319,7 @@ pub struct PrinttargConfig {
|
||||
pub bit_depth: u8, // 8 or 16
|
||||
#[serde(default = "default_dpi")]
|
||||
pub dpi: u32, // TIFF resolution, defaults to 300 DPI
|
||||
pub custom_label: Option<String>, // Custom chart label / description metadata string (-d)
|
||||
pub basename: String, // Must match the .ti1 basename from Stage 1
|
||||
pub cwd: String, // Working directory where the .ti1 file resides
|
||||
}
|
||||
@@ -370,6 +371,11 @@ pub fn build_printtarg_args(config: &PrinttargConfig) -> Vec<String> {
|
||||
config.page_size.clone(),
|
||||
];
|
||||
|
||||
if let Some(ref label) = config.custom_label {
|
||||
args.push("-d".to_string());
|
||||
args.push(label.clone());
|
||||
}
|
||||
|
||||
if config.bit_depth == 16 {
|
||||
args.push("-T".to_string());
|
||||
} else {
|
||||
@@ -850,6 +856,7 @@ mod tests {
|
||||
page_size: "A4".to_string(),
|
||||
bit_depth: 8,
|
||||
dpi: 100,
|
||||
custom_label: None,
|
||||
basename: "my_profile".to_string(),
|
||||
cwd: "/tmp".to_string(),
|
||||
};
|
||||
@@ -864,6 +871,7 @@ mod tests {
|
||||
page_size: "Letter".to_string(),
|
||||
bit_depth: 16,
|
||||
dpi: 300,
|
||||
custom_label: None,
|
||||
basename: "cmyk_profile".to_string(),
|
||||
cwd: "/home/user".to_string(),
|
||||
};
|
||||
@@ -878,6 +886,7 @@ mod tests {
|
||||
page_size: "200x400".to_string(),
|
||||
bit_depth: 8,
|
||||
dpi: 150,
|
||||
custom_label: None,
|
||||
basename: "custom_target".to_string(),
|
||||
cwd: "/tmp".to_string(),
|
||||
};
|
||||
@@ -885,6 +894,36 @@ mod tests {
|
||||
assert_eq!(args, vec!["-v", "-u", "-i", "SS", "-p", "200x400", "-t", "150", "custom_target"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_build_printtarg_args_with_custom_label() {
|
||||
let config = PrinttargConfig {
|
||||
instrument: "i1".to_string(),
|
||||
page_size: "A4".to_string(),
|
||||
bit_depth: 8,
|
||||
dpi: 300,
|
||||
custom_label: Some("ICCery - Pro900 - Luster - 29/08/2026 12:00".to_string()),
|
||||
basename: "my_profile".to_string(),
|
||||
cwd: "/tmp".to_string(),
|
||||
};
|
||||
let args = build_printtarg_args(&config);
|
||||
assert_eq!(
|
||||
args,
|
||||
vec![
|
||||
"-v",
|
||||
"-u",
|
||||
"-i",
|
||||
"i1",
|
||||
"-p",
|
||||
"A4",
|
||||
"-d",
|
||||
"ICCery - Pro900 - Luster - 29/08/2026 12:00",
|
||||
"-t",
|
||||
"300",
|
||||
"my_profile"
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_build_chartread_args_auto() {
|
||||
let config = ChartreadConfig {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "https://schema.tauri.app/config/2",
|
||||
"productName": "ICCery",
|
||||
"version": "0.4.0",
|
||||
"version": "0.3.4",
|
||||
"identifier": "com.gronod.iccery",
|
||||
"build": {
|
||||
"frontendDist": "../src"
|
||||
|
||||
@@ -181,6 +181,43 @@
|
||||
<label for="tiffDpi">Target Resolution (DPI)</label>
|
||||
<input type="number" id="tiffDpi" min="72" max="600" value="300" placeholder="300">
|
||||
</div>
|
||||
|
||||
<!-- Target Label & Metadata (printtarg -d) -->
|
||||
<div class="form-group" style="margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--border-color, #333);">
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 6px;">
|
||||
<label style="margin: 0; font-weight: 600;">Target Label & Metadata (Optional)</label>
|
||||
<button type="button" class="secondary" id="btnToggleLabelEdit" style="font-size: 0.75rem; padding: 2px 8px;">✏️ Edit Label</button>
|
||||
</div>
|
||||
<p class="sub-label" style="margin-bottom: 10px;">Printed below test patches to identify hardware, ink, and media used for this profiling run.</p>
|
||||
|
||||
<div class="input-row" style="margin-bottom: 10px;">
|
||||
<div>
|
||||
<label for="targetMetadataPrinter" class="sub-label">Printer Model</label>
|
||||
<input type="text" id="targetMetadataPrinter" placeholder="e.g. Epson SC-P900">
|
||||
</div>
|
||||
<div>
|
||||
<label for="targetMetadataInkSet" class="sub-label">Ink Set</label>
|
||||
<input type="text" id="targetMetadataInkSet" placeholder="e.g. UltraChrome PRO10">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="input-row" style="margin-bottom: 10px;">
|
||||
<div>
|
||||
<label for="targetMetadataDriverPaper" class="sub-label">Driver Paper Setting</label>
|
||||
<input type="text" id="targetMetadataDriverPaper" placeholder="e.g. Premium Luster Photo Paper">
|
||||
</div>
|
||||
<div>
|
||||
<label for="targetMetadataActualPaper" class="sub-label">Actual Paper Substrate</label>
|
||||
<input type="text" id="targetMetadataActualPaper" placeholder="e.g. Ilford Galerie Smooth Pearl 310">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Live Assembled Label Preview / Manual Override -->
|
||||
<div>
|
||||
<label for="targetLabelPreview" class="sub-label">Printed Page Label Preview</label>
|
||||
<input type="text" id="targetLabelPreview" placeholder="ICCery - Target Label Preview" readonly style="font-family: monospace; font-size: 0.85rem;">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button class="primary" id="btnCreateLayout">Create Layout (.ti2 + .tif)</button>
|
||||
|
||||
@@ -9,6 +9,8 @@ let stage1Cwd = "";
|
||||
let currentManifest = null;
|
||||
let discoveredPrinters = [];
|
||||
|
||||
let updateLabelPreviewFn = null;
|
||||
|
||||
/**
|
||||
* Called by targen.js (or app.js) after Stage 1 completes.
|
||||
* Passes the basename and working directory forward.
|
||||
@@ -17,6 +19,9 @@ export function setStage1Result(basename, cwd) {
|
||||
stage1Basename = basename || wizardState.basename;
|
||||
stage1Cwd = cwd || wizardState.cwd;
|
||||
wizardState.setTarget(stage1Basename, stage1Cwd);
|
||||
if (updateLabelPreviewFn) {
|
||||
updateLabelPreviewFn();
|
||||
}
|
||||
}
|
||||
|
||||
export function initPrinttarg() {
|
||||
@@ -34,6 +39,93 @@ export function initPrinttarg() {
|
||||
const galleryInfo = document.getElementById("galleryInfo");
|
||||
const galleryGrid = document.getElementById("galleryGrid");
|
||||
|
||||
// Target Label & Metadata elements (printtarg -d)
|
||||
const targetMetadataPrinter = document.getElementById("targetMetadataPrinter");
|
||||
const targetMetadataInkSet = document.getElementById("targetMetadataInkSet");
|
||||
const targetMetadataDriverPaper = document.getElementById("targetMetadataDriverPaper");
|
||||
const targetMetadataActualPaper = document.getElementById("targetMetadataActualPaper");
|
||||
const targetLabelPreview = document.getElementById("targetLabelPreview");
|
||||
const btnToggleLabelEdit = document.getElementById("btnToggleLabelEdit");
|
||||
|
||||
let isManualLabelOverride = false;
|
||||
|
||||
/**
|
||||
* Format current local date & time into standard DD/MM/YYYY HH:MM format.
|
||||
*/
|
||||
function formatTimestamp(d = new Date()) {
|
||||
const pad = (n) => String(n).padStart(2, "0");
|
||||
const day = pad(d.getDate());
|
||||
const month = pad(d.getMonth() + 1);
|
||||
const year = d.getFullYear();
|
||||
const hours = pad(d.getHours());
|
||||
const mins = pad(d.getMinutes());
|
||||
return `${day}/${month}/${year} ${hours}:${mins}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assemble dynamic label string from Stage 1 run name and metadata inputs.
|
||||
*/
|
||||
function assembleTargetLabel() {
|
||||
const parts = ["ICCery"];
|
||||
const runName = stage1Basename || wizardState.basename || "";
|
||||
if (runName.trim()) {
|
||||
parts.push(runName.trim());
|
||||
}
|
||||
|
||||
const printer = targetMetadataPrinter ? targetMetadataPrinter.value.trim() : "";
|
||||
if (printer) parts.push(printer);
|
||||
|
||||
const inkSet = targetMetadataInkSet ? targetMetadataInkSet.value.trim() : "";
|
||||
if (inkSet) parts.push(inkSet);
|
||||
|
||||
const driverPaper = targetMetadataDriverPaper ? targetMetadataDriverPaper.value.trim() : "";
|
||||
if (driverPaper) parts.push(driverPaper);
|
||||
|
||||
const actualPaper = targetMetadataActualPaper ? targetMetadataActualPaper.value.trim() : "";
|
||||
if (actualPaper) parts.push(actualPaper);
|
||||
|
||||
parts.push(formatTimestamp());
|
||||
return parts.join(" - ");
|
||||
}
|
||||
|
||||
function updateLabelPreview() {
|
||||
if (!targetLabelPreview) return;
|
||||
if (!isManualLabelOverride) {
|
||||
targetLabelPreview.value = assembleTargetLabel();
|
||||
}
|
||||
}
|
||||
updateLabelPreviewFn = updateLabelPreview;
|
||||
updateLabelPreview();
|
||||
|
||||
// Bind input listeners for dynamic label assembly
|
||||
[targetMetadataPrinter, targetMetadataInkSet, targetMetadataDriverPaper, targetMetadataActualPaper].forEach(input => {
|
||||
if (input) {
|
||||
input.addEventListener("input", () => {
|
||||
updateLabelPreview();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Toggle between auto-assembled preview and manual edit
|
||||
if (btnToggleLabelEdit && targetLabelPreview) {
|
||||
btnToggleLabelEdit.addEventListener("click", () => {
|
||||
isManualLabelOverride = !isManualLabelOverride;
|
||||
if (isManualLabelOverride) {
|
||||
targetLabelPreview.removeAttribute("readonly");
|
||||
targetLabelPreview.style.background = "var(--bg-color)";
|
||||
targetLabelPreview.style.borderColor = "var(--accent-color, #3b82f6)";
|
||||
btnToggleLabelEdit.textContent = "↺ Reset Auto";
|
||||
targetLabelPreview.focus();
|
||||
} else {
|
||||
targetLabelPreview.setAttribute("readonly", true);
|
||||
targetLabelPreview.style.background = "var(--bg-color)";
|
||||
targetLabelPreview.style.borderColor = "var(--border-color, #333)";
|
||||
btnToggleLabelEdit.textContent = "✏️ Edit Label";
|
||||
updateLabelPreview();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Raw Printing UI elements
|
||||
const rawPrintPanel = document.getElementById("rawPrintPanel");
|
||||
const printerSelect = document.getElementById("printerSelect");
|
||||
@@ -302,11 +394,19 @@ export function initPrinttarg() {
|
||||
});
|
||||
|
||||
const dpi = tiffDpi && tiffDpi.value ? parseInt(tiffDpi.value, 10) || 300 : 300;
|
||||
|
||||
// Obtain custom label string
|
||||
let customLabel = null;
|
||||
if (targetLabelPreview && targetLabelPreview.value.trim()) {
|
||||
customLabel = targetLabelPreview.value.trim();
|
||||
}
|
||||
|
||||
const config = {
|
||||
instrument: instrumentSelect.value,
|
||||
page_size: pageSize,
|
||||
bit_depth: bitDepth,
|
||||
dpi: dpi,
|
||||
custom_label: customLabel,
|
||||
basename: stage1Basename,
|
||||
cwd: stage1Cwd,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user