Files
gniza4linux/tui/screens/main_menu.py
shuki 587149f062 Add Python Textual TUI replacing gum-based bash TUI
New tui/ package with 14 screens (main menu, backup, restore, targets,
remotes, snapshots, verify, retention, schedule, logs, settings, wizard),
3 custom widgets (folder picker, confirm dialog, operation log), async
backend wrapper, pure-Python config parser, and TCSS theme.

bin/gniza now launches Textual TUI when available, falls back to gum.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 23:39:48 +02:00

59 lines
2.6 KiB
Python

from textual.app import ComposeResult
from textual.screen import Screen
from textual.widgets import Header, Footer, Static, Button
from textual.containers import Vertical, Center
LOGO = """\
[green]
\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593
\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593 \u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593
\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593
\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593
[/green]
gniza - Linux Backup Manager
"""
class MainMenuScreen(Screen):
BINDINGS = [("q", "quit_app", "Quit")]
def compose(self) -> ComposeResult:
yield Header()
with Center():
with Vertical(id="main-menu"):
yield Static(LOGO, id="logo", markup=True)
yield Button("Backup", id="menu-backup", variant="primary")
yield Button("Restore", id="menu-restore")
yield Button("Targets", id="menu-targets")
yield Button("Remotes", id="menu-remotes")
yield Button("Snapshots", id="menu-snapshots")
yield Button("Verify", id="menu-verify")
yield Button("Retention", id="menu-retention")
yield Button("Schedules", id="menu-schedule")
yield Button("Logs", id="menu-logs")
yield Button("Settings", id="menu-settings")
yield Button("Quit", id="menu-quit", variant="error")
yield Footer()
def on_button_pressed(self, event: Button.Pressed) -> None:
button_map = {
"menu-backup": "backup",
"menu-restore": "restore",
"menu-targets": "targets",
"menu-remotes": "remotes",
"menu-snapshots": "snapshots",
"menu-verify": "verify",
"menu-retention": "retention",
"menu-schedule": "schedule",
"menu-logs": "logs",
"menu-settings": "settings",
}
if event.button.id == "menu-quit":
self.app.exit()
elif event.button.id in button_map:
self.app.push_screen(button_map[event.button.id])
def action_quit_app(self) -> None:
self.app.exit()