# Copyright 2021 (c) Anna Schumaker. import audio import lib from gi.repository import Gtk, GLib, Pango from lib import settings BoldAttr = Pango.AttrList.new() BoldAttr.insert(Pango.attr_weight_new(Pango.Weight.BOLD)) class TrackLabel(Gtk.Label): def set_item(self, item, text): audio.Player.connect("track-changed", self.track_changed, item) self.track_changed(audio.Player, None, audio.Player.track, item) self.set_text(text) def unset_item(self, item): self.set_text("") audio.Player.disconnect_by_func(self.track_changed) def track_changed(self, player, old, new, this): self.set_attributes(BoldAttr if this == new else None) class LabelFactory(Gtk.SignalListItemFactory): def __init__(self, xalign): Gtk.SignalListItemFactory.__init__(self) self.connect("setup", self.on_setup) self.connect("bind", self.on_bind) self.connect("unbind", self.on_unbind) self.connect("teardown", self.on_teardown) self.xalign = xalign def get_track_text(self, track): raise NotImplementedError def get_track_dim(self, track): return False def on_setup(self, factory, listitem): listitem.set_child(TrackLabel(xalign=self.xalign)) def on_bind(self, factory, listitem): item = listitem.get_item() if child := listitem.get_child(): child.set_item(item, self.get_track_text(item)) child.set_sensitive(not self.get_track_dim(item)) def on_unbind(self, factory, listitem): listitem.get_child().unset_item(listitem.get_item()) def on_teardown(self, factory, listitem): listitem.set_child(None) class TracknoFactory(LabelFactory): def __init__(self): LabelFactory.__init__(self, xalign=1) def get_track_text(self, track): return f"{track.disc.number}-{track.number:02}" class TitleFactory(LabelFactory): def __init__(self): LabelFactory.__init__(self, xalign=0) def get_track_text(self, track): return track.title class LengthFactory(LabelFactory): def __init__(self): LabelFactory.__init__(self, xalign=1) def get_track_text(self, track): (m, s) = divmod(int(track.length), 60) return f"{m}:{s:02}" class ArtistFactory(LabelFactory): def __init__(self): LabelFactory.__init__(self, xalign=0) def get_track_text(self, track): return track.artist.name class AlbumFactory(LabelFactory): def __init__(self): LabelFactory.__init__(self, xalign=0) def get_track_text(self, track): return track.album.name class SubtitleFactory(LabelFactory): def __init__(self): LabelFactory.__init__(self, xalign=0) def get_track_dim(self, track): return len(track.disc.subtitle) == 0 def get_track_text(self, track): subtitle = track.disc.subtitle return subtitle if len(subtitle) > 0 else track.disc.name class YearFactory(LabelFactory): def __init__(self): LabelFactory.__init__(self, xalign=1) def get_track_text(self, track): return str(track.year.year) class PlayCountFactory(LabelFactory): def __init__(self): LabelFactory.__init__(self, xalign=1) def get_track_text(self, track): return str(track.playcount) class LastPlayedFactory(LabelFactory): def __init__(self): LabelFactory.__init__(self, xalign=0) def get_track_text(self, track): return "Never" if track.playcount == 0 else str(track.lastplayed) class Column(Gtk.ColumnViewColumn): def __init__(self, title, factory, width=-1, **kwargs): Gtk.ColumnViewColumn.__init__(self, title=title, **kwargs) self.set_factory(factory) self.set_resizable(True) lib.settings.initialize(f"column.{title}", width) self.set_fixed_width(settings.get_int(f"column.{title}")) self.connect("notify::fixed-width", self.width_changed) def width_changed(self, col, param): lib.settings.set(f"column.{self.get_title()}", self.get_fixed_width()) def TracknoColumn(): return Column("#", TracknoFactory()) def TitleColumn(): return Column("Title", TitleFactory(), width=250, expand=True) def LengthColumn(): return Column("Length", LengthFactory()) def ArtistColumn(): return Column("Artist", ArtistFactory(), width=150, expand=True) def AlbumColumn(): return Column("Album", AlbumFactory(), width=150, expand=True) def SubtitleColumn(): return Column("Subtitle", SubtitleFactory(), width=150, expand=True) def YearColumn(): return Column("Year", YearFactory()) def PlayCountColumn(): return Column("Count", PlayCountFactory()) def LastPlayedColumn(): return Column("Last Played", LastPlayedFactory())