"""Main Textual application for the Translation Viewer TUI.""" from __future__ import annotations from pathlib import Path from textual.app import App, ComposeResult from textual.binding import Binding from textual.containers import Horizontal, ScrollableContainer from textual.widgets import Footer, Header from src.tui.data_provider import TUIDataProvider from src.tui.widgets import DetailPanel, VerseSelected, VerseTree class TranslationViewerApp(App): """TUI for viewing Bible translations and evaluations.""" TITLE = "Japanese Bible Translator Viewer" CSS = """ Screen { layout: horizontal; } #tree-container { width: 30%; min-width: 25; height: 100%; border: solid $primary; } #tree { width: 100%; height: 100%; } #detail-container { width: 70%; height: 100%; border: solid $secondary; } #detail { width: 100%; height: auto; padding: 1; } """ BINDINGS = [ Binding("q", "quit", "Quit"), Binding("d", "toggle_dark_mode", "Toggle dark mode"), Binding("r", "refresh", "Refresh"), ] def __init__(self, data_dir: Path | str = "data") -> None: """Initialize the app. Args: data_dir: Path to the data directory. """ super().__init__() self.data_dir = Path(data_dir) self.data_provider = TUIDataProvider(self.data_dir) def compose(self) -> ComposeResult: # pragma: no cover """Compose the application layout.""" yield Header() with Horizontal(): with ScrollableContainer(id="tree-container"): yield VerseTree(self.data_provider, id="tree") with ScrollableContainer(id="detail-container"): yield DetailPanel(self.data_provider, id="detail") yield Footer() def on_verse_selected(self, message: VerseSelected) -> None: # pragma: no cover """Handle verse selection from the tree.""" detail_panel = self.query_one("#detail", DetailPanel) detail_panel.update_verse(message.book, message.chapter, message.verse) def action_toggle_dark_mode(self) -> None: # pragma: no cover """Toggle dark mode.""" self.theme = ( "textual-light" if self.theme == "textual-dark" else "textual-dark" ) def action_refresh(self) -> None: # pragma: no cover """Refresh the tree view.""" tree = self.query_one("#tree", VerseTree) tree.clear() tree._populate_tree() def run_tui(data_dir: Path | str = "data") -> None: # pragma: no cover """Run the TUI application. Args: data_dir: Path to the data directory. """ app = TranslationViewerApp(data_dir=data_dir) app.run() if __name__ == "__main__": run_tui()