117 lines
4.1 KiB
Python
117 lines
4.1 KiB
Python
# Copyright 2022 (c) Anna Schumaker.
|
|
"""A Gtk.Label set up for displaying nowplaying tags."""
|
|
from gi.repository import GObject
|
|
from gi.repository import Gdk
|
|
from gi.repository import Gtk
|
|
from gi.repository import Pango
|
|
|
|
|
|
class Label(Gtk.Label):
|
|
"""A Gtk.Label wrapped in a ScrolledWindow for displaying tags."""
|
|
|
|
prefix = GObject.Property(type=str)
|
|
size = GObject.Property(type=int)
|
|
|
|
def __init__(self, prefix="", **kwargs):
|
|
"""Initialize our Label."""
|
|
super().__init__(prefix=prefix, xalign=0, **kwargs)
|
|
self.connect("notify::size", self.__set_size)
|
|
|
|
@GObject.Property(type=str)
|
|
def text(self) -> str:
|
|
"""Get the text set to the label (without any prefix)."""
|
|
return self.get_text()[len(self.prefix):]
|
|
|
|
@text.setter
|
|
def text(self, text: str) -> None:
|
|
"""Set text to the label (adding any prefix)."""
|
|
text = f"{self.prefix}{text}" if text else ""
|
|
self.set_text(text)
|
|
|
|
def __set_size(self, label: Gtk.Label, param) -> None:
|
|
# Note that we have to create a new Pango.AttrList here because
|
|
# Gtk.Label.get_attributes() returns a COPY of the AttrList, so
|
|
# any modifications won't take effect.
|
|
attrlist = Pango.AttrList.new()
|
|
attrlist.insert(Pango.attr_size_new_absolute(self.size * Pango.SCALE))
|
|
self.set_attributes(attrlist)
|
|
|
|
|
|
class PreferArtistMenu(Gtk.Box):
|
|
"""Menu for selecting the prefer-artist property."""
|
|
|
|
prefer_artist = GObject.Property(type=bool, default=True)
|
|
|
|
def __init__(self):
|
|
"""Configure the Prefer Artist Menu."""
|
|
super().__init__(orientation=Gtk.Orientation.VERTICAL)
|
|
self._artist = Gtk.CheckButton(active=True)
|
|
self._albumartist = Gtk.CheckButton()
|
|
|
|
self._artist.set_label("Prefer the artist tag.")
|
|
self._albumartist.set_label("Prefer the album artist tag.")
|
|
self._albumartist.set_group(self._artist)
|
|
|
|
self.bind_property("prefer-artist", self._artist, "active",
|
|
GObject.BindingFlags.BIDIRECTIONAL)
|
|
self.bind_property("prefer-artist", self._albumartist, "active",
|
|
GObject.BindingFlags.INVERT_BOOLEAN)
|
|
|
|
self.append(self._artist)
|
|
self.append(self._albumartist)
|
|
|
|
|
|
class ArtistLabel(Label):
|
|
"""A label that shows either Artist or Album Artist information."""
|
|
|
|
artist = GObject.Property(type=str)
|
|
album_artist = GObject.Property(type=str)
|
|
prefer_artist = GObject.Property(type=bool, default=True)
|
|
|
|
def __init__(self, **kwargs):
|
|
"""Initialize the Artist Label."""
|
|
super().__init__(**kwargs)
|
|
self._menu = PreferArtistMenu()
|
|
self._popover = Gtk.Popover(child=self._menu)
|
|
self._clicked = Gtk.GestureClick()
|
|
|
|
self.bind_property("prefer-artist", self._menu, "prefer-artist",
|
|
GObject.BindingFlags.BIDIRECTIONAL)
|
|
|
|
self.add_controller(self._clicked)
|
|
self._clicked.connect("released", self.__clicked)
|
|
|
|
self.connect("notify::artist", self.__notify)
|
|
self.connect("notify::album-artist", self.__notify)
|
|
self.connect("notify::prefer-artist", self.__notify)
|
|
self.connect("notify::size", self.__notify_size)
|
|
|
|
rect = Gdk.Rectangle()
|
|
rect.x, rect.y = (8, 8)
|
|
self._popover.set_pointing_to(rect)
|
|
self._popover.set_parent(self)
|
|
|
|
def __del__(self) -> None:
|
|
"""Clean up the Artist Label."""
|
|
self._popover.unparent()
|
|
|
|
def __clicked(self, gesture, n_press, x, y) -> None:
|
|
self._popover.popup()
|
|
|
|
def __notify_size(self, label, param) -> None:
|
|
rect = Gdk.Rectangle()
|
|
(rect.x, rect.y) = (self.size, self.size)
|
|
self._popover.set_pointing_to(rect)
|
|
|
|
def __notify(self, label, param) -> None:
|
|
if self.prefer_artist:
|
|
if len(self.artist) > 0:
|
|
self.text = self.artist
|
|
else:
|
|
self.text = self.album_artist
|
|
else:
|
|
if len(self.album_artist) > 0:
|
|
self.text = self.album_artist
|
|
else:
|
|
self.text = self.artist
|