Use ListModel for faster directory traversal
This commit is contained in:
parent
c54f183b0a
commit
2fb5265463
2 changed files with 55 additions and 16 deletions
lazy_player
|
@ -7,20 +7,20 @@ from typing import Any, cast
|
|||
|
||||
import gi
|
||||
|
||||
from .file_model import FileItem, FileType
|
||||
from .file_model import FileItem, FileListModel, FileType
|
||||
|
||||
gi.require_version("Gdk", "4.0")
|
||||
gi.require_version("Gtk", "4.0")
|
||||
gi.require_version("Gst", "1.0")
|
||||
gi.require_version("Pango", "1.0")
|
||||
from gi.repository import Gdk, Gio, Gst, Gtk, Pango # NOQA: E402
|
||||
from gi.repository import Gdk, Gst, Gtk, Pango # NOQA: E402
|
||||
|
||||
|
||||
class MainWindow(Gtk.ApplicationWindow):
|
||||
file_info_label: Gtk.Label
|
||||
stack: Gtk.Stack
|
||||
list_view: Gtk.ListView
|
||||
list_store: Gio.ListStore
|
||||
list_model: FileListModel
|
||||
selection_model: Gtk.SingleSelection
|
||||
video_widget: Gtk.Picture
|
||||
pipeline: Gst.Pipeline
|
||||
|
@ -137,10 +137,10 @@ class MainWindow(Gtk.ApplicationWindow):
|
|||
|
||||
main_box.append(grid)
|
||||
|
||||
# Create list store and view
|
||||
self.list_store = Gio.ListStore(item_type=FileItem)
|
||||
# Create list model and view
|
||||
self.list_model = FileListModel()
|
||||
self.list_view = Gtk.ListView()
|
||||
self.selection_model = Gtk.SingleSelection.new(self.list_store)
|
||||
self.selection_model = Gtk.SingleSelection.new(self.list_model)
|
||||
self.selection_model.connect("selection-changed", self._on_selection_changed)
|
||||
self.list_view.set_model(self.selection_model)
|
||||
self.list_view.set_vexpand(True)
|
||||
|
@ -285,8 +285,8 @@ class MainWindow(Gtk.ApplicationWindow):
|
|||
self._populate_file_list()
|
||||
|
||||
# Find and select the directory we came from
|
||||
for i in range(self.list_store.get_n_items()):
|
||||
item = self.list_store.get_item(i)
|
||||
for i in range(self.list_model.get_n_items()):
|
||||
item = self.list_model.get_item(i)
|
||||
if not item:
|
||||
continue
|
||||
|
||||
|
@ -392,7 +392,7 @@ class MainWindow(Gtk.ApplicationWindow):
|
|||
file_item.save_attribute("position", duration)
|
||||
|
||||
# Force the list to update the changed item
|
||||
self.list_store.items_changed(self.selection_model.get_selected(), 1, 1)
|
||||
self.list_model.items_changed(self.selection_model.get_selected(), 1, 1)
|
||||
|
||||
def _on_menu_key_pressed(
|
||||
self,
|
||||
|
@ -551,11 +551,7 @@ class MainWindow(Gtk.ApplicationWindow):
|
|||
# Sort directories first, then files, both alphabetically
|
||||
items.sort(key=lambda x: (x.file_type != FileType.DIRECTORY, x.name.lower()))
|
||||
|
||||
while self.list_store.get_n_items():
|
||||
self.list_store.remove(0)
|
||||
|
||||
for item in items:
|
||||
self.list_store.append(item)
|
||||
self.list_model.set_items(items)
|
||||
|
||||
if items:
|
||||
self.file_info_label.set_text(items[0].name)
|
||||
|
|
|
@ -3,12 +3,12 @@ from __future__ import annotations
|
|||
import os
|
||||
from enum import Enum, auto
|
||||
from pathlib import Path
|
||||
from typing import overload
|
||||
from typing import Optional, overload
|
||||
|
||||
import gi
|
||||
|
||||
gi.require_version("GObject", "2.0")
|
||||
from gi.repository import GObject # NOQA: E402
|
||||
from gi.repository import Gio, GObject # NOQA: E402
|
||||
|
||||
|
||||
class FileType(Enum):
|
||||
|
@ -54,3 +54,46 @@ class FileItem(GObject.Object):
|
|||
pass
|
||||
|
||||
self.notify("attrs-changed")
|
||||
|
||||
|
||||
class FileListModel(GObject.Object, Gio.ListModel):
|
||||
"""A ListModel implementation for FileItems"""
|
||||
|
||||
__gtype_name__ = "FileListModel"
|
||||
|
||||
items: list[FileItem]
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.items = []
|
||||
|
||||
def do_get_item_type(self) -> GObject.GType:
|
||||
return GObject.type_from_name("FileItem")
|
||||
|
||||
def do_get_n_items(self) -> int:
|
||||
return len(self.items)
|
||||
|
||||
def do_get_item(self, position: int) -> Optional[FileItem]:
|
||||
if 0 <= position < len(self.items):
|
||||
return self.items[position]
|
||||
return None
|
||||
|
||||
def remove_all(self) -> None:
|
||||
removed = len(self.items)
|
||||
self.items = []
|
||||
self.items_changed(0, removed, 0)
|
||||
|
||||
def set_items(self, items: list[FileItem]):
|
||||
removed = len(self.items)
|
||||
self.items = list(items)
|
||||
self.items_changed(0, removed, len(self.items))
|
||||
|
||||
def append(self, item: FileItem) -> None:
|
||||
pos = len(self.items)
|
||||
self.items.append(item)
|
||||
self.items_changed(pos, 0, 1)
|
||||
|
||||
def remove(self, position: int) -> None:
|
||||
if 0 <= position < len(self.items):
|
||||
self.items.pop(position)
|
||||
self.items_changed(position, 1, 0)
|
||||
|
|
Loading…
Reference in a new issue