simvx.editor.panels.inspector_widgets

Inspector widget registry and built-in factories.

The inspector maps each property to an editor widget via a priority-ordered registry of :class:WidgetFactory objects. Built-in factories dispatch on (a) typed :class:~simvx.core.Property subclasses – :class:Colour,

class:

FilePath, :class:Multiline, :class:Bitmask, :class:NodePath – and (b) value types for plain :class:Property declarations (bool, int, float, Vec2/3/4, Quat, tuple, str, enum).

External callers compose a :class:WidgetContext and call

func:

build_widget, which scans the registry in descending priority order and returns the first factory’s widget or None.

Module Contents

Classes

WidgetContext

Bundle of data passed to widget factories.

WidgetFactory

Protocol for widget factories.

WidgetRegistry

Ordered registry of :class:WidgetFactory objects.

ListEditor

Inspector widget for list-typed Properties.

DictEditor

Inspector widget for dict-typed Properties.

ListPropertyFactory

Factory for list-typed properties.

DictPropertyFactory

Factory for dict-typed properties.

Functions

default_registry

Return the lazily-initialised module-level default registry.

build_widget

Build an editor widget for (node, name, value) via the registry.

Data

API

class simvx.editor.panels.inspector_widgets.WidgetContext[source]

Bundle of data passed to widget factories.

Attributes: node: The node whose property is being edited. inspector: The owning :class:PropertiesPanel (used for scene access and undo/redo via inspector.state). setting: The Property descriptor (may be a typed subclass). name: Attribute name of the property on node. value: Current value (getattr(node, name)).

node: simvx.core.Node

None

inspector: simvx.editor.panels.properties.PropertiesPanel

None

setting: simvx.core.Property

None

name: str

None

value: Any

None

push_change(old: Any, new: Any) None[source]

Push an undo-aware property change.

class simvx.editor.panels.inspector_widgets.WidgetFactory[source]

Bases: typing.Protocol

Protocol for widget factories.

matches(ctx: simvx.editor.panels.inspector_widgets.WidgetContext) bool[source]
build(ctx: simvx.editor.panels.inspector_widgets.WidgetContext) simvx.core.Control | None[source]
__slots__

()

classmethod __init_subclass__(*args, **kwargs)
classmethod __class_getitem__(item)
class simvx.editor.panels.inspector_widgets.WidgetRegistry[source]

Ordered registry of :class:WidgetFactory objects.

Factories are scanned highest priority first; the first matching factory wins. Ties are resolved by insertion order.

register(factory: simvx.editor.panels.inspector_widgets.WidgetFactory, *, priority: int = 0) None[source]

Register factory at the given priority.

build(ctx: simvx.editor.panels.inspector_widgets.WidgetContext) simvx.core.Control | None[source]

Return the first matching factory’s widget, or None.

class simvx.editor.panels.inspector_widgets.ListEditor(ctx: simvx.editor.panels.inspector_widgets.WidgetContext)[source]

Bases: simvx.editor.panels.inspector_widgets._CollectionEditor

Inspector widget for list-typed Properties.

Renders a clickable header (collapse/expand) above one row per element. Each row has an index label, an inline editor (chosen via the registry’s normal type dispatch), and a small - button that removes the element. A + button appended after the rows grows the list using

Func:

_default_for_list to pick the new element’s value.

Initialization

property values: list[source]

Shallow copy of the editor’s current list.

process(dt: float) None
draw(renderer)
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(…)’

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]
is_point_inside(point) bool
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)
draw_popup(renderer)
is_popup_point_inside(point) bool
popup_input(event)
dismiss_popup()
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 position: simvx.core.math.types.Vec2
property rotation: float
property rotation_degrees: float
property scale: simvx.core.math.types.Vec2
property world_position: simvx.core.math.types.Vec2
property world_rotation: float
property world_scale: simvx.core.math.types.Vec2
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(node_type: type, 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
ready() None
enter_tree() None
exit_tree() None
physics_process(dt: float) None
picked(event: simvx.core.events.InputEvent) None
handle_input(event: simvx.core.events.TreeInputEvent) None
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.editor.panels.inspector_widgets.DictEditor(ctx: simvx.editor.panels.inspector_widgets.WidgetContext)[source]

Bases: simvx.editor.panels.inspector_widgets._CollectionEditor

Inspector widget for dict-typed Properties.

Mirrors :class:ListEditor but keys are user-supplied strings rather than integer indices. The + button reveals an inline TextEdit for the new key; pressing Enter appends {key: <default>}. Duplicate keys are rejected via :class:ValueError (strict-raise) so callers see the error rather than silently clobbering an existing entry.

Initialization

property values: dict[source]

Shallow copy of the editor’s current dict.

process(dt: float) None
draw(renderer)
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(…)’

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]
is_point_inside(point) bool
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)
draw_popup(renderer)
is_popup_point_inside(point) bool
popup_input(event)
dismiss_popup()
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 position: simvx.core.math.types.Vec2
property rotation: float
property rotation_degrees: float
property scale: simvx.core.math.types.Vec2
property world_position: simvx.core.math.types.Vec2
property world_rotation: float
property world_scale: simvx.core.math.types.Vec2
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(node_type: type, 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
ready() None
enter_tree() None
exit_tree() None
physics_process(dt: float) None
picked(event: simvx.core.events.InputEvent) None
handle_input(event: simvx.core.events.TreeInputEvent) None
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.editor.panels.inspector_widgets.ListPropertyFactory[source]

Factory for list-typed properties.

Matches whenever the current value is a list. Per-element widgets are built via the same registry so any type the inspector already understands (str, int, float, Vec2/Vec3, bool, …) works automatically inside a list.

__slots__

()

matches(ctx: simvx.editor.panels.inspector_widgets.WidgetContext) bool[source]
build(ctx: simvx.editor.panels.inspector_widgets.WidgetContext) simvx.core.Control | None[source]
class simvx.editor.panels.inspector_widgets.DictPropertyFactory[source]

Factory for dict-typed properties.

Matches whenever the current value is a dict. Per-value widgets are built via the same registry so any value type the inspector understands works automatically inside a dict. Keys must be strings.

__slots__

()

matches(ctx: simvx.editor.panels.inspector_widgets.WidgetContext) bool[source]
build(ctx: simvx.editor.panels.inspector_widgets.WidgetContext) simvx.core.Control | None[source]
simvx.editor.panels.inspector_widgets.default_registry() simvx.editor.panels.inspector_widgets.WidgetRegistry[source]

Return the lazily-initialised module-level default registry.

simvx.editor.panels.inspector_widgets.build_widget(node: simvx.core.Node, inspector: simvx.editor.panels.properties.PropertiesPanel, setting: simvx.core.Property, name: str, value: Any, *, registry: simvx.editor.panels.inspector_widgets.WidgetRegistry | None = None) simvx.core.Control | None[source]

Build an editor widget for (node, name, value) via the registry.

simvx.editor.panels.inspector_widgets.__all__

[‘DictEditor’, ‘DictPropertyFactory’, ‘ListEditor’, ‘ListPropertyFactory’, ‘WidgetContext’, ‘WidgetF…