Improve thumbnailing process

This commit is contained in:
Jan Hamal Dvořák 2025-03-11 10:38:42 +01:00
parent 4985de9ca8
commit 0972dbd238
3 changed files with 35 additions and 19 deletions

View file

@ -8,6 +8,8 @@ from typing import Optional, overload
from gi.repository import Gio, GObject
from .thumbnailer import Thumbnailer
class FileType(Enum):
DIRECTORY = auto()
@ -18,6 +20,8 @@ class FileItem(GObject.Object):
file_type: FileType
full_path: Path
thumbnail: bytes
attempted_thumbnail: bool
_has_thumbnail: bool
__gtype_name__ = "FileItem"
@ -28,6 +32,7 @@ class FileItem(GObject.Object):
self.file_type = file_type
self.full_path = full_path
self.thumbnail = b""
self.attempted_thumbnail = False
self._has_thumbnail = False
@GObject.Property(type=GObject.TYPE_UINT64)
@ -75,6 +80,13 @@ class FileItem(GObject.Object):
self._has_thumbnail = value
self.notify("has-thumbnail")
def ensure_thumbnail(self, thumbnailer: Thumbnailer):
if self.thumbnail or self.attempted_thumbnail:
return
if not self.attempted_thumbnail:
thumbnailer.generate_thumbnail(self)
@overload
def _load_attribute(self, name: str, dfl: str) -> str: ...

View file

@ -246,21 +246,20 @@ class MainWindow(Gtk.ApplicationWindow):
item.connect("notify::saved-duration", update_icon)
update_icon()
def _refresh(self):
self._populate_file_list()
pos = self.selection_history.get(str(os.getcwd()), 0)
def _restore_selection(self):
pos = self.selection_history.get(os.getcwd(), 0)
self.selection_model.set_selected(pos)
self.list_view.scroll_to(pos, Gtk.ListScrollFlags.SELECT | Gtk.ListScrollFlags.FOCUS, None)
def _refresh(self):
self._populate_file_list()
self._restore_selection()
def _navigate_to(self, path: Path):
self.directory_history.append(Path(os.getcwd()))
os.chdir(path)
self._populate_file_list()
pos = self.selection_history.get(str(path), 0)
self.selection_model.set_selected(pos)
self.list_view.scroll_to(pos, Gtk.ListScrollFlags.SELECT | Gtk.ListScrollFlags.FOCUS, None)
self._restore_selection()
def _navigate_back(self):
if not self.directory_history:
@ -269,10 +268,7 @@ class MainWindow(Gtk.ApplicationWindow):
prev_dir = self.directory_history.pop()
os.chdir(prev_dir)
self._populate_file_list()
pos = self.selection_history.get(str(prev_dir), 0)
self.selection_model.set_selected(pos)
self.list_view.scroll_to(pos, Gtk.ListScrollFlags.SELECT | Gtk.ListScrollFlags.FOCUS, None)
self._restore_selection()
def _on_selection_changed(
self,
@ -287,8 +283,7 @@ class MainWindow(Gtk.ApplicationWindow):
self.selection_history[os.getcwd()] = position
file_item = self.selection
if file_item is not None:
if file_item := self.selection:
# Update thumbnail if available
if file_item.thumbnail:
gbytes = GLib.Bytes.new(cast(Any, file_item.thumbnail))
@ -475,9 +470,9 @@ class MainWindow(Gtk.ApplicationWindow):
self.last_position_save = frame_time
# Update thumbnail if available
file_item = self.selection
if file_item := self.selection:
file_item.ensure_thumbnail(self.thumbnailer)
if file_item is not None:
if file_item.thumbnail and not self.thumbnail_image.get_paintable():
gbytes = GLib.Bytes.new(cast(Any, file_item.thumbnail))
texture = Gdk.Texture.new_from_bytes(gbytes)

View file

@ -3,7 +3,7 @@ from __future__ import annotations
import threading
from queue import Empty, Queue
from gi.repository import Gst
from gi.repository import GLib, Gst
from .file_model import FileItem
@ -28,6 +28,7 @@ class Thumbnailer(threading.Thread):
self.queue.get_nowait()
except Empty:
pass
self.queue.put_nowait(file_item)
def stop(self):
@ -51,6 +52,7 @@ class Thumbnailer(threading.Thread):
if file_item is None:
break
file_item.attempted_thumbnail = True
self._generate_thumbnail(file_item)
def _generate_thumbnail(self, file_item: FileItem):
@ -105,11 +107,18 @@ class Thumbnailer(threading.Thread):
return
try:
file_item.thumbnail = bytes(map_info.data)
file_item.has_thumbnail = True
thumbnail = bytes(map_info.data)
finally:
buffer.unmap(map_info)
def set_thumbnail():
file_item.thumbnail = thumbnail
file_item.has_thumbnail = True
GLib.idle_add(set_thumbnail)
except Exception as err:
print("Failed:", file_item.full_path, err)
finally:
pipeline.set_state(Gst.State.NULL)