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.

on_update(dt: float) → None¶
on_draw(renderer)¶
size_x¶

‘Property(…)’

size_y¶

‘Property(…)’

min_size_x¶

‘Property(…)’

min_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(…)’

anchor¶

‘Property(…)’

inset¶

‘Property(…)’

dismiss_on_outside_click¶

‘Property(…)’

clip_contents¶

‘Property(…)’

focus_mode¶

‘Property(…)’

tooltip¶

‘Property(…)’

pointer_filter¶

‘Property(…)’

cursor_shape¶

‘Property(…)’

pointer_types: frozenset[simvx.core.input.enums.PointerType] | None¶

None

touch_target: bool¶

False

property wants_text_input: bool¶
size_flags_horizontal¶

‘Property(…)’

size_flags_vertical¶

‘Property(…)’

stretch_ratio¶

‘Property(…)’

max_size¶

‘Property(…)’

property size: simvx.core.math.types.Vec2¶
property min_size: simvx.core.math.types.Vec2¶
content_signature() → object¶
content_uses(chars: str) → bool¶
autosize_to_content() → None¶
accepts_pointers¶

‘Property(…)’

property theme: simvx.core.ui.types.Theme | None¶
property mouse_over: bool¶
property disabled: bool¶
get_theme() → simvx.core.ui.types.Theme¶
property viewport_size: simvx.core.math.types.Vec2¶
property viewport_insets: tuple[float, float, float, float]¶
queue_redraw()¶
size_floor() → tuple[float, float]¶
get_minimum_size() → simvx.core.math.types.Vec2¶
add_child(node: simvx.core.node.T) → simvx.core.node.T¶
get_rect() → tuple[float, float, float, float]¶
get_global_rect() → tuple[float, float, float, float]¶
property focus_rect: tuple[float, float, float, float] | None¶
is_point_inside(point) → bool¶
is_hit(event: simvx.core.input.events.PointerEvent) → bool¶
classmethod __init_subclass__(**kwargs)¶
activate() → bool¶
focus_next_control()¶
focus_previous_control()¶
set_drag_preview(control: simvx.core.ui.core.Control)¶
property is_overlay_open: bool¶
show_overlay(modality: str = 'light', *, dim: bool | None = None, dismiss: bool | None = None, inert: bool | None = None, owner: simvx.core.ui.core.Control | None = None, initial_focus: simvx.core.ui.core.Control | None = None) → None¶
close_overlay() → None¶
position¶

‘_SpatialVecProperty(…)’

rotation¶

‘Property(…)’

scale¶

‘_SpatialVecProperty(…)’

top_level¶

‘Property(…)’

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)¶
to_global(point) → simvx.core.math.types.Vec2¶
to_local(point) → simvx.core.math.types.Vec2¶
transform_points(points: list[simvx.core.math.types.Vec2]) → list[simvx.core.math.types.Vec2]¶
wrap_screen(margin: float = 20)¶
post_processed¶

‘Property(…)’

property transform_render_dirty: bool¶
strict_errors: ClassVar[bool]¶

True

dev_checks: ClassVar[bool]¶

None

dev_warnings: ClassVar[bool]¶

None

freeze_check_interval: ClassVar[float]¶

1.0

dynamic: bool¶

False

visible¶

‘Property(…)’

update_mode¶

‘Property(…)’

drag_threshold¶

‘Property(…)’

focus_entered¶

‘Signal(…)’

focus_exited¶

‘Signal(…)’

__properties__: ClassVar[dict[str, simvx.core.descriptors.Property]]¶

None

property name: str¶
property visible_in_tree: bool¶
property input_player: simvx.core.input.players.InputPlayer¶
property input_context: simvx.core.input.contexts.InputContext | None¶
reset_error() → None¶
remove_child(node: simvx.core.node.Node) → None¶
reparent(new_parent: simvx.core.node.Node)¶
node_at(path, default=_NO_DEFAULT)¶
find(target, *, direct: bool = False)¶
find_all(target, *, direct: bool = False)¶
expect(target, *, direct: bool = False)¶
ancestor(target)¶
walk(*, include_self: bool = True) → collections.abc.Iterator[simvx.core.node.Node]¶
property path: str¶
property is_scene_root: bool¶
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_fixed_update(dt: float) → None¶
on_draw_3d(gizmos) → None¶
on_picked(event: simvx.core.input.events.PickEvent) → bool | None¶
on_gui_input(event: simvx.core.input.events.GuiInputEvent) → bool | None¶
start_coroutine(gen: simvx.core.descriptors.Coroutine) → simvx.core.descriptors.CoroutineHandle¶
stop_coroutine(gen_or_handle)¶
property focused: bool¶
drag_threshold_for(pointer_type: simvx.core.input.enums.PointerType | str) → float¶
grab_focus() → None¶
release_focus() → None¶
capture_pointer(pointer_id: int | None = None) → None¶
release_pointer(pointer_id: int | None = None) → None¶
property render_dirty: bool¶
clear_children()¶
destroy()¶
property destroying: bool¶
property destroyed: bool¶
call_deferred(method: collections.abc.Callable[..., Any], *args: Any) → None¶
property app¶
property tree: simvx.core.scene_tree.SceneTree¶
property physics¶
property physics_2d¶
__getitem__(key: str)¶
classmethod get_properties() → dict[str, simvx.core.descriptors.Property]¶
__repr__()¶
__slots__¶

()

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.

on_update(dt: float) → None¶
on_draw(renderer)¶
size_x¶

‘Property(…)’

size_y¶

‘Property(…)’

min_size_x¶

‘Property(…)’

min_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(…)’

anchor¶

‘Property(…)’

inset¶

‘Property(…)’

dismiss_on_outside_click¶

‘Property(…)’

clip_contents¶

‘Property(…)’

focus_mode¶

‘Property(…)’

tooltip¶

‘Property(…)’

pointer_filter¶

‘Property(…)’

cursor_shape¶

‘Property(…)’

pointer_types: frozenset[simvx.core.input.enums.PointerType] | None¶

None

touch_target: bool¶

False

property wants_text_input: bool¶
size_flags_horizontal¶

‘Property(…)’

size_flags_vertical¶

‘Property(…)’

stretch_ratio¶

‘Property(…)’

max_size¶

‘Property(…)’

property size: simvx.core.math.types.Vec2¶
property min_size: simvx.core.math.types.Vec2¶
content_signature() → object¶
content_uses(chars: str) → bool¶
autosize_to_content() → None¶
accepts_pointers¶

‘Property(…)’

property theme: simvx.core.ui.types.Theme | None¶
property mouse_over: bool¶
property disabled: bool¶
get_theme() → simvx.core.ui.types.Theme¶
property viewport_size: simvx.core.math.types.Vec2¶
property viewport_insets: tuple[float, float, float, float]¶
queue_redraw()¶
size_floor() → tuple[float, float]¶
get_minimum_size() → simvx.core.math.types.Vec2¶
add_child(node: simvx.core.node.T) → simvx.core.node.T¶
get_rect() → tuple[float, float, float, float]¶
get_global_rect() → tuple[float, float, float, float]¶
property focus_rect: tuple[float, float, float, float] | None¶
is_point_inside(point) → bool¶
is_hit(event: simvx.core.input.events.PointerEvent) → bool¶
classmethod __init_subclass__(**kwargs)¶
activate() → bool¶
focus_next_control()¶
focus_previous_control()¶
set_drag_preview(control: simvx.core.ui.core.Control)¶
property is_overlay_open: bool¶
show_overlay(modality: str = 'light', *, dim: bool | None = None, dismiss: bool | None = None, inert: bool | None = None, owner: simvx.core.ui.core.Control | None = None, initial_focus: simvx.core.ui.core.Control | None = None) → None¶
close_overlay() → None¶
position¶

‘_SpatialVecProperty(…)’

rotation¶

‘Property(…)’

scale¶

‘_SpatialVecProperty(…)’

top_level¶

‘Property(…)’

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)¶
to_global(point) → simvx.core.math.types.Vec2¶
to_local(point) → simvx.core.math.types.Vec2¶
transform_points(points: list[simvx.core.math.types.Vec2]) → list[simvx.core.math.types.Vec2]¶
wrap_screen(margin: float = 20)¶
post_processed¶

‘Property(…)’

property transform_render_dirty: bool¶
strict_errors: ClassVar[bool]¶

True

dev_checks: ClassVar[bool]¶

None

dev_warnings: ClassVar[bool]¶

None

freeze_check_interval: ClassVar[float]¶

1.0

dynamic: bool¶

False

visible¶

‘Property(…)’

update_mode¶

‘Property(…)’

drag_threshold¶

‘Property(…)’

focus_entered¶

‘Signal(…)’

focus_exited¶

‘Signal(…)’

__properties__: ClassVar[dict[str, simvx.core.descriptors.Property]]¶

None

property name: str¶
property visible_in_tree: bool¶
property input_player: simvx.core.input.players.InputPlayer¶
property input_context: simvx.core.input.contexts.InputContext | None¶
reset_error() → None¶
remove_child(node: simvx.core.node.Node) → None¶
reparent(new_parent: simvx.core.node.Node)¶
node_at(path, default=_NO_DEFAULT)¶
find(target, *, direct: bool = False)¶
find_all(target, *, direct: bool = False)¶
expect(target, *, direct: bool = False)¶
ancestor(target)¶
walk(*, include_self: bool = True) → collections.abc.Iterator[simvx.core.node.Node]¶
property path: str¶
property is_scene_root: bool¶
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_fixed_update(dt: float) → None¶
on_draw_3d(gizmos) → None¶
on_picked(event: simvx.core.input.events.PickEvent) → bool | None¶
on_gui_input(event: simvx.core.input.events.GuiInputEvent) → bool | None¶
start_coroutine(gen: simvx.core.descriptors.Coroutine) → simvx.core.descriptors.CoroutineHandle¶
stop_coroutine(gen_or_handle)¶
property focused: bool¶
drag_threshold_for(pointer_type: simvx.core.input.enums.PointerType | str) → float¶
grab_focus() → None¶
release_focus() → None¶
capture_pointer(pointer_id: int | None = None) → None¶
release_pointer(pointer_id: int | None = None) → None¶
property render_dirty: bool¶
clear_children()¶
destroy()¶
property destroying: bool¶
property destroyed: bool¶
call_deferred(method: collections.abc.Callable[..., Any], *args: Any) → None¶
property app¶
property tree: simvx.core.scene_tree.SceneTree¶
property physics¶
property physics_2d¶
__getitem__(key: str)¶
classmethod get_properties() → dict[str, simvx.core.descriptors.Property]¶
__repr__()¶
__slots__¶

()

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…