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"]