# Copyright 2021 (c) Anna Schumaker. import audio from gi.repository import Gtk from gi.repository import Pango from . import widgets BoldAttr = Pango.AttrList.new() BoldAttr.insert(Pango.attr_weight_new(Pango.Weight.BOLD)) class Label(Gtk.Label): def __init__(self): Gtk.Label.__init__(self) self.set_ellipsize(Pango.EllipsizeMode.MIDDLE) self.set_halign(Gtk.Align.START) self.set_hexpand(True) def set_bold(self, newval): self.set_attributes(BoldAttr if newval else None) class Grid(Gtk.Grid): def __init__(self): Gtk.Grid.__init__(self) self.icon = self.attach(Gtk.Image(), 0, 0, 1, 2) self.name = self.attach(Label(), 1, 0, 1, 1) self.count = self.attach(Label(), 1, 1, 1, 1) self.set_column_spacing(5) self.cbid = None def attach(self, widget, x, y, w, h): super().attach(widget, x, y, w, h) return widget def plist_changed(self, player, old, new, this): self.name.set_bold(new == this) self.count.set_bold(new == this) def set_count(self, item, *args): n = item.get_n_tracks() self.count.set_text(f"{n} Track{'s' if n != 1 else ''}") def set_item(self, item): self.icon.set_from_icon_name(item.get_property("icon-name")) self.name.set_text(item.get_property("name")) self.plist_changed(None, None, audio.Player.playlist, item) self.set_count(item) item.connect("track-added", self.set_count) item.connect("track-removed", self.set_count) item.connect("refreshed", self.set_count) self.cbid = audio.Player.connect("playlist-changed", self.plist_changed, item) def unset_item(self, item): if item: self.cbid = audio.Player.disconnect(self.cbid) item.disconnect_by_func(self.set_count) item.disconnect_by_func(self.set_count) item.disconnect_by_func(self.set_count) class UserGrid(Grid): def __init__(self): Grid.__init__(self) self.remove = self.attach(Gtk.Button(), 2, 0, 1, 2) self.remove.set_icon_name("list-remove") self.remove.add_css_class("flat") self.remove.set_halign(Gtk.Align.CENTER) self.remove.set_valign(Gtk.Align.CENTER) def set_item(self, item): system = [ "Collection", "Favorites", "New Tracks", "Previous", "Queued Tracks" ] super().set_item(item) self.remove.set_visible(item.name not in system) self.remove.connect("clicked", self.clicked, item) def unset_item(self, item): self.remove.disconnect_by_func(self.clicked) def clicked(self, button, item): item.delete() class LibraryGrid(Grid): def __init__(self): Grid.__init__(self) self.menu = self.attach(Gtk.MenuButton(), 2, 0, 1, 2) self.menu.add_css_class("flat") self.menu.get_first_child().add_css_class("flat") self.menu.set_direction(Gtk.ArrowType.LEFT) self.menu.set_halign(Gtk.Align.CENTER) self.menu.set_valign(Gtk.Align.CENTER) def set_item(self, item): super().set_item(item) self.menu.set_popover(widgets.LibraryPopover(item)) def unset_item(self, item): super().unset_item(item) self.menu.set_popover(None) class TreeRow(Gtk.TreeExpander): def __init__(self, child): Gtk.TreeExpander.__init__(self) self.set_child(child) def set_item(self, listitem): self.set_list_row(listitem) self.get_child().set_item(listitem.get_item()) def unset_item(self, listitem): self.get_child().unset_item(listitem.get_item()) self.set_list_row(None) class TreeRowFactory(Gtk.SignalListItemFactory): def __init__(self): Gtk.SignalListItemFactory.__init__(self) self.connect("setup", self.setup) self.connect("bind", self.bind) self.connect("unbind", self.unbind) self.connect("teardown", self.teardown) def setup(self, factory, treeitem): treeitem.set_child(TreeRow(Grid())) def bind(self, factory, treeitem): treeitem.get_child().set_item(treeitem.get_item()) def unbind(self, factory, treeitem): treeitem.get_child().unset_item(treeitem.get_item()) def teardown(self, factory, treeitem): treeitem.set_child(None) Factory = TreeRowFactory() class UserTreeRowFactory(TreeRowFactory): def setup(self, factory, treeitem): treeitem.set_child(TreeRow(UserGrid())) UserFactory = UserTreeRowFactory() class LibraryTreeRowFactory(TreeRowFactory): def setup(self, factory, treeitem): treeitem.set_child(TreeRow(LibraryGrid())) LibraryFactory = LibraryTreeRowFactory() class UserRow(Gtk.Box): def __init__(self): Gtk.Box.__init__(self) self.icon = Gtk.Image() self.name = Label() self.set_spacing(5) self.append(self.icon) self.append(self.name) def set_item(self, item): self.icon.set_from_icon_name(item.get_property("icon-name")) self.name.set_text(item.get_property("name")) class UserRowFactory(Gtk.SignalListItemFactory): def __init__(self): Gtk.SignalListItemFactory.__init__(self) self.connect("setup", self.setup) self.connect("bind", self.bind) self.connect("teardown", self.teardown) def setup(self, factory, item): item.set_child(UserRow()) def bind(self, factory, item): item.get_child().set_item(item.get_item()) def teardown(self, factory, item): item.set_child(None)