Release v0.3.4 #133
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "iccery",
|
"name": "iccery",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.4.0",
|
"version": "0.3.4",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"fetch-argyll": "node scripts/fetch-argyll.mjs",
|
"fetch-argyll": "node scripts/fetch-argyll.mjs",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "iccery"
|
name = "iccery"
|
||||||
version = "0.4.0"
|
version = "0.3.4"
|
||||||
description = "Modern Printer Profiling UI frontend for ArgyllCMS"
|
description = "Modern Printer Profiling UI frontend for ArgyllCMS"
|
||||||
authors = ["Gordon"]
|
authors = ["Gordon"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|||||||
@@ -319,6 +319,7 @@ pub struct PrinttargConfig {
|
|||||||
pub bit_depth: u8, // 8 or 16
|
pub bit_depth: u8, // 8 or 16
|
||||||
#[serde(default = "default_dpi")]
|
#[serde(default = "default_dpi")]
|
||||||
pub dpi: u32, // TIFF resolution, defaults to 300 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 basename: String, // Must match the .ti1 basename from Stage 1
|
||||||
pub cwd: String, // Working directory where the .ti1 file resides
|
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(),
|
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 {
|
if config.bit_depth == 16 {
|
||||||
args.push("-T".to_string());
|
args.push("-T".to_string());
|
||||||
} else {
|
} else {
|
||||||
@@ -850,6 +856,7 @@ mod tests {
|
|||||||
page_size: "A4".to_string(),
|
page_size: "A4".to_string(),
|
||||||
bit_depth: 8,
|
bit_depth: 8,
|
||||||
dpi: 100,
|
dpi: 100,
|
||||||
|
custom_label: None,
|
||||||
basename: "my_profile".to_string(),
|
basename: "my_profile".to_string(),
|
||||||
cwd: "/tmp".to_string(),
|
cwd: "/tmp".to_string(),
|
||||||
};
|
};
|
||||||
@@ -864,6 +871,7 @@ mod tests {
|
|||||||
page_size: "Letter".to_string(),
|
page_size: "Letter".to_string(),
|
||||||
bit_depth: 16,
|
bit_depth: 16,
|
||||||
dpi: 300,
|
dpi: 300,
|
||||||
|
custom_label: None,
|
||||||
basename: "cmyk_profile".to_string(),
|
basename: "cmyk_profile".to_string(),
|
||||||
cwd: "/home/user".to_string(),
|
cwd: "/home/user".to_string(),
|
||||||
};
|
};
|
||||||
@@ -878,6 +886,7 @@ mod tests {
|
|||||||
page_size: "200x400".to_string(),
|
page_size: "200x400".to_string(),
|
||||||
bit_depth: 8,
|
bit_depth: 8,
|
||||||
dpi: 150,
|
dpi: 150,
|
||||||
|
custom_label: None,
|
||||||
basename: "custom_target".to_string(),
|
basename: "custom_target".to_string(),
|
||||||
cwd: "/tmp".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"]);
|
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]
|
#[test]
|
||||||
fn test_build_chartread_args_auto() {
|
fn test_build_chartread_args_auto() {
|
||||||
let config = ChartreadConfig {
|
let config = ChartreadConfig {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://schema.tauri.app/config/2",
|
"$schema": "https://schema.tauri.app/config/2",
|
||||||
"productName": "ICCery",
|
"productName": "ICCery",
|
||||||
"version": "0.4.0",
|
"version": "0.3.4",
|
||||||
"identifier": "com.gronod.iccery",
|
"identifier": "com.gronod.iccery",
|
||||||
"build": {
|
"build": {
|
||||||
"frontendDist": "../src"
|
"frontendDist": "../src"
|
||||||
|
|||||||
@@ -181,6 +181,43 @@
|
|||||||
<label for="tiffDpi">Target Resolution (DPI)</label>
|
<label for="tiffDpi">Target Resolution (DPI)</label>
|
||||||
<input type="number" id="tiffDpi" min="72" max="600" value="300" placeholder="300">
|
<input type="number" id="tiffDpi" min="72" max="600" value="300" placeholder="300">
|
||||||
</div>
|
</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>
|
</div>
|
||||||
|
|
||||||
<button class="primary" id="btnCreateLayout">Create Layout (.ti2 + .tif)</button>
|
<button class="primary" id="btnCreateLayout">Create Layout (.ti2 + .tif)</button>
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ let stage1Cwd = "";
|
|||||||
let currentManifest = null;
|
let currentManifest = null;
|
||||||
let discoveredPrinters = [];
|
let discoveredPrinters = [];
|
||||||
|
|
||||||
|
let updateLabelPreviewFn = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called by targen.js (or app.js) after Stage 1 completes.
|
* Called by targen.js (or app.js) after Stage 1 completes.
|
||||||
* Passes the basename and working directory forward.
|
* Passes the basename and working directory forward.
|
||||||
@@ -17,6 +19,9 @@ export function setStage1Result(basename, cwd) {
|
|||||||
stage1Basename = basename || wizardState.basename;
|
stage1Basename = basename || wizardState.basename;
|
||||||
stage1Cwd = cwd || wizardState.cwd;
|
stage1Cwd = cwd || wizardState.cwd;
|
||||||
wizardState.setTarget(stage1Basename, stage1Cwd);
|
wizardState.setTarget(stage1Basename, stage1Cwd);
|
||||||
|
if (updateLabelPreviewFn) {
|
||||||
|
updateLabelPreviewFn();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function initPrinttarg() {
|
export function initPrinttarg() {
|
||||||
@@ -34,6 +39,93 @@ export function initPrinttarg() {
|
|||||||
const galleryInfo = document.getElementById("galleryInfo");
|
const galleryInfo = document.getElementById("galleryInfo");
|
||||||
const galleryGrid = document.getElementById("galleryGrid");
|
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
|
// Raw Printing UI elements
|
||||||
const rawPrintPanel = document.getElementById("rawPrintPanel");
|
const rawPrintPanel = document.getElementById("rawPrintPanel");
|
||||||
const printerSelect = document.getElementById("printerSelect");
|
const printerSelect = document.getElementById("printerSelect");
|
||||||
@@ -302,11 +394,19 @@ export function initPrinttarg() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const dpi = tiffDpi && tiffDpi.value ? parseInt(tiffDpi.value, 10) || 300 : 300;
|
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 = {
|
const config = {
|
||||||
instrument: instrumentSelect.value,
|
instrument: instrumentSelect.value,
|
||||||
page_size: pageSize,
|
page_size: pageSize,
|
||||||
bit_depth: bitDepth,
|
bit_depth: bitDepth,
|
||||||
dpi: dpi,
|
dpi: dpi,
|
||||||
|
custom_label: customLabel,
|
||||||
basename: stage1Basename,
|
basename: stage1Basename,
|
||||||
cwd: stage1Cwd,
|
cwd: stage1Cwd,
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user