KEYC-COMPARE: = and - make the grid thumbnails larger and smaller

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.
This commit is contained in:
Atmik Shetty
2026-10-13 16:11:47 +05:30
parent b3d392b499
commit 25e832b404
9 changed files with 192 additions and 11 deletions
+2
View File
@@ -123,6 +123,8 @@ const LAYOUT: &[(&str, &[&str])] = &[
"view.photoGrid",
"view.squareGrid",
"@Grid Info",
"view.thumbSizeUp",
"view.thumbSizeDown",
"view.detail",
"view.compare",
"view.survey",
+18
View File
@@ -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<Re
app.ui.zoom = if next == 0.0 { Zoom::Fit } else { Zoom::Percent(next) };
Ok(Value::Null)
}
"view.thumbSizeUp" | "view.thumbSizeDown" => {
// 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<Re
Some(r)
}
/// Views whose bottom bar has the thumbnail-size slider and that draw tiles of that size.
fn thumb_size_view(app: &LightcraftApp) -> 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" => {
+3 -2
View File
@@ -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() }
+3
View File
@@ -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}"#),
+7 -1
View File
@@ -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);
+138 -1
View File
@@ -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::<crate::state::UiState>(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::<crate::state::UiState>(wild).unwrap().sanitized().thumb_size, crate::state::THUMB_SIZE_MAX);
}
+11 -1
View File
@@ -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)
+6 -5
View File
@@ -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.
<!-- /parity:summary -->
## 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 (🟡) |
+4 -1
View File
@@ -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 |