diff --git a/ROADMAP.md b/ROADMAP.md index 76e983013..304dc9ed9 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -456,6 +456,7 @@ Newest first. - 2026-10-15: Properties › Edit Page works as InDesign's: the Page tool on the page in view, and Properties shows that page alone (Page Size: page, preset, orientation, W/H; Margins and Columns; Quick Actions) with Back. It opened Document Setup, which changes every page. - 2026-10-15: Deleting pages that contain objects asks first, as InDesign does ("The affected page contains objects. Delete the page anyway?", with Don't show again), from the Pages panel, Layout › Pages › Delete Page and Properties. - 2026-10-15: A page scrolled or jumped to shows its paper while its render is on its way, as in InDesign, instead of the black of its shadow. +- 2026-10-15: Tab, Shift+Tab and Presentation hide the icon column's panel flyout and the classic floating panels too, as InDesign hides floating panels. - **2026-10-14** · The Type tool draws a new text frame over a locked empty frame, as InDesign does, instead of turning the locked frame into a text frame. No readiness percentage change. - **2026-10-14** · 100% black shows as pure black on screen by default, as InDesign's Appearance of Black does out of the box (Display All Blacks as Rich Black); Preferences › Appearance of Black › Display All Blacks Accurately still shows it as the dark grey it prints, and a saved choice is kept. No readiness percentage change. - **2026-10-14** · Pathfinder keeps the frontmost object, as InDesign does: a photo placed over shapes and intersected with them shows through the shapes (it was dropped, and the shapes kept their black fill); Add, Exclude Overlap and Minus Back take the front object's fill too, Subtract still keeps the back one. No readiness percentage change. diff --git a/crates/ui-egui/src/lib.rs b/crates/ui-egui/src/lib.rs index 49dbde30a..145e23db7 100644 --- a/crates/ui-egui/src/lib.rs +++ b/crates/ui-egui/src/lib.rs @@ -1554,8 +1554,11 @@ impl DesignApp { ); self.switch_pane(self.focus_pane); } - dock::flyout(self, &ctx); - dock::floating(self, &ctx); + // Tab, Shift+Tab and Presentation hide the floating panels with the docked ones. + if !presenting && self.ui.hidden_panels == 0 { + dock::flyout(self, &ctx); + dock::floating(self, &ctx); + } story_editor::show(self, &ctx); dialogs::show(self, &ctx); about::show(self, &ctx); diff --git a/crates/ui-egui/src/menus.rs b/crates/ui-egui/src/menus.rs index b799d3a7c..75e85221c 100644 --- a/crates/ui-egui/src/menus.rs +++ b/crates/ui-egui/src/menus.rs @@ -3864,6 +3864,57 @@ mod tests { assert!((width(&app) - 200.0).abs() < 1e-6, "fitted: {}", width(&app)); } + #[test] + fn tab_and_presentation_hide_floating_panels_too() { + let mut app = crate::DesignApp::new(designcraft_engine::Session::new(), crate::Services::default()); + app.session.execute("file.new", &json!({})).unwrap(); + let ctx = egui::Context::default(); + let frame = |app: &mut crate::DesignApp| { + for _ in 0..2 { + let input = egui::RawInput { + screen_rect: Some(egui::Rect::from_min_size(egui::Pos2::ZERO, egui::vec2(1400.0, 900.0))), + ..Default::default() + }; + let mut out = ctx.run_ui(input, |ui| { + app.logic(&ui.ctx().clone()); + app.ui(ui); + }); + out.textures_delta.clear(); + } + }; + // The icon column's flyout (the classic dock) and a floating panel group (the docking layout). + let flyout = egui::LayerId::new(egui::Order::Foreground, egui::Id::new("panel_flyout")); + let group = egui::LayerId::new(egui::Order::Middle, egui::Id::new("designcraft-panel-docking").with(("floating", "preflight"))); + let shown = |layer: egui::LayerId| ctx.memory(|m| m.areas().is_visible(&layer)); + let toggles = [ + ("window.hidePanels", json!({}), json!({})), + ("window.hidePanelsExceptTools", json!({}), json!({})), + ("view.screenMode", json!({"mode": "presentation"}), json!({"mode": "normal"})), + ]; + app.run("window.panel", json!({"panel": "preflight"})).unwrap(); + frame(&mut app); + assert!(app.ui.docking.is_none() && shown(flyout)); + for (id, hide, show) in &toggles { + app.run(id, hide.clone()).unwrap(); + frame(&mut app); + assert!(!shown(flyout), "{id} hides the flyout"); + app.run(id, show.clone()).unwrap(); + frame(&mut app); + assert!(shown(flyout), "{id} again brings it back"); + } + app.run("window.floatPanel", json!({"panel": "preflight", "x": 400, "y": 200})).unwrap(); + frame(&mut app); + assert!(app.ui.docking.is_some() && shown(group)); + for (id, hide, show) in &toggles { + app.run(id, hide.clone()).unwrap(); + frame(&mut app); + assert!(!shown(group), "{id} hides the floating panel"); + app.run(id, show.clone()).unwrap(); + frame(&mut app); + assert!(shown(group), "{id} again brings it back"); + } + } + #[test] fn tab_hides_panels_and_documents_cycle() { let mut app = crate::DesignApp::new(designcraft_engine::Session::new(), crate::Services::default());