from __future__ import annotations import os from pathlib import Path from typing import Any, cast import gi gi.require_version("Gtk", "4.0") from gi.repository import Gdk, Gtk # NOQA: E402 class MainWindow(Gtk.ApplicationWindow): def __init__(self, *args: Any, **kwargs: Any): super().__init__(*args, **kwargs) # Make window fullscreen and borderless self.set_decorated(False) self.fullscreen() # Main horizontal box to split the screen main_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) # Left half left_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) left_box.set_valign(Gtk.Align.CENTER) left_box.set_halign(Gtk.Align.CENTER) left_label = Gtk.Label(label="Left Side") left_box.append(left_label) left_box.set_hexpand(True) # Right half - File list right_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) right_box.set_hexpand(True) # Create list store and view list_store = Gtk.StringList() list_view = Gtk.ListView() list_view.set_model(Gtk.SingleSelection.new(list_store)) list_view.set_vexpand(True) # Factory for list items factory = Gtk.SignalListItemFactory() factory.connect("setup", self._setup_list_item) factory.connect("bind", self._bind_list_item) list_view.set_factory(factory) # Populate the list store self._populate_file_list(list_store) # Add list view to a scrolled window scrolled = Gtk.ScrolledWindow() scrolled.set_child(list_view) right_box.append(scrolled) # Add both halves to main box main_box.append(left_box) main_box.append(right_box) self.set_child(main_box) def _setup_list_item(self, factory: Gtk.SignalListItemFactory, list_item: Gtk.ListItem) -> None: label = Gtk.Label() label.set_halign(Gtk.Align.START) list_item.set_child(label) def _bind_list_item(self, factory: Gtk.SignalListItemFactory, list_item: Gtk.ListItem) -> None: label = cast(Gtk.Label, list_item.get_child()) item = cast(Gtk.StringObject, list_item.get_item()) label.set_text(item.get_string()) def _populate_file_list(self, list_store: Gtk.StringList) -> None: # TODO: Implement proper version sort (strverscmp equivalent) directories: list[str] = [] files: list[str] = [] with os.scandir(".") as it: for entry in it: if entry.name == ".." or not entry.name.startswith("."): if entry.is_dir(): directories.append(entry.name) else: files.append(entry.name) directories.sort(key=lambda x: x.lower()) files.sort(key=lambda x: x.lower()) for name in directories: list_store.append(f"{name}/") for name in files: list_store.append(name) class App(Gtk.Application): def __init__(self): super().__init__() # Load CSS css_provider = Gtk.CssProvider() css_file = Path(__file__).parent / "style.css" css_provider.load_from_path(str(css_file)) display = Gdk.Display.get_default() if display is None: raise RuntimeError("No display available") Gtk.StyleContext.add_provider_for_display( display, css_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION, ) def do_activate(self): win = MainWindow(application=self) win.present() def main(): app = App() app.run(None)