Skip to content

UI Components

magmacrunchmedia edited this page Aug 24, 2026 · 4 revisions

UI Components

All three widgets draw straight onto the game canvas using tagged items, so they share the surface with your game. None of them handle input — you drive them from your own key handling, which is what lets you use the same code for keyboard and controller.

from texastoast.ui import DialogueBox, Menu, HUD

Draw order matters. renderer.clear() deletes every canvas item, including these. Either render UI after clearing, or drive it from update.

DialogueBox

A bottom-of-screen text box with typewriter output and an optional speaker name.

dialogue = DialogueBox(game.canvas, 400, 300, box_height=100, speed=0.03)

dialogue.show("Welcome, traveler!", speaker="Old Wizard",
              on_complete=lambda: print("done"))

dialogue.active    # a box is on screen
dialogue.waiting   # all text is revealed, waiting for dismissal

speed is seconds per character.

dismiss() does the two-stage thing players expect:

  • while text is still typing, it completes the text immediately
  • once fully revealed, it closes the box and fires on_complete

So a single key can drive the whole interaction:

def on_key(event):
    if dialogue.active and event.keysym in ("z", "Return", "space"):
        dialogue.dismiss()
        return
    ...

Typing is driven by the canvas's own after() timer, not by your game loop, so dialogue keeps animating even while the game is paused.

Menu

A centered list with keyboard-driven selection.

menu = Menu(game.canvas, 400, 300)

menu.show(
    ["Resume", "Settings", "Quit"],
    on_select=lambda index, label: handle(label),
    on_cancel=lambda: menu.hide(),
    title="PAUSED",
    selected=0,
)

menu.move_up()
menu.move_down()
menu.confirm()          # hides, then calls on_select
menu.cancel()           # hides, then calls on_cancel
menu.hide()             # hides, calls nothing

menu.active
menu.selected_index

Items can be greyed out, and the selection skips them:

menu.set_enabled(1, False)   # "Settings" is now unselectable

Two behaviors to be aware of:

  • show([]) does nothing. An empty item list returns early and leaves the menu inactive, so check before calling if the list is built dynamically.
  • confirm() hides the menu before calling on_select. If your handler tracks a paused flag, remember to clear it — otherwise an unhandled option leaves the game paused with no menu on screen. Handle every label, including the ones that do nothing yet.
def on_select(index, label):
    global paused
    paused = False            # always clear it
    if label == "Quit":
        game.quit()

HUD

Screen-space stat bars and text that ignore the camera.

hud = HUD(game.canvas, 400, 300)

hud.add_stat("hp", "HP", value=100, max_value=100, color="#e94560")
hud.set_stat("hp", 75)        # clamped to 0..max_value

hud.add_text("score", "Score: 0", x=300, y=8, fill="#fdd835")
hud.set_text("score", "Score: 120")
hud.remove_text("score")

hud.clear()                   # drop every stat and text
hud.render()                  # draw — call once per frame

Stats are laid out top-left in insertion order. Extra keyword arguments to add_text go to tkinter's create_text.

set_stat and set_text silently do nothing if the key does not exist, so a typo shows up as a value that never changes rather than an error. Register with add_* first.

For text that appears and disappears — a "Press Z to talk" hint — add_text and remove_text are the pair to use; calling add_text every frame works but rebuilds the entry each time.

Clone this wiki locally