Files
cell/prosperon/clay_input.cm
2025-08-04 21:29:33 -05:00

66 lines
1.7 KiB
Plaintext

// clay_input.cm - Input handling for clay UI
// Separates input concerns from layout/rendering
var geometry = use('geometry')
var point = use('point')
var clay_input = {}
// Hit-test boxes against a mouse position
// boxes: array of box objects from clay.draw()
// mousepos: {x, y} position to test
// prev_state: previous input state for tracking changes
clay_input.hit = function hit(boxes, mouse, prev_state = {}) {
var mousepos = {...mouse}
mousepos.x *= 640
mousepos.y *= 360
var hovered = null
var clicked = null
// Find the topmost hovered box (iterate in reverse for proper z-order)
for (var i = boxes.length - 1; i >= 0; i--) {
var box = boxes[i]
var boundingbox = geometry.rect_move(box.boundingbox, box.config.offset)
if (geometry.rect_point_inside(boundingbox, mousepos)) {
hovered = box
break
}
}
// Update hover state
if (hovered && hovered.config.hovered) {
hovered.state = hovered.state || {}
hovered.state.hovered = true
}
// Clear previous hover state if different
if (prev_state.hovered && prev_state.hovered != hovered) {
prev_state.hovered.state = prev_state.hovered.state || {}
prev_state.hovered.state.hovered = false
}
return {
hovered: hovered,
clicked: clicked
}
}
// Handle click events
clay_input.click = function click(boxes, mousepos, button = 'left') {
var hit_result = clay_input.hit(boxes, mousepos)
var clicked = hit_result.hovered
if (clicked && clicked.config.action) {
clicked.config.action()
return clicked
}
return null
}
// Get boxes with actions for navigation
clay_input.get_actionable = function get_actionable(boxes) {
return boxes.filter(box => box.config.action)
}
return clay_input