Replace main menu buttons with OptionList for arrow key navigation

OptionList supports up/down arrow keys and Enter to select,
giving a proper menu feel instead of Tab-through buttons.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
shuki
2026-03-05 23:49:06 +02:00
parent fd0ccefad0
commit b13514e478
2 changed files with 31 additions and 31 deletions

View File

@@ -19,10 +19,10 @@ Screen {
overflow-y: auto;
}
#main-menu Button {
#menu-list {
width: 100%;
height: 3;
margin: 0;
height: auto;
max-height: 100%;
}
#logo {

View File

@@ -1,6 +1,7 @@
from textual.app import ComposeResult
from textual.screen import Screen
from textual.widgets import Header, Footer, Static, Button
from textual.widgets import Header, Footer, Static, OptionList
from textual.widgets.option_list import Option
from textual.containers import Vertical, Center
LOGO = """\
@@ -13,6 +14,20 @@ LOGO = """\
gniza - Linux Backup Manager
"""
MENU_ITEMS = [
("backup", "Backup"),
("restore", "Restore"),
("targets", "Targets"),
("remotes", "Remotes"),
("snapshots", "Snapshots"),
("verify", "Verify"),
("retention", "Retention"),
("schedule", "Schedules"),
("logs", "Logs"),
("settings", "Settings"),
("quit", "Quit"),
]
class MainMenuScreen(Screen):
@@ -23,36 +38,21 @@ class MainMenuScreen(Screen):
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 OptionList(
*[Option(label, id=mid) for mid, label in MENU_ITEMS],
id="menu-list",
)
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":
def on_mount(self) -> None:
self.query_one("#menu-list", OptionList).focus()
def on_option_list_option_selected(self, event: OptionList.OptionSelected) -> None:
option_id = event.option.id
if option_id == "quit":
self.app.exit()
elif event.button.id in button_map:
self.app.push_screen(button_map[event.button.id])
elif option_id:
self.app.push_screen(option_id)
def action_quit_app(self) -> None:
self.app.exit()