[gnome-music/wip/mschraal/rework-art-widget: 13/18] artstack: Move loading logic to CoverPaintable




commit deee9be6426fdef070fc60323d32e2970893ca7d
Author: Marinus Schraal <mschraal gnome org>
Date:   Sat Apr 2 15:09:14 2022 +0200

    artstack: Move loading logic to CoverPaintable

 gnomemusic/coverpaintable.py   | 63 ++++++++++++++++++++++++++++++++++++++++++
 gnomemusic/widgets/artstack.py | 50 +++------------------------------
 2 files changed, 67 insertions(+), 46 deletions(-)
---
diff --git a/gnomemusic/coverpaintable.py b/gnomemusic/coverpaintable.py
index 722516726..407f7d14f 100644
--- a/gnomemusic/coverpaintable.py
+++ b/gnomemusic/coverpaintable.py
@@ -23,12 +23,23 @@
 # delete this exception statement from your version.
 
 from __future__ import annotations
+from typing import Optional, Union
+import typing
 
 import gi
 gi.require_versions({"Gdk": "4.0", "Gtk": "4.0", "Gsk": "4.0"})
 from gi.repository import Adw, Gsk, Gtk, GObject, Graphene, Gdk
 
+from gnomemusic.asyncqueue import AsyncQueue
+from gnomemusic.mediaartloader import MediaArtLoader
 from gnomemusic.utils import ArtSize, DefaultIconType
+if typing.TYPE_CHECKING:
+    from gnomemusic.corealbum import CoreAlbum
+    from gnomemusic.coreartist import CoreArtist
+    from gnomemusic.coresong import CoreSong
+
+if typing.TYPE_CHECKING:
+    CoreObject = Union[CoreAlbum, CoreArtist, CoreSong]
 
 
 class CoverPaintable(GObject.GObject, Gdk.Paintable):
@@ -40,6 +51,8 @@ class CoverPaintable(GObject.GObject, Gdk.Paintable):
 
     __gtype_name__ = "CoverPaintable"
 
+    _async_queue = AsyncQueue("CoverPaintable")
+
     def __init__(
             self, art_size: ArtSize, widget: Gtk.Widget,
             icon_type: DefaultIconType = DefaultIconType.ALBUM,
@@ -54,12 +67,16 @@ class CoverPaintable(GObject.GObject, Gdk.Paintable):
         """
         super().__init__()
 
+        self._art_loader = MediaArtLoader()
+        self._art_loading_id = 0
         self._art_size = art_size
+        self._coreobject: Optional[CoreObject] = None
         self._icon_theme = Gtk.IconTheme.new().get_for_display(
             widget.get_display())
         self._icon_type = icon_type
         self._style_manager = Adw.StyleManager.get_default()
         self._texture = texture
+        self._thumbnail_id = 0
         self._widget = widget
 
         self._style_manager.connect("notify::dark", self._on_dark_changed)
@@ -117,6 +134,52 @@ class CoverPaintable(GObject.GObject, Gdk.Paintable):
 
         self.invalidate_contents()
 
+    @GObject.Property(type=object, default=None)
+    def coreobject(self) -> Optional[CoreObject]:
+        return self._coreobject
+
+    @coreobject.setter  # type: ignore
+    def coreobject(self, coreobject: CoreObject) -> None:
+        if coreobject is self._coreobject:
+            return
+
+        self._texture = None
+        self.invalidate_contents()
+
+        if self._thumbnail_id != 0:
+            self._coreobject.disconnect(self._thumbnail_id)
+            self._thumbnail_id = 0
+
+        self._coreobject = coreobject
+        self._thumbnail_id = self._coreobject.connect(
+            "notify::thumbnail", self._on_thumbnail_changed)
+
+        if self._coreobject.props.thumbnail is not None:
+            self._on_thumbnail_changed(self._coreobject, None)
+
+    def _on_thumbnail_changed(
+            self, coreobject: CoreObject,
+            uri: GObject.ParamSpecString) -> None:
+        thumbnail_uri = coreobject.props.thumbnail
+        if self._art_loading_id != 0:
+            self._art_loader.disconnect(self._art_loading_id)
+            self._art_loading_id = 0
+
+        if thumbnail_uri == "generic":
+            self._texture = None
+            self.invalidate_contents()
+            return
+
+        self._art_loader = MediaArtLoader()
+        self._art_loading_id = self._art_loader.connect(
+            "finished", self._on_art_loading_finished)
+        self._async_queue.queue(self._art_loader, thumbnail_uri)
+
+    def _on_art_loading_finished(self, art_loader, texture) -> None:
+        if texture:
+            self._texture = texture
+            self.invalidate_contents()
+
     @GObject.Property(type=object, flags=GObject.ParamFlags.READWRITE)
     def icon_type(self) -> DefaultIconType:
         """Type of the stack cover
diff --git a/gnomemusic/widgets/artstack.py b/gnomemusic/widgets/artstack.py
index 116760eff..9cbf17824 100644
--- a/gnomemusic/widgets/artstack.py
+++ b/gnomemusic/widgets/artstack.py
@@ -28,9 +28,7 @@ import typing
 
 from gi.repository import GObject, Gtk
 
-from gnomemusic.asyncqueue import AsyncQueue
 from gnomemusic.coverpaintable import CoverPaintable
-from gnomemusic.mediaartloader import MediaArtLoader
 from gnomemusic.utils import ArtSize, DefaultIconType
 if typing.TYPE_CHECKING:
     from gnomemusic.corealbum import CoreAlbum
@@ -52,8 +50,6 @@ class ArtStack(Gtk.Stack):
 
     __gtype_name__ = "ArtStack"
 
-    _async_queue = AsyncQueue("ArtStack")
-
     def __init__(self, size: ArtSize = ArtSize.MEDIUM) -> None:
         """Initialize the ArtStack
 
@@ -61,15 +57,11 @@ class ArtStack(Gtk.Stack):
         """
         super().__init__()
 
-        self._art_loader = MediaArtLoader()
-        self._art_loading_id = 0
         self._art_type = DefaultIconType.ALBUM
         self._coreobject: Optional[CoreObject] = None
-        self._default_icon = CoverPaintable(
+        self._cover_paintable = CoverPaintable(
             size, self, icon_type=self._art_type)
         self._size = size
-        self._texture = None
-        self._thumbnail_id = 0
 
         self._cover = Gtk.Image()
         self._cover.props.visible = True
@@ -120,7 +112,7 @@ class ArtStack(Gtk.Stack):
         """
         self._art_type = value
 
-        self._default_icon.props.icon_type = self._art_type
+        self._cover_paintable.props.icon_type = self._art_type
 
     @GObject.Property(type=object, default=None)
     def coreobject(self) -> Optional[CoreObject]:
@@ -131,40 +123,6 @@ class ArtStack(Gtk.Stack):
         if coreobject is self._coreobject:
             return
 
-        self._cover.props.paintable = self._default_icon
-
-        if self._thumbnail_id != 0:
-            self._coreobject.disconnect(self._thumbnail_id)
-            self._thumbnail_id = 0
-
         self._coreobject = coreobject
-        self._thumbnail_id = self._coreobject.connect(
-            "notify::thumbnail", self._on_thumbnail_changed)
-
-        if self._coreobject.props.thumbnail is not None:
-            self._on_thumbnail_changed(self._coreobject, None)
-
-    def _on_thumbnail_changed(
-            self, coreobject: CoreObject,
-            uri: GObject.ParamSpecString) -> None:
-        thumbnail_uri = coreobject.props.thumbnail
-        if self._art_loading_id != 0:
-            self._art_loader.disconnect(self._art_loading_id)
-            self._art_loading_id = 0
-
-        if thumbnail_uri == "generic":
-            self._cover.props.paintable = self._default_icon
-            return
-
-        self._art_loader = MediaArtLoader()
-        self._art_loading_id = self._art_loader.connect(
-            "finished", self._on_art_loading_finished)
-        self._async_queue.queue(self._art_loader, thumbnail_uri)
-
-    def _on_art_loading_finished(self, art_loader, texture) -> None:
-        if texture:
-            paintable = CoverPaintable(
-                self._size, self, icon_type=self._art_type,
-                texture=texture)
-
-            self._cover.props.paintable = paintable
+        self._cover_paintable.props.coreobject = coreobject
+        self._cover.props.paintable = self._cover_paintable


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