@@ -1185,197 +1185,170 @@ impl App {
11851185 let obscured = !self . modals . is_empty ( ) ;
11861186
11871187 Responsive :: new ( move |viewport| {
1188- let content = Container :: new (
1189- Column :: new ( )
1190- . spacing ( 5 )
1188+ let left_controls = DropDown :: new (
1189+ button:: icon ( Icon :: Menu )
1190+ . on_press ( Message :: ShowMenu { show : None } )
1191+ . obscured ( obscured) ,
1192+ Container :: new (
1193+ Column :: new ( )
1194+ . push (
1195+ button:: menu ( Icon :: FolderOpen , lang:: action:: open_playlist ( ) )
1196+ . on_press ( Message :: menu ( Message :: PlaylistSelect { force : false } ) )
1197+ . padding ( 4 ) ,
1198+ )
1199+ . push (
1200+ button:: menu ( Icon :: Save , lang:: action:: save_playlist ( ) )
1201+ . on_press ( Message :: menu ( Message :: PlaylistSave ) )
1202+ . enabled ( self . playlist_dirty && self . playlist_path . is_some ( ) )
1203+ . padding ( 4 ) ,
1204+ )
1205+ . push (
1206+ button:: menu ( Icon :: SaveAs , lang:: action:: save_playlist_as_new_file ( ) )
1207+ . on_press ( Message :: menu ( Message :: PlaylistSaveAs ) )
1208+ . padding ( 4 ) ,
1209+ )
1210+ . push (
1211+ button:: menu ( Icon :: PlaylistRemove , lang:: action:: start_new_playlist ( ) )
1212+ . on_press ( Message :: menu ( Message :: PlaylistReset { force : false } ) )
1213+ . enabled ( self . playlist_dirty || self . playlist_path . is_some ( ) )
1214+ . padding ( 4 ) ,
1215+ )
1216+ . push_maybe ( STEAM_DECK . then ( || {
1217+ button:: menu ( Icon :: LogOut , lang:: action:: exit_app ( ) )
1218+ . on_press ( Message :: menu ( Message :: Exit { force : false } ) )
1219+ . padding ( 4 )
1220+ } ) )
1221+ // .spacing(10)
1222+ . padding ( 4 ) ,
1223+ )
1224+ . class ( style:: Container :: Tooltip ) ,
1225+ self . viewing_menu ,
1226+ )
1227+ . on_dismiss ( Message :: ShowMenu { show : Some ( false ) } ) ;
1228+
1229+ let right_controls = Row :: new ( ) . push (
1230+ button:: icon ( Icon :: Settings )
1231+ . on_press ( Message :: ShowSettings )
1232+ . obscured ( obscured)
1233+ . tooltip_below ( lang:: thing:: settings ( ) ) ,
1234+ ) ;
1235+
1236+ let center_controls = Container :: new (
1237+ Row :: new ( )
11911238 . push (
1192- Stack :: new ( )
1193- . push (
1194- Container :: new (
1195- Row :: new ( ) . push (
1196- button:: icon ( Icon :: Settings )
1197- . on_press ( Message :: ShowSettings )
1198- . obscured ( obscured)
1199- . tooltip_below ( lang:: thing:: settings ( ) ) ,
1200- ) ,
1201- )
1202- . align_right ( Length :: Fill ) ,
1203- )
1204- . push (
1205- Container :: new (
1206- DropDown :: new (
1207- button:: icon ( Icon :: Menu )
1208- . on_press ( Message :: ShowMenu { show : None } )
1209- . obscured ( obscured) ,
1210- Container :: new (
1211- Column :: new ( )
1212- . push (
1213- button:: menu ( Icon :: FolderOpen , lang:: action:: open_playlist ( ) )
1214- . on_press ( Message :: menu ( Message :: PlaylistSelect {
1215- force : false ,
1216- } ) )
1217- . padding ( 4 ) ,
1218- )
1219- . push (
1220- button:: menu ( Icon :: Save , lang:: action:: save_playlist ( ) )
1221- . on_press ( Message :: menu ( Message :: PlaylistSave ) )
1222- . enabled ( self . playlist_dirty && self . playlist_path . is_some ( ) )
1223- . padding ( 4 ) ,
1224- )
1225- . push (
1226- button:: menu (
1227- Icon :: SaveAs ,
1228- lang:: action:: save_playlist_as_new_file ( ) ,
1229- )
1230- . on_press ( Message :: menu ( Message :: PlaylistSaveAs ) )
1231- . padding ( 4 ) ,
1232- )
1233- . push (
1234- button:: menu (
1235- Icon :: PlaylistRemove ,
1236- lang:: action:: start_new_playlist ( ) ,
1237- )
1238- . on_press ( Message :: menu ( Message :: PlaylistReset { force : false } ) )
1239- . enabled ( self . playlist_dirty || self . playlist_path . is_some ( ) )
1240- . padding ( 4 ) ,
1241- )
1242- . push_maybe ( STEAM_DECK . then ( || {
1243- button:: menu ( Icon :: LogOut , lang:: action:: exit_app ( ) )
1244- . on_press ( Message :: menu ( Message :: Exit { force : false } ) )
1245- . padding ( 4 )
1246- } ) )
1247- // .spacing(10)
1248- . padding ( 4 ) ,
1249- )
1250- . class ( style:: Container :: Tooltip ) ,
1251- self . viewing_menu ,
1252- )
1253- . on_dismiss ( Message :: ShowMenu { show : Some ( false ) } ) ,
1254- )
1255- . align_left ( Length :: Fill ) ,
1256- )
1257- . push (
1258- Container :: new (
1259- Container :: new (
1260- Row :: new ( )
1261- . push (
1262- button:: icon ( if self . config . playback . synchronized {
1263- Icon :: Link
1264- } else {
1265- Icon :: Unlink
1266- } )
1267- . on_press ( Message :: SetSynchronized ( !self . config . playback . synchronized ) )
1268- . obscured ( obscured)
1269- . tooltip_below (
1270- if self . config . playback . synchronized {
1271- lang:: action:: desynchronize ( )
1272- } else {
1273- lang:: action:: synchronize ( )
1274- } ,
1275- ) ,
1276- )
1277- . push (
1278- button:: icon ( if self . config . playback . muted {
1279- Icon :: Mute
1280- } else {
1281- Icon :: VolumeHigh
1282- } )
1283- . on_press ( Message :: SetMute ( !self . config . playback . muted ) )
1284- . obscured ( obscured)
1285- . tooltip_below (
1286- if self . config . playback . muted {
1287- lang:: action:: unmute ( )
1288- } else {
1289- lang:: action:: mute ( )
1290- } ,
1291- ) ,
1292- )
1293- . push (
1294- button:: icon ( if self . config . playback . paused {
1295- Icon :: Play
1296- } else {
1297- Icon :: Pause
1298- } )
1299- . on_press ( Message :: SetPause ( !self . config . playback . paused ) )
1300- . obscured ( obscured)
1301- . tooltip_below (
1302- if self . config . playback . paused {
1303- lang:: action:: play ( )
1304- } else {
1305- lang:: action:: pause ( )
1306- } ,
1307- ) ,
1308- )
1309- . push (
1310- button:: icon ( Icon :: TimerRefresh )
1311- . on_press ( Message :: AllPlayers {
1312- event : player:: Event :: SeekRandom ,
1313- } )
1314- . enabled ( !self . all_idle ( ) && self . can_jump ( ) )
1315- . obscured ( obscured)
1316- . tooltip_below ( lang:: action:: jump_position ( ) ) ,
1317- )
1318- . push (
1319- button:: icon ( Icon :: Refresh )
1320- . on_press ( Message :: Refresh )
1321- . enabled ( !self . all_idle ( ) )
1322- . obscured ( obscured)
1323- . tooltip_below ( lang:: action:: shuffle ( ) ) ,
1324- ) ,
1325- )
1326- . class ( style:: Container :: Player ) ,
1327- )
1328- . center ( Length :: Fill ) ,
1329- ) ,
1239+ button:: icon ( if self . config . playback . synchronized {
1240+ Icon :: Link
1241+ } else {
1242+ Icon :: Unlink
1243+ } )
1244+ . on_press ( Message :: SetSynchronized ( !self . config . playback . synchronized ) )
1245+ . obscured ( obscured)
1246+ . tooltip_below ( if self . config . playback . synchronized {
1247+ lang:: action:: desynchronize ( )
1248+ } else {
1249+ lang:: action:: synchronize ( )
1250+ } ) ,
13301251 )
13311252 . push (
1332- PaneGrid :: new ( & self . grids , |grid_id, grid, _maximized| {
1333- pane_grid:: Content :: new (
1334- Container :: new ( grid. view ( grid_id, obscured, dragging_file) )
1335- . padding ( 5 )
1336- . class ( style:: Container :: PlayerGroup ) ,
1337- )
1338- . title_bar ( {
1339- let mut bar = pane_grid:: TitleBar :: new ( " " )
1340- . class ( style:: Container :: PlayerGroupTitle )
1341- . controls ( pane_grid:: Controls :: dynamic (
1342- grid. controls ( grid_id, obscured, self . grids . len ( ) > 1 ) ,
1343- DropDown :: new (
1344- button:: mini_icon ( Icon :: MoreVert )
1345- . on_press ( Message :: Pane {
1346- event : PaneEvent :: ShowControls { grid_id } ,
1347- } )
1348- . obscured ( obscured) ,
1349- Container :: new ( grid. controls ( grid_id, obscured, self . grids . len ( ) > 1 ) )
1350- . class ( style:: Container :: PlayerGroupControls ) ,
1351- self . viewing_pane_controls . is_some_and ( |x| x == grid_id) ,
1352- )
1353- . on_dismiss ( Message :: Pane {
1354- event : PaneEvent :: CloseControls ,
1355- } ) ,
1356- ) ) ;
1357-
1358- if grid. is_idle ( ) {
1359- bar = bar. always_show_controls ( ) ;
1360- }
1361-
1362- bar
1363- } )
1253+ button:: icon ( if self . config . playback . muted {
1254+ Icon :: Mute
1255+ } else {
1256+ Icon :: VolumeHigh
13641257 } )
1365- . spacing ( 5 )
1366- . on_drag ( |event| Message :: Pane {
1367- event : PaneEvent :: Drag ( event) ,
1258+ . on_press ( Message :: SetMute ( !self . config . playback . muted ) )
1259+ . obscured ( obscured)
1260+ . tooltip_below ( if self . config . playback . muted {
1261+ lang:: action:: unmute ( )
1262+ } else {
1263+ lang:: action:: mute ( )
1264+ } ) ,
1265+ )
1266+ . push (
1267+ button:: icon ( if self . config . playback . paused {
1268+ Icon :: Play
1269+ } else {
1270+ Icon :: Pause
13681271 } )
1369- . on_resize ( 5 , |event| Message :: Pane {
1370- event : PaneEvent :: Resize ( event) ,
1272+ . on_press ( Message :: SetPause ( !self . config . playback . paused ) )
1273+ . obscured ( obscured)
1274+ . tooltip_below ( if self . config . playback . paused {
1275+ lang:: action:: play ( )
1276+ } else {
1277+ lang:: action:: pause ( )
13711278 } ) ,
1279+ )
1280+ . push (
1281+ button:: icon ( Icon :: TimerRefresh )
1282+ . on_press ( Message :: AllPlayers {
1283+ event : player:: Event :: SeekRandom ,
1284+ } )
1285+ . enabled ( !self . all_idle ( ) && self . can_jump ( ) )
1286+ . obscured ( obscured)
1287+ . tooltip_below ( lang:: action:: jump_position ( ) ) ,
1288+ )
1289+ . push (
1290+ button:: icon ( Icon :: Refresh )
1291+ . on_press ( Message :: Refresh )
1292+ . enabled ( !self . all_idle ( ) )
1293+ . obscured ( obscured)
1294+ . tooltip_below ( lang:: action:: shuffle ( ) ) ,
13721295 ) ,
1373- ) ;
1296+ )
1297+ . class ( style:: Container :: Player ) ;
1298+
1299+ let controls = Stack :: new ( )
1300+ . push ( Container :: new ( left_controls) . align_left ( Length :: Fill ) )
1301+ . push ( Container :: new ( right_controls) . align_right ( Length :: Fill ) )
1302+ . push ( Container :: new ( center_controls) . center ( Length :: Fill ) ) ;
1303+
1304+ let grids = PaneGrid :: new ( & self . grids , |grid_id, grid, _maximized| {
1305+ pane_grid:: Content :: new (
1306+ Container :: new ( grid. view ( grid_id, obscured, dragging_file) )
1307+ . padding ( 5 )
1308+ . class ( style:: Container :: PlayerGroup ) ,
1309+ )
1310+ . title_bar ( {
1311+ let mut bar = pane_grid:: TitleBar :: new ( " " )
1312+ . class ( style:: Container :: PlayerGroupTitle )
1313+ . controls ( pane_grid:: Controls :: dynamic (
1314+ grid. controls ( grid_id, obscured, self . grids . len ( ) > 1 ) ,
1315+ DropDown :: new (
1316+ button:: mini_icon ( Icon :: MoreVert )
1317+ . on_press ( Message :: Pane {
1318+ event : PaneEvent :: ShowControls { grid_id } ,
1319+ } )
1320+ . obscured ( obscured) ,
1321+ Container :: new ( grid. controls ( grid_id, obscured, self . grids . len ( ) > 1 ) )
1322+ . class ( style:: Container :: PlayerGroupControls ) ,
1323+ self . viewing_pane_controls . is_some_and ( |x| x == grid_id) ,
1324+ )
1325+ . on_dismiss ( Message :: Pane {
1326+ event : PaneEvent :: CloseControls ,
1327+ } ) ,
1328+ ) ) ;
1329+
1330+ if grid. is_idle ( ) {
1331+ bar = bar. always_show_controls ( ) ;
1332+ }
1333+
1334+ bar
1335+ } )
1336+ } )
1337+ . spacing ( 5 )
1338+ . on_drag ( |event| Message :: Pane {
1339+ event : PaneEvent :: Drag ( event) ,
1340+ } )
1341+ . on_resize ( 5 , |event| Message :: Pane {
1342+ event : PaneEvent :: Resize ( event) ,
1343+ } ) ;
1344+
1345+ let content =
1346+ Container :: new ( Column :: new ( ) . spacing ( 5 ) . push ( controls) . push ( grids) ) . class ( style:: Container :: Primary ) ;
13741347
13751348 let stack = Stack :: new ( )
13761349 . width ( Length :: Fill )
13771350 . height ( Length :: Fill )
1378- . push ( content. class ( style :: Container :: Primary ) )
1351+ . push ( content)
13791352 . push_maybe ( self . modals . last ( ) . map ( |modal| {
13801353 modal. view (
13811354 viewport,
0 commit comments