52 lines
1.3 KiB
Python
52 lines
1.3 KiB
Python
import gi
|
|
import functools
|
|
|
|
from concurrent.futures import Future
|
|
|
|
gi.require_version('Gtk', '3.0')
|
|
from gi.repository import Gio, Gtk
|
|
|
|
|
|
def button_with_icon(
|
|
icon_name,
|
|
relief=False,
|
|
icon_size=Gtk.IconSize.BUTTON,
|
|
) -> Gtk.Button:
|
|
button = Gtk.Button()
|
|
icon = Gio.ThemedIcon(name=icon_name)
|
|
image = Gtk.Image.new_from_gicon(icon, icon_size)
|
|
button.add(image)
|
|
|
|
if not relief:
|
|
button.props.relief = Gtk.ReliefStyle.NONE
|
|
|
|
return button
|
|
|
|
|
|
def format_song_duration(duration_secs) -> str:
|
|
return f'{duration_secs // 60}:{duration_secs % 60:02}'
|
|
|
|
|
|
def async_callback(future_fn):
|
|
"""
|
|
Defines the ``async_callback`` decorator.
|
|
|
|
When a function is annotated with this decorator, the function becomes the
|
|
done callback for the given future-generating lambda function. The
|
|
annotated function will be called with the result of the future generated
|
|
by said lambda function.
|
|
|
|
:param future_fn: a function which generates a
|
|
``concurrent.futures.Future``.
|
|
"""
|
|
|
|
def decorator(callback_fn):
|
|
@functools.wraps(callback_fn)
|
|
def wrapper(self, *args, **kwargs):
|
|
future: Future = future_fn(*args, **kwargs)
|
|
future.add_done_callback(lambda f: callback_fn(self, f.result()))
|
|
|
|
return wrapper
|
|
|
|
return decorator
|