@@ -5,6 +5,7 @@ use iced::widget::{
55} ;
66use iced:: { Element , Length } ;
77
8+ use crate :: remote_browser:: RemoteBrowserMessage ;
89use crate :: { Message , Pane , Ultimate64Browser } ;
910
1011impl Ultimate64Browser {
@@ -14,7 +15,10 @@ impl Ultimate64Browser {
1415 fn device_drive_control_strip ( & self ) -> Element < ' _ , Message > {
1516 let fs = crate :: styles:: FontSizes :: from_base ( self . settings . preferences . font_size ) ;
1617 let dim = iced:: Color :: from_rgb ( 0.55 , 0.57 , 0.62 ) ;
17- let connected = self . status . connected ;
18+ // Gate on "we have a connection", not "the last status poll succeeded":
19+ // the poll can transiently fail on a reachable device, and gating device
20+ // actions on it would wrongly lock the user out.
21+ let connected = self . connection . is_some ( ) ;
1822 const TYPES : [ & str ; 3 ] = [ "1541" , "1571" , "1581" ] ;
1923
2024 // One drive: a type dropdown, a state-aware power toggle, and a reset.
@@ -90,6 +94,16 @@ impl Ultimate64Browser {
9094 }
9195
9296 pub ( crate ) fn view_dual_pane_browser ( & self ) -> Element < ' _ , Message > {
97+ // Game Mode takes over the whole tab — a full-width immersive launcher
98+ // instead of the two file panes.
99+ if self . remote_browser . game . active {
100+ return self
101+ . remote_browser
102+ . game
103+ . view ( self . settings . preferences . font_size )
104+ . map ( |m| Message :: RemoteBrowser ( RemoteBrowserMessage :: Game ( m) ) ) ;
105+ }
106+
93107 // Left pane - Local files
94108 let left_content = container (
95109 self . left_browser
@@ -186,9 +200,23 @@ impl Ultimate64Browser {
186200 // Device-control quick actions — gated on connection so an
187201 // offline click can't fire a hopeless REST request.
188202 button( text( "⏏ Eject A+B" ) . size( small) )
189- . on_press_maybe( self . status . connected . then_some( Message :: EjectAllDrives ) , )
203+ . on_press_maybe( self . connection . is_some ( ) . then_some( Message :: EjectAllDrives ) , )
190204 . padding( [ 4 , 8 ] )
191205 . style( crate :: styles:: nav_button) ,
206+ // Game Mode — full-width EmulationStation-style launcher over
207+ // the folders in the configured game library. Always available:
208+ // local libraries need no device, and a device library shows a
209+ // clear error if it can't be reached.
210+ button( text( "🎮 Games" ) . size( small) )
211+ . on_press( Message :: RemoteBrowser (
212+ crate :: remote_browser:: RemoteBrowserMessage :: Game (
213+ crate :: game_mode:: GameModeMessage :: Toggle (
214+ self . settings. preferences. game_library_roots. clone( ) ,
215+ ) ,
216+ ) ,
217+ ) )
218+ . padding( [ 4 , 8 ] )
219+ . style( crate :: styles:: action_button) ,
192220 // Run last — re-fires the most recent PRG/CRT/SID/disk
193221 // the local browser sent. Greys out when nothing's been
194222 // run yet OR when the device is offline.
@@ -201,7 +229,7 @@ impl Ultimate64Browser {
201229 . size( small) ,
202230 )
203231 . on_press_maybe(
204- ( self . status . connected && self . left_browser. last_run( ) . is_some( ) )
232+ ( self . connection . is_some ( ) && self . left_browser. last_run( ) . is_some( ) )
205233 . then_some( Message :: RunLast ) ,
206234 )
207235 . padding( [ 4 , 8 ] )
0 commit comments