From 25e832b404ba7ee78ce509565f30cd14d3cbbc99 Mon Sep 17 00:00:00 2001 From: Atmik Shetty Date: Tue, 13 Oct 2026 16:11:47 +0530 Subject: [PATCH] KEYC-COMPARE: = and - make the grid thumbnails larger and smaller MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit View ▸ Increase / Decrease Grid Thumbnail Size (view.thumbSizeUp / view.thumbSizeDown) step the bottom-bar slider by 30 pt within its 90–480 range in Photo Grid, Square Grid and People, as Lightroom Classic's Library Grid keys do; + also enlarges. Detail, Compare, Survey and Reference ignore the keys, text fields keep them, and ⌘= / ⌘− still zoom the photo. The slider's range is now shared constants. --- crates/ui-egui/src/menubar.rs | 2 + crates/ui-egui/src/menus.rs | 18 ++++ crates/ui-egui/src/panels/bottombar.rs | 5 +- crates/ui-egui/src/shortcuts.rs | 3 + crates/ui-egui/src/state.rs | 8 +- crates/ui-egui/src/tests_zoom_keys.rs | 139 ++++++++++++++++++++++++- docs/library-shortcuts.md | 12 ++- docs/parity-checklist.md | 11 +- docs/ui-parity.md | 5 +- 9 files changed, 192 insertions(+), 11 deletions(-) diff --git a/crates/ui-egui/src/menubar.rs b/crates/ui-egui/src/menubar.rs index 04eea2439..6dd974105 100644 --- a/crates/ui-egui/src/menubar.rs +++ b/crates/ui-egui/src/menubar.rs @@ -123,6 +123,8 @@ const LAYOUT: &[(&str, &[&str])] = &[ "view.photoGrid", "view.squareGrid", "@Grid Info", + "view.thumbSizeUp", + "view.thumbSizeDown", "view.detail", "view.compare", "view.survey", diff --git a/crates/ui-egui/src/menus.rs b/crates/ui-egui/src/menus.rs index 141d6d782..b50e2d099 100644 --- a/crates/ui-egui/src/menus.rs +++ b/crates/ui-egui/src/menus.rs @@ -86,6 +86,9 @@ pub const UI_COMMANDS: &[UiCommand] = &[ ("view.navigate", "Set Image Zoom and Pan", None, ""), ("view.zoomIn", "Zoom In", Some("Cmd+="), "View"), ("view.zoomOut", "Zoom Out", Some("Cmd+-"), "View"), + // Library grids only (Photo Grid, Square Grid, People): the bottom-bar slider's step by key + ("view.thumbSizeUp", "Increase Grid Thumbnail Size", Some("="), "View"), + ("view.thumbSizeDown", "Decrease Grid Thumbnail Size", Some("-"), "View"), ("view.clipping", "Show Clipping", Some("J"), "View"), ("view.visualizeHdr", "Visualize HDR", None, "View"), // in grids S expands/collapses stacks (the engine command it shadows) @@ -737,6 +740,15 @@ pub fn run_ui_command(app: &mut LightcraftApp, id: &str, p: &Value) -> Option { + // the bottom-bar slider's range, one `THUMB_SIZE_STEP` per call; {} → {size} + if !thumb_size_view(app) { + return Some(Err(format!("{id}: only in Photo Grid, Square Grid or People"))); + } + let step = if id == "view.thumbSizeUp" { crate::state::THUMB_SIZE_STEP } else { -crate::state::THUMB_SIZE_STEP }; + app.ui.thumb_size = (app.ui.thumb_size + step).clamp(crate::state::THUMB_SIZE_MIN, crate::state::THUMB_SIZE_MAX); + Ok(json!({"size": app.ui.thumb_size})) + } "view.navigate" => { // {zoom?: "fit"|"fill"|{percent: number}, pan?: [x, y]} (normalized image centre). // Validate the complete request before changing either part of the viewport. @@ -1845,8 +1857,14 @@ pub fn run_ui_command(app: &mut LightcraftApp, id: &str, p: &Value) -> Option bool { + matches!(app.ui.view, ViewMode::PhotoGrid | ViewMode::SquareGrid | ViewMode::People) +} + pub fn ui_enabled(app: &LightcraftApp, id: &str) -> bool { match id { + "view.thumbSizeUp" | "view.thumbSizeDown" => thumb_size_view(app), "dialog.contactSheet" | "app.contactSheet" => !cfg!(target_arch = "wasm32") && app.session.active().is_some() && app.export.is_none(), s if s.starts_with("panel.") || s.starts_with("tool.") || s.starts_with("section.") => app.session.active().is_some() || s == "panel.close", "app.export" | "dialog.export" | "dialog.createPreset" | "dialog.rename" | "dialog.captureTime" | "dialog.copySettings" => { diff --git a/crates/ui-egui/src/panels/bottombar.rs b/crates/ui-egui/src/panels/bottombar.rs index 874df26cc..1079f16df 100644 --- a/crates/ui-egui/src/panels/bottombar.rs +++ b/crates/ui-egui/src/panels/bottombar.rs @@ -239,13 +239,14 @@ fn right_side(app: &mut LightcraftApp, ui: &mut egui::Ui, full: Rect, compact_zo let p = child.painter(); let y = r.center().y; p.line_segment([pos2(r.left(), y), pos2(r.right(), y)], egui::Stroke::new(2.0, t.track)); - let f = (app.ui.thumb_size - 90.0) / (480.0 - 90.0); + let (min, max) = (crate::state::THUMB_SIZE_MIN, crate::state::THUMB_SIZE_MAX); + let f = (app.ui.thumb_size - min) / (max - min); let x = r.left() + f * r.width(); p.rect_filled(Rect::from_center_size(pos2(x, y), vec2(3.0, 14.0)), 1.0, t.thumb_hover); if let Some(pp) = resp.interact_pointer_pos() && (resp.dragged() || resp.clicked()) { - app.ui.thumb_size = 90.0 + ((pp.x - r.left()) / r.width()).clamp(0.0, 1.0) * (480.0 - 90.0); + app.ui.thumb_size = min + ((pp.x - r.left()) / r.width()).clamp(0.0, 1.0) * (max - min); } } if child.min_rect().width() > 0.0 { child.min_rect().left() } else { full.right() } diff --git a/crates/ui-egui/src/shortcuts.rs b/crates/ui-egui/src/shortcuts.rs index 1a21ab2fc..d07b75d9d 100644 --- a/crates/ui-egui/src/shortcuts.rs +++ b/crates/ui-egui/src/shortcuts.rs @@ -203,6 +203,9 @@ pub const ALIASES: &[(&str, &str, &str)] = &[ ("F6", "view.filmstrip", "{}"), ("F7", "view.leftPanel", "{}"), ("Shift+M", "version.create", "{}"), + // grid thumbnail size: Classic's key is `=`; `+` (keypad, or Shift+= reported as Plus) agrees + ("Plus", "view.thumbSizeUp", "{}"), + ("Shift+Plus", "view.thumbSizeUp", "{}"), ("Shift+X", "photo.flag", r#"{"flag": "reject", "advance": true}"#), ("Shift+Z", "photo.flag", r#"{"flag": "pick", "advance": true}"#), ("Shift+U", "photo.flag", r#"{"flag": "none", "advance": true}"#), diff --git a/crates/ui-egui/src/state.rs b/crates/ui-egui/src/state.rs index 6c4dd3f6a..a38d5f5e7 100644 --- a/crates/ui-egui/src/state.rs +++ b/crates/ui-egui/src/state.rs @@ -449,6 +449,12 @@ impl AppSettings { /// Click-zoom ratios offered (percent): 1:1, 2:1, 3:1, 4:1, 8:1. pub const CLICK_ZOOMS: [u32; 5] = [100, 200, 300, 400, 800]; +/// Grid thumbnail size (points): the bottom-bar slider's range, and the `=` / `-` keys' step +/// (`view.thumbSizeUp` / `view.thumbSizeDown`), about a thirteenth of the range. +pub const THUMB_SIZE_MIN: f32 = 90.0; +pub const THUMB_SIZE_MAX: f32 = 480.0; +pub const THUMB_SIZE_STEP: f32 = 30.0; + /// Width limits of a side panel the user resizes (points). #[derive(Clone, Copy, Debug, PartialEq)] pub struct PanelWidth { @@ -1193,7 +1199,7 @@ impl UiState { } /// Clamp values restored from disk. pub fn sanitized(mut self) -> Self { - self.thumb_size = self.thumb_size.clamp(90.0, 480.0); + self.thumb_size = self.thumb_size.clamp(THUMB_SIZE_MIN, THUMB_SIZE_MAX); self.left_width = LEFT_WIDTH.clamp(self.left_width); self.right_width = RIGHT_WIDTH.clamp(self.right_width); self.brush_size = self.brush_size.clamp(0.002, 0.5); diff --git a/crates/ui-egui/src/tests_zoom_keys.rs b/crates/ui-egui/src/tests_zoom_keys.rs index 3c1111217..e814230e2 100644 --- a/crates/ui-egui/src/tests_zoom_keys.rs +++ b/crates/ui-egui/src/tests_zoom_keys.rs @@ -1,7 +1,8 @@ //! Headless tests of the View ▸ Zoom shortcuts and modifier-wheel zoom: Cmd+= / Cmd+- / Cmd+0 //! (Ctrl on Windows and Linux) zoom the photo and never egui's interface scale, which would //! otherwise take the same keys at the end of the frame; Ctrl+wheel over the photo in the Edit -//! view zooms it. +//! view zooms it. Also the grid thumbnail-size keys `=` / `-` (Classic's Library Grid keys), which +//! share the physical keys with Cmd+= / Cmd+- but act on the grids only. use std::time::Duration; @@ -85,3 +86,139 @@ fn ctrl_wheel_over_the_photo_zooms_it_in_the_edit_view() { } assert!((h.app.image_rect.unwrap().width() - zoomed.width()).abs() < 0.01, "a plain wheel changed the zoom"); } + +fn grid_view(view: crate::state::ViewMode) -> Headless { + let services = Services { png: None, ..Default::default() }; + let mut app = LightcraftApp::new(lightcraft_engine::Session::with_demo(), services); + app.ui.settings.gpu = false; + app.ui.view = view; + let mut h = Headless::new(app, [1400.0, 900.0], 1.0); + h.step(); + h.step(); + h +} + +fn press(h: &mut Headless, k: &str, shift: bool, cmd: bool) { + let r = h.request("ui.key", json!({"key": k, "shift": shift, "cmd": cmd}), T); + assert_eq!(r["ok"], true, "{r}"); + h.step(); + h.step(); +} + +#[test] +fn equals_and_minus_step_the_grid_thumbnail_size_and_clamp() { + use crate::state::{THUMB_SIZE_MAX, THUMB_SIZE_MIN, THUMB_SIZE_STEP, ViewMode}; + for view in [ViewMode::PhotoGrid, ViewMode::SquareGrid, ViewMode::People] { + let mut h = grid_view(view); + h.app.ui.thumb_size = 220.0; + press(&mut h, "=", false, false); + assert_eq!(h.app.ui.thumb_size, 220.0 + THUMB_SIZE_STEP, "{view:?}: ="); + press(&mut h, "-", false, false); + press(&mut h, "-", false, false); + assert_eq!(h.app.ui.thumb_size, 220.0 - THUMB_SIZE_STEP, "{view:?}: - -"); + // `+` (Shift+= on a US layout, or the keypad) is the same key for the same job + press(&mut h, "Plus", true, false); + press(&mut h, "Plus", false, false); + assert_eq!(h.app.ui.thumb_size, 220.0 + THUMB_SIZE_STEP, "{view:?}: +"); + // clamped at both ends of the bottom-bar slider's range, however many presses + h.app.ui.thumb_size = THUMB_SIZE_MAX - 5.0; + for _ in 0..3 { + press(&mut h, "=", false, false); + assert!(h.app.ui.thumb_size <= THUMB_SIZE_MAX); + } + assert_eq!(h.app.ui.thumb_size, THUMB_SIZE_MAX, "{view:?}"); + h.app.ui.thumb_size = THUMB_SIZE_MIN + 5.0; + for _ in 0..3 { + press(&mut h, "-", false, false); + assert!(h.app.ui.thumb_size >= THUMB_SIZE_MIN); + } + assert_eq!(h.app.ui.thumb_size, THUMB_SIZE_MIN, "{view:?}"); + // the whole range is walked in whole steps from either end + let mut presses = 0; + while h.app.ui.thumb_size < THUMB_SIZE_MAX { + press(&mut h, "=", false, false); + presses += 1; + assert!(presses <= 20, "never reached the maximum"); + } + assert_eq!(presses, ((THUMB_SIZE_MAX - THUMB_SIZE_MIN) / THUMB_SIZE_STEP).ceil() as usize); + } +} + +#[test] +fn thumbnail_size_keys_do_nothing_outside_the_grids() { + use crate::state::ViewMode; + for view in [ViewMode::Detail, ViewMode::Compare, ViewMode::Survey, ViewMode::Reference] { + let mut h = grid_view(view); + h.app.ui.thumb_size = 220.0; + let zoom = h.app.ui.zoom; + for (k, shift) in [("=", false), ("-", false), ("Plus", true)] { + press(&mut h, k, shift, false); + } + assert_eq!(h.app.ui.thumb_size, 220.0, "{view:?}"); + assert_eq!(h.app.ui.zoom, zoom, "{view:?}: a bare = / - is not a zoom key"); + // the command says why, and the menu shows it unavailable + let r = h.request("ui.menu.invoke", json!({"id": "view.thumbSizeUp"}), T); + assert_eq!(r["ok"], false, "{view:?}: {r}"); + assert_eq!(h.app.ui.thumb_size, 220.0); + let list = h.request("ui.menu.list", json!({}), T); + let entry = list["result"].as_array().and_then(|a| a.iter().find(|e| e["id"] == "view.thumbSizeUp")).cloned().unwrap_or_default(); + assert_eq!(entry["enabled"], false, "{view:?}: {entry}"); + } +} + +#[test] +fn cmd_equals_and_minus_still_zoom_and_leave_the_thumbnail_size_alone() { + // in the loupe: the photo zooms, the grid size is untouched + let mut h = edit_view(); + h.app.ui.thumb_size = 220.0; + key(&mut h, "="); + assert_eq!(h.app.ui.zoom, Zoom::Percent(50.0)); + key(&mut h, "-"); + assert_eq!(h.app.ui.zoom, Zoom::Percent(25.0)); + assert_eq!(h.app.ui.thumb_size, 220.0); + // in a grid Cmd+= / Cmd+- are View ▸ Zoom In / Out, not the size keys + let mut h = grid_view(crate::state::ViewMode::PhotoGrid); + h.app.ui.thumb_size = 220.0; + key(&mut h, "="); + key(&mut h, "-"); + assert_eq!(h.app.ui.thumb_size, 220.0, "Cmd+= / Cmd+- changed the grid size"); +} + +#[test] +fn search_field_keeps_equals_and_minus() { + let mut h = grid_view(crate::state::ViewMode::PhotoGrid); + h.app.ui.thumb_size = 220.0; + let r = h.request("ui.clickWidget", json!({"id": "field:search"}), T); + assert_eq!(r["ok"], true, "{r}"); + h.step(); + for (k, text) in [("-", "-"), ("=", "="), ("Plus", "+")] { + press(&mut h, k, false, false); + let r = h.request("ui.text", json!({"text": text}), T); + assert_eq!(r["ok"], true, "{r}"); + h.step(); + } + assert_eq!(h.app.ui.thumb_size, 220.0, "typing in the search field resized the grid"); + assert_eq!(h.app.ui.search, "-=+", "the search field did not receive the keys"); +} + +#[test] +fn thumbnail_size_commands_run_from_the_control_channel_and_persist() { + let mut h = grid_view(crate::state::ViewMode::SquareGrid); + h.app.ui.thumb_size = 120.0; + let r = h.request("ui.menu.invoke", json!({"id": "view.thumbSizeUp"}), T); + assert_eq!(r["ok"], true, "{r}"); + assert_eq!(r["result"]["size"], 150.0); + let r = h.request("engine.execute", json!({"command": "view.thumbSizeDown"}), T); + assert_eq!(r["ok"], true, "{r}"); + assert_eq!(h.app.ui.thumb_size, 120.0); + let r = h.request("ui.menu.invoke", json!({"id": "view.thumbSizeUp"}), T); + assert_eq!(r["ok"], true, "{r}"); + // the size is saved with the rest of the UI state, like the slider's, and restored clamped + let saved = serde_json::to_value(&h.app.ui).unwrap(); + assert_eq!(saved["thumbSize"], 150.0); + let loaded = serde_json::from_value::(saved).unwrap().sanitized(); + assert_eq!(loaded.thumb_size, 150.0); + let mut wild = serde_json::to_value(&h.app.ui).unwrap(); + wild["thumbSize"] = json!(9000.0); + assert_eq!(serde_json::from_value::(wild).unwrap().sanitized().thumb_size, crate::state::THUMB_SIZE_MAX); +} diff --git a/docs/library-shortcuts.md b/docs/library-shortcuts.md index 414e9166b..fab02d628 100644 --- a/docs/library-shortcuts.md +++ b/docs/library-shortcuts.md @@ -46,7 +46,17 @@ commit `4e012a59a6d2442ba749f109ea27aadb5c0b11a5` by Gardy, and addresses the ca [issue #283](https://github.com/storytold/lightcraft/issues/283). That PR was open when checked on 2026-10-08; this work extends its fix with library culling bindings and tests. -Public behaviour references, checked 2026-10-08: +## Grid thumbnail size + +`=` makes the grid thumbnails larger and `-` smaller (`+` also enlarges), as in Lightroom Classic. Each +press moves the bottom-bar slider by 30 pt within its 90–480 pt range and stops at either end. The keys +work in Photo Grid, Square Grid and People (the views with the slider), do nothing in Detail, Compare, +Survey and Reference, and leave text fields alone, so the search box still types `-` and `=`. `⌘=` / +`⌘−` remain Zoom In / Out. The same steps are the View ▸ Increase / Decrease Grid Thumbnail Size +commands (`view.thumbSizeUp`, `view.thumbSizeDown`, reachable from the control channel and MCP, which +return `{"size"}`); the size is saved with the other interface settings. + +Public behaviour references, checked 2026-10-08 (thumbnail size: 2026-10-13): - [Lightroom Classic keyboard shortcuts](https://helpx.adobe.com/lightroom-classic/help/keyboard-shortcuts.html) - [Lightroom Classic flagging, labelling and rating](https://helpx.adobe.com/lightroom-classic/help/flag-label-rate-photos.html) diff --git a/docs/parity-checklist.md b/docs/parity-checklist.md index 76d91ba3e..5a5c0f317 100644 --- a/docs/parity-checklist.md +++ b/docs/parity-checklist.md @@ -1,6 +1,6 @@ # Lightroom parity checklist -> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-11 · **Change:** minor (LR-MERGE-HDR: merges of raws without colour matrices keep their colour (#965); rapid slider entry; LR-PROF-CAMERACOLOR: tone curve from black-and-white camera JPEGs; LR-VIEW-ZOOM, LR-VIEW-COMPARE: Compare and Reference zoom windows; LR-IMP-FORMATS, LR-IMP-CAMERA-COVERAGE: EOS R5 Mark II CR3 decodes; renamed from `parity.md`; Top gaps moved to gaps.md, shortcut notes to ui-parity.md; filesystem history retry/Undo/Redo evidence; renamed from `parity.md`; Top gaps moved to gaps.md, shortcut notes to ui-parity.md) · **Target:** Adobe Lightroom Classic 15.5 / Lightroom 9.6 +> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-13 · **Change:** minor (KEYC-COMPARE: `=` / `-` change the grid thumbnail size; LR-MERGE-HDR: merges of raws without colour matrices keep their colour (#965); rapid slider entry; LR-PROF-CAMERACOLOR: tone curve from black-and-white camera JPEGs; LR-VIEW-ZOOM, LR-VIEW-COMPARE: Compare and Reference zoom windows; LR-IMP-FORMATS, LR-IMP-CAMERA-COVERAGE: EOS R5 Mark II CR3 decodes; renamed from `parity.md`; Top gaps moved to gaps.md, shortcut notes to ui-parity.md; filesystem history retry/Undo/Redo evidence; renamed from `parity.md`; Top gaps moved to gaps.md, shortcut notes to ui-parity.md) · **Target:** Adobe Lightroom Classic 15.5 / Lightroom 9.6 The measured, row-by-row checklist: one row per Lightroom feature, menu item and shortcut, what we have and what is missing. It answers *does the feature exist?* (feature breadth). Whether it is good @@ -36,7 +36,7 @@ cited here still exists. Formerly docs/parity.md. | H. Crop & rotate (CROP) | 9 | 0 | 0 | 1 | 6/6 (100%) | 3/3 (100%) | | I. Remove / healing (REM) | 8 | 1 | 2 | 2 | 4/4 (100%) | 2/3 (67%) | | J. Red eye (EYE) | 2 | 0 | 0 | 0 | — | 1/1 (100%) | -| K. Masking (MASK) | 13 | 5 | 5 | 0 | 7/8 (88%) | 5/5 (100%) | +| K. Masking (MASK) | 14 | 5 | 5 | 0 | 7/8 (88%) | 6/6 (100%) | | L. Presets (PRE) | 6 | 0 | 1 | 1 | 2/2 (100%) | 2/2 (100%) | | M. Versions & history (VER) | 5 | 0 | 0 | 0 | 1/1 (100%) | 3/3 (100%) | | N. Copy / paste / sync (SYNC) | 5 | 0 | 0 | 0 | 3/3 (100%) | 1/1 (100%) | @@ -53,9 +53,9 @@ cited here still exists. Formerly docs/parity.md. | Y. Menus | 84 | 0 | 4 | 8 | 47/47 (100%) | 23/23 (100%) | | Z. Keyboard shortcuts (desktop) | 76 | 3 | 3 | 1 | 49/52 (94%) | 23/24 (96%) | | Lightroom Classic extras | 34 | 16 | 35 | 8 | — | 24/26 (92%) | -| **Total** | 408 | 52 | 72 | 35 | 193/201 (96%) | 145/157 (92%) | +| **Total** | 409 | 52 | 72 | 35 | 193/201 (96%) | 146/158 (92%) | -Weighted completion (✅ = 1, 🟡 = ½, 🚫 left out): **81.6%** of 532 in-scope rows — P0 98.0% of 201 · P1 95.2% of 157 · P2 50.0% of 173. +Weighted completion (✅ = 1, 🟡 = ½, 🚫 left out): **81.6%** of 533 in-scope rows — P0 98.0% of 201 · P1 95.3% of 158 · P2 50.0% of 173. ## Top gaps and shortcut notes @@ -769,7 +769,7 @@ From `08-lightroom-classic-extras.md` (Classic-only features) and part 2 of `06- | KEYC-VIEWS | Classic view keys (E, G, C, N, L, F, I, ⇧R, ⌘⌥0) | P2 | 🟡 | `cmd:view.photoGrid`, `cmd:view.zoom100` | G works; E opens Edit (not loupe); no compare/survey/lights-out/screen modes | | KEYC-SECONDWINDOW | Classic secondary-window keys | P2 | ⬜ | | | | KEYC-CATALOG | Classic photo/catalog keys (⇧⌘I, ⌘', ⌘R, F2, ⌫, ⇧⌘E…) | P2 | ✅ | `cmd:library.import`, `cmd:photo.delete`, `cmd:photo.virtualCopy`, `cmd:app.showInFinder`, `cmd:dialog.rename`, `cmd:photo.editInExternal` | ⇧⌘I add, ⌘' virtual copy, ⌘R show in Finder, F2 rename, ⌫ delete, ⇧⌘E external editor | -| KEYC-COMPARE | Classic grid/compare keys (Z, Home/End, =/−, ⌘⇧D, S…) | P2 | 🟡 | `cmd:view.zoomToggle` | Z toggles zoom; no compare, stacks, thumbnail-size keys | +| KEYC-COMPARE | Classic grid/compare keys (Z, Home/End, =/−, ⌘⇧D, S…) | P2 | 🟡 | `cmd:view.zoomToggle`, `cmd:view.thumbSizeUp`, `cmd:view.thumbSizeDown`, `crates/ui-egui/src/tests_zoom_keys.rs` | Z toggles zoom; `=` / `-` (and `+`) step the grid thumbnail size by 30 pt within the bottom-bar slider's 90–480 range in Photo Grid, Square Grid and People (nothing in Detail, Compare, Survey or Reference; a text field keeps the keys; ⌘= / ⌘− still zoom); no compare, stacks keys | | KEYC-RATING | Classic rating/flag keys (1–5, ⇧1–5, 6–9, P, X, U, ⇧X, ⇧U, `[` `]`, \`) | P2 | 🟡 | `cmd:photo.rate`, `cmd:photo.pick`, `cmd:photo.flag` | 0–5 / Shift+0–5 and 6–9 / Shift+6–9; P/X/U, Shift+X/U and grid Shift+P work; tests cover batch/undo, active Compare candidate and text focus. Missing: Shift+P outside grids (Presets), rating `[` / `]`, flag cycle and filter-bar keys | | KEYC-COLLECTIONS | Classic collection keys (⌘N, B…) | P2 | 🟡 | `cmd:dialog.newAlbum` | ⌘N new album; no quick collection | | KEYC-METADATA | Classic keyword/metadata keys (⌘K, ⌘S, ⌘⌥⇧C/V…) | P2 | 🟡 | `cmd:photo.saveMetadataToFile` | ⌘S saves metadata; no keyword sets, metadata copy/paste | @@ -814,3 +814,4 @@ Latin stays upright. Advanced Japanese composition remains open. Regression cove | 2026-10-10 | patch | LR-BEHAV-UNDO: file/XMP repair retries and merged rename Undo/Redo evidence; status and summary counts unchanged. | | 2026-10-10 | minor | Renamed from `parity.md` (progress-docs standard); Top gaps moved to gaps.md (its duplicated items 1–2 from a bad merge resolved there), shortcut notes moved to ui-parity.md. Rows unchanged; a recount of the rows gives 81.1% of 517 in-scope rows (P0 98.0%, P1 95.1%, P2 46.9%), so the generated summary above is due a `cargo xtask parity --write` | | 2026-09-30 – 2026-10-11 | — | Rows added and updated with each feature (see `git log -- docs/parity.md docs/parity-checklist.md`) | +| 2026-10-13 | minor | KEYC-COMPARE: `=` / `-` (also `+`) increase / decrease the grid thumbnail size (`view.thumbSizeUp` / `view.thumbSizeDown`, View menu), grids only; status unchanged (🟡) | diff --git a/docs/ui-parity.md b/docs/ui-parity.md index 2236f02a7..f15a34864 100644 --- a/docs/ui-parity.md +++ b/docs/ui-parity.md @@ -1,6 +1,6 @@ # UI parity -> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-12 · **Change:** minor (accessibility audit: test over the AccessKit tree; fields, sliders and dialogs named) · **Target:** Adobe Lightroom Classic 15.5 / Lightroom 9.6 +> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-13 · **Change:** minor (`=` / `-` grid thumbnail size keys; accessibility audit: test over the AccessKit tree; fields, sliders and dialogs named) · **Target:** Adobe Lightroom Classic 15.5 / Lightroom 9.6 How LightCraft's interaction compares with Lightroom's: views, panels, tools and handles, modifier keys, shortcuts, zoom, context menus and feel. Rows for individual menu items and shortcuts live in @@ -67,6 +67,8 @@ under the UI command that wraps it (a no-op error); the UI command now wins. **Library culling (KEYC-RATING):** `0–5`, `6–9` and `P/X/U` reach egui on macOS even when displayed in the native menu (adapted from PR #261; issue #283). `Shift+0–9` applies and advances once; `Shift+P` picks and advances in Photo Grid / Square Grid and retains Presets elsewhere. See [library shortcuts](library-shortcuts.md) for the verified Classic mapping and regression coverage. Remaining Classic gaps: rating `[` / `]`, flag cycling and filter-bar keys. +**Grid thumbnail size (KEYC-COMPARE):** Classic's `=` and `-` increase and decrease the Grid thumbnail size (same keys on macOS and Windows; `+` also works for the larger size here, as Shift+`=` or the keypad). They step the bottom-bar slider by 30 pt inside its 90–480 pt range, in Photo Grid, Square Grid and People only; Detail, Compare, Survey and Reference ignore them, and ⌘= / ⌘− stay Zoom In / Out. See [library shortcuts](library-shortcuts.md). + **Still missing / broken:** - No command yet: F1 help (verify the rest of the old list: full screen, settings, stacks, visualize spots and merges have commands now). @@ -105,6 +107,7 @@ left panel, canvas, right panel, which is sensible but not tuned). | Date | Change | Summary | |---|---|---| +| 2026-10-13 | minor | KEYC-COMPARE: `=` / `-` grid thumbnail size keys noted in the shortcuts section | | 2026-10-12 | minor | Accessibility: an AccessKit tree audit test over every view, Develop tool and 13 dialogs; unnamed fields, slider ranges and the Auto Stack slider fixed; 30% → 55%; UI remaining 40–70 h → 34–58 h | | 2026-10-11 | minor | Zoom row: Compare and Reference get zoom windows; what remains of LR-VIEW-ZOOM is overlays and soft proofing | | 2026-10-10 | major | Created: measured command and shortcut counts, assessment by area, estimates; moved the shortcut conflicts section here from the checklist |