75 lines
2.6 KiB
Python
75 lines
2.6 KiB
Python
# Copyright 2022 (c) Anna Schumaker.
|
|
"""Custom icon widgets for playlist rows."""
|
|
import pathlib
|
|
from gi.repository import GObject
|
|
from gi.repository import GLib
|
|
from gi.repository import Gio
|
|
from gi.repository import Gtk
|
|
from gi.repository import Adw
|
|
from .. import texture
|
|
|
|
|
|
IMAGE_FILTERS = Gio.ListStore()
|
|
IMAGE_FILTERS.append(Gtk.FileFilter(name="Image Files",
|
|
mime_types=["inode/directory"]))
|
|
IMAGE_FILTERS[0].add_pixbuf_formats()
|
|
|
|
|
|
class Icon(Adw.Bin):
|
|
"""A custom Adw.Avatar that can load images from a file path."""
|
|
|
|
text = GObject.Property(type=str)
|
|
filepath = GObject.Property(type=GObject.TYPE_PYOBJECT)
|
|
icon_name = GObject.Property(type=str)
|
|
show_initials = GObject.Property(type=bool, default=False)
|
|
|
|
def __init__(self, **kwargs):
|
|
"""Initialize our Playlist icon."""
|
|
super().__init__(**kwargs)
|
|
self._icon = Adw.Avatar(size=40, show_initials=self.show_initials)
|
|
|
|
self.bind_property("text", self._icon, "text")
|
|
self.bind_property("icon-name", self._icon, "icon-name")
|
|
self.bind_property("show-initials", self._icon, "show-initials")
|
|
|
|
self.connect("notify::filepath", self.__notify_filepath)
|
|
|
|
self.set_child(self._icon)
|
|
|
|
def __notify_filepath(self, icon: Adw.Bin, param) -> None:
|
|
self._icon.set_custom_image(texture.CACHE[self.filepath])
|
|
|
|
|
|
class Settable(Icon):
|
|
"""A custom Avatar with an attached popover for selecting an image."""
|
|
|
|
settable = GObject.Property(type=bool, default=False)
|
|
|
|
def __init__(self):
|
|
"""Initialize our settable icon."""
|
|
super().__init__()
|
|
self._dialog = Gtk.FileDialog(title="Pick an Image",
|
|
filters=IMAGE_FILTERS)
|
|
self._long_press = Gtk.GestureLongPress()
|
|
self._long_press.connect("pressed", self.__long_press)
|
|
self.add_controller(self._long_press)
|
|
|
|
def __async_ready(self, dialog: Gtk.FileDialog, task: Gio.Task) -> None:
|
|
try:
|
|
file = dialog.open_finish(task)
|
|
path = pathlib.Path(file.get_path())
|
|
texture.CACHE.drop(path)
|
|
self.filepath = path
|
|
except GLib.Error:
|
|
self.filepath = None
|
|
|
|
def __long_press(self, gesture: Gtk.GestureLongPress,
|
|
x: float, y: float) -> None:
|
|
"""Handle a click event."""
|
|
if self.settable:
|
|
if self.filepath is not None:
|
|
file = Gio.File.new_for_path(str(self.filepath))
|
|
self._dialog.set_initial_file(file)
|
|
self._dialog.open(self.get_ancestor(Gtk.Window), None,
|
|
self.__async_ready)
|