simvx.core.ui.menu

Menu widgets – MenuItem, PopupMenu, MenuBar.

The MenuBar is the modal owner: when any of its menus is open, MenuBar captures input via the unified modal API. PopupMenus are children of the MenuBar (or of their parent popup for submenu chains) marked top_level=True so they render above sibling Controls. Outside-click and Escape dismiss the whole chain via the router.

Module Contents

Classes

MenuItem

Data for a single menu entry (text, callback, shortcut, or separator).

PopupMenu

Dropdown popup showing a vertical list of MenuItems.

MenuBar

Horizontal menu bar with named dropdown popups.

Data

API

simvx.core.ui.menu.log

‘getLogger(…)’

simvx.core.ui.menu.__all__

[‘MenuItem’, ‘PopupMenu’, ‘MenuBar’]

class simvx.core.ui.menu.MenuItem(text: str = '', callback: collections.abc.Callable = None, shortcut: str = '', separator: bool = False, submenu: list[simvx.core.ui.menu.MenuItem] | None = None)[source]

Data for a single menu entry (text, callback, shortcut, or separator).

Initialization

__slots__

(‘text’, ‘callback’, ‘shortcut’, ‘separator’, ‘submenu’)

class simvx.core.ui.menu.PopupMenu(items: list[simvx.core.ui.menu.MenuItem] = None, **kwargs)[source]

Bases: simvx.core.ui.core.Control

Dropdown popup showing a vertical list of MenuItems.

A PopupMenu is a non-modal floating Control with top_level=True. It relies on the owning MenuBar (or parent PopupMenu) to be modal: the router gates input to the modal subtree, the popup gets its clicks via standard child hit-testing within that subtree.

Initialization

bg_colour

‘ThemeColour(…)’

hover_colour

‘ThemeColour(…)’

text_colour

‘ThemeColour(…)’

shortcut_colour

‘ThemeColour(…)’

separator_colour

‘ThemeColour(…)’

border_colour

‘ThemeColour(…)’

style

‘ThemeStyleBox(…)’

style_hover

‘ThemeStyleBox(…)’

show(x: float, y: float)[source]

Position the menu and make it visible.

If no ancestor :class:MenuBar and no parent :class:PopupMenu exists, this popup pushes itself onto the modal stack so outside clicks dismiss it (used for standalone context menus). When part of a menu chain, the owning MenuBar / parent popup holds modality.

hide()[source]

Close this menu and any open child submenu.

is_point_inside(point) bool[source]
on_draw(renderer)[source]
size_x

‘Property(…)’

size_y

‘Property(…)’

anchor_left

‘Property(…)’

anchor_top

‘Property(…)’

anchor_right

‘Property(…)’

anchor_bottom

‘Property(…)’

margin_left

‘Property(…)’

margin_top

‘Property(…)’

margin_right

‘Property(…)’

margin_bottom

‘Property(…)’

modal

‘Property(…)’

dismiss_on_outside_click

‘Property(…)’

pause_tree_when_modal

‘Property(…)’

top_level

‘Property(…)’

property size: simvx.core.math.types.Vec2
touch_mode: str

‘mouse’

property theme: simvx.core.ui.types.Theme | None
property mouse_over: bool
property focused: bool
property disabled: bool
get_theme() simvx.core.ui.types.Theme
queue_redraw()
get_minimum_size() simvx.core.math.types.Vec2
get_rect() tuple[float, float, float, float]
get_global_rect() tuple[float, float, float, float]
place_bottom_strip(height: float) None
place_top_strip(height: float) None
set_anchor_preset(preset: simvx.core.ui.enums.AnchorPreset)
set_focus()
grab_focus()
release_focus()
has_focus() bool
focus_next_control()
focus_previous_control()
grab_mouse()
release_mouse()
set_drag_preview(control: simvx.core.ui.core.Control)
show_modal()
close_modal()
position

‘_SpatialVecProperty(…)’

rotation

‘Property(…)’

scale

‘_SpatialVecProperty(…)’

z_index

‘Property(…)’

z_as_relative

‘Property(…)’

render_layer

‘Property(…)’

set_render_layer(index: int, enabled: bool = True) None
is_on_render_layer(index: int) bool
property absolute_z_index: int
property rotation_degrees: float
property world_position: simvx.core.math.types.Vec2
property world_rotation: float
property world_scale: simvx.core.math.types.Vec2
property world_transform: tuple[simvx.core.math.types.Vec2, simvx.core.math.types.Vec2, float]
property forward: simvx.core.math.types.Vec2
property right: simvx.core.math.types.Vec2
translate(offset: tuple[float, float] | numpy.ndarray)
rotate(radians: float)
rotate_deg(degrees: float)
look_at(target: tuple[float, float] | numpy.ndarray)
transform_points(points: list[simvx.core.math.types.Vec2]) list[simvx.core.math.types.Vec2]
draw_polygon(renderer, points: list[simvx.core.math.types.Vec2], closed=True, colour=None)
wrap_screen(margin: float = 20)
strict_errors: ClassVar[bool]

True

script_error_raised

‘Signal(…)’

classmethod __init_subclass__(**kwargs)
property name: str
property process_mode: simvx.core.descriptors.ProcessMode
property visible: bool
reset_error() None
add_child(node: simvx.core.node.Node) simvx.core.node.Node
remove_child(node: simvx.core.node.Node)
reparent(new_parent: simvx.core.node.Node)
get_node(path: str) simvx.core.node.Node
find_child(name: str, recursive: bool = False) simvx.core.node.Node | None
find(target: type | str, recursive: bool = True) simvx.core.node.Node | None
find_all(node_type: type, recursive: bool = True) list
walk(*, include_self: bool = True) collections.abc.Iterator[simvx.core.node.Node]
property path: str
add_to_group(group: str)
remove_from_group(group: str)
is_in_group(group: str) bool
on_ready() None
on_enter_tree() None
on_exit_tree() None
on_process(dt: float) None
on_physics_process(dt: float) None
on_picked(event: simvx.core.events.InputEvent) None
on_unhandled_input(event: simvx.core.events.TreeInputEvent) None
start_coroutine(gen: simvx.core.descriptors.Coroutine) simvx.core.descriptors.CoroutineHandle
stop_coroutine(gen_or_handle)
clear_children()
destroy()
property app
property tree: simvx.core.scene_tree.SceneTree
__getitem__(key: str)
classmethod get_properties() dict[str, simvx.core.descriptors.Property]
__repr__()
class simvx.core.ui.menu.MenuBar(**kwargs)[source]

Bases: simvx.core.ui.core.Control

Horizontal menu bar with named dropdown popups.

The MenuBar owns modality: opening any menu calls :meth:show_modal so the router gates input to the bar + open popup chain. Hovering another label while a menu is open switches to it; clicking outside the bar/popup dismisses the whole chain via the router’s outside-click path.

Initialization

BAR_HEIGHT

28.0

bg_colour

‘ThemeColour(…)’

text_colour

‘ThemeColour(…)’

hover_colour

‘ThemeColour(…)’

add_menu(name: str, items: list[simvx.core.ui.menu.MenuItem]) simvx.core.ui.menu.PopupMenu[source]

Add a named dropdown menu to the bar.

is_point_inside(point) bool[source]

Bar covers its own label strip; while a menu is open the modal scope also includes the popup chain (handled via child hit-testing).

show_modal()[source]

Open the bar’s modal scope. visible stays True; only the popup children reveal additional content.

close_modal()[source]
on_draw(renderer)[source]
size_x

‘Property(…)’

size_y

‘Property(…)’

anchor_left

‘Property(…)’

anchor_top

‘Property(…)’

anchor_right

‘Property(…)’

anchor_bottom

‘Property(…)’

margin_left

‘Property(…)’

margin_top

‘Property(…)’

margin_right

‘Property(…)’

margin_bottom

‘Property(…)’

modal

‘Property(…)’

dismiss_on_outside_click

‘Property(…)’

pause_tree_when_modal

‘Property(…)’

top_level

‘Property(…)’

property size: simvx.core.math.types.Vec2
touch_mode: str

‘mouse’

property theme: simvx.core.ui.types.Theme | None
property mouse_over: bool
property focused: bool
property disabled: bool
get_theme() simvx.core.ui.types.Theme
queue_redraw()
get_minimum_size() simvx.core.math.types.Vec2
get_rect() tuple[float, float, float, float]
get_global_rect() tuple[float, float, float, float]
place_bottom_strip(height: float) None
place_top_strip(height: float) None
set_anchor_preset(preset: simvx.core.ui.enums.AnchorPreset)
set_focus()
grab_focus()
release_focus()
has_focus() bool
focus_next_control()
focus_previous_control()
grab_mouse()
release_mouse()
set_drag_preview(control: simvx.core.ui.core.Control)
position

‘_SpatialVecProperty(…)’

rotation

‘Property(…)’

scale

‘_SpatialVecProperty(…)’

z_index

‘Property(…)’

z_as_relative

‘Property(…)’

render_layer

‘Property(…)’

set_render_layer(index: int, enabled: bool = True) None
is_on_render_layer(index: int) bool
property absolute_z_index: int
property rotation_degrees: float
property world_position: simvx.core.math.types.Vec2
property world_rotation: float
property world_scale: simvx.core.math.types.Vec2
property world_transform: tuple[simvx.core.math.types.Vec2, simvx.core.math.types.Vec2, float]
property forward: simvx.core.math.types.Vec2
property right: simvx.core.math.types.Vec2
translate(offset: tuple[float, float] | numpy.ndarray)
rotate(radians: float)
rotate_deg(degrees: float)
look_at(target: tuple[float, float] | numpy.ndarray)
transform_points(points: list[simvx.core.math.types.Vec2]) list[simvx.core.math.types.Vec2]
draw_polygon(renderer, points: list[simvx.core.math.types.Vec2], closed=True, colour=None)
wrap_screen(margin: float = 20)
strict_errors: ClassVar[bool]

True

script_error_raised

‘Signal(…)’

classmethod __init_subclass__(**kwargs)
property name: str
property process_mode: simvx.core.descriptors.ProcessMode
property visible: bool
reset_error() None
add_child(node: simvx.core.node.Node) simvx.core.node.Node
remove_child(node: simvx.core.node.Node)
reparent(new_parent: simvx.core.node.Node)
get_node(path: str) simvx.core.node.Node
find_child(name: str, recursive: bool = False) simvx.core.node.Node | None
find(target: type | str, recursive: bool = True) simvx.core.node.Node | None
find_all(node_type: type, recursive: bool = True) list
walk(*, include_self: bool = True) collections.abc.Iterator[simvx.core.node.Node]
property path: str
add_to_group(group: str)
remove_from_group(group: str)
is_in_group(group: str) bool
on_ready() None
on_enter_tree() None
on_exit_tree() None
on_process(dt: float) None
on_physics_process(dt: float) None
on_picked(event: simvx.core.events.InputEvent) None
on_unhandled_input(event: simvx.core.events.TreeInputEvent) None
start_coroutine(gen: simvx.core.descriptors.Coroutine) simvx.core.descriptors.CoroutineHandle
stop_coroutine(gen_or_handle)
clear_children()
destroy()
property app
property tree: simvx.core.scene_tree.SceneTree
__getitem__(key: str)
classmethod get_properties() dict[str, simvx.core.descriptors.Property]
__repr__()