[gnome-music/wip/jfelder/repeatmode-player-simplify] player: Bind repeat-mode property the right way



commit 70ef7ae3203cd915a6ce43a1f412fa34027aeb46
Author: Jean Felder <jfelder src gnome org>
Date:   Wed Apr 10 22:11:09 2019 +0200

    player: Bind repeat-mode property the right way
    
    repeat-mode is saved as a gsettings variable. At start-up, its value
    is read by PlayerPlaylist which propagates the change to Player
    through a binding.
    repeat-mode setting can be changed from the PlayerToolbar, an MPRIS
    client or a keyboard shortcut. All these changes are then propagated
    to the Player which also propagates the change to PlayerPlaylist. The
    new setting state is saved by PlayerPlaylist.
    A bidirectional binding between PlayerPlaylist's repeat-mode and
    Player's repeat-mode allows to synchronize the changes.
    
    This behavior is simplified by moving the whole repeat-mode
    logic into the Player object. Thus, the binding can become
    unidirectional.
    This is a first step to solve #225.

 gnomemusic/player.py | 69 ++++++++++++++++++++--------------------------------
 1 file changed, 27 insertions(+), 42 deletions(-)
---
diff --git a/gnomemusic/player.py b/gnomemusic/player.py
index c29e8568..4be9f9d7 100644
--- a/gnomemusic/player.py
+++ b/gnomemusic/player.py
@@ -91,15 +91,13 @@ class PlayerPlaylist(GObject.GObject):
 
     _nb_songs_max = 10
 
+    repeat_mode = GObject.Property(type=int, default=RepeatMode.NONE)
+
     def __repr__(self):
         return '<PlayerPlayList>'
 
     @log
-    def __init__(self, application):
-        """Initialize the player playlist
-
-        :param Gtk.Application application: Application object
-        """
+    def __init__(self):
         super().__init__()
 
         GstPbutils.pb_utils_init()
@@ -111,16 +109,13 @@ class PlayerPlaylist(GObject.GObject):
         self._type = -1
         self._id = -1
 
-        self._settings = application.props.settings
-        self._settings.connect(
-            'changed::repeat', self._on_repeat_setting_changed)
-        self._repeat = self._settings.get_enum('repeat')
-
         self._validation_indexes = None
         self._discoverer = GstPbutils.Discoverer()
         self._discoverer.connect('discovered', self._on_discovered)
         self._discoverer.start()
 
+        self.connect("notify::repeat-mode", self._on_repeat_mode_changed)
+
     @log
     def set_playlist(self, playlist_type, playlist_id, model, model_iter):
         """Set a new playlist or change the song being played
@@ -269,10 +264,6 @@ class PlayerPlaylist(GObject.GObject):
                 index - 1 if index > song_index else index
                 for index in self._shuffle_indexes]
 
-    @log
-    def _on_repeat_setting_changed(self, settings, value):
-        self.props.repeat_mode = settings.get_enum('repeat')
-
     @log
     def _on_discovered(self, discoverer, info, error):
         url = info.get_uri()
@@ -454,34 +445,15 @@ class PlayerPlaylist(GObject.GObject):
         current_item = self._songs[self._current_index]
         return current_item[PlayerField.VALIDATION] != ValidationStatus.FAILED
 
-    @GObject.Property(type=int, default=RepeatMode.NONE)
-    def repeat_mode(self):
-        """Get repeat mode.
-
-        :returns: the repeat mode
-        :rtype: RepeatMode
-        """
-        return self._repeat
-
-    @repeat_mode.setter
-    def repeat_mode(self, mode):
-        """Set repeat mode.
-
-        :param RepeatMode mode: new repeat_mode
-        """
-        if mode == self._repeat:
-            return
-
-        if (mode == RepeatMode.SHUFFLE
+    @log
+    def _on_repeat_mode_changed(self, klass, param):
+        if (self.props.repeat_mode == RepeatMode.SHUFFLE
                 and self._songs):
             self._shuffle_indexes = list(range(len(self._songs)))
             shuffle(self._shuffle_indexes)
             self._shuffle_indexes.remove(self._current_index)
             self._shuffle_indexes.insert(0, self._current_index)
 
-        self._repeat = mode
-        self._settings.set_enum('repeat', mode)
-
     @GObject.Property(type=int, flags=GObject.ParamFlags.READABLE)
     def playlist_id(self):
         """Get playlist unique identifier.
@@ -581,12 +553,17 @@ class Player(GObject.GObject):
         """
         super().__init__()
 
-        self._playlist = PlayerPlaylist(application)
+        self._playlist = PlayerPlaylist()
         self._playlist.connect('song-validated', self._on_song_validated)
-        self._playlist.bind_property(
-            'repeat-mode', self, 'repeat-mode',
-            GObject.BindingFlags.SYNC_CREATE
-            | GObject.BindingFlags.BIDIRECTIONAL)
+
+        self._settings = application.props.settings
+        self._settings.connect(
+            'changed::repeat', self._on_repeat_setting_changed)
+
+        self._repeat = self._settings.get_enum('repeat')
+        self.bind_property(
+            'repeat-mode', self._playlist, 'repeat-mode',
+            GObject.BindingFlags.SYNC_CREATE)
 
         self._new_clock = True
 
@@ -829,13 +806,21 @@ class Player(GObject.GObject):
 
         self.emit('clock-tick', int(position))
 
-    @GObject.Property(type=int)
+    @log
+    def _on_repeat_setting_changed(self, settings, value):
+        self.props.repeat_mode = settings.get_enum('repeat')
+
+    @GObject.Property(type=int, default=RepeatMode.NONE)
     def repeat_mode(self):
         return self._repeat
 
     @repeat_mode.setter
     def repeat_mode(self, mode):
+        if mode == self._repeat:
+            return
+
         self._repeat = mode
+        self._settings.set_enum('repeat', mode)
         self.emit('prev-next-invalidated')
 
     @GObject.Property(


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]