Files
sublime-music/sublime_music/ui/common/spinner_picture.py
Benjamin Schaaf 14a7b2bb77 WIP
2021-12-20 22:09:28 +11:00

82 lines
2.3 KiB
Python

from typing import Optional
from gi.repository import Gdk, GdkPixbuf, Gtk
class SpinnerPicture(Gtk.Bin):
def __init__(
self,
loading: bool = True,
spinner_name: str = None,
**kwargs,
):
"""An picture with a loading overlay."""
super().__init__()
self.filename: Optional[str] = None
self.pixbuf = None
self.offset = (0, 0)
self.sized_pixbuf = None
self.spinner = Gtk.Spinner(
name=spinner_name,
active=loading,
halign=Gtk.Align.CENTER,
valign=Gtk.Align.CENTER,
)
self.add(self.spinner)
def set_from_file(self, filename: Optional[str]):
"""Set the picture to the given filename."""
filename = filename or None
if self.filename == filename:
return
self.filename = filename
if self.filename:
self.pixbuf = GdkPixbuf.Pixbuf.new_from_file(self.filename)
else:
self.pixbuf = None
self._update_sized_pixbuf()
def set_loading(self, loading_status: bool):
if loading_status:
self.spinner.start()
self.spinner.show()
else:
self.spinner.stop()
self.spinner.hide()
def do_size_allocate(self, allocation):
Gtk.Bin.do_size_allocate(self, allocation)
self._update_sized_pixbuf()
def do_draw(self, cr):
if self.sized_pixbuf:
Gdk.cairo_set_source_pixbuf(cr, self.sized_pixbuf, self.offset[0], self.offset[1])
cr.paint()
Gtk.Bin.do_draw(self, cr)
def _update_sized_pixbuf(self):
if self.pixbuf is None:
self.sized_pixbuf = None
return
pix_width = self.pixbuf.get_width()
pix_height = self.pixbuf.get_height()
alloc_width = self.get_allocated_width()
alloc_height = self.get_allocated_height()
scale = max(alloc_width / pix_width, alloc_height / pix_height)
scaled_width = pix_width * scale
scaled_height = pix_height * scale
self.sized_pixbuf = self.pixbuf.scale_simple(scaled_width, scaled_height, GdkPixbuf.InterpType.BILINEAR)
self.offset = (
(alloc_width - scaled_width) / 2,
(alloc_height - scaled_height) / 2,
)