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 AnchorPreset, 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")
26 self.set_anchor_preset(AnchorPreset.FULL_RECT)
27 self.z_index = 6000 # above the cards and the HUD
28
29 dim = self.add_child(Panel(name="Dim"))
30 dim.set_anchor_preset(AnchorPreset.FULL_RECT)
31 dim.bg_colour = (0.03, 0.12, 0.07, 0.72)
32
33 rows = [("New game", "MenuNewGame", on_new_game)]
34 if on_continue is not None:
35 rows.append(("Continue saved game", "MenuContinue", on_continue))
36 rows.append(("Quit", "MenuQuit", on_quit))
37
38 card_h = 190 + len(rows) * (BUTTON_H + 14)
39 card = self.add_child(Panel(name="Card"))
40 card.set_anchor_preset(AnchorPreset.CENTER)
41 card.margin_left, card.margin_right = -CARD_W * 0.5, CARD_W * 0.5
42 card.margin_top, card.margin_bottom = -card_h * 0.5, card_h * 0.5
43 card.bg_colour = (0.04, 0.09, 0.14, 0.94)
44
45 self._line(card, "Klondike Solitaire", top=26, height=44, size=32.0, colour=(1.0, 0.95, 0.6, 1.0), name="Title")
46 self._line(
47 card,
48 "SimVX port inspired by zaccnz/solitaire",
49 top=76,
50 height=22,
51 size=15.0,
52 colour=(0.82, 0.88, 0.94, 1.0),
53 name="Credit",
54 )
55
56 y = 120
57 for label, name, handler in rows:
58 button = card.add_child(Button(label, on_press=handler, name=name))
59 button.set_anchor_preset(AnchorPreset.TOP_WIDE)
60 button.margin_left, button.margin_right = 90, 90
61 button.margin_top, button.margin_bottom = y, y + BUTTON_H
62 button.font_size = 18.0
63 y += BUTTON_H + 14
64
65 self._line(
66 card,
67 "Drag cards onto piles, or click a card to auto-move it",
68 top=y + 8,
69 height=22,
70 size=14.0,
71 colour=(0.78, 0.85, 0.92, 1.0),
72 name="Hint",
73 )
74
75 def _line(
76 self,
77 parent: Control,
78 text: str,
79 *,
80 top: float,
81 height: float,
82 size: float,
83 colour: tuple[float, float, float, float],
84 name: str,
85 ) -> Label:
86 label = parent.add_child(Label(text, name=name))
87 label.set_anchor_preset(AnchorPreset.TOP_WIDE)
88 label.margin_top, label.margin_bottom = top, top + height
89 label.font_size = size
90 label.alignment = "center"
91 label.text_colour = colour
92 return label
93
94
95__all__ = ["TitleMenu"]