nodes/menu.pyΒΆ

Part of Klondike Solitaire.

 1"""Title menu shown before the first deal.
 2
 3A full-rect ``Control`` that dims the table behind it and offers the two
 4entry points: a fresh deal, or resuming the save on disk (offered only when
 5a save file exists). Everything is anchored, so the card stays centred at
 6any window size.
 7"""
 8
 9from __future__ import annotations
10
11from collections.abc import Callable
12
13from simvx.core.ui import Anchor, Button, Control, Label, Panel
14
15CARD_W = 520
16BUTTON_H = 46
17
18
19class TitleMenu(Control):
20    """Dimmed title card with New game / Continue / Quit."""
21
22    def __init__(
23        self, *, on_new_game: Callable[[], None], on_continue: Callable[[], None] | None, on_quit: Callable[[], None]
24    ) -> None:
25        super().__init__(name="TitleMenu", anchor=Anchor.FULL_RECT)
26        self.z_index = 6000  # above the cards and the HUD
27
28        dim = self.add_child(Panel(name="Dim", anchor=Anchor.FULL_RECT))
29        dim.bg_colour = (0.03, 0.12, 0.07, 0.72)
30
31        rows = [("New game", "MenuNewGame", on_new_game)]
32        if on_continue is not None:
33            rows.append(("Continue saved game", "MenuContinue", on_continue))
34        rows.append(("Quit", "MenuQuit", on_quit))
35
36        card_h = 190 + len(rows) * (BUTTON_H + 14)
37        card = self.add_child(Panel(name="Card", anchor=Anchor.CENTER, size=(CARD_W, card_h)))
38        card.bg_colour = (0.04, 0.09, 0.14, 0.94)
39
40        self._line(card, "Klondike Solitaire", top=26, height=44, size=32.0, colour=(1.0, 0.95, 0.6, 1.0), name="Title")
41        self._line(
42            card,
43            "SimVX port inspired by zaccnz/solitaire",
44            top=76,
45            height=22,
46            size=15.0,
47            colour=(0.82, 0.88, 0.94, 1.0),
48            name="Credit",
49        )
50
51        y = 120
52        for label, name, handler in rows:
53            button = card.add_child(
54                Button(label, on_press=handler, name=name, anchor=Anchor.TOP_WIDE, size=(0, BUTTON_H), inset=(90, y))
55            )
56            button.font_size = 18.0
57            y += BUTTON_H + 14
58
59        self._line(
60            card,
61            "Drag cards onto piles, or click a card to auto-move it",
62            top=y + 8,
63            height=22,
64            size=14.0,
65            colour=(0.78, 0.85, 0.92, 1.0),
66            name="Hint",
67        )
68
69    def _line(
70        self,
71        parent: Control,
72        text: str,
73        *,
74        top: float,
75        height: float,
76        size: float,
77        colour: tuple[float, float, float, float],
78        name: str,
79    ) -> Label:
80        label = parent.add_child(Label(text, name=name, anchor=Anchor.TOP_WIDE, size=(0, height), inset=(0, top)))
81        label.font_size = size
82        label.alignment = "centre"
83        label.text_colour = colour
84        return label
85
86
87__all__ = ["TitleMenu"]