TermUI.Mouse.Router (TermUI v0.2.0)

View Source

Routes mouse events to components based on position.

The router uses component bounds to determine which component should receive a mouse event, handles z-order for overlapping components, and transforms coordinates to component-local space.

Usage

# Find component at position
{component_id, local_x, local_y} = Router.hit_test(components, x, y)

# Route event to component
{target_id, transformed_event} = Router.route(components, mouse_event)

Summary

Functions

Checks if two bounds overlap.

Clips coordinates to be within bounds.

Finds the component at the given position.

Finds all components at the given position, ordered by z-index (highest first).

Checks if a point is within bounds.

Routes a mouse event to the appropriate component.

Transforms component-local coordinates to global coordinates.

Transforms global coordinates to component-local coordinates.

Types

bounds()

@type bounds() :: %{x: integer(), y: integer(), width: integer(), height: integer()}

component_entry()

@type component_entry() :: %{bounds: bounds(), z_index: integer()}

components()

@type components() :: %{required(atom()) => component_entry()}

Functions

bounds_overlap?(a, b)

@spec bounds_overlap?(bounds(), bounds()) :: boolean()

Checks if two bounds overlap.

clip_to_bounds(x, y, bounds)

@spec clip_to_bounds(integer(), integer(), bounds()) :: {integer(), integer()}

Clips coordinates to be within bounds.

hit_test(components, x, y)

@spec hit_test(components(), integer(), integer()) ::
  {atom(), integer(), integer()} | nil

Finds the component at the given position.

Returns {component_id, local_x, local_y} or nil if no component at position.

When multiple components overlap, returns the one with highest z_index.

hit_test_all(components, x, y)

@spec hit_test_all(components(), integer(), integer()) :: [
  {atom(), integer(), integer()}
]

Finds all components at the given position, ordered by z-index (highest first).

Useful for event bubbling through overlapping components.

point_in_bounds?(x, y, bounds)

@spec point_in_bounds?(integer(), integer(), bounds()) :: boolean()

Checks if a point is within bounds.

route(components, event)

@spec route(components(), TermUI.Event.Mouse.t()) ::
  {atom(), TermUI.Event.Mouse.t()} | nil

Routes a mouse event to the appropriate component.

Returns {component_id, transformed_event} where the event has coordinates transformed to component-local space.

Returns nil if no component at the event position.

to_global(bounds, local_x, local_y)

@spec to_global(bounds(), integer(), integer()) :: {integer(), integer()}

Transforms component-local coordinates to global coordinates.

to_local(bounds, x, y)

@spec to_local(bounds(), integer(), integer()) :: {integer(), integer()}

Transforms global coordinates to component-local coordinates.