@@ -13,6 +13,7 @@ public class Turntable.Views.Window : Adw.ApplicationWindow {
1313 GLib . SimpleAction cover_scaling_action;
1414 GLib . SimpleAction component_tonearm_action;
1515 GLib . SimpleAction component_center_text_action;
16+ GLib . SimpleAction component_more_controls_action;
1617 public string uuid { get ; private set ; }
1718
1819 ~Window () {
@@ -219,7 +220,7 @@ public class Turntable.Views.Window : Adw.ApplicationWindow {
219220 prog. progress = 0 ;
220221 } else {
221222 #if SCROBBLING
222- if (value == 0 && this . player != null && this . player. looping && _position > 0 ) {
223+ if (value == 0 && this . player != null && this . player. loop_status == Mpris . Entry . LoopStatus . TRACK && _position > 0 ) {
223224 this . length = this . length; // re-trigger it
224225 }
225226 #endif
@@ -251,11 +252,9 @@ public class Turntable.Views.Window : Adw.ApplicationWindow {
251252 public bool playing {
252253 get { return _playing; }
253254 set {
254- _playing = value ;
255+ _playing =
256+ mpris_controls. playing =
255257 art_pic. turntable_playing = value ;
256- button_play. icon_name = value ? " pause-large-symbolic" : " play-large-symbolic" ;
257- // translators: button tooltip text
258- button_play. tooltip_text = value ? _(" Pause" ) : _(" Play" );
259258 #if SCROBBLING
260259 update_scrobbler_playing ();
261260 #endif
@@ -357,10 +356,8 @@ public class Turntable.Views.Window : Adw.ApplicationWindow {
357356 Gtk . Box non_art_box;
358357 Widgets . ProgressBin prog;
359358 Gtk . Box main_box;
360- Gtk . Button button_play;
361- Gtk . Button button_prev;
362- Gtk . Button button_next;
363359 Widgets . ControlsOverlay controls_overlay;
360+ Widgets . MPRISControls mpris_controls;
364361 construct {
365362 this . uuid = GLib . Uuid . string_random ();
366363 this . icon_name = Build . DOMAIN ;
@@ -416,43 +413,14 @@ public class Turntable.Views.Window : Adw.ApplicationWindow {
416413 content = main_box
417414 };
418415
419- var box3 = new Gtk . Box ( Gtk . Orientation . HORIZONTAL , 8 ) {
416+ mpris_controls = new Widgets . MPRISControls ( ) {
420417 hexpand = true ,
421418 vexpand = true ,
422419 halign = Gtk . Align . CENTER ,
423420 valign = Gtk . Align . CENTER ,
424421 };
425- non_art_box. append (box3);
426-
427- button_prev = new Gtk .Button .from_icon_name (is_rtl ? " skip-forward-large-symbolic" : " skip-backward-large-symbolic" ) {
428- css_classes = {" circular" },
429- halign = Gtk . Align . CENTER ,
430- valign = Gtk . Align . CENTER ,
431- // translators: button tooltip text
432- tooltip_text = _ ("Previous Song ")
433- };
434- box3.append (button_prev );
435-
436- button_play = new Gtk .Button .from_icon_name (" play-large-symbolic" ) {
437- css_classes = {" circular" , " large" },
438- halign = Gtk . Align . CENTER ,
439- valign = Gtk . Align . CENTER ,
440- tooltip_text = _ ("Play ")
441- };
442- box3.append (button_play );
443-
444- button_next = new Gtk .Button .from_icon_name (is_rtl ? " skip-backward-large-symbolic" : " skip-forward-large-symbolic" ) {
445- css_classes = {" circular" },
446- halign = Gtk . Align . CENTER ,
447- valign = Gtk . Align . CENTER ,
448- // translators: button tooltip text
449- tooltip_text = _ ("Next Song ")
450- };
451- box3.append (button_next );
452-
453- button_next.clicked.connect (play_next );
454- button_play.clicked.connect (play_pause );
455- button_prev.clicked.connect (play_back );
422+ mpris_controls. commanded. connect (mpris_command_received);
423+ non_art_box. append (mpris_controls);
456424
457425 #if SCROBBLING
458426 var scrobbling_action = new GLib .SimpleAction (" open-scrobbling-setup" , null );
@@ -512,6 +480,10 @@ public class Turntable.Views.Window : Adw.ApplicationWindow {
512480 component_center_text_action. change_state. connect (on_change_component_center_text);
513481 this . add_action (component_center_text_action);
514482
483+ component_more_controls_action = new GLib .SimpleAction .stateful (" component-more-controls" , null , settings. component_more_controls);
484+ component_more_controls_action. change_state. connect (on_change_component_more_controls);
485+ this . add_action (component_more_controls_action);
486+
515487 component_cover_fit_action = new GLib .SimpleAction .stateful (" component-cover-fit" , null , settings. component_cover_fit);
516488 component_cover_fit_action. change_state. connect (on_change_component_cover_fit);
517489 this . add_action (component_cover_fit_action);
@@ -535,6 +507,7 @@ public class Turntable.Views.Window : Adw.ApplicationWindow {
535507 settings. notify[" component-client-icon" ]. connect (update_component_client_icon_from_settings);
536508 settings. notify[" component-tonearm" ]. connect (update_component_tonearm_from_settings);
537509 settings. notify[" component-center-text" ]. connect (update_component_center_text_from_settings);
510+ settings. notify[" component-more-controls" ]. connect (update_component_more_controls_from_settings);
538511 settings. notify[" component-cover-fit" ]. connect (update_component_cover_fit_from_settings);
539512 settings. notify[" meta-dim" ]. connect (update_meta_dim_from_settings);
540513 settings. notify[" text-size" ]. connect (update_text_size_from_settings);
@@ -560,16 +533,34 @@ public class Turntable.Views.Window : Adw.ApplicationWindow {
560533 if (controls_overlay. hide_overlay ()) this . focus_widget = null ;
561534 }
562535
563- private void play_next () {
564- if (this . player != null ) this . player. next ();
565- }
566-
567- private void play_back () {
568- if (this . player != null ) this . player. back ();
569- }
570-
571- private void play_pause () {
572- if (this . player != null ) this . player. play_pause ();
536+ private void mpris_command_received (Widgets .MPRISControls .Command command ) {
537+ if (this . player == null || ! this . player. can_control) return ;
538+
539+ switch (command) {
540+ case PLAY_PAUSE :
541+ this . player. play_pause ();
542+ break ;
543+ case NEXT :
544+ this . player. next ();
545+ break ;
546+ case PREVIOUS :
547+ this . player. back ();
548+ break ;
549+ case SHUFFLE :
550+ this . player. toggle_shuffle ();
551+ break ;
552+ case LOOP_NONE :
553+ this . player. loop_none ();
554+ break ;
555+ case LOOP_PLAYLIST :
556+ this . player. loop_playlist ();
557+ break ;
558+ case LOOP_TRACK :
559+ this . player. loop_track ();
560+ break ;
561+ default:
562+ assert_not_reached ();
563+ }
573564 }
574565
575566 private void on_mapped () {
@@ -609,6 +600,7 @@ public class Turntable.Views.Window : Adw.ApplicationWindow {
609600 update_cover_size_from_settings ();
610601 update_cover_scaling_from_settings ();
611602 update_component_center_text_from_settings ();
603+ update_component_more_controls_from_settings ();
612604 }
613605
614606 private void update_cover_scaling_from_settings () {
@@ -686,6 +678,11 @@ public class Turntable.Views.Window : Adw.ApplicationWindow {
686678 component_center_text_action. set_state (settings. component_center_text);
687679 }
688680
681+ private void update_component_more_controls_from_settings () {
682+ mpris_controls. more_controls = settings. component_more_controls;
683+ component_more_controls_action. set_state (settings. component_more_controls);
684+ }
685+
689686 private void update_component_cover_fit_from_settings () {
690687 this . art_pic. fit_cover = settings. component_cover_fit;
691688 component_cover_fit_action. set_state (settings. component_cover_fit);
@@ -738,9 +735,7 @@ public class Turntable.Views.Window : Adw.ApplicationWindow {
738735 this . length = 0 ;
739736
740737 this . playing =
741- button_next. sensitive =
742- button_prev. sensitive =
743- button_play. sensitive = false ;
738+ mpris_controls. can_control = false ;
744739
745740 return ;
746741 }
@@ -752,14 +747,16 @@ public class Turntable.Views.Window : Adw.ApplicationWindow {
752747 player_bindings + = this . player. bind_property (" position" , this , " position" , GLib . BindingFlags . SYNC_CREATE );
753748 player_bindings + = this . player. bind_property (" length" , this , " length" , GLib . BindingFlags . SYNC_CREATE );
754749 player_bindings + = this . player. bind_property (" playing" , this , " playing" , GLib . BindingFlags . SYNC_CREATE );
755- player_bindings + = this . player. bind_property (" can-go-next" , button_next, " sensitive" , GLib . BindingFlags . SYNC_CREATE );
756- player_bindings + = this . player. bind_property (" can-go-back" , button_prev, " sensitive" , GLib . BindingFlags . SYNC_CREATE );
757- player_bindings + = this . player. bind_property (" can-control" , button_play, " sensitive" , GLib . BindingFlags . SYNC_CREATE );
750+ player_bindings + = this . player. bind_property (" can-go-next" , mpris_controls, " can-go-next" , GLib . BindingFlags . SYNC_CREATE );
751+ player_bindings + = this . player. bind_property (" can-go-back" , mpris_controls, " can-go-back" , GLib . BindingFlags . SYNC_CREATE );
752+ player_bindings + = this . player. bind_property (" can-control" , mpris_controls, " can-control" , GLib . BindingFlags . SYNC_CREATE );
753+ player_bindings + = this . player. bind_property (" shuffle" , mpris_controls, " shuffle" , GLib . BindingFlags . SYNC_CREATE );
754+ player_bindings + = this . player. bind_property (" loop-status" , mpris_controls, " loop-status" , GLib . BindingFlags . SYNC_CREATE );
758755
759756 prog. client_icon = this . player. client_info_icon;
760757 prog. client_name = this . player. client_info_name;
761758
762- button_play . grab_focus ();
759+ mpris_controls . grab_play_focus ();
763760 #if SCROBBLING
764761 update_scrobble_status ();
765762 #endif
@@ -853,6 +850,11 @@ public class Turntable.Views.Window : Adw.ApplicationWindow {
853850 settings. component_center_text = value . get_boolean ();
854851 }
855852
853+ private void on_change_component_more_controls (GLib .SimpleAction action , GLib .Variant ? value ) {
854+ if (value == null ) return ;
855+ settings. component_more_controls = value . get_boolean ();
856+ }
857+
856858 private void on_change_component_cover_fit (GLib .SimpleAction action , GLib .Variant ? value ) {
857859 if (value == null ) return ;
858860 settings. component_cover_fit = value . get_boolean ();
0 commit comments