@@ -291,63 +291,46 @@ impl App {
291291 }
292292 }
293293
294- fn generate_player_event_in_selection < T > (
294+ fn generate_event_in_selection (
295295 & mut self ,
296- message : impl FnOnce ( T ) -> player:: Event ,
297- from_app : impl FnOnce ( & mut Self ) -> T ,
298- from_grid : impl FnOnce ( & Grid ) -> T ,
299- from_player : impl FnOnce ( & Player ) -> T ,
300- ) {
296+ from_app : impl FnOnce ( & Self ) -> Option < Message > ,
297+ from_grid : impl FnOnce ( grid:: Id , & Grid ) -> Option < PaneEvent > ,
298+ from_player : impl FnOnce ( & Player ) -> Option < player:: Event > ,
299+ ) -> Task < Message > {
300+ self . generate_event_in_selection_maybe ( from_app, from_grid, from_player)
301+ . unwrap_or_else ( Task :: none)
302+ }
303+
304+ fn generate_event_in_selection_maybe (
305+ & mut self ,
306+ from_app : impl FnOnce ( & Self ) -> Option < Message > ,
307+ from_grid : impl FnOnce ( grid:: Id , & Grid ) -> Option < PaneEvent > ,
308+ from_player : impl FnOnce ( & Player ) -> Option < player:: Event > ,
309+ ) -> Option < Task < Message > > {
301310 match self . selection . pair ( ) {
302311 Some ( ( grid_id, player_id) ) => {
303- if let Some ( grid) = self . grids . get_mut ( grid_id) {
304- match player_id {
305- Some ( player_id) => {
306- if let Some ( value) = grid. player ( player_id) . map ( from_player) {
307- let update = grid. update_player (
308- player_id,
309- message ( value) ,
310- & mut self . media ,
311- & self . config . playback ,
312- ) ;
313- if let Some ( update) = update {
314- self . handle_grid_update ( update, grid_id) ;
315- }
316- }
317- }
318- None => {
319- let event = message ( from_grid ( grid) ) ;
320- grid. update_all_players ( event. clone ( ) , & mut self . media , & self . config . playback ) ;
321- self . synchronize_players ( grid_id, None , event) ;
322- }
312+ let grid = self . grids . get_mut ( grid_id) ?;
313+ match player_id {
314+ Some ( player_id) => {
315+ let player = grid. player ( player_id) ?;
316+ let event = from_player ( player) ?;
317+ Some ( self . update ( Message :: Player {
318+ grid_id,
319+ player_id,
320+ event,
321+ } ) )
322+ }
323+ None => {
324+ let event = from_grid ( grid_id, grid) ?;
325+ Some ( self . update ( Message :: Pane { event } ) )
323326 }
324327 }
325328 }
326- None => match message ( from_app ( self ) ) {
327- player:: Event :: SetPause ( paused) => {
328- self . set_paused ( paused) ;
329- }
330- player:: Event :: SetLoop ( _) => { }
331- player:: Event :: SetMute ( muted) => {
332- self . set_muted ( muted) ;
333- }
334- player:: Event :: SetVolume ( _) => { }
335- player:: Event :: Seek ( _) => { }
336- player:: Event :: SeekRelative ( _) => { }
337- player:: Event :: SeekStop => { }
338- player:: Event :: SeekRandom => { }
339- player:: Event :: EndOfStream => { }
340- player:: Event :: NewFrame => { }
341- player:: Event :: MouseEnter => { }
342- player:: Event :: MouseExit => { }
343- player:: Event :: Refresh => { }
344- player:: Event :: Close => { }
345- player:: Event :: WindowFocused => { }
346- player:: Event :: WindowUnfocused => { }
347- } ,
329+ None => {
330+ let message = from_app ( self ) ?;
331+ Some ( self . update ( message) )
332+ }
348333 }
349-
350- self . update_playback ( ) ;
351334 }
352335
353336 fn set_muted ( & mut self , muted : bool ) {
@@ -567,12 +550,27 @@ impl App {
567550 let mut out = vec ! [ ] ;
568551
569552 for ( grid_id, grid) in self . grids . iter ( ) {
570- out. push ( ( * grid_id, None ) ) ;
571553 let player_ids = grid. player_ids ( ) ;
572- if player_ids. len ( ) > 1 {
573- for player_id in player_ids {
574- out. push ( ( * grid_id, Some ( player_id) ) ) ;
554+ if player_ids. len ( ) != 1 {
555+ out. push ( ( * grid_id, None ) ) ;
556+ }
557+ for player_id in player_ids {
558+ out. push ( ( * grid_id, Some ( player_id) ) ) ;
559+ }
560+ }
561+
562+ out
563+ }
564+
565+ fn selectables_in_grid ( & self ) -> Vec < ( grid:: Id , player:: Id ) > {
566+ let mut out = vec ! [ ] ;
567+
568+ for ( grid_id, grid) in self . grids . iter ( ) {
569+ if self . selection . is_grid_selected ( * grid_id) {
570+ for player_id in grid. player_ids ( ) {
571+ out. push ( ( * grid_id, player_id) ) ;
575572 }
573+ break ;
576574 }
577575 }
578576
@@ -594,6 +592,7 @@ impl App {
594592 grid:: Update :: PlayerClosed => {
595593 self . playlist_dirty = true ;
596594 self . update_playback ( ) ;
595+ self . selection . ensure_valid_in_grid ( self . selectables_in_grid ( ) ) ;
597596
598597 if let Some ( grid) = self . grids . get ( grid_id) {
599598 if grid. is_idle ( ) {
@@ -779,7 +778,7 @@ impl App {
779778 Task :: none ( )
780779 }
781780 Message :: KeyboardEvent ( event) => {
782- use iced:: keyboard:: { self , key, Key } ;
781+ use iced:: keyboard:: { self , key, Key , Modifiers } ;
783782
784783 match event {
785784 keyboard:: Event :: KeyPressed { key, modifiers, .. } => match key {
@@ -801,36 +800,88 @@ impl App {
801800 } else if !self . dragged_files . is_empty ( ) {
802801 self . dragged_files . clear ( ) ;
803802 } else if self . selection . is_any_selected ( ) {
804- self . selection . deselect ( ) ;
803+ self . selection . clear ( ) ;
805804 }
806805 Task :: none ( )
807806 }
808807 Key :: Named ( key:: Named :: Space ) => {
809808 if self . modals . is_empty ( ) {
810- self . generate_player_event_in_selection (
811- player:: Event :: SetPause ,
812- |app| !app. config . playback . paused ,
813- |grid| !grid. all_paused ( ) . unwrap_or_default ( ) ,
814- |player| !player. is_paused ( ) . unwrap_or_default ( ) ,
815- ) ;
809+ self . generate_event_in_selection (
810+ |app| Some ( Message :: SetPause ( !app. config . playback . paused ) ) ,
811+ |grid_id, grid| {
812+ Some ( PaneEvent :: SetPause {
813+ grid_id,
814+ paused : !grid. all_paused ( ) . unwrap_or_default ( ) ,
815+ } )
816+ } ,
817+ |player| Some ( player:: Event :: SetPause ( !player. is_paused ( ) . unwrap_or_default ( ) ) ) ,
818+ )
819+ } else {
820+ Task :: none ( )
821+ }
822+ }
823+ Key :: Named ( key:: Named :: Backspace | key:: Named :: Delete ) => {
824+ if self . modals . is_empty ( ) {
825+ self . generate_event_in_selection (
826+ |_| None ,
827+ |grid_id, _| Some ( PaneEvent :: Close { grid_id } ) ,
828+ |_| Some ( player:: Event :: Close ) ,
829+ )
830+ } else {
831+ Task :: none ( )
816832 }
817- Task :: none ( )
818833 }
819834 Key :: Character ( c) => {
835+ let command = modifiers == Modifiers :: COMMAND ;
836+ let command_shift = modifiers == Modifiers :: COMMAND | Modifiers :: SHIFT ;
837+
820838 if self . modals . is_empty ( ) {
821839 match c. as_str ( ) {
822- "M" | "m" => {
823- self . generate_player_event_in_selection (
824- player:: Event :: SetMute ,
825- |app| !app. config . playback . muted ,
826- |grid| !grid. all_muted ( ) . unwrap_or_default ( ) ,
827- |player| !player. is_muted ( ) . unwrap_or_default ( ) ,
828- ) ;
840+ "J" | "j" => self . generate_event_in_selection (
841+ |_| {
842+ Some ( Message :: AllPlayers {
843+ event : player:: Event :: SeekRandom ,
844+ } )
845+ } ,
846+ |grid_id, _| Some ( PaneEvent :: SeekRandom { grid_id } ) ,
847+ |_| Some ( player:: Event :: SeekRandom ) ,
848+ ) ,
849+ "L" | "l" => {
850+ self . update ( Message :: SetSynchronized ( !self . config . playback . synchronized ) )
829851 }
830- _ => { }
852+ "M" | "m" => self . generate_event_in_selection (
853+ |app| Some ( Message :: SetMute ( !app. config . playback . muted ) ) ,
854+ |grid_id, grid| {
855+ Some ( PaneEvent :: SetMute {
856+ grid_id,
857+ muted : !grid. all_muted ( ) . unwrap_or_default ( ) ,
858+ } )
859+ } ,
860+ |player| Some ( player:: Event :: SetMute ( !player. is_muted ( ) . unwrap_or_default ( ) ) ) ,
861+ ) ,
862+ "N" | "n" if modifiers. is_empty ( ) => {
863+ if let Some ( ( grid_id, _) ) = self . selection . pair ( ) {
864+ self . update ( Message :: Pane {
865+ event : PaneEvent :: AddPlayer { grid_id } ,
866+ } )
867+ } else {
868+ Task :: none ( )
869+ }
870+ }
871+ "N" | "n" if command => self . update ( Message :: PlaylistReset { force : false } ) ,
872+ "O" | "o" if command => self . update ( Message :: PlaylistSelect { force : false } ) ,
873+ "R" | "r" => self . generate_event_in_selection (
874+ |_| Some ( Message :: Refresh ) ,
875+ |grid_id, _| Some ( PaneEvent :: Refresh { grid_id } ) ,
876+ |_| Some ( player:: Event :: Refresh ) ,
877+ ) ,
878+ "S" | "s" if command => self . update ( Message :: PlaylistSave ) ,
879+ "S" | "s" if command_shift => self . update ( Message :: PlaylistSaveAs ) ,
880+ _ => Task :: none ( ) ,
831881 }
882+ } else {
883+ Task :: none ( )
832884 }
833- Task :: none ( )
834885 }
835886 _ => Task :: none ( ) ,
836887 } ,
@@ -1071,6 +1122,7 @@ impl App {
10711122 self . playlist_dirty = true ;
10721123 self . grids . close ( grid_id) ;
10731124 self . update_playback ( ) ;
1125+ self . selection . clear ( ) ;
10741126 }
10751127 PaneEvent :: AddPlayer { grid_id } => {
10761128 self . playlist_dirty = true ;
@@ -1410,16 +1462,17 @@ impl App {
14101462 . push ( Container :: new ( center_controls) . center ( Length :: Fill ) ) ;
14111463
14121464 let grids = PaneGrid :: new ( & self . grids , |grid_id, grid, _maximized| {
1465+ let selected = self . selection . is_grid_only_selected ( grid_id) ;
14131466 pane_grid:: Content :: new (
14141467 Container :: new ( grid. view (
14151468 grid_id,
1416- self . selection . is_grid_selected ( grid_id ) ,
1469+ selected ,
14171470 self . selection . player_for_grid ( grid_id) ,
14181471 obscured,
14191472 dragging_file,
14201473 ) )
14211474 . padding ( 5 )
1422- . class ( style:: Container :: PlayerGroup ) ,
1475+ . class ( style:: Container :: PlayerGroup { selected } ) ,
14231476 )
14241477 . title_bar ( {
14251478 let mut bar = pane_grid:: TitleBar :: new ( " " )
0 commit comments