77use bevy:: ecs:: system:: SystemState ;
88use bevy:: prelude:: * ;
99use bevy_egui:: PrimaryEguiContext ;
10- use std:: collections:: HashMap ;
10+ use std:: collections:: { HashMap , HashSet } ;
1111use std:: sync:: Mutex ;
1212
1313/// Serializable snapshot of the dock layout.
@@ -152,6 +152,8 @@ pub struct TileLayoutState {
152152 pub ( crate ) layout_load_path : Option < std:: path:: PathBuf > ,
153153 /// Panels requested to open (processed in exclusive system with undo recording).
154154 pub ( crate ) pending_open_requests : Vec < String > ,
155+ /// Panel IDs hidden from the Window menu at runtime (overrides `show_in_window_menu()`).
156+ window_menu_hidden : HashSet < String > ,
155157}
156158
157159impl TileLayoutState {
@@ -387,14 +389,15 @@ impl TileLayoutState {
387389 }
388390
389391 /// Returns list of (panel_str_id, title, is_visible) for building the Window menu.
390- /// Only includes panels where `show_in_window_menu()` returns `true`.
392+ /// Only includes panels where `show_in_window_menu()` returns `true`
393+ /// and not hidden via `hide_from_window_menu()`.
391394 pub fn panel_list ( & self ) -> Vec < ( String , String , bool ) > {
392395 let mut result = Vec :: new ( ) ;
393396 for ( str_id, & panel_id) in & self . panel_id_map {
394397 let Some ( panel) = self . panels . get ( & panel_id) else {
395398 continue ;
396399 } ;
397- if !panel. show_in_window_menu ( ) {
400+ if !panel. show_in_window_menu ( ) || self . window_menu_hidden . contains ( str_id ) {
398401 continue ;
399402 }
400403 let title = panel. title ( ) ;
@@ -409,6 +412,23 @@ impl TileLayoutState {
409412 result
410413 }
411414
415+ /// Hide a panel from the built-in Window menu (it can still be managed
416+ /// programmatically or via a custom menu).
417+ pub fn hide_from_window_menu ( & mut self , panel_str_id : & str ) {
418+ self . window_menu_hidden . insert ( panel_str_id. to_string ( ) ) ;
419+ }
420+
421+ /// Check whether a panel is currently visible in the layout.
422+ pub fn is_panel_visible ( & self , panel_str_id : & str ) -> bool {
423+ let Some ( & panel_id) = self . panel_id_map . get ( panel_str_id) else {
424+ return false ;
425+ } ;
426+ self . panel_tile_map
427+ . get ( & panel_id)
428+ . and_then ( |& tid| self . tree . as_ref ( ) . map ( |t| t. tiles . get ( tid) . is_some ( ) ) )
429+ . unwrap_or ( false )
430+ }
431+
412432 /// Get a mutable reference to a panel by its string ID, with downcasting.
413433 pub fn get_panel_mut < T : WorkbenchPanel + ' static > (
414434 & mut self ,
0 commit comments