sidebar: Use the Texture Cache for album art and user icons

I make sure to clear an existing texture before setting a new one in
case the user downloads a new file with the same path. Otherwise we'll
end up using a stale texture in the list.

Implements: #54 ("Convert the SideBar to use the Texture Cache")
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This commit is contained in:
Anna Schumaker 2023-06-27 16:57:03 -04:00
parent 51b290e1f0
commit a4f30d87e6
2 changed files with 16 additions and 18 deletions

View File

@ -4,9 +4,9 @@ import pathlib
from gi.repository import GObject
from gi.repository import GLib
from gi.repository import Gio
from gi.repository import Gdk
from gi.repository import Gtk
from gi.repository import Adw
from .. import texture
IMAGE_FILTERS = Gio.ListStore()
@ -37,11 +37,7 @@ class Icon(Adw.Bin):
self.set_child(self._icon)
def __notify_filepath(self, icon: Adw.Bin, param) -> None:
if self.filepath is None:
texture = None
else:
texture = Gdk.Texture.new_from_filename(str(self.filepath))
self._icon.set_custom_image(texture)
self._icon.set_custom_image(texture.CACHE[self.filepath])
class Settable(Icon):
@ -61,7 +57,9 @@ class Settable(Icon):
def __async_ready(self, dialog: Gtk.FileDialog, task: Gio.Task) -> None:
try:
file = dialog.open_finish(task)
self.filepath = pathlib.Path(file.get_path())
path = pathlib.Path(file.get_path())
texture.CACHE.drop(path)
self.filepath = path
except GLib.Error:
self.filepath = None

View File

@ -69,18 +69,14 @@ class TestIcon(unittest.TestCase):
"""Test the filepath property."""
self.assertIsNone(self.icon.filepath)
with unittest.mock.patch("gi.repository.Gdk.Texture.new_from_filename",
wraps=Gdk.Texture.new_from_filename) \
as mock_new:
self.icon.filepath = tests.util.COVER_JPG
mock_new.assert_called_with(str(tests.util.COVER_JPG))
self.assertIsInstance(self.icon._icon.get_custom_image(),
Gdk.Texture)
self.icon.filepath = tests.util.COVER_JPG
texture = self.icon._icon.get_custom_image()
self.assertIsInstance(texture, Gdk.Texture)
self.assertDictEqual(emmental.texture.CACHE,
{tests.util.COVER_JPG: texture})
mock_new.reset_mock()
self.icon.filepath = None
self.assertIsNone(self.icon._icon.get_custom_image())
mock_new.assert_not_called()
self.icon.filepath = None
self.assertIsNone(self.icon._icon.get_custom_image())
class TestSettable(unittest.TestCase):
@ -123,11 +119,15 @@ class TestSettable(unittest.TestCase):
task = Gio.Task()
cover_path = str(tests.util.COVER_JPG)
mock_finish.return_value = Gio.File.new_for_path(cover_path)
emmental.texture.CACHE[tests.util.COVER_JPG] = "abcde"
self.icon._Settable__async_ready(self.icon._dialog, task)
mock_finish.assert_called_with(task)
self.assertEqual(self.icon.filepath, tests.util.COVER_JPG)
texture = emmental.texture.CACHE[tests.util.COVER_JPG]
self.assertIsInstance(texture, Gdk.Texture)
def test_clearing(self):
"""Test clearing the icon by canceling the FileDialog."""
mock_set_initial_file = unittest.mock.Mock()