Port UI to GTK 4

This commit is contained in:
coderkun 2023-01-08 18:20:30 +01:00
commit 8359143663
21 changed files with 1038 additions and 2066 deletions

View file

@ -2,56 +2,24 @@
import gi
gi.require_version('Gtk', '3.0')
gi.require_version('Gtk', '4.0')
gi.require_version('Adw', '1')
import logging
import math
import threading
from gi.repository import Gtk, GObject, GdkPixbuf
from gi.repository import Gtk, Gdk, Gio, GObject, GdkPixbuf, Adw
from mcg import client
from mcg.albumheaderbar import AlbumHeaderbar
from mcg.utils import Utils
@Gtk.Template(resource_path='/xyz/suruatoel/mcg/ui/playlist-toolbar.ui')
class PlaylistToolbar(Gtk.ButtonBox):
__gtype_name__ = 'McgPlaylistToolbar'
__gsignals__ = {
'select': (GObject.SIGNAL_RUN_FIRST, None, (bool,)),
'clear-playlist': (GObject.SIGNAL_RUN_FIRST, None, ())
}
# Widgets
playlist_clear_button = Gtk.Template.Child()
select_button = Gtk.Template.Child()
def __init__(self):
super().__init__()
@Gtk.Template.Callback()
def on_select_toggled(self, widget):
self.emit('select', widget.get_active())
@Gtk.Template.Callback()
def on_clear_clicked(self, widget):
if widget is self.playlist_clear_button:
self.emit('clear-playlist')
def exit_selection(self):
self.select_button.set_active(False)
from mcg.utils import GridItem
@Gtk.Template(resource_path='/xyz/suruatoel/mcg/ui/playlist-panel.ui')
class PlaylistPanel(Gtk.Stack):
class PlaylistPanel(Adw.Bin):
__gtype_name__ = 'McgPlaylistPanel'
__gsignals__ = {
'open-standalone': (GObject.SIGNAL_RUN_FIRST, None, ()),
@ -67,6 +35,10 @@ class PlaylistPanel(Gtk.Stack):
# Widgets
panel_standalone = Gtk.Template.Child()
actionbar_revealer = Gtk.Template.Child()
# Toolbar
toolbar = Gtk.Template.Child()
playlist_clear_button = Gtk.Template.Child()
select_button = Gtk.Template.Child()
# Playlist Grid
playlist_grid = Gtk.Template.Child()
# Action bar (normal)
@ -79,8 +51,8 @@ class PlaylistPanel(Gtk.Stack):
standalone_image = Gtk.Template.Child()
def __init__(self, client):
GObject.GObject.__init__(self)
def __init__(self, client, **kwargs):
super().__init__(**kwargs)
self._client = client
self._host = None
self._item_size = 150
@ -88,7 +60,7 @@ class PlaylistPanel(Gtk.Stack):
self._playlist_albums = None
self._playlist_lock = threading.Lock()
self._playlist_stop = threading.Event()
self._icon_theme = Gtk.IconTheme.get_default()
self._icon_theme = Gtk.IconTheme.get_for_display(Gdk.Display.get_default())
self._standalone_pixbuf = None
self._selected_albums = []
self._is_selected = False
@ -101,12 +73,10 @@ class PlaylistPanel(Gtk.Stack):
self._headerbar_standalone = AlbumHeaderbar()
self._headerbar_standalone.connect('close', self.on_headerbar_close_clicked)
# Playlist Grid: Model
self._playlist_grid_model = Gtk.ListStore(GdkPixbuf.Pixbuf, str, str)
self._playlist_grid_model = Gio.ListStore()
self._playlist_grid_selection = Gtk.MultiSelection.new(self._playlist_grid_model)
# Playlist Grid
self.playlist_grid.set_model(self._playlist_grid_model)
self.playlist_grid.set_pixbuf_column(0)
self.playlist_grid.set_text_column(-1)
self.playlist_grid.set_tooltip_column(1)
self.playlist_grid.set_model(self._playlist_grid_selection)
def get_headerbar_standalone(self):
@ -114,7 +84,7 @@ class PlaylistPanel(Gtk.Stack):
def get_toolbar(self):
return self._toolbar
return self.toolbar
def set_selected(self, selected):
@ -137,13 +107,13 @@ class PlaylistPanel(Gtk.Stack):
@Gtk.Template.Callback()
def on_playlist_grid_clicked(self, widget, path):
def on_playlist_grid_clicked(self, widget, position):
# Get selected album
iter = self._playlist_grid_model.get_iter(path)
hash = self._playlist_grid_model.get_value(iter, 2)
album = self._playlist_albums[hash]
item = self._playlist_grid_model.get_item(position)
album = item.get_album()
id = album.get_id()
self._selected_albums = [album]
self.emit('albumart', hash)
self.emit('albumart', id)
# Show standalone album
if widget.get_selection_mode() == Gtk.SelectionMode.SINGLE:
@ -248,10 +218,7 @@ class PlaylistPanel(Gtk.Stack):
self._playlist_albums = {}
for album in playlist:
self._playlist_albums[album.get_id()] = album
self.playlist_grid.set_model(None)
self.playlist_grid.freeze_child_notify()
self._playlist_grid_model.clear()
GObject.idle_add(self.playlist_grid.set_item_padding, size / 100)
self._playlist_grid_model.remove_all()
cache = client.MCGCache(host, size)
for album in playlist:
@ -265,29 +232,22 @@ class PlaylistPanel(Gtk.Stack):
except Exception:
self._logger.exception("Failed to load albumart")
if pixbuf is None:
pixbuf = self._icon_theme.load_icon(
pixbuf = self._icon_theme.lookup_icon(
Utils.STOCK_ICON_DEFAULT,
None,
self._item_size,
Gtk.IconLookupFlags.FORCE_SVG & Gtk.IconLookupFlags.FORCE_SIZE
self._item_size,
Gtk.TextDirection.LTR,
Gtk.IconLookupFlags.FORCE_SYMBOLIC
)
if pixbuf is not None:
self._playlist_grid_model.append([
pixbuf,
GObject.markup_escape_text("\n".join([
album.get_title(),
', '.join(album.get_dates()),
Utils.create_artists_label(album),
Utils.create_length_label(album)
])),
album.get_id()
])
self._playlist_grid_model.append(GridItem(album, pixbuf))
if self._playlist_stop.is_set():
self._playlist_lock.release()
return
self.playlist_grid.set_model(self._playlist_grid_model)
self.playlist_grid.thaw_child_notify()
self.playlist_grid.set_model(self._playlist_grid_selection)
# TODO why set_columns()?
#self.playlist_grid.set_columns(len(playlist))
self._playlist_lock.release()
@ -342,12 +302,11 @@ class PlaylistPanel(Gtk.Stack):
def _get_default_image(self):
return self._icon_theme.load_icon(
return self._icon_theme.lookup_icon(
Utils.STOCK_ICON_DEFAULT,
None,
512,
Gtk.IconLookupFlags.FORCE_SVG & Gtk.IconLookupFlags.FORCE_SIZE
512,
Gtk.TextDirection.LTR,
Gtk.IconLookupFlags.FORCE_SYMBOLIC
)