Source code for simvx.core.events
"""Input event types for the node tree."""
import logging
from .input.enums import JoyAxis, JoyButton, Key, MouseButton
log = logging.getLogger(__name__)
# ============================================================================
# InputEvent: Delivered to pickable nodes on mouse click
# ============================================================================
[docs]
class InputEvent:
"""Mouse click event delivered to 3D nodes via on_picked().
Attributes:
screen_pos: Click position in screen pixels.
button: Mouse button (typed MouseButton enum).
ray_origin: World-space ray origin.
ray_direction: World-space ray direction (normalized).
distance: Distance along ray to the hit point.
"""
__slots__ = ('screen_pos', 'button', 'ray_origin', 'ray_direction', 'distance')
def __init__(self, screen_pos: tuple[float, float], button: MouseButton,
ray_origin: tuple[float, float, float],
ray_direction: tuple[float, float, float],
distance: float = 0.0):
self.screen_pos = screen_pos
self.button: MouseButton = button
self.ray_origin = ray_origin
self.ray_direction = ray_direction
self.distance = distance
# ============================================================================
# TreeInputEvent: Propagated through SceneTree to @on_input handlers
# ============================================================================
[docs]
class TreeInputEvent:
"""Input event propagated through the scene tree to @on_input handlers.
Carries typed key/button enums alongside legacy string/int fields so
SceneTree dispatch tables can route by ``Key`` / ``MouseButton`` /
``JoyButton`` / ``JoyAxis`` directly without per-event string lookups.
Attributes:
type: Event kind: "key", "mouse_button", "mouse_motion", "scroll",
"joy_button", or "joy_axis".
pressed: True on press, False on release (key, mouse_button, joy_button).
position: Mouse position in screen pixels (mouse events).
delta: Motion delta (mouse_motion) or scroll offset (scroll).
key: Typed key enum for "key" events; None otherwise.
mouse_button: Typed mouse-button enum for "mouse_button" events; None otherwise.
joy_button: Typed joypad-button enum for "joy_button" events; None otherwise.
joy_axis: Typed joypad-axis enum for "joy_axis" events; None otherwise.
joy_value: Axis value for "joy_axis" events (-1.0 to 1.0).
ctrl, shift, alt, meta: Modifier state at event time.
echo: True for key-repeat events (auto-fired while a key is held).
handled: True if any handler returned truthy. Stops on_unhandled_input dispatch.
"""
__slots__ = (
'type', 'pressed', 'position', 'delta',
'key', 'mouse_button', 'joy_button', 'joy_axis', 'joy_value',
'ctrl', 'shift', 'alt', 'meta', 'echo', 'handled',
)
def __init__(
self,
type: str,
*,
pressed: bool = False,
position: tuple[float, float] = (0.0, 0.0),
delta: tuple[float, float] = (0.0, 0.0),
key: Key | None = None,
mouse_button: MouseButton | None = None,
joy_button: JoyButton | None = None,
joy_axis: JoyAxis | None = None,
joy_value: float = 0.0,
ctrl: bool = False,
shift: bool = False,
alt: bool = False,
meta: bool = False,
echo: bool = False,
):
self.type = type
self.pressed = pressed
self.position = position
self.delta = delta
self.key = key
self.mouse_button = mouse_button
self.joy_button = joy_button
self.joy_axis = joy_axis
self.joy_value = joy_value
self.ctrl = ctrl
self.shift = shift
self.alt = alt
self.meta = meta
self.echo = echo
self.handled = False
[docs]
def __repr__(self) -> str:
parts = [f"type={self.type!r}"]
if self.key is not None:
parts.append(f"key={self.key.name}")
if self.mouse_button is not None:
parts.append(f"button={self.mouse_button.name}")
if self.joy_button is not None:
parts.append(f"joy_button={self.joy_button.name}")
if self.joy_axis is not None:
parts.append(f"joy_axis={self.joy_axis.name}={self.joy_value:.2f}")
if self.pressed:
parts.append("pressed=True")
mods = [m for m, v in (("Ctrl", self.ctrl), ("Shift", self.shift),
("Alt", self.alt), ("Meta", self.meta)) if v]
if mods:
parts.append("+".join(mods))
return f"TreeInputEvent({', '.join(parts)})"