From 0c0588f9203a3cc9d37281c4dd64fabac4e744ac Mon Sep 17 00:00:00 2001 From: adlee-was-taken Date: Tue, 7 Apr 2026 19:38:38 -0400 Subject: [PATCH] TUI: add double-escape quit and minor layout tweaks Co-Authored-By: Claude Opus 4.6 (1M context) --- client/timing-config.js | 1 - tui_client/src/tui_client/screens/connect.py | 15 ++++++-- tui_client/src/tui_client/screens/lobby.py | 36 ++++++++------------ tui_client/src/tui_client/styles.tcss | 5 ++- 4 files changed, 28 insertions(+), 29 deletions(-) diff --git a/client/timing-config.js b/client/timing-config.js index 6e634ed..4389c5b 100644 --- a/client/timing-config.js +++ b/client/timing-config.js @@ -1,4 +1,3 @@ -// SPDX-License-Identifier: GPL-3.0-or-later // Centralized timing configuration for all animations and pauses // Edit these values to tune the feel of card animations and CPU gameplay diff --git a/tui_client/src/tui_client/screens/connect.py b/tui_client/src/tui_client/screens/connect.py index 101cd89..bc60fc8 100644 --- a/tui_client/src/tui_client/screens/connect.py +++ b/tui_client/src/tui_client/screens/connect.py @@ -2,6 +2,8 @@ from __future__ import annotations +import time + from textual.app import ComposeResult from textual.containers import Container, Horizontal, Vertical from textual.screen import Screen @@ -23,6 +25,7 @@ class ConnectScreen(Screen): def __init__(self): super().__init__() self._mode: str = "login" # "login" or "signup" + self._last_esc: float = 0.0 def compose(self) -> ComposeResult: with Container(id="connect-container"): @@ -30,7 +33,7 @@ class ConnectScreen(Screen): # Login form with Vertical(id="login-form"): - yield Static("Log in to play") + yield Static("Log in to play\n") yield Input(placeholder="Username", id="input-username") yield Input(placeholder="Password", password=True, id="input-password") with Horizontal(id="connect-buttons"): @@ -64,7 +67,7 @@ class ConnectScreen(Screen): with Horizontal(classes="screen-footer"): yield Static("", id="connect-footer-left", classes="screen-footer-left") - yield Static("\\[q] quit", id="connect-footer-right", classes="screen-footer-right") + yield Static("\\[q]uit or \\[esc]x2", id="connect-footer-right", classes="screen-footer-right") def on_mount(self) -> None: self._update_form_visibility() @@ -103,11 +106,17 @@ class ConnectScreen(Screen): self._update_form_visibility() def handle_escape(self) -> None: - """Escape goes back to login if on signup form.""" + """Escape goes back to login if on signup form. Double-escape quits.""" if self._mode == "signup": self._mode = "login" self._set_status("") self._update_form_visibility() + self._last_esc = 0.0 + else: + now = time.monotonic() + if now - self._last_esc < 0.5: + self.app.exit() + self._last_esc = now def on_input_submitted(self, event: Input.Submitted) -> None: if event.input.id == "input-password": diff --git a/tui_client/src/tui_client/screens/lobby.py b/tui_client/src/tui_client/screens/lobby.py index 0536fed..9afc587 100644 --- a/tui_client/src/tui_client/screens/lobby.py +++ b/tui_client/src/tui_client/screens/lobby.py @@ -72,7 +72,7 @@ class LobbyScreen(Screen): # In-room: player list + controls + settings with Vertical(id="in-room"): yield Static("", id="room-info") - yield Static("[bold]Players[/bold]", id="player-list-label") + yield Static("[bold]Players[/bold]\n", id="player-list-label") yield Static("", id="player-list") # CPU controls: compact [+] [-] @@ -185,18 +185,18 @@ class LobbyScreen(Screen): yield Label("Wolfpack") yield Switch(id="sw-wolfpack") - with Collapsible(title="Deck Style", collapsed=True, id="coll-deck"): - with Horizontal(classes="setting-row"): - yield Select( - [(name.replace("-", " ").title(), name) for name in DECK_PRESETS], - value="classic", - id="sel-deck-style", - allow_blank=False, - ) - yield Static( - self._render_deck_preview("classic"), - id="deck-preview", - ) + with Horizontal(classes="setting-row"): + yield Label("Deck Style") + yield Select( + [(name.replace("-", " ").title(), name) for name in DECK_PRESETS], + value="classic", + id="sel-deck-style", + allow_blank=False, + ) + yield Static( + self._render_deck_preview("classic"), + id="deck-preview", + ) yield Button("Start Game", id="btn-start", variant="success") @@ -398,15 +398,7 @@ class LobbyScreen(Screen): ) line3 = "".join(parts3) - parts4: list[str] = [] - for color_name in seen: - hc = BACK_COLORS.get(color_name, BACK_COLORS["red"]) - parts4.append( - f"[{bc}]└───┘[/{bc}] " - ) - line4 = "".join(parts4) - - return f"{line1}\n{line2}\n{line3}\n{line4}" + return f"{line1}\n{line2}\n{line3}" def _add_random_cpu(self) -> None: """Add a random CPU (server picks the profile).""" diff --git a/tui_client/src/tui_client/styles.tcss b/tui_client/src/tui_client/styles.tcss index f90bc32..2c2d41b 100644 --- a/tui_client/src/tui_client/styles.tcss +++ b/tui_client/src/tui_client/styles.tcss @@ -205,9 +205,8 @@ LobbyScreen { #deck-preview { width: auto; - height: auto; - padding: 1 1 0 1; - text-align: center; + height: 3; + padding: 0 1; } .rule-row {