Menu Bar¶
a desktop-style menu strip with dropdown menus.
▶ Run in browserTags: ui menu menubar desktop-ui
A MenuBar is a strip of titles; clicking one drops its menu open, and while
a menu is open, hovering another title switches to that menu. Choosing an item
runs its callback and closes the menu, as does clicking anywhere else or
pressing Escape. Here the bar holds File, Edit and View menus, and a status
line along the bottom echoes the last item chosen.
Build a menu from plain data with MenuBar.add_menu(title, items), where each
entry is a MenuItem:
MenuItem(text=..., callback=...)runscallback()with no arguments when chosen;functools.partialbinds any arguments it needs.shortcut="Ctrl+S"prints a hint at the right of the row. It is text only: binding the key is the game’s job.MenuItem(separator=True)draws a divider that does nothing when clicked.
The bar is placed with anchor=Anchor.TOP_WIDE, full width and
MenuBar.BAR_HEIGHT tall, and the content panel fills the window below it
with inset=(0, MenuBar.BAR_HEIGHT, 0, 0). Dropdowns are overlays, so they
draw over the panel and take input ahead of it while open.
Source¶
1# /// simvx
2# tags = ["ui", "menu", "menubar", "desktop-ui"]
3# web = { width = 800, height = 600, responsive = true }
4# ///
5"""Menu Bar: a desktop-style menu strip with dropdown menus.
6
7A `MenuBar` is a strip of titles; clicking one drops its menu open, and while
8a menu is open, hovering another title switches to that menu. Choosing an item
9runs its callback and closes the menu, as does clicking anywhere else or
10pressing Escape. Here the bar holds File, Edit and View menus, and a status
11line along the bottom echoes the last item chosen.
12
13Build a menu from plain data with `MenuBar.add_menu(title, items)`, where each
14entry is a `MenuItem`:
15
16- `MenuItem(text=..., callback=...)` runs `callback()` with no arguments when
17 chosen; `functools.partial` binds any arguments it needs.
18- `shortcut="Ctrl+S"` prints a hint at the right of the row. It is text only:
19 binding the key is the game's job.
20- `MenuItem(separator=True)` draws a divider that does nothing when clicked.
21
22The bar is placed with `anchor=Anchor.TOP_WIDE`, full width and
23`MenuBar.BAR_HEIGHT` tall, and the content panel fills the window below it
24with `inset=(0, MenuBar.BAR_HEIGHT, 0, 0)`. Dropdowns are overlays, so they
25draw over the panel and take input ahead of it while open.
26"""
27
28from functools import partial
29
30from simvx.core import Anchor, Colour, Label, MenuBar, MenuItem, Node, Panel
31from simvx.graphics import App
32
33
34class MenuDemo(Node):
35 def on_ready(self):
36 content = self.add_child(Panel(anchor=Anchor.FULL_RECT, inset=(0, MenuBar.BAR_HEIGHT, 0, 0)))
37 content.bg_colour = Colour.hex("#1A1A2E")
38 hint = content.add_child(Label("Click File, Edit or View to open a menu", anchor=Anchor.CENTER, font_size=16))
39 hint.text_colour = Colour.GRAY
40 self.status = content.add_child(Label("Ready", anchor=Anchor.BOTTOM_LEFT, inset=10))
41 self.status.text_colour = Colour.LIGHT_GRAY
42
43 menubar = self.add_child(MenuBar(name="menubar", anchor=Anchor.TOP_WIDE))
44 menubar.add_menu(
45 "File",
46 [
47 self.item("New", "Ctrl+N"),
48 self.item("Open", "Ctrl+O"),
49 self.item("Save", "Ctrl+S"),
50 MenuItem(separator=True),
51 MenuItem(text="Quit", callback=lambda: self.app.quit(), shortcut="Ctrl+Q"),
52 ],
53 )
54 menubar.add_menu(
55 "Edit",
56 [
57 self.item("Undo", "Ctrl+Z"),
58 self.item("Redo", "Ctrl+Y"),
59 MenuItem(separator=True),
60 self.item("Cut", "Ctrl+X"),
61 self.item("Copy", "Ctrl+C"),
62 self.item("Paste", "Ctrl+V"),
63 ],
64 )
65 menubar.add_menu(
66 "View",
67 [self.item("Zoom In", "Ctrl++"), self.item("Zoom Out", "Ctrl+-"), self.item("Reset Zoom", "Ctrl+0")],
68 )
69
70 def item(self, text: str, shortcut: str) -> MenuItem:
71 """A menu entry that reports itself on the status line when chosen."""
72 return MenuItem(text=text, callback=partial(self.chose, text), shortcut=shortcut)
73
74 def chose(self, text: str):
75 self.status.text = f"Action: {text}"
76
77
78if __name__ == "__main__":
79 App(title="SimVX Menu Demo", width=800, height=600).run(MenuDemo())