nodes/_back_button.pyΒΆ

Part of Dungeon Explorer.

 1"""Back-button helpers shared across popup screens.
 2
 3Renders a circular touch-friendly back glyph in the top-left corner. Hit-test
 4returns True for clicks landing on the disc. Used by popups that want a tap
 5target equivalent to pressing Esc.
 6"""
 7
 8import math
 9
10__all__ = [
11    "BACK_BTN_CX",
12    "BACK_BTN_CY",
13    "BACK_BTN_R",
14    "draw_back_button",
15    "back_button_hit",
16    "check_menu_click",
17]
18
19# Circular back button anchored to the top-left corner. ~56px diameter is
20# finger-friendly and visually consistent across popups.
21BACK_BTN_CX = 40.0
22BACK_BTN_CY = 40.0
23BACK_BTN_R = 28.0
24
25
26def draw_back_button(renderer) -> None:
27    """Draw a tappable "back" glyph (curved arrow) in the top-left corner."""
28    cx, cy, r = BACK_BTN_CX, BACK_BTN_CY, BACK_BTN_R
29    renderer.draw_circle((cx, cy), r, colour=(0.08, 0.08, 0.10, 0.85), filled=True)
30    renderer.draw_circle((cx, cy), r - 3, colour=(0.22, 0.22, 0.26, 0.9), filled=True)
31    arc_r = r * 0.55
32    for deg in range(-70, 200, 12):
33        rad = math.radians(deg)
34        px = cx + math.cos(rad) * arc_r
35        py = cy + math.sin(rad) * arc_r
36        renderer.draw_rect((px - 1.5, py - 1.5), (3, 3), colour=(1.0, 0.9, 0.3, 1.0), filled=True)
37    ax = cx + math.cos(math.radians(200)) * arc_r
38    ay = cy + math.sin(math.radians(200)) * arc_r
39    renderer.fill_triangle(
40        ax - 8,
41        ay,
42        ax + 4,
43        ay - 7,
44        ax + 4,
45        ay + 7,
46        colour=(1.0, 0.9, 0.3, 1.0),
47    )
48
49
50def back_button_hit(mx: float, my: float) -> bool:
51    """True when a click/touch lands on the back button."""
52    dx = mx - BACK_BTN_CX
53    dy = my - BACK_BTN_CY
54    return (dx * dx + dy * dy) <= BACK_BTN_R * BACK_BTN_R
55
56
57def check_menu_click(
58    mx: float, my: float, count: int, origin_x: float, origin_y: float, item_w: float, item_h: float, spacing: float
59) -> int | None:
60    """Return the index of the clicked menu item in a vertical list, or None."""
61    for i in range(count):
62        iy = origin_y + i * spacing
63        if origin_x <= mx <= origin_x + item_w and iy - 4 <= my <= iy + item_h:
64            return i
65    return None