[gnome-music/wip/jfelder/playlistsview-template: 11/13] playlistsview: Port to template



commit 850527a367b4fce825b6104682fda52702c5adc1
Author: Jean Felder <jfelder src gnome org>
Date:   Thu Sep 12 16:52:55 2019 +0200

    playlistsview: Port to template
    
    With this change, PlaylistsView does inherite from BaseView anymore.

 data/org.gnome.Music.gresource.xml     |  1 +
 data/ui/PlaylistControls.ui            |  1 +
 data/ui/PlaylistsView.ui               | 63 ++++++++++++++++++++++++++++++++++
 gnomemusic/views/baseview.py           |  3 +-
 gnomemusic/views/playlistsview.py      | 61 ++++++++++----------------------
 gnomemusic/widgets/playlistcontrols.py | 40 ++++++++++++++++-----
 6 files changed, 115 insertions(+), 54 deletions(-)
---
diff --git a/data/org.gnome.Music.gresource.xml b/data/org.gnome.Music.gresource.xml
index 0132a33b..3a0aca4f 100644
--- a/data/org.gnome.Music.gresource.xml
+++ b/data/org.gnome.Music.gresource.xml
@@ -22,6 +22,7 @@
     <file preprocess="xml-stripblanks">ui/PlaylistControls.ui</file>
     <file preprocess="xml-stripblanks">ui/PlaylistDialog.ui</file>
     <file preprocess="xml-stripblanks">ui/PlaylistDialogRow.ui</file>
+    <file preprocess="xml-stripblanks">ui/PlaylistsView.ui</file>
     <file preprocess="xml-stripblanks">ui/PlaylistTile.ui</file>
     <file preprocess="xml-stripblanks">ui/SearchHeaderBar.ui</file>
     <file preprocess="xml-stripblanks">ui/SearchView.ui</file>
diff --git a/data/ui/PlaylistControls.ui b/data/ui/PlaylistControls.ui
index 4f4c0e3d..d0db94b0 100644
--- a/data/ui/PlaylistControls.ui
+++ b/data/ui/PlaylistControls.ui
@@ -31,6 +31,7 @@
     <property name="margin_bottom">18</property>
     <child>
       <object class="GtkStack" id="_name_stack">
+        <property name="visible">True</property>
         <child>
           <object class="GtkLabel" id="_name_label">
             <property name="visible">True</property>
diff --git a/data/ui/PlaylistsView.ui b/data/ui/PlaylistsView.ui
new file mode 100644
index 00000000..9842e42f
--- /dev/null
+++ b/data/ui/PlaylistsView.ui
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <requires lib="gtk+" version="3.18"/>
+  <template class="PlaylistsView" parent="GtkStack">
+    <property name="visible">True</property>
+    <child>
+      <object class="GtkBox" id="main_container">
+        <property name="visible">True</property>
+        <child>
+          <object class="GtkScrolledWindow" id="all_playlists">
+            <property name="visible">True</property>
+            <property name="width-request">220</property>
+            <style>
+              <class name="sidebar"/>
+            </style>
+            <child>
+              <object class="GtkListBox" id="_sidebar">
+                <property name="selection-mode">single</property>
+                <property name="visible">True</property>
+                <signal name="row-activated" handler="_on_playlist_activated" swapped="no"/>
+              </object>
+            </child>
+          </object>
+        </child>
+        <child>
+          <object class="GtkBox" id="main_view_container">
+            <property name="orientation">vertical</property>
+            <property name="visible">True</property>
+            <child>
+              <object class="PlaylistControls" id="_pl_ctrls">
+                <property name="visible">True</property>
+              </object>
+            </child>
+            <child>
+              <object class="GtkScrolledWindow" id="playlist-container">
+                <property name="vexpand">True</property>
+                <property name="visible">True</property>
+                <child>
+                  <object class="GtkListBox" id="_view">
+                    <property name="margin-left">80</property>
+                    <property name="margin-right">80</property>
+                    <property name="margin-top">20</property>
+                    <property name="valign">start</property>
+                    <property name="visible">True</property>
+                    <style>
+                      <class name="songs-list"/>
+                    </style>
+                  </object>
+                </child>
+              </object>
+            </child>
+          </object>
+        </child>
+      </object>
+    </child>
+  </template>
+  <object class="GtkGestureMultiPress" id="_view_ctrlr">
+    <property name="widget">_view</property>
+    <property name="propagation_phase">capture</property>
+    <property name="button">3</property>
+    <signal name="pressed" handler="_on_view_right_clicked" swapped="no"/>
+  </object>
+</interface>
diff --git a/gnomemusic/views/baseview.py b/gnomemusic/views/baseview.py
index 0323c42e..4b0ad0cc 100644
--- a/gnomemusic/views/baseview.py
+++ b/gnomemusic/views/baseview.py
@@ -63,8 +63,7 @@ class BaseView(Gtk.Stack):
             "selection-mode", self._window, "selection-mode",
             GObject.BindingFlags.BIDIRECTIONAL)
 
-        self._selection_mode_id = self.connect(
-            "notify::selection-mode", self._on_selection_mode_changed)
+        self.connect("notify::selection-mode", self._on_selection_mode_changed)
 
     def _setup_view(self):
         """Instantiate and set up the view object"""
diff --git a/gnomemusic/views/playlistsview.py b/gnomemusic/views/playlistsview.py
index 0c695a48..80f5d246 100644
--- a/gnomemusic/views/playlistsview.py
+++ b/gnomemusic/views/playlistsview.py
@@ -27,30 +27,36 @@ from gettext import gettext as _
 from gi.repository import Gdk, GObject, Gtk
 
 from gnomemusic.player import PlayerPlaylist
-from gnomemusic.views.baseview import BaseView
 from gnomemusic.widgets.playlistcontextmenu import PlaylistContextMenu
-from gnomemusic.widgets.playlistcontrols import PlaylistControls
+from gnomemusic.widgets.playlistcontrols import PlaylistControls  # noqa: F401
 from gnomemusic.widgets.playlistdialog import PlaylistDialog
 from gnomemusic.widgets.notificationspopup import PlaylistNotification
 from gnomemusic.widgets.playlisttile import PlaylistTile
 from gnomemusic.widgets.songwidget import SongWidget
 
 
-class PlaylistsView(BaseView):
+@Gtk.Template(resource_path="/org/gnome/Music/ui/PlaylistsView.ui")
+class PlaylistsView(Gtk.Stack):
     """Main view for playlists"""
 
+    __gtype_name__ = "PlaylistsView"
+
+    _pl_ctrls = Gtk.Template.Child()
+    _sidebar = Gtk.Template.Child()
+    _view = Gtk.Template.Child()
+    _view_ctrlr = Gtk.Template.Child()
+
     def __init__(self, application, player):
         """Initialize
 
         :param GtkApplication window: The application object
         :param player: The main player object
         """
-        self._sidebar = Gtk.ListBox()
-        sidebar_container = Gtk.ScrolledWindow()
-        sidebar_container.add(self._sidebar)
+        super().__init__(transition_type=Gtk.StackTransitionType.CROSSFADE)
 
-        super().__init__(
-            'playlists', _("Playlists"), application, sidebar_container)
+        # FIXME: Make these properties.
+        self.name = "playlists"
+        self.title = _("Playlists")
 
         self._coremodel = application.props.coremodel
         self._model = self._coremodel.props.playlists_sort
@@ -63,6 +69,8 @@ class PlaylistsView(BaseView):
 
         self._song_popover = PlaylistContextMenu(application, self._view)
 
+        self._pl_ctrls.props.application = application
+
         play_song = self._window.lookup_action("play_song")
         play_song.connect("activate", self._play_song)
 
@@ -73,21 +81,9 @@ class PlaylistsView(BaseView):
         self._remove_song_action.connect(
             "activate", self._stage_song_for_deletion)
 
-        self._pl_ctrls = PlaylistControls(application)
-        self._grid.insert_row(0)
-        self._grid.attach(self._pl_ctrls, 1, 0, 1, 1)
-
         playlist_play_action = self._window.lookup_action("playlist_play")
         playlist_play_action.connect("activate", self._on_play_playlist)
 
-        sidebar_container.set_size_request(220, -1)
-        sidebar_container.get_style_context().add_class('sidebar')
-        self._sidebar.set_selection_mode(Gtk.SelectionMode.SINGLE)
-        self._sidebar.connect('row-activated', self._on_playlist_activated)
-
-        self._grid.child_set_property(sidebar_container, 'top-attach', 0)
-        self._grid.child_set_property(sidebar_container, 'height', 2)
-
         self._sidebar.bind_model(self._model, self._add_playlist_to_sidebar)
 
         self._coremodel.connect(
@@ -96,29 +92,6 @@ class PlaylistsView(BaseView):
         self._model.connect("items-changed", self._on_playlists_model_changed)
         self._on_playlists_model_changed(self._model, 0, 0, 0)
 
-        # Selection is only possible from the context menu
-        self.disconnect(self._selection_mode_id)
-
-        self.show_all()
-
-    def _setup_view(self):
-        view_container = Gtk.ScrolledWindow(hexpand=True, vexpand=True)
-        self._box.pack_start(view_container, True, True, 0)
-
-        self._view = Gtk.ListBox()
-        self._view.get_style_context().add_class("songs-list")
-        self._view.props.margin_top = 20
-        self._view.props.margin_left = 80
-        self._view.props.margin_right = 80
-        self._view.props.valign = Gtk.Align.START
-
-        self._controller = Gtk.GestureMultiPress().new(self._view)
-        self._controller.props.propagation_phase = Gtk.PropagationPhase.CAPTURE
-        self._controller.props.button = Gdk.BUTTON_SECONDARY
-        self._controller.connect("pressed", self._on_view_right_clicked)
-
-        view_container.add(self._view)
-
     def _add_playlist_to_sidebar(self, playlist):
         """Add a playlist to sidebar
 
@@ -147,6 +120,7 @@ class PlaylistsView(BaseView):
             self._sidebar.select_row(row_next)
             self._on_playlist_activated(self._sidebar, row_next, True)
 
+    @Gtk.Template.Callback()
     def _on_view_right_clicked(self, gesture, n_press, x, y):
         requested_row = self._view.get_row_at_y(y)
         self._view.select_row(requested_row)
@@ -194,6 +168,7 @@ class PlaylistsView(BaseView):
             PlaylistNotification.Type.SONG, selected_playlist, position,
             coresong)
 
+    @Gtk.Template.Callback()
     def _on_playlist_activated(self, sidebar, row, untouched=False):
         """Update view with content from selected playlist"""
         if untouched is False:
diff --git a/gnomemusic/widgets/playlistcontrols.py b/gnomemusic/widgets/playlistcontrols.py
index 8ff91d3a..f3a9bb81 100644
--- a/gnomemusic/widgets/playlistcontrols.py
+++ b/gnomemusic/widgets/playlistcontrols.py
@@ -42,28 +42,50 @@ class PlaylistControls(Gtk.Grid):
     _rename_done_button = Gtk.Template.Child()
     _songs_count_label = Gtk.Template.Child()
 
-    def __init__(self, application):
-        """Initialize
-
-        :param GtkApplication application: The application object
-        """
+    def __init__(self):
         super().__init__()
 
+        self._application = None
+
         self._playlist = None
         self._count_id = 0
         self._binding_count = None
-        self._coremodel = application.props.coremodel
-        self._window = application.props.window
 
         self._delete_action = Gio.SimpleAction.new("playlist_delete", None)
         self._delete_action.connect("activate", self._on_delete_action)
-        self._window.add_action(self._delete_action)
 
         self._play_action = Gio.SimpleAction.new("playlist_play", None)
-        self._window.add_action(self._play_action)
 
         self._rename_action = Gio.SimpleAction.new("playlist_rename", None)
         self._rename_action.connect("activate", self._on_rename_action)
+
+    # FIXME: This is a workaround for not being able to pass the application
+    # object via init when using Gtk.Builder.
+    @GObject.Property(default=None)
+    def application(self):
+        """The Application object used
+
+        :return: application object
+        :rtype: Application
+        """
+        return self._application
+
+    @application.setter
+    def application(self, application):
+        """Set the Application object used
+
+        :param Application application: The Application to use
+        """
+        if (application is None
+                or (self._application is not None
+                    and self._player != application)):
+            return
+
+        self._coremodel = application.props.coremodel
+        self._window = application.props.window
+
+        self._window.add_action(self._delete_action)
+        self._window.add_action(self._play_action)
         self._window.add_action(self._rename_action)
 
     def _on_rename_action(self, menuitem, data=None):


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