LR-EDIT-SECTION-SOLO: register section.calibration, refuse unknown sections

Calibration's header runs section.calibration, now a registered command (no menu
item); section.<id> refuses an id the Edit panel hasn't got instead of closing
the real sections for a phantom one. "Solo Mode" sits with the other So… keys
in the catalogs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Matthew James Sivak
2026-10-13 14:13:48 +02:00
co-authored by Claude Opus 5.5
parent 12015179ea
commit eeb2ca2f6a
12 changed files with 22 additions and 15 deletions
+1 -1
View File
@@ -529,7 +529,6 @@
"Filmstrip (/)": "Filmstreifen (/)",
"Filter": "Filter",
"Filter Bar": "Filterleiste",
"Solo Mode": "Solo-Modus",
"Filter Presets": "Filtervorgaben",
"Filter bar": "Filterleiste",
"Filter fields": "Filterfelder",
@@ -1433,6 +1432,7 @@
"Soft Pastel": "Sanftes Pastell",
"Soft Proofing": "Softproof",
"Soft Skin": "Weiche Haut",
"Solo Mode": "Solo-Modus",
"Sony ARWs from before about 2017 (RX100, RX100 II–V, RX10, NEX, SLT, ILCE-6000, A7 / A7 II / A7R II and their": "Sony-ARWs von vor etwa 2017, RX100, RX100 II–V, RX10, NEX, SLT, ILCE-6000, A7, A7 II, A7R II und verwandte",
"Sony ILCE-7M4 downsized lossless ARWs now decode subsampled YCbCr tiles into linear RGB,": "Verkleinerte verlustfreie ARW-Dateien der Sony ILCE-7M4 werden jetzt aus unterabgetasteten YCbCr-Kacheln in lineares RGB decodiert.",
"Sort": "Sortieren",
+1 -1
View File
@@ -511,7 +511,6 @@
"Filmstrip (/)": "Tira de película (/)",
"Filter": "Filtro",
"Filter Bar": "Barra de filtros",
"Solo Mode": "Modo solo",
"Filter Presets": "Ajustes preestablecidos de filtro",
"Filter bar": "Barra de filtros",
"Filter fields": "Campos de filtro",
@@ -1400,6 +1399,7 @@
"Soft Pastel": "Pastel suave",
"Soft Proofing": "Prueba en pantalla",
"Soft Skin": "Piel suave",
"Solo Mode": "Modo solo",
"Sort": "Ordenar",
"Sort Albums by Name": "Ordenar álbumes por nombre",
"Sort by": "Ordenar por",
+1 -1
View File
@@ -494,7 +494,6 @@
"Filmstrip (/)": "Pellicule (/)",
"Filter": "Filtre",
"Filter Bar": "Barre de filtres",
"Solo Mode": "Mode solo",
"Filter Presets": "Préréglages de filtre",
"Filter bar": "Barre de filtres",
"Filter fields": "Champs de filtre",
@@ -1366,6 +1365,7 @@
"Soft Pastel": "Pastel doux",
"Soft Proofing": "Épreuvage à l'écran",
"Soft Skin": "Peau douce",
"Solo Mode": "Mode solo",
"Sort": "Trier",
"Sort by": "Trier par",
"Source": "Source",
+1 -1
View File
@@ -709,7 +709,6 @@
"Filmstrip": "フィルムストリップ",
"Filter": "フィルター",
"Filter Bar": "フィルターバー",
"Solo Mode": "ソロモード",
"Filter Presets": "フィルタープリセット",
"Filter bar": "フィルターバー",
"Filter fields": "項目を絞り込む",
@@ -1311,6 +1310,7 @@
"Soft Pastel": "ソフトパステル",
"Soft Proofing": "ソフト校正",
"Soft Skin": "ソフトスキン",
"Solo Mode": "ソロモード",
"Sort": "並べ替え",
"Sort by": "並べ替え",
"Source": "読み込み元",
+1 -1
View File
@@ -502,7 +502,6 @@
"Filmstrip (/)": "Película (/)",
"Filter": "Filtro",
"Filter Bar": "Barra de filtros",
"Solo Mode": "Modo solo",
"Filter Presets": "Predefinições de filtro",
"Filter bar": "Barra de filtros",
"Filter fields": "Campos de filtro",
@@ -1389,6 +1388,7 @@
"Soft Pastel": "Pastel suave",
"Soft Proofing": "Prova suave",
"Soft Skin": "Pele suave",
"Solo Mode": "Modo solo",
"Sort": "Classificar",
"Sort by": "Classificar por",
"Source": "Origem",
+1 -1
View File
@@ -412,7 +412,6 @@
"Filmstrip (/)": "Лента (/)",
"Filter": "Фильтр",
"Filter Bar": "Панель фильтров",
"Solo Mode": "Режим соло",
"Filter Presets": "Пресеты фильтров",
"Filter bar": "Панель фильтров",
"Filter fields": "Поля фильтра",
@@ -1153,6 +1152,7 @@
"Soft Pastel": "Мягкий пастельный",
"Soft Proofing": "Экранная цветопроба",
"Soft Skin": "Мягкая кожа",
"Solo Mode": "Режим соло",
"Sort": "Сортировка",
"Sort by": "Сортировать по",
"Source": "Источник",
+1 -1
View File
@@ -915,7 +915,6 @@
"Fill Edges": "Заповнити краї",
"Filmstrip": "Стрічка",
"Filter Bar": "Панель фільтрів",
"Solo Mode": "Режим соло",
"Filter Presets": "Набори налаштувань фільтрів",
"Filter bar": "Панель фільтрів",
"Filter fields": "Поля фільтрів",
@@ -1375,6 +1374,7 @@
"Soft Pastel": "М’яка пастель",
"Soft Proofing": "Екранна кольоропроба",
"Soft Skin": "М’яка шкіра",
"Solo Mode": "Режим соло",
"Sort by": "Сортувати за",
"Spherical": "Сферична",
"Split Stack": "Розділити стос",
+1 -1
View File
@@ -652,7 +652,6 @@
"Filmstrip (/)": "胶片窗格 (/)",
"Filter": "过滤器",
"Filter Bar": "过滤器栏",
"Solo Mode": "单独模式",
"Filter Presets": "过滤器预设",
"Filter bar": "过滤器栏",
"Filter fields": "过滤字段",
@@ -1374,6 +1373,7 @@
"Soft Pastel": "柔和粉彩",
"Soft Proofing": "软打样",
"Soft Skin": "柔和肤质",
"Solo Mode": "单独模式",
"Sort": "排序",
"Sort by": "排序方式",
"Source": "来源",
+1 -1
View File
@@ -652,7 +652,6 @@
"Filmstrip (/)": "底片列(/)",
"Filter": "篩選",
"Filter Bar": "篩選列",
"Solo Mode": "單獨模式",
"Filter Presets": "篩選預設集",
"Filter bar": "篩選列",
"Filter fields": "篩選欄位",
@@ -1374,6 +1373,7 @@
"Soft Pastel": "柔和粉彩",
"Soft Proofing": "軟式校樣",
"Soft Skin": "柔和膚質",
"Solo Mode": "單獨模式",
"Sort": "排序",
"Sort by": "排序依據",
"Source": "來源",
+7 -2
View File
@@ -130,6 +130,7 @@ pub const UI_COMMANDS: &[UiCommand] = &[
("section.effects", "Effects", Some("Cmd+3"), "Window>Edit Sections"),
("section.detail", "Detail", Some("Cmd+4"), "Window>Edit Sections"),
("section.optics", "Optics", Some("Cmd+5"), "Window>Edit Sections"),
("section.calibration", "Calibration", None, ""),
// {on?}; no params toggles. Opening one Edit section closes the others.
("view.soloSections", "Solo Mode", None, "Window>Edit Sections"),
("tool.brush", "Brush", Some("B"), "Window>Tools"),
@@ -1040,7 +1041,11 @@ pub fn run_ui_command(app: &mut LightcraftApp, id: &str, p: &Value) -> Option<Re
app.ui.presets = false;
Ok(Value::Null)
}
s if s.starts_with("section.") => bool_param(s, p, "solo").map(|solo| {
s if s.starts_with("section.") => bool_param(s, p, "solo").and_then(|solo| {
// only the Edit sections listed above: an unknown one would close the real ones
if !UI_COMMANDS.iter().any(|c| c.0 == s) {
return Err(format!("{s}: no such Edit section"));
}
let sec = &s["section.".len()..];
if app.ui.right != RightPanel::Edit {
app.ui.right = RightPanel::Edit;
@@ -1050,7 +1055,7 @@ pub fn run_ui_command(app: &mut LightcraftApp, id: &str, p: &Value) -> Option<Re
} else {
app.ui.toggle_section(sec);
}
Value::Null
Ok(Value::Null)
}),
s if s.starts_with("tool.") => {
let tool = &s["tool.".len()..];
+5 -3
View File
@@ -80,15 +80,17 @@ fn option_click_opens_just_that_section() {
click(&mut h, json!({"id": "section:detail", "alt": true}));
assert_eq!(h.app.ui.open_sections, ["detail"], "⌥-click closes the others");
assert!(!h.app.ui.single_panel, "⌥-click doesn't turn Solo Mode on");
// agents do the same with the section's command (Calibration has no menu item but runs too)
// agents do the same with the section's command (Calibration has one, though not in the menu)
exec(&mut h, "section.calibration", json!({"solo": true}));
assert_eq!(h.app.ui.open_sections, ["calibration"]);
}
#[test]
fn flags_that_are_not_true_or_false_are_refused() {
fn bad_flags_and_unknown_sections_are_refused() {
let mut h = edit_open();
for (command, params) in [("view.soloSections", json!({"on": "yes"})), ("section.color", json!({"solo": 1}))] {
for (command, params) in
[("view.soloSections", json!({"on": "yes"})), ("section.color", json!({"solo": 1})), ("section.typo", json!({"solo": true}))]
{
let r = h.request("engine.execute", json!({"command": command, "params": params}), T);
assert_eq!(r["ok"], false, "{command} {params}: {r}");
}
+1 -1
View File
@@ -222,7 +222,7 @@ differences and missing bindings are in [ui-parity.md](ui-parity.md#shortcuts).
| LR-EDIT-LENSBLUR | Lens blur | P2 | ⬜ | | settings field reserved, not rendered |
| LR-EDIT-CALIB | Calibration [Classic] | P1 | ✅ | `ctl:calibration.*` | shadows tint, red/green/blue primary hue and saturation; read/written in XMP |
| LR-EDIT-SECTION-TOGGLE | Section on/off | P1 | ✅ | `cmd:develop.sectionEnabled`, `crates/develop/src/lib.rs` (`effective`) | the eye on a section header hides its adjustments: Light (with the curve), Color (white balance, presence, mixers, grading, point colour), Effects, Detail, Optics, Geometry, Calibration; masks stay on (issue #316 fixed Light, Color and Detail, which had no effect) |
| LR-EDIT-SECTION-SOLO | Solo Mode for Edit sections | P2 | ✅ | `cmd:view.soloSections`, `crates/ui-egui/src/state.rs` (`toggle_section`, `set_single_panel`, `solo_section`), `crates/ui-egui/src/panels/edit.rs` (`section`), `crates/ui-egui/src/tests_solo_sections.rs` | Lightroom Classic's panel Solo Mode: while it is on, opening one Edit section (a header click or ⌘1–⌘5) closes the others. Window ▸ Edit Sections ▸ Solo Mode (checked while on) or a right-click on any section header (`sectionMenu:solo`) turns it on and off; turning it on keeps only the section opened last. ⌥-click on a header opens just that section once, without turning the mode on (agents: `section.<id>` `{solo: true}`; header clicks run `section.<id>` too). `view.soloSections` `{on?}` (no params toggles) answers `{soloSections}`. Kept with the UI state (`singlePanel`) |
| LR-EDIT-SECTION-SOLO | Solo Mode for Edit sections | P2 | ✅ | `cmd:view.soloSections`, `cmd:section.calibration`, `crates/ui-egui/src/state.rs` (`toggle_section`, `set_single_panel`, `solo_section`), `crates/ui-egui/src/panels/edit.rs` (`section`), `crates/ui-egui/src/tests_solo_sections.rs` | Lightroom Classic's panel Solo Mode: while it is on, opening one Edit section (a header click or ⌘1–⌘5) closes the others. Window ▸ Edit Sections ▸ Solo Mode (checked while on) or a right-click on any section header (`sectionMenu:solo`) turns it on and off; turning it on keeps only the section opened last. ⌥-click on a header opens just that section once, without turning the mode on (agents: `section.<id>` `{solo: true}`, refused for a section the Edit panel has not got; header clicks run `section.<id>` too, Calibration included). `view.soloSections` `{on?}` (no params toggles) answers `{soloSections}`. Kept with the UI state (`singlePanel`) |
| LR-EDIT-RESET | Reset all / section / slider | P0 | ✅ | `cmd:develop.reset`, `cmd:develop.resetSection`, `cmd:develop.resetControl`, `crates/ui-egui/src/widgets.rs` (double-click) | no "reset to open" |
| LR-EDIT-SHOWORIG | Show original | P0 | ✅ | `cmd:view.showOriginal` | |