emmental/emmental/sidebar/playlist.py

84 lines
3.4 KiB
Python

# Copyright 2022 (c) Anna Schumaker.
"""Displays user and system playlists."""
import collections
from gi.repository import Gtk
from .. import db
from .. import buttons
from . import row
from . import section
ATTR_NAMES = ["icon_name", "activatable", "modifiable"]
Attrs = collections.namedtuple("Attrs", ATTR_NAMES)
PLAYLIST_ATTRS = {
"Collection": Attrs("library-music", True, False),
"Favorite Tracks": Attrs("heart-filled", True, False),
"Most Played Tracks": Attrs("right-large", True, False),
"New Tracks": Attrs("music-note-single", True, False),
"Previous Tracks": Attrs("media-skip-backward", False, False),
"Queued Tracks": Attrs("music-queue", True, False),
"Unplayed Tracks": Attrs("circle-outline-thick", True, False),
}
FALLBACK_ATTR = Attrs("playlist2", True, True)
class PlaylistRow(row.TreeRow):
"""A factory for making PlaylistRows."""
def __init__(self, *args, **kwargs):
"""Initialize a PlaylistRow."""
super().__init__(*args, indented=False, **kwargs)
self.child = row.PlaylistRow()
def do_bind(self) -> None:
"""Bind a Playlist to this Row."""
super().do_bind()
attr = PLAYLIST_ATTRS.get(self.item.name, FALLBACK_ATTR)
self.listitem.set_activatable(attr.activatable)
self.child.icon_name = f"{attr.icon_name}-symbolic"
self.child.modifiable = attr.modifiable
self.bind_and_set_property("image", "filepath", bidirectional=True)
class Section(section.Section):
"""A sidebar Section for user and system playlists."""
def __init__(self, table: db.playlists.Table):
"""Initialize our playlist section."""
super().__init__(table, PlaylistRow, icon_name="playlist2",
title="Playlists", subtitle="0 playlists")
self._entry = Gtk.Entry(placeholder_text="add new playlist",
primary_icon_name="list-add")
self.extra_widget = buttons.PopoverButton(icon_name="document-new",
tooltip_text=("add new "
"playlist"),
has_frame=False,
popover_child=self._entry)
self._entry.connect("activate", self.__add_new_playlist)
self._entry.connect("changed", self.__entry_changed)
self._entry.connect("icon-release", self.__entry_icon_release)
self._entry.add_css_class("card")
def __add_new_playlist(self, entry: Gtk.Entry) -> None:
if self.table.create(entry.get_text()) is not None:
self.table.sql.commit()
self.extra_widget.popdown()
def __entry_changed(self, entry: Gtk.Entry) -> None:
icon_name = "edit-clear-symbolic" if entry.get_text() != "" else ""
self._entry.set_icon_from_icon_name(Gtk.EntryIconPosition.SECONDARY,
icon_name)
def __entry_icon_release(self, entry: Gtk.Entry,
pos: Gtk.EntryIconPosition) -> None:
if pos == Gtk.EntryIconPosition.PRIMARY:
self.__add_new_playlist(entry)
else:
entry.set_text("")
def do_get_subtitle(self, n_playlists: int) -> str:
"""Return a subtitle for this section."""
s_playlists = "s" if n_playlists != 1 else ""
return f"{n_playlists} playlist{s_playlists}"