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
|
import gi
|
||||||
|
|
||||||
from .file_model import FileItem, FileType
|
from .file_model import FileItem, FileListModel, FileType
|
||||||
|
|
||||||
gi.require_version("Gdk", "4.0")
|
gi.require_version("Gdk", "4.0")
|
||||||
gi.require_version("Gtk", "4.0")
|
gi.require_version("Gtk", "4.0")
|
||||||
gi.require_version("Gst", "1.0")
|
gi.require_version("Gst", "1.0")
|
||||||
gi.require_version("Pango", "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):
|
class MainWindow(Gtk.ApplicationWindow):
|
||||||
file_info_label: Gtk.Label
|
file_info_label: Gtk.Label
|
||||||
stack: Gtk.Stack
|
stack: Gtk.Stack
|
||||||
list_view: Gtk.ListView
|
list_view: Gtk.ListView
|
||||||
list_store: Gio.ListStore
|
list_model: FileListModel
|
||||||
selection_model: Gtk.SingleSelection
|
selection_model: Gtk.SingleSelection
|
||||||
video_widget: Gtk.Picture
|
video_widget: Gtk.Picture
|
||||||
pipeline: Gst.Pipeline
|
pipeline: Gst.Pipeline
|
||||||
|
@ -137,10 +137,10 @@ class MainWindow(Gtk.ApplicationWindow):
|
||||||
|
|
||||||
main_box.append(grid)
|
main_box.append(grid)
|
||||||
|
|
||||||
# Create list store and view
|
# Create list model and view
|
||||||
self.list_store = Gio.ListStore(item_type=FileItem)
|
self.list_model = FileListModel()
|
||||||
self.list_view = Gtk.ListView()
|
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.selection_model.connect("selection-changed", self._on_selection_changed)
|
||||||
self.list_view.set_model(self.selection_model)
|
self.list_view.set_model(self.selection_model)
|
||||||
self.list_view.set_vexpand(True)
|
self.list_view.set_vexpand(True)
|
||||||
|
@ -285,8 +285,8 @@ class MainWindow(Gtk.ApplicationWindow):
|
||||||
self._populate_file_list()
|
self._populate_file_list()
|
||||||
|
|
||||||
# Find and select the directory we came from
|
# Find and select the directory we came from
|
||||||
for i in range(self.list_store.get_n_items()):
|
for i in range(self.list_model.get_n_items()):
|
||||||
item = self.list_store.get_item(i)
|
item = self.list_model.get_item(i)
|
||||||
if not item:
|
if not item:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
@ -392,7 +392,7 @@ class MainWindow(Gtk.ApplicationWindow):
|
||||||
file_item.save_attribute("position", duration)
|
file_item.save_attribute("position", duration)
|
||||||
|
|
||||||
# Force the list to update the changed item
|
# 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(
|
def _on_menu_key_pressed(
|
||||||
self,
|
self,
|
||||||
|
@ -551,11 +551,7 @@ class MainWindow(Gtk.ApplicationWindow):
|
||||||
# Sort directories first, then files, both alphabetically
|
# Sort directories first, then files, both alphabetically
|
||||||
items.sort(key=lambda x: (x.file_type != FileType.DIRECTORY, x.name.lower()))
|
items.sort(key=lambda x: (x.file_type != FileType.DIRECTORY, x.name.lower()))
|
||||||
|
|
||||||
while self.list_store.get_n_items():
|
self.list_model.set_items(items)
|
||||||
self.list_store.remove(0)
|
|
||||||
|
|
||||||
for item in items:
|
|
||||||
self.list_store.append(item)
|
|
||||||
|
|
||||||
if items:
|
if items:
|
||||||
self.file_info_label.set_text(items[0].name)
|
self.file_info_label.set_text(items[0].name)
|
||||||
|
|
|
@ -3,12 +3,12 @@ from __future__ import annotations
|
||||||
import os
|
import os
|
||||||
from enum import Enum, auto
|
from enum import Enum, auto
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import overload
|
from typing import Optional, overload
|
||||||
|
|
||||||
import gi
|
import gi
|
||||||
|
|
||||||
gi.require_version("GObject", "2.0")
|
gi.require_version("GObject", "2.0")
|
||||||
from gi.repository import GObject # NOQA: E402
|
from gi.repository import Gio, GObject # NOQA: E402
|
||||||
|
|
||||||
|
|
||||||
class FileType(Enum):
|
class FileType(Enum):
|
||||||
|
@ -54,3 +54,46 @@ class FileItem(GObject.Object):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
self.notify("attrs-changed")
|
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