[gnome-music/wip/jfelder/gtk4-v3: 47/200] Add CoverPaintable for art (FIXME)




commit 1ae0af205ccec1cae9dafde30259c69015de3490
Author: Marinus Schraal <mschraal gnome org>
Date:   Mon Apr 12 16:12:34 2021 +0200

    Add CoverPaintable for art (FIXME)
    
    Very simple implementation.
    
    Anything Gsk related seems to fail, which limits abilities for now.

 gnomemusic/artcache.py         | 24 +++++++++++----------
 gnomemusic/coverpaintable.py   | 49 ++++++++++++++++++++++++++++++++++++++++++
 gnomemusic/defaulticon.py      | 16 ++++++++------
 gnomemusic/widgets/artstack.py | 10 ++++-----
 4 files changed, 76 insertions(+), 23 deletions(-)
---
diff --git a/gnomemusic/artcache.py b/gnomemusic/artcache.py
index 07ef47765..86b7e1fb9 100644
--- a/gnomemusic/artcache.py
+++ b/gnomemusic/artcache.py
@@ -27,7 +27,8 @@ from gi.repository import Gdk, GdkPixbuf, Gio, Gtk, GLib, GObject
 from gnomemusic.corealbum import CoreAlbum
 from gnomemusic.coreartist import CoreArtist
 from gnomemusic.coresong import CoreSong
-from gnomemusic.defaulticon import DefaultIcon, make_icon_frame
+from gnomemusic.coverpaintable import CoverPaintable
+from gnomemusic.defaulticon import DefaultIcon
 from gnomemusic.musiclogger import MusicLogger
 from gnomemusic.utils import ArtSize, DefaultIconType
 
@@ -115,16 +116,17 @@ class ArtCache(GObject.GObject):
         stream.close_async(
             GLib.PRIORITY_DEFAULT_IDLE, None, self._close_stream, None)
 
-        scale = self._widget.props.scale_factor
-        surface = Gdk.cairo_surface_create_from_pixbuf(pixbuf, scale, None)
-        if isinstance(self._coreobject, CoreArtist):
-            surface = make_icon_frame(
-                surface, self._size, scale, round_shape=True)
-        elif (isinstance(self._coreobject, CoreAlbum)
-                or isinstance(self._coreobject, CoreSong)):
-            surface = make_icon_frame(surface, self._size, scale)
-
-        self._surface = surface
+        # scale = self._widget.props.scale_factor
+        # surface = Gdk.cairo_surface_create_from_pixbuf(pixbuf, scale, None)
+        # if isinstance(self._coreobject, CoreArtist):
+        #     surface = make_icon_frame(
+        #         surface, self._size, scale, round_shape=True)
+        # elif (isinstance(self._coreobject, CoreAlbum)
+        #         or isinstance(self._coreobject, CoreSong)):
+        #     surface = make_icon_frame(surface, self._size, scale)
+        paintable = CoverPaintable(self._size)
+
+        self._surface = paintable
 
     def _close_stream(self, stream, result, data):
         try:
diff --git a/gnomemusic/coverpaintable.py b/gnomemusic/coverpaintable.py
new file mode 100644
index 000000000..2ee97b30f
--- /dev/null
+++ b/gnomemusic/coverpaintable.py
@@ -0,0 +1,49 @@
+import gi
+gi.require_versions({"Gdk": "4.0", "Gtk": "4.0"})
+# from gi.repository import Gsk, Gtk, GObject, Graphene, Gdk
+from gi.repository import Gtk, GObject, Graphene, Gdk
+
+
+class CoverPaintable(GObject.GObject, Gdk.Paintable):
+
+    __gtype_name__ = "CoverPaintable"
+
+    def __init__(self, art_size, texture=None):
+        super().__init__()
+
+        self._texture = texture
+        self._art_size = art_size
+
+    def do_snapshot(self, snapshot, width, height):
+        w = width
+        h = height
+
+        if self._texture is not None:
+            snapshot.translate(Graphene.Point().init(width / 2, height / 2))
+
+            rect = Graphene.Rect().init(-(w / 2), -(h / 2), w, h)
+            rect2 = Graphene.Rect().init(-50, -50, 100, 100)
+
+            # Anything Gsk related seems to be failing, no rounded
+            # clips for now. Related: pygobject#471
+            #
+            # gskrr = Gsk.RoundedRect().init_from_rect(rect2, 10)
+            # snapshot.push_rounded_clip(gskrr)
+
+            snapshot.push_clip(rect2)
+            snapshot.append_texture(self._texture, rect)
+            snapshot.pop()
+        else:
+            theme = Gtk.IconTheme.new()
+            icon_pt = theme.lookup_icon(
+                "folder-music-symbolic", None, w, 1, 0, 0)
+            icon_pt.snapshot(snapshot, w, h)
+
+    def do_get_flags(self):
+        return Gdk.PaintableFlags.SIZE | Gdk.PaintableFlags.CONTENTS
+
+    def do_get_intrinsic_height(self):
+        return self._art_size.height
+
+    def do_get_intrinsic_width(self):
+        return self._art_size.width
diff --git a/gnomemusic/defaulticon.py b/gnomemusic/defaulticon.py
index 8c43f2a81..17b29f482 100644
--- a/gnomemusic/defaulticon.py
+++ b/gnomemusic/defaulticon.py
@@ -30,6 +30,7 @@ from typing import Dict, Tuple
 import cairo
 from gi.repository import Adw, Gtk, GObject, Gdk
 
+from gnomemusic.coverpaintable import CoverPaintable
 from gnomemusic.utils import ArtSize, DefaultIconType
 
 
@@ -120,15 +121,16 @@ class DefaultIcon(GObject.GObject):
     def _make_default_icon(
             self, icon_type: DefaultIconType, art_size: ArtSize, scale: int,
             dark: bool) -> cairo.ImageSurface:
-        icon_info = self._default_theme.lookup_icon(
-            icon_type.value, art_size.width / 3, scale, 0, 0)
-        icon = icon_info.load_surface()
+        # icon_info = self._default_theme.lookup_icon(
+        #     icon_type.value, art_size.width / 3, scale, 0, 0)
+        # icon = icon_info.load_surface()
 
-        round_shape = icon_type == DefaultIconType.ARTIST
-        icon_surface = make_icon_frame(
-            icon, art_size, scale, True, round_shape, dark)
+        # round_shape = icon_type == DefaultIconType.ARTIST
+        # icon_surface = make_icon_frame(
+        #     icon, art_size, scale, True, round_shape, dark)
+        paintable = CoverPaintable(art_size)
 
-        return icon_surface
+        return paintable
 
     def get(self, icon_type: DefaultIconType,
             art_size: ArtSize) -> cairo.ImageSurface:
diff --git a/gnomemusic/widgets/artstack.py b/gnomemusic/widgets/artstack.py
index 96d8f520e..9acaa8447 100644
--- a/gnomemusic/widgets/artstack.py
+++ b/gnomemusic/widgets/artstack.py
@@ -163,24 +163,24 @@ class ArtStack(Gtk.Stack):
 
         self._async_queue.queue(self._cache, coreobject, self._size)
 
-    def _swap_thumbnails(self, surface: ImageSurface, animate: bool) -> None:
+    def _swap_thumbnails(self, paintable: Paintable, animate: bool) -> None:
         if self.props.visible_child_name == "B":
-            self._cover_a.props.surface = surface
+            self._cover_a.props.paintable = paintable
             if animate:
                 self.set_visible_child_full(
                     "A", Gtk.StackTransitionType.CROSSFADE)
             else:
                 self.props.visible_child_name = "A"
         else:
-            self._cover_b.props.surface = surface
+            self._cover_b.props.paintable = paintable
             if animate:
                 self.set_visible_child_full(
                     "B", Gtk.StackTransitionType.CROSSFADE)
             else:
                 self.props.visible_child_name = "B"
 
-    def _on_cache_result(self, cache: ArtCache, surface: ImageSurface) -> None:
-        self._swap_thumbnails(surface, True)
+    def _on_cache_result(self, cache: ArtCache, paintable: Gdk.Paintable) -> None:
+        self._swap_thumbnails(paintable, True)
 
     def _on_destroy(self, widget: ArtStack) -> None:
         # If the stack is destroyed while the art is updated, an error


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]