[gnome-music/wip/jfelder/songwidget-menu-v3: 10/18] Introduce SongWidgetMenu




commit 20e1a2e684ffd29433cfa0835284cbb02ea5c357
Author: Jean Felder <jfelder src gnome org>
Date:   Wed Nov 11 23:05:47 2020 +0100

    Introduce SongWidgetMenu
    
    This widget acts as a menu inserted in a menu button for each
    SongWidget.
    It is only available for PlaylistsView at the moment. The next commits
    will allow to generalize this menu to handle songs from an album.

 data/org.gnome.Music.gresource.xml    |   1 +
 data/ui/SongWidgetMenu.ui             |  48 ++++++++++++++++
 gnomemusic/widgets/playlistswidget.py |   3 +
 gnomemusic/widgets/songwidgetmenu.py  | 100 ++++++++++++++++++++++++++++++++++
 po/POTFILES.in                        |   1 +
 5 files changed, 153 insertions(+)
---
diff --git a/data/org.gnome.Music.gresource.xml b/data/org.gnome.Music.gresource.xml
index 4ef28690c..f534657b9 100644
--- a/data/org.gnome.Music.gresource.xml
+++ b/data/org.gnome.Music.gresource.xml
@@ -36,6 +36,7 @@
     <file preprocess="xml-stripblanks">ui/SelectionToolbar.ui</file>
     <file preprocess="xml-stripblanks">ui/SongsView.ui</file>
     <file preprocess="xml-stripblanks">ui/SongWidget.ui</file>
+    <file preprocess="xml-stripblanks">ui/SongWidgetMenu.ui</file>
     <file preprocess="xml-stripblanks">ui/TwoLineTip.ui</file>
     <file preprocess="xml-stripblanks">ui/Window.ui</file>
   </gresource>
diff --git a/data/ui/SongWidgetMenu.ui b/data/ui/SongWidgetMenu.ui
new file mode 100644
index 000000000..628f50dfd
--- /dev/null
+++ b/data/ui/SongWidgetMenu.ui
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <template class="SongWidgetMenu" parent="GtkPopoverMenu">
+    <property name="modal">True</property>
+    <property name="visible">False</property>
+    <child>
+      <object class="GtkBox">
+        <property name="can-focus">False</property>
+        <property name="margin-bottom">6</property>
+        <property name="margin-end">6</property>
+        <property name="margin-start">6</property>
+        <property name="margin-top">6</property>
+        <property name="orientation">vertical</property>
+        <property name="visible">True</property>
+        <child>
+          <object class="GtkModelButton">
+            <property name="visible">True</property>
+            <property name="text" translatable="yes">Play</property>
+            <signal name="clicked" handler="_on_play_clicked" swapped="no"/>
+            <style>
+              <class name="flat"/>
+            </style>
+          </object>
+        </child>
+        <child>
+          <object class="GtkModelButton">
+            <property name="visible">True</property>
+            <property name="text" translatable="yes">Add to Playlist…</property>
+            <signal name="clicked" handler="_on_add_to_playlist_clicked" swapped="no"/>
+            <style>
+              <class name="flat"/>
+            </style>
+          </object>
+        </child>
+        <child>
+          <object class="GtkModelButton" id="_remove_from_playlist_button">
+            <property name="visible">True</property>
+            <property name="text" translatable="yes">Remove From Playlist</property>
+            <signal name="clicked" handler="_on_remove_from_playlist_clicked" swapped="no"/>
+            <style>
+              <class name="flat"/>
+            </style>
+          </object>
+        </child>
+      </object>
+    </child>
+  </template>
+</interface>
diff --git a/gnomemusic/widgets/playlistswidget.py b/gnomemusic/widgets/playlistswidget.py
index 30bceafc9..e8239052f 100644
--- a/gnomemusic/widgets/playlistswidget.py
+++ b/gnomemusic/widgets/playlistswidget.py
@@ -32,6 +32,7 @@ from gnomemusic.widgets.playlistcontextmenu import PlaylistContextMenu
 from gnomemusic.widgets.playlistcontrols import PlaylistControls  # noqa: F401
 from gnomemusic.widgets.playlistdialog import PlaylistDialog
 from gnomemusic.widgets.songwidget import SongWidget
+from gnomemusic.widgets.songwidgetmenu import SongWidgetMenu
 if typing.TYPE_CHECKING:
     from gnomemusic.application import Application
     from gnomemusic.coresong import CoreSong
@@ -107,6 +108,8 @@ class PlaylistsWidget(Gtk.Box):
         song_widget = SongWidget(coresong, can_dnd, True)
         song_widget.props.selectable = True
         song_widget.props.show_song_number = False
+        song_widget.props.menu = SongWidgetMenu(
+            self._application, song_widget, playlist)
 
         if can_dnd is True:
             song_widget.connect("widget_moved", self._on_song_widget_moved)
diff --git a/gnomemusic/widgets/songwidgetmenu.py b/gnomemusic/widgets/songwidgetmenu.py
new file mode 100644
index 000000000..0bc33dece
--- /dev/null
+++ b/gnomemusic/widgets/songwidgetmenu.py
@@ -0,0 +1,100 @@
+# Copyright 2021 The GNOME Music developers
+#
+# GNOME Music is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# GNOME Music is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with GNOME Music; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# The GNOME Music authors hereby grant permission for non-GPL compatible
+# GStreamer plugins to be used and distributed together with GStreamer
+# and GNOME Music.  This permission is above and beyond the permissions
+# granted by the GPL license by which GNOME Music is covered.  If you
+# modify this code, you may extend this exception to your version of the
+# code, but you are not obligated to do so.  If you do not wish to do so,
+# delete this exception statement from your version.
+
+from __future__ import annotations
+import typing
+
+from gi.repository import Gtk
+
+from gnomemusic.widgets.notificationspopup import PlaylistNotification
+from gnomemusic.widgets.playlistdialog import PlaylistDialog
+if typing.TYPE_CHECKING:
+    from gnomemusic.application import Application
+    from gnomemusic.grilowrappers.grltrackerplaylists import Playlist
+    from gnomemusic.widgets.songwidget import SongWidget
+
+
+@Gtk.Template(resource_path="/org/gnome/Music/ui/SongWidgetMenu.ui")
+class SongWidgetMenu(Gtk.PopoverMenu):
+
+    __gtype_name__ = "SongWidgetMenu"
+
+    _remove_from_playlist_button = Gtk.Template.Child()
+
+    def __init__(
+            self, application: Application, song_widget: SongWidget,
+            playlist: Playlist) -> None:
+        """Menu to interact with the song of a SongWidget.
+
+        :param Application application: The application object
+        :param SongWidget song_widget: The songwidget associated with the menu
+        :param Playlist playlist: The coreobject associated with the
+            menu
+        """
+        super().__init__()
+
+        self._application = application
+        self._coremodel = application.props.coremodel
+        self._player = application.props.player
+        self._window = application.props.window
+
+        self._playlist = playlist
+        self._song_widget = song_widget
+        self._coresong = song_widget.props.coresong
+
+        self._remove_from_playlist_button.props.sensitive = (
+            not playlist.props.is_smart)
+
+    @Gtk.Template.Callback()
+    def _on_play_clicked(self, widget: Gtk.Button) -> None:
+        self.popdown()
+        signal_id = 0
+
+        def _on_playlist_loaded(klass, playlist_type):
+            self._player.play(self._coresong)
+            self._coremodel.disconnect(signal_id)
+
+        signal_id = self._coremodel.connect(
+            "playlist-loaded", _on_playlist_loaded)
+        self._coremodel.props.active_core_object = self._playlist
+
+    @Gtk.Template.Callback()
+    def _on_add_to_playlist_clicked(self, widget: Gtk.Button) -> None:
+        self.popdown()
+        playlist_dialog = PlaylistDialog(self._application)
+        playlist_dialog.props.transient_for = self._window
+        if playlist_dialog.run() == Gtk.ResponseType.ACCEPT:
+            playlist = playlist_dialog.props.selected_playlist
+            playlist.add_songs([self._coresong])
+
+        playlist_dialog.destroy()
+
+    @Gtk.Template.Callback()
+    def _on_remove_from_playlist_clicked(self, widget: Gtk.Button) -> None:
+        self.popdown()
+        position = self._song_widget.get_index()
+        notification = PlaylistNotification(  # noqa: F841
+            self._window.notifications_popup, self._application,
+            PlaylistNotification.Type.SONG, self._playlist, position,
+            self._coresong)
diff --git a/po/POTFILES.in b/po/POTFILES.in
index a880ab386..da339e5e9 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -19,6 +19,7 @@ data/ui/SearchHeaderBar.ui
 data/ui/SearchView.ui
 data/ui/SelectionBarMenuButton.ui
 data/ui/SelectionToolbar.ui
+data/ui/SongWidgetMenu.ui
 gnomemusic/__init__.py
 gnomemusic/application.py
 gnomemusic/grilowrappers/grltrackerplaylists.py


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