Port UI to GTK 4 (close #85)

This commit is contained in:
coderkun 2023-01-08 18:20:30 +01:00
commit 75b99e5820
36 changed files with 1730 additions and 3285 deletions

View file

@ -2,7 +2,7 @@
import gi
gi.require_version('Gtk', '3.0')
gi.require_version('Gtk', '4.0')
import logging
import math
@ -13,27 +13,6 @@ from mcg.utils import Utils
@Gtk.Template(resource_path='/xyz/suruatoel/mcg/ui/cover-toolbar.ui')
class CoverToolbar(Gtk.ButtonBox):
__gtype_name__ = 'McgCoverToolbar'
__gsignals__ = {
'fullscreen': (GObject.SIGNAL_RUN_FIRST, None, ())
}
# Widgets
fullscreen_button = Gtk.Template.Child()
def __init__(self):
super().__init__()
def set_fullscreen_sensitive(self, sensitive):
self.fullscreen_button.set_sensitive(sensitive)
@Gtk.Template(resource_path='/xyz/suruatoel/mcg/ui/cover-panel.ui')
class CoverPanel(Gtk.Overlay):
__gtype_name__ = 'McgCoverPanel'
@ -44,9 +23,13 @@ class CoverPanel(Gtk.Overlay):
}
# Widgets
# Toolbar
toolbar = Gtk.Template.Child()
fullscreen_button = Gtk.Template.Child()
# Cover
cover_stack = Gtk.Template.Child()
cover_spinner = Gtk.Template.Child()
cover_default = Gtk.Template.Child()
cover_scroll = Gtk.Template.Child()
cover_box = Gtk.Template.Child()
cover_image = Gtk.Template.Child()
@ -61,57 +44,57 @@ class CoverPanel(Gtk.Overlay):
def __init__(self):
super().__init__()
def __init__(self, **kwargs):
super().__init__(**kwargs)
self._current_album = None
self._current_cover_album = None
self._cover_pixbuf = None
self._timer = None
self._properties = {}
self._icon_theme = Gtk.IconTheme.get_default()
self._icon_theme = Gtk.IconTheme.get_for_display(Gdk.Display.get_default())
self._fullscreened = False
self._is_selected = False
self._current_size = None
self._cover_pixbuf = self._get_default_image()
# Widgets
self._toolbar = CoverToolbar()
self.cover_stack.set_visible_child(self.cover_scroll)
# Initial actions
GObject.idle_add(self._enable_tracklist)
# Click handler for image
clickController = Gtk.GestureClick()
clickController.connect('pressed', self.on_cover_box_pressed)
self.cover_box.add_controller(clickController)
# Button controller for songs scale
buttonController = Gtk.GestureClick()
buttonController.connect('pressed', self.on_songs_scale_pressed)
buttonController.connect('unpaired-release', self.on_songs_scale_released)
self.songs_scale.add_controller(buttonController)
def get_toolbar(self):
return self._toolbar
return self.toolbar
def set_selected(self, selected):
self._is_selected = selected
pass
@Gtk.Template.Callback()
def on_cover_box_pressed(self, widget, event):
if self._current_album and event.type == Gdk.EventType._2BUTTON_PRESS:
def on_cover_box_pressed(self, widget, npress, x, y):
if self._current_album and npress == 2:
self.emit('toggle-fullscreen')
@Gtk.Template.Callback()
def on_cover_size_allocate(self, widget, allocation):
def set_width(self, width):
GObject.idle_add(self._resize_image)
self.cover_info_scroll.set_max_content_width(allocation.width // 2)
self.cover_info_scroll.set_max_content_width(width // 2)
@Gtk.Template.Callback()
def on_songs_start_change(self, widget, event):
def on_songs_scale_pressed(self, widget, npress, x, y):
if self._timer:
GObject.source_remove(self._timer)
self._timer = None
@Gtk.Template.Callback()
def on_songs_change(self, widget, event):
def on_songs_scale_released(self, widget, x, y, npress, sequence):
value = int(self.songs_scale.get_value())
time = self._current_album.get_length()
tracks = self._current_album.get_tracks()
@ -144,7 +127,7 @@ class CoverPanel(Gtk.Overlay):
# Set current album
self._current_album = album
self._enable_tracklist()
self._toolbar.set_fullscreen_sensitive(self._current_album is not None)
self.fullscreen_button.set_sensitive(self._current_album is not None)
def set_play(self, pos, time):
@ -168,13 +151,12 @@ class CoverPanel(Gtk.Overlay):
def set_fullscreen(self, active):
if active:
self.info_revealer.set_reveal_child(False)
self.cover_box.override_background_color(Gtk.StateFlags.NORMAL, Gdk.RGBA(0, 0, 0, 1))
GObject.idle_add(self._resize_image)
self._fullscreened = True
else:
self._fullscreened = False
self.info_revealer.set_reveal_child(True)
self.cover_box.override_background_color(Gtk.StateFlags.NORMAL, Gdk.RGBA(0, 0, 0, 0))
if self._current_album:
self.info_revealer.set_reveal_child(True)
GObject.idle_add(self._resize_image)
@ -186,10 +168,10 @@ class CoverPanel(Gtk.Overlay):
self._cover_pixbuf = Utils.load_pixbuf(data)
except Exception as e:
self._logger.exception("Failed to set albumart")
self._cover_pixbuf = self._get_default_image()
self._cover_pixbuf = None
else:
# Reset image
self._cover_pixbuf = self._get_default_image()
self._cover_pixbuf = None
self._current_size = None
self._current_cover_album = album
# Show image
@ -222,7 +204,8 @@ class CoverPanel(Gtk.Overlay):
def _enable_tracklist(self):
if self._current_album:
# enable
self.info_revealer.set_reveal_child(True)
if not self._fullscreened:
self.info_revealer.set_reveal_child(True)
else:
# disable
self.info_revealer.set_reveal_child(False)
@ -236,8 +219,11 @@ class CoverPanel(Gtk.Overlay):
def _show_image(self):
self._resize_image()
self.cover_stack.set_visible_child(self.cover_scroll)
if self._cover_pixbuf:
self._resize_image()
self.cover_stack.set_visible_child(self.cover_scroll)
else:
self.cover_stack.set_visible_child(self.cover_default)
self.cover_spinner.stop()
@ -246,11 +232,14 @@ class CoverPanel(Gtk.Overlay):
auf die Größe des Fensters unter Beibehalt der Seitenverhältnisse
"""
# Get size
size = self.cover_scroll.get_allocation()
size_width = self.cover_stack.get_size(Gtk.Orientation.HORIZONTAL)
size_height = self.cover_stack.get_size(Gtk.Orientation.HORIZONTAL)
# Abort if size is the same
if self._current_size and size.width == self._current_size.width and size.height == self._current_size.height:
return
self._current_size = size
if self._current_size:
current_width, current_height = self._current_size
if size_width == current_width and size_height == current_height:
return
self._current_size = (size_width, size_height,)
# Get pixelbuffer
pixbuf = self._cover_pixbuf
@ -259,8 +248,8 @@ class CoverPanel(Gtk.Overlay):
return
# Skalierungswert für Breite und Höhe ermitteln
ratioW = float(size.width) / float(pixbuf.get_width())
ratioH = float(size.height) / float(pixbuf.get_height())
ratioW = float(size_width) / float(pixbuf.get_width())
ratioH = float(size_height) / float(pixbuf.get_height())
# Kleineren beider Skalierungswerte nehmen, nicht Hochskalieren
ratio = min(ratioW, ratioH)
ratio = min(ratio, 1)
@ -269,15 +258,5 @@ class CoverPanel(Gtk.Overlay):
height = int(math.floor(pixbuf.get_height()*ratio))
if width <= 0 or height <= 0:
return
# Pixelpuffer auf Oberfläche zeichnen
self.cover_image.set_allocation(self.cover_scroll.get_allocation())
self.cover_image.set_from_pixbuf(pixbuf.scale_simple(width, height, GdkPixbuf.InterpType.HYPER))
self.cover_image.show()
def _get_default_image(self):
return self._icon_theme.load_icon(
Utils.STOCK_ICON_DEFAULT,
512,
Gtk.IconLookupFlags.FORCE_SVG & Gtk.IconLookupFlags.FORCE_SIZE
)