diff --git a/crates/ui-egui/src/panels/bottombar.rs b/crates/ui-egui/src/panels/bottombar.rs index 874df26cc..b986b8995 100644 --- a/crates/ui-egui/src/panels/bottombar.rs +++ b/crates/ui-egui/src/panels/bottombar.rs @@ -6,7 +6,7 @@ use serde_json::json; use crate::LightcraftApp; use crate::icons::{Icon, paint}; -use crate::state::{BeforeAfter, ViewMode, Zoom}; +use crate::state::{ViewMode, Zoom}; use crate::theme::Tokens; use crate::widgets::{icon_button, register, stars}; @@ -178,16 +178,8 @@ fn right_side(app: &mut LightcraftApp, ui: &mut egui::Ui, full: Rect, compact_zo if app.ui.view == ViewMode::Survey { // no zoom or thumbnail size in Survey } else if matches!(app.ui.view, ViewMode::Detail | ViewMode::Compare) { - if icon_button( - &mut child, - "beforeAfter", - Icon::BeforeAfter, - vec2(30.0, 30.0), - app.ui.before_after != BeforeAfter::Off, - true, - "Before/After (Y)", - ) - .clicked() + if icon_button(&mut child, "beforeAfter", Icon::BeforeAfter, vec2(30.0, 30.0), app.ui.before_after.is_layout(), true, "Before/After (Y)") + .clicked() { let _ = app.run("view.beforeAfter", json!({})); } diff --git a/crates/ui-egui/src/state.rs b/crates/ui-egui/src/state.rs index 6c4dd3f6a..234b5a604 100644 --- a/crates/ui-egui/src/state.rs +++ b/crates/ui-egui/src/state.rs @@ -70,6 +70,14 @@ pub enum BeforeAfter { SplitTopBottom, } +impl BeforeAfter { + /// One of the Before / After layouts (two views or a split line), which the bottom bar's + /// Before/After (Y) button stands for. Show Original (`\`) is a view of its own, not a layout. + pub fn is_layout(self) -> bool { + !matches!(self, BeforeAfter::Off | BeforeAfter::Original) + } +} + #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub enum CropOverlay { diff --git a/crates/ui-egui/src/tests_before_after.rs b/crates/ui-egui/src/tests_before_after.rs index ae35a35b2..50ec66cf4 100644 --- a/crates/ui-egui/src/tests_before_after.rs +++ b/crates/ui-egui/src/tests_before_after.rs @@ -132,3 +132,30 @@ fn zoomed_in_the_after_side_shows_the_edits() { } } } + +/// Show Original (`\`) is not one of the Before / After layouts, so the bottom bar's +/// Before/After (Y) button stays dark for it; clicking the button then lays out Before and After +/// side by side, as it does from the plain view. It used to light up for `\` too, so the same +/// lit button stood for two different views (#1497). +#[test] +fn show_original_does_not_light_the_before_after_button() { + assert!(!BeforeAfter::Off.is_layout()); + assert!(!BeforeAfter::Original.is_layout()); + for mode in [BeforeAfter::SideBySide, BeforeAfter::Split, BeforeAfter::TopBottom, BeforeAfter::SplitTopBottom] { + assert!(mode.is_layout(), "{mode:?}"); + } + let app = LightcraftApp::new(lightcraft_engine::Session::with_demo(), Services { png: None, ..Default::default() }); + let mut h = Headless::new(app, [1400.0, 900.0], 1.0); + let id = h.app.session.visible_cloned()[2]; + h.request("engine.execute", json!({"command": "library.select", "params": {"ids": [id.0], "active": id.0}}), T); + h.app.ui.view = ViewMode::Detail; + h.settle(SETTLE); + assert_eq!(h.request("engine.execute", json!({"command": "view.showOriginal"}), T)["ok"], true); + assert_eq!(h.app.ui.before_after, BeforeAfter::Original); + assert!(!h.app.ui.before_after.is_layout(), "the button is dark while the original is shown"); + h.settle(SETTLE); + assert_eq!(h.request("ui.clickWidget", json!({"id": "icon:beforeAfter"}), T)["ok"], true); + assert_eq!(h.app.ui.before_after, BeforeAfter::SideBySide, "a click on the dark button opens the layout"); + assert_eq!(h.request("ui.clickWidget", json!({"id": "icon:beforeAfter"}), T)["ok"], true); + assert_eq!(h.app.ui.before_after, BeforeAfter::Off, "a second click closes it"); +}