| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118 |
- # -*- coding: utf-8 -*-
- """
- Progress-Dialog (Modal) fuer die TUI.
- Zeigt einen Fortschrittsbalken mit Cancel-Button waehrend
- lang laufender Aktionen (z.B. TTS-Generierung).
- """
- from __future__ import annotations
- from textual.screen import ModalScreen
- from textual.containers import Vertical
- from textual.widgets import Static, Button, ProgressBar
- from textual.app import ComposeResult
- class ProgressDialog(ModalScreen[bool]):
- """
- Modaler Progress-Dialog.
- Zeigt Titel, Statustext, Fortschrittsbalken und Cancel-Button.
- Gibt True zurueck wenn erfolgreich abgeschlossen, False bei Cancel.
- """
- DEFAULT_CSS = """
- ProgressDialog {
- align: center middle;
- }
- ProgressDialog > Vertical {
- width: 64;
- height: auto;
- max-height: 14;
- border: thick $accent;
- background: $surface;
- padding: 1 2;
- }
- ProgressDialog > Vertical > #progress-title {
- text-style: bold;
- margin-bottom: 1;
- }
- ProgressDialog > Vertical > #progress-status {
- margin-bottom: 1;
- }
- ProgressDialog > Vertical > ProgressBar {
- margin-bottom: 1;
- }
- ProgressDialog > Vertical > #progress-cancel {
- width: 100%;
- }
- """
- def __init__(self, title: str = "Generierung", **kwargs) -> None:
- super().__init__(**kwargs)
- self._title = title
- self._cancelled = False
- @property
- def cancelled(self) -> bool:
- """Ob der Benutzer abgebrochen hat."""
- return self._cancelled
- def compose(self) -> ComposeResult:
- with Vertical():
- yield Static(self._title, id="progress-title")
- yield Static("[yellow]Wird vorbereitet...[/yellow]", id="progress-status")
- yield ProgressBar(total=100, show_eta=False, id="progress-bar")
- yield Button("Abbrechen", variant="warning", id="progress-cancel")
- def update_progress(self, current: int, total: int, message: str = "") -> None:
- """Aktualisiert Fortschritt und Status-Text."""
- try:
- bar = self.query_one("#progress-bar", ProgressBar)
- bar.update(total=total, progress=current)
- except Exception:
- pass
- if message:
- try:
- status = self.query_one("#progress-status", Static)
- pct = int(current / max(total, 1) * 100)
- status.update(f"[yellow]{message} ({pct}%)[/yellow]")
- except Exception:
- pass
- def finish(self, message: str = "Fertig!") -> None:
- """Zeigt Abschluss-Nachricht und schliesst nach kurzer Pause."""
- try:
- status = self.query_one("#progress-status", Static)
- status.update(f"[green]{message}[/green]")
- bar = self.query_one("#progress-bar", ProgressBar)
- bar.update(total=100, progress=100)
- btn = self.query_one("#progress-cancel", Button)
- btn.label = "Schliessen"
- btn.variant = "primary"
- except Exception:
- pass
- def show_error(self, message: str) -> None:
- """Zeigt Fehlermeldung."""
- try:
- status = self.query_one("#progress-status", Static)
- status.update(f"[red]{message}[/red]")
- btn = self.query_one("#progress-cancel", Button)
- btn.label = "Schliessen"
- btn.variant = "error"
- except Exception:
- pass
- def on_button_pressed(self, event: Button.Pressed) -> None:
- """Cancel/Schliessen Button."""
- if event.button.id == "progress-cancel":
- self._cancelled = True
- self.dismiss(False)
|