simvx.core.nodes_2d.ninepatch

PatchRect and NinePatchRect – 9-slice scalable bordered texture.

Module Contents

Classes

PatchRect

A rectangle defined by position and size.

NinePatchRect

9-slice scalable bordered texture for UI panels, speech bubbles, and HUD elements.

API

class simvx.core.nodes_2d.ninepatch.PatchRect[source]

Bases: typing.NamedTuple

A rectangle defined by position and size.

x: float

None

y: float

None

w: float

None

h: float

None

class simvx.core.nodes_2d.ninepatch.NinePatchRect(name: str = '', **kwargs)[source]

Bases: simvx.core.graphics.texture_slot.TextureSlot, simvx.core.nodes_2d.node2d.Node2D

9-slice scalable bordered texture for UI panels, speech bubbles, and HUD elements.

Divides a source texture into 9 regions using margin values. Corners stay fixed-size, edges grow along one axis, and the centre fills the remainder.

axis_stretch_horizontal and axis_stretch_vertical choose how that growth happens. "stretch" (the default) scales one run of the source to fill the span. "tile" repeats the source at its own pixel size and clips the last repetition, which keeps a patterned border at its authored scale however far the rect is dragged. "tile_fit" repeats a whole number of times, resizing each repetition just enough to divide the span exactly, so no repetition is ever cut off. The horizontal mode governs the top edge, bottom edge and centre; the vertical mode governs the left edge, right edge and centre. Corners are never repeated: their source and destination are the same size by construction.

A tiled span emits one draw per repetition, so a one-pixel margin tiled across a wide rect costs a draw call per pixel. Size the source region for the span it has to cover.

texture takes the same sources Sprite2D does, including a

Class:

~simvx.core.graphics.Texture resource, and reassigning it re-resolves. texture_size is seeded from the image when it was left unset, and re-seeded when the texture changes; a value the author set – at construction or at any point after – is never overwritten.

Initialization

texture

‘Property(…)’

texture_size

‘Property(…)’

size

‘Property(…)’

patch_margin_left

‘Property(…)’

patch_margin_top

‘Property(…)’

patch_margin_right

‘Property(…)’

patch_margin_bottom

‘Property(…)’

draw_center

‘Property(…)’

axis_stretch_horizontal

‘Property(…)’

axis_stretch_vertical

‘Property(…)’

modulate

‘Colour(…)’

seed_texture_size(size: tuple[int, int]) None[source]

Record the resolved image’s dimensions, if the author did not set them.

The backend calls this once it knows the pixel size. An authored texture_size wins and is left alone; a seeded one is remembered as seeded so it can be re-seeded from the next texture.

A backend that cannot measure the image hands back a degenerate size: the browser decodes PNG and JPEG itself, so a web export knows no pixel dimensions at seed time. Fall back to reading them off the source, and if that fails too leave the property untouched rather than poisoning it with a size that would make every patch collapse to nothing.

get_rect() simvx.core.nodes_2d.ninepatch.PatchRect[source]

Bounding rectangle at global position with current display size.

property nine_patch_rects: list[tuple[simvx.core.nodes_2d.ninepatch.PatchRect, simvx.core.nodes_2d.ninepatch.PatchRect]][source]

(source_uv_rect, dest_position_rect) pairs for the patches.

Up to 9 pairs (8 if draw_center is False) while both axes stretch. A tile or tile_fit axis splits each region it governs into one pair per repetition, so the list is longer. Patches with zero width or height are omitted.

Pairs come out in region row-major order (top-left, top-centre, top-right, then the middle row, then the bottom), and within a region in the same order across its repetitions.

on_draw(renderer) None[source]

Draw the 9-patch texture via renderer.draw_texture_region().

property texture_slot: int
publish_texture_slot(slot: int) None
publish_overlay_slot(slot: int) None
strict_errors: ClassVar[bool]

True

dev_checks: ClassVar[bool]

None

script_error_raised

‘Signal(…)’

dynamic: bool

False

visible

‘Property(…)’

update_mode

‘Property(…)’

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

None

classmethod __init_subclass__(**kwargs)
property name: str
property visible_in_tree: bool
reset_error() None
add_child(node: simvx.core.node.T) simvx.core.node.T
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_update(dt: float) None
on_fixed_update(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)
queue_redraw() None
property render_dirty: bool
clear_children()
destroy()
property destroying: 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__()
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)
hdr

‘Property(…)’

property transform_render_dirty: bool