Grid Inventory¶
a 4x3 grid of selectable item slots.
▶ Run in browserTags: ui inventory game-ui
An inventory is a grid of slots the player picks from. A GridContainer lays its
children out in rows of columns, so the slots are plain Buttons added in
order and the grid places them; nothing here computes a position.
Each slot is a toggle button in one ButtonGroup. Joining a group turns a button
into a toggle, and the group keeps exactly one checked, so the chosen slot stays
drawn in its checked state until another is picked. The group’s
checked_changed(button) signal is the one place selection is handled: it fills
the detail line under the grid with the item name and slot number, or says the
slot is empty. A slot’s colour swatch is its bg_colour, which colours the
button’s normal state; hovered and checked slots draw the theme’s colours.
The grid and its labels sit in a VBoxContainer inset inside a Panel placed
with anchor=Anchor.CENTER, so the whole inventory stays centred as the window
resizes. Click or tap a slot to select it.
Source¶
1# /// simvx
2# tags = ["ui", "inventory", "game-ui"]
3# web = { width = 800, height = 600, responsive = true }
4# ///
5"""Grid Inventory: a 4x3 grid of selectable item slots.
6
7An inventory is a grid of slots the player picks from. A `GridContainer` lays its
8children out in rows of `columns`, so the slots are plain `Button`s added in
9order and the grid places them; nothing here computes a position.
10
11Each slot is a toggle button in one `ButtonGroup`. Joining a group turns a button
12into a toggle, and the group keeps exactly one checked, so the chosen slot stays
13drawn in its checked state until another is picked. The group's
14`checked_changed(button)` signal is the one place selection is handled: it fills
15the detail line under the grid with the item name and slot number, or says the
16slot is empty. A slot's colour swatch is its `bg_colour`, which colours the
17button's normal state; hovered and checked slots draw the theme's colours.
18
19The grid and its labels sit in a `VBoxContainer` inset inside a `Panel` placed
20with `anchor=Anchor.CENTER`, so the whole inventory stays centred as the window
21resizes. Click or tap a slot to select it.
22"""
23
24from simvx.core import Anchor, ButtonGroup, Colour, HAlign, Label, Node, Panel
25from simvx.core.ui import Button, GridContainer, VBoxContainer
26from simvx.graphics import App
27
28# (name, swatch colour); None marks an empty slot.
29ITEMS = [
30 ("Sword", "#C0392B"),
31 ("Shield", "#2980B9"),
32 ("Potion", "#27AE60"),
33 ("Key", "#F1C40F"),
34 ("Bow", "#8E44AD"),
35 ("Arrow", "#7F8C8D"),
36 ("Gem", "#16A085"),
37 ("Map", "#E67E22"),
38 ("Bread", "#D35400"),
39 (None, None),
40 ("Torch", "#E74C3C"),
41 (None, None),
42]
43
44
45class InventoryDemo(Node):
46 """A centred grid inventory with click-to-select slots."""
47
48 def on_ready(self):
49 panel = Panel(anchor=Anchor.CENTER, size=(480, 400))
50 panel.bg_colour = Colour.hex("#1B1B26")
51 self.add_child(panel)
52
53 column = VBoxContainer(anchor=Anchor.FULL_RECT, inset=(24, 20), separation=16)
54 panel.add_child(column)
55 column.add_child(Label("Inventory", font_size=22, alignment=HAlign.CENTRE))
56
57 self.slots = ButtonGroup()
58 self.slots.checked_changed.connect(self.on_slot_selected)
59 grid = GridContainer(columns=4, separation=8)
60 for name, swatch in ITEMS:
61 slot = Button(name or "(empty)", group=self.slots, size=(96, 64))
62 if swatch:
63 slot.bg_colour = Colour.hex(swatch)
64 grid.add_child(slot)
65 column.add_child(grid)
66
67 self.detail = Label("Select an item.", font_size=15, alignment=HAlign.CENTRE)
68 self.detail.text_colour = Colour.LIGHT_GRAY
69 column.add_child(self.detail)
70
71 def on_slot_selected(self, slot: Button):
72 number = self.slots.buttons.index(slot) + 1
73 name = ITEMS[number - 1][0]
74 self.detail.text = f"Selected: {name} (slot {number})" if name else f"Slot {number} is empty."
75
76
77if __name__ == "__main__":
78 App(title="SimVX Inventory", width=800, height=600).run(InventoryDemo())