From 32146348b8894201fd3fdabee8d8cd8db72705e2 Mon Sep 17 00:00:00 2001 From: moppeeer Date: Thu, 15 Oct 2026 16:43:38 +0200 Subject: [PATCH] UI: Tab, Shift+Tab and Presentation hide flyout and floating panels too Co-Authored-By: Claude Opus 5.5 --- ROADMAP.md | 1 + crates/ui-egui/src/lib.rs | 7 +++-- crates/ui-egui/src/menus.rs | 51 +++++++++++++++++++++++++++++++++++++ 3 files changed, 57 insertions(+), 2 deletions(-) diff --git a/ROADMAP.md b/ROADMAP.md index d60a6bf49..db6a63196 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -347,6 +347,7 @@ list) · [roadmap.md](docs/roadmap.md) (milestones, plan) · [parity-checklist.m Newest first. +- 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 59c7ebb59..326214ce0 100644 --- a/crates/ui-egui/src/lib.rs +++ b/crates/ui-egui/src/lib.rs @@ -1366,8 +1366,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 a35261d59..1ce66d2a6 100644 --- a/crates/ui-egui/src/menus.rs +++ b/crates/ui-egui/src/menus.rs @@ -3164,6 +3164,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());