separate clay layout and clay input

This commit is contained in:
2025-07-16 14:51:19 -05:00
parent 7edbb85e4e
commit d1d9a296a8
2 changed files with 71 additions and 10 deletions

View File

@@ -259,21 +259,19 @@ clay.textbox = function(str, on_change, ...configs) {
var point = use('point')
// mousepos given in hud coordinates
clay.draw_commands = function draw_commands(cmds, pos = {x:0,y:0}, mousepos = {x:0,y:0})
// Pure rendering function - no input handling
clay.draw_commands = function draw_commands(cmds, pos = {x:0,y:0})
{
cmds.hovered = null
for (var cmd of cmds) {
var config = cmd.config
var boundingbox = geometry.rect_move(cmd.boundingbox,point.add(pos,config.offset))
var content = geometry.rect_move(cmd.content,point.add(pos, config.offset))
if (config.hovered && geometry.rect_point_inside(boundingbox, mousepos))
{
config.hovered.__proto__ = config
config = config.hovered
cmds.hovered = cmd
}
// Check if this box should use hover styling
if (cmd.state && cmd.state.hovered && config.hovered) {
config.hovered.__proto__ = config
config = config.hovered
}
if (config.background_image)
if (config.slice)

63
prosperon/clay_input.cm Normal file
View File

@@ -0,0 +1,63 @@
// 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, mousepos, prev_state = {}) {
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