simvx.core.properties

Typed Property subclasses for editor-visible values.

These subclasses extend :class:simvx.core.descriptors.Property with type-specific metadata so the editor can dispatch the correct widget without relying on name heuristics or tuple-shape guessing. Stored values remain primitive (str, int, tuple) so scene serialisation is unaffected.

The five subclasses are:

  • class:

    Colour – RGB/RGBA tuple with optional alpha channel. Also carries a palette of named colour constants (Colour.RED etc.) and factory helpers (Colour.hex, Colour.rgba, Colour.from_rgb255).

  • class:

    FilePath – File / resource path with filter and relative base.

  • class:

    Multiline – Multi-line string with optional syntax hint.

  • class:

    Bitmask – N-bit integer with optional per-bit names.

  • class:

    NodePath – Scene-relative node path with optional type filter.

All five accept the existing hint=, group=, on_change=, link=, propagate= kwargs exactly like :class:Property.

Module Contents

Classes

Colour

RGB or RGBA colour property (tuple of floats in [0, 1]).

FilePath

File / resource path property.

Multiline

Multi-line string property with optional syntax hint.

Bitmask

Bit flag integer property with optional per-bit names.

NodePath

Scene-relative node path property.

Data

API

class simvx.core.properties.Colour(default: tuple = (1.0, 1.0, 1.0, 1.0), *, has_alpha: bool = True, **kwargs)[source]

Bases: simvx.core.descriptors.Property

RGB or RGBA colour property (tuple of floats in [0, 1]).

Also exposes a palette of common colour constants and hex/rgba factory helpers for use anywhere an RGBA tuple is expected.

Example as a Property::

class Light(Node3D):
    tint = Colour((1.0, 0.5, 0.0, 1.0))
    ambient = Colour((0.1, 0.1, 0.15), has_alpha=False)

Example as a palette::

panel.bg_colour = Colour.RED
label.text_colour = Colour.hex("#FF6600")
button.bg_colour = Colour.rgba(0.2, 0.4, 0.8)

Assigning None to a :class:Colour Property reverts the value to the descriptor’s declared default (mirroring :class:ThemeColour’s “no override” semantics). Widget setters that accept Colour.coerce output (Panel.bg_colour etc.) treat None as “use the theme default”.

Initialization

Create an editor-visible property descriptor.

Args: default: Default value for the property. Mutually exclusive with default_factory. Mutable containers (list, dict, set, bytearray) are rejected here because a single shared instance would alias across every owning object: pass default_factory instead. default_factory: Zero-arg callable invoked the first time each instance reads the property. The result is cached on the instance, matching functools.cached_property and dataclasses.field(default_factory=...) semantics. range: Optional (min, max) tuple for numeric clamping. enum: Optional list of allowed values. hint: Description shown in the editor inspector. link: When True, child values are offset from the parent’s value. propagate: When True, bool/enum Settings inherit disabling values from parents. group: Inspector section name for grouping. Empty string = default “Properties” section. on_change: Name of a bound method to invoke on the owning instance after a successful value change (i.e. when the new value differs from the old). Hooks fired during __init__ are deferred until __init__ returns, then dispatched once each (deduplicated by (property, hook) pair) so the hook always sees a fully constructed object. After construction, hooks fire synchronously inside __set__ (unless coalesce=True: see below). coalesce: When True and on_change is set, post-init hook calls fire at most once per scene-tree frame. Multiple writes within one tick collapse to a single deferred call drained at the end of :meth:SceneTree.tick: useful for expensive handlers like HUD rasterisation that don’t care about intermediate values (Tower Defence: coins -= 1 repeated five times in one frame rasterised the HUD text five times). The owning object must be attached to a SceneTree (obj._tree set); for tree-less owners the flag is ignored and hooks fire synchronously. persist: When True, the value is included in SaveManager snapshots. save_version: Optional integer schema version recorded alongside the persisted value. scalar: When True, reject array-like values (numpy ndarray with ndim >= 1, Vec2/Vec3, list, tuple, dict, set) at assignment with a clear TypeError. Plain Python numbers, numpy scalar types (np.float32, np.int64 etc.), and 0-d numpy arrays are accepted. Use for properties that semantically represent a single number (e.g. Camera2D.zoom) so a stray Vec2 doesn’t leak into downstream math and produce visual glitches.

WHITE

(1.0, 1.0, 1.0, 1.0)

BLACK

(0.0, 0.0, 0.0, 1.0)

RED

(1.0, 0.0, 0.0, 1.0)

GREEN

(0.0, 1.0, 0.0, 1.0)

BLUE

(0.0, 0.0, 1.0, 1.0)

YELLOW

(1.0, 1.0, 0.0, 1.0)

CYAN

(0.0, 1.0, 1.0, 1.0)

MAGENTA

(1.0, 0.0, 1.0, 1.0)

TRANSPARENT

(0.0, 0.0, 0.0, 0.0)

GRAY

(0.5, 0.5, 0.5, 1.0)

DARK_GRAY

(0.2, 0.2, 0.2, 1.0)

LIGHT_GRAY

(0.75, 0.75, 0.75, 1.0)

ORANGE

(1.0, 0.6, 0.0, 1.0)

PURPLE

(0.6, 0.2, 0.8, 1.0)

PINK

(1.0, 0.4, 0.7, 1.0)

__slots__

(‘has_alpha’,)

__set__(obj, value)[source]
static coerce(value, *, name: str = 'colour') tuple[float, ...] | None[source]

Coerce a colour-ish value to an RGBA-or-RGB float tuple, or None.

Accepts:

  • None – sentinel meaning “no override, use the theme default”. Returned as None so callers can fall back to a theme-resolved colour. Raw draw callsites that cannot tolerate None must check the result and either resolve it or raise loudly.

  • tuple / list of 3 or 4 numeric components

  • a :class:Colour Property instance (uses its default tuple)

Raises TypeError / ValueError for anything else.

static hex(h: str) tuple[float, float, float, float][source]

Parse hex colour string '#RRGGBB' / '#RRGGBBAA' into RGBA tuple.

static rgba(r: float, g: float, b: float, a: float = 1.0) tuple[float, float, float, float][source]

Create colour from float components (0.0-1.0).

static from_rgb255(r: int, g: int, b: int, a: int = 255) tuple[float, float, float, float][source]

Create colour from 0-255 integer components (alpha defaults to 255 = opaque).

Returns a canonical 0-1 RGBA float tuple. This is the designer-ergonomic entry point for callers who think in 0-255: the rest of the engine speaks float 0-1 (HDR-ready, shader-native).

__set_name__(owner, name)
__get__(obj, objtype=None)
try_decrement(obj, amount: float | int) bool
__repr__()
class simvx.core.properties.FilePath(default: str = '', *, filter: str = '*.*', relative_to: str | None = None, **kwargs)[source]

Bases: simvx.core.descriptors.Property

File / resource path property.

Example::

icon = FilePath("", filter="*.png;*.jpg")

Initialization

Create an editor-visible property descriptor.

Args: default: Default value for the property. Mutually exclusive with default_factory. Mutable containers (list, dict, set, bytearray) are rejected here because a single shared instance would alias across every owning object: pass default_factory instead. default_factory: Zero-arg callable invoked the first time each instance reads the property. The result is cached on the instance, matching functools.cached_property and dataclasses.field(default_factory=...) semantics. range: Optional (min, max) tuple for numeric clamping. enum: Optional list of allowed values. hint: Description shown in the editor inspector. link: When True, child values are offset from the parent’s value. propagate: When True, bool/enum Settings inherit disabling values from parents. group: Inspector section name for grouping. Empty string = default “Properties” section. on_change: Name of a bound method to invoke on the owning instance after a successful value change (i.e. when the new value differs from the old). Hooks fired during __init__ are deferred until __init__ returns, then dispatched once each (deduplicated by (property, hook) pair) so the hook always sees a fully constructed object. After construction, hooks fire synchronously inside __set__ (unless coalesce=True: see below). coalesce: When True and on_change is set, post-init hook calls fire at most once per scene-tree frame. Multiple writes within one tick collapse to a single deferred call drained at the end of :meth:SceneTree.tick: useful for expensive handlers like HUD rasterisation that don’t care about intermediate values (Tower Defence: coins -= 1 repeated five times in one frame rasterised the HUD text five times). The owning object must be attached to a SceneTree (obj._tree set); for tree-less owners the flag is ignored and hooks fire synchronously. persist: When True, the value is included in SaveManager snapshots. save_version: Optional integer schema version recorded alongside the persisted value. scalar: When True, reject array-like values (numpy ndarray with ndim >= 1, Vec2/Vec3, list, tuple, dict, set) at assignment with a clear TypeError. Plain Python numbers, numpy scalar types (np.float32, np.int64 etc.), and 0-d numpy arrays are accepted. Use for properties that semantically represent a single number (e.g. Camera2D.zoom) so a stray Vec2 doesn’t leak into downstream math and produce visual glitches.

__slots__

(‘filter’, ‘relative_to’)

__set__(obj, value)[source]
__set_name__(owner, name)
__get__(obj, objtype=None)
try_decrement(obj, amount: float | int) bool
__repr__()
class simvx.core.properties.Multiline(default: str = '', *, min_lines: int = 3, syntax: str | None = None, **kwargs)[source]

Bases: simvx.core.descriptors.Property

Multi-line string property with optional syntax hint.

When syntax='python' the editor uses its code editor widget; otherwise it uses the plain multi-line text editor.

Example::

description = Multiline("", min_lines=4)
script_body = Multiline("", syntax="python")

Initialization

Create an editor-visible property descriptor.

Args: default: Default value for the property. Mutually exclusive with default_factory. Mutable containers (list, dict, set, bytearray) are rejected here because a single shared instance would alias across every owning object: pass default_factory instead. default_factory: Zero-arg callable invoked the first time each instance reads the property. The result is cached on the instance, matching functools.cached_property and dataclasses.field(default_factory=...) semantics. range: Optional (min, max) tuple for numeric clamping. enum: Optional list of allowed values. hint: Description shown in the editor inspector. link: When True, child values are offset from the parent’s value. propagate: When True, bool/enum Settings inherit disabling values from parents. group: Inspector section name for grouping. Empty string = default “Properties” section. on_change: Name of a bound method to invoke on the owning instance after a successful value change (i.e. when the new value differs from the old). Hooks fired during __init__ are deferred until __init__ returns, then dispatched once each (deduplicated by (property, hook) pair) so the hook always sees a fully constructed object. After construction, hooks fire synchronously inside __set__ (unless coalesce=True: see below). coalesce: When True and on_change is set, post-init hook calls fire at most once per scene-tree frame. Multiple writes within one tick collapse to a single deferred call drained at the end of :meth:SceneTree.tick: useful for expensive handlers like HUD rasterisation that don’t care about intermediate values (Tower Defence: coins -= 1 repeated five times in one frame rasterised the HUD text five times). The owning object must be attached to a SceneTree (obj._tree set); for tree-less owners the flag is ignored and hooks fire synchronously. persist: When True, the value is included in SaveManager snapshots. save_version: Optional integer schema version recorded alongside the persisted value. scalar: When True, reject array-like values (numpy ndarray with ndim >= 1, Vec2/Vec3, list, tuple, dict, set) at assignment with a clear TypeError. Plain Python numbers, numpy scalar types (np.float32, np.int64 etc.), and 0-d numpy arrays are accepted. Use for properties that semantically represent a single number (e.g. Camera2D.zoom) so a stray Vec2 doesn’t leak into downstream math and produce visual glitches.

__slots__

(‘min_lines’, ‘syntax’)

__set__(obj, value)[source]
__set_name__(owner, name)
__get__(obj, objtype=None)
try_decrement(obj, amount: float | int) bool
__repr__()
class simvx.core.properties.Bitmask(default: int = 0, *, bits: int = 32, names: list[str] | None = None, **kwargs)[source]

Bases: simvx.core.descriptors.Property

Bit flag integer property with optional per-bit names.

Stores an ordinary int. The editor renders a grid of bits toggles arranged as bits // 8 rows of 8.

Example::

collision_layer = Bitmask(1, bits=32, group="Collision")

Initialization

Create an editor-visible property descriptor.

Args: default: Default value for the property. Mutually exclusive with default_factory. Mutable containers (list, dict, set, bytearray) are rejected here because a single shared instance would alias across every owning object: pass default_factory instead. default_factory: Zero-arg callable invoked the first time each instance reads the property. The result is cached on the instance, matching functools.cached_property and dataclasses.field(default_factory=...) semantics. range: Optional (min, max) tuple for numeric clamping. enum: Optional list of allowed values. hint: Description shown in the editor inspector. link: When True, child values are offset from the parent’s value. propagate: When True, bool/enum Settings inherit disabling values from parents. group: Inspector section name for grouping. Empty string = default “Properties” section. on_change: Name of a bound method to invoke on the owning instance after a successful value change (i.e. when the new value differs from the old). Hooks fired during __init__ are deferred until __init__ returns, then dispatched once each (deduplicated by (property, hook) pair) so the hook always sees a fully constructed object. After construction, hooks fire synchronously inside __set__ (unless coalesce=True: see below). coalesce: When True and on_change is set, post-init hook calls fire at most once per scene-tree frame. Multiple writes within one tick collapse to a single deferred call drained at the end of :meth:SceneTree.tick: useful for expensive handlers like HUD rasterisation that don’t care about intermediate values (Tower Defence: coins -= 1 repeated five times in one frame rasterised the HUD text five times). The owning object must be attached to a SceneTree (obj._tree set); for tree-less owners the flag is ignored and hooks fire synchronously. persist: When True, the value is included in SaveManager snapshots. save_version: Optional integer schema version recorded alongside the persisted value. scalar: When True, reject array-like values (numpy ndarray with ndim >= 1, Vec2/Vec3, list, tuple, dict, set) at assignment with a clear TypeError. Plain Python numbers, numpy scalar types (np.float32, np.int64 etc.), and 0-d numpy arrays are accepted. Use for properties that semantically represent a single number (e.g. Camera2D.zoom) so a stray Vec2 doesn’t leak into downstream math and produce visual glitches.

__slots__

(‘bits’, ‘names’)

__set__(obj, value)[source]
__set_name__(owner, name)
__get__(obj, objtype=None)
try_decrement(obj, amount: float | int) bool
__repr__()
class simvx.core.properties.NodePath(default: str = '', *, type_filter: type | None = None, **kwargs)[source]

Bases: simvx.core.descriptors.Property

Scene-relative node path property.

Stores a path string (e.g. "../Camera2D"). type_filter is an optional Node subclass used by the editor picker to grey out nodes that would be invalid targets.

Example::

remote_path = NodePath("", type_filter=Node2D)

Initialization

Create an editor-visible property descriptor.

Args: default: Default value for the property. Mutually exclusive with default_factory. Mutable containers (list, dict, set, bytearray) are rejected here because a single shared instance would alias across every owning object: pass default_factory instead. default_factory: Zero-arg callable invoked the first time each instance reads the property. The result is cached on the instance, matching functools.cached_property and dataclasses.field(default_factory=...) semantics. range: Optional (min, max) tuple for numeric clamping. enum: Optional list of allowed values. hint: Description shown in the editor inspector. link: When True, child values are offset from the parent’s value. propagate: When True, bool/enum Settings inherit disabling values from parents. group: Inspector section name for grouping. Empty string = default “Properties” section. on_change: Name of a bound method to invoke on the owning instance after a successful value change (i.e. when the new value differs from the old). Hooks fired during __init__ are deferred until __init__ returns, then dispatched once each (deduplicated by (property, hook) pair) so the hook always sees a fully constructed object. After construction, hooks fire synchronously inside __set__ (unless coalesce=True: see below). coalesce: When True and on_change is set, post-init hook calls fire at most once per scene-tree frame. Multiple writes within one tick collapse to a single deferred call drained at the end of :meth:SceneTree.tick: useful for expensive handlers like HUD rasterisation that don’t care about intermediate values (Tower Defence: coins -= 1 repeated five times in one frame rasterised the HUD text five times). The owning object must be attached to a SceneTree (obj._tree set); for tree-less owners the flag is ignored and hooks fire synchronously. persist: When True, the value is included in SaveManager snapshots. save_version: Optional integer schema version recorded alongside the persisted value. scalar: When True, reject array-like values (numpy ndarray with ndim >= 1, Vec2/Vec3, list, tuple, dict, set) at assignment with a clear TypeError. Plain Python numbers, numpy scalar types (np.float32, np.int64 etc.), and 0-d numpy arrays are accepted. Use for properties that semantically represent a single number (e.g. Camera2D.zoom) so a stray Vec2 doesn’t leak into downstream math and produce visual glitches.

__slots__

(‘type_filter’,)

__set__(obj, value)[source]
__set_name__(owner, name)
__get__(obj, objtype=None)
try_decrement(obj, amount: float | int) bool
__repr__()
simvx.core.properties.__all__

[‘Bitmask’, ‘Colour’, ‘FilePath’, ‘Multiline’, ‘NodePath’]