element.size, element.position, mouse pos in cb

This commit is contained in:
Face
2025-09-09 19:41:19 +03:00
parent b6379f97d2
commit 72d4648ed1
4 changed files with 178 additions and 5 deletions

View File

@@ -359,7 +359,8 @@ func _on_gui_input_click(event: InputEvent, subscription: EventSubscription) ->
if event is InputEventMouseButton:
var mouse_event = event as InputEventMouseButton
if mouse_event.button_index == MOUSE_BUTTON_LEFT and mouse_event.pressed:
_execute_lua_callback(subscription)
var mouse_info = _get_element_relative_mouse_position(mouse_event, subscription.element_id)
_execute_lua_callback(subscription, [mouse_info])
func _on_gui_input_mouse_universal(event: InputEvent, signal_node: Node) -> void:
if event is InputEventMouseButton:
@@ -376,7 +377,8 @@ func _on_gui_input_mouse_universal(event: InputEvent, signal_node: Node) -> void
should_trigger = true
if should_trigger:
_execute_lua_callback(subscription)
var mouse_info = _get_element_relative_mouse_position(mouse_event, subscription.element_id)
_execute_lua_callback(subscription, [mouse_info])
# Event callback handlers
func _on_gui_input_mousemove(event: InputEvent, subscription: EventSubscription) -> void:
@@ -449,6 +451,30 @@ func _input(event: InputEvent) -> void:
if subscription.event_name == "mousemove":
_handle_mousemove_event(mouse_event, subscription)
func _get_element_relative_mouse_position(mouse_event: InputEvent, element_id: String) -> Dictionary:
var dom_node = dom_parser.parse_result.dom_nodes.get(element_id, null)
if not dom_node or not dom_node is Control:
return {"x": 0, "y": 0}
var control = dom_node as Control
var global_pos: Vector2
if mouse_event is InputEventMouseButton:
global_pos = (mouse_event as InputEventMouseButton).global_position
elif mouse_event is InputEventMouseMotion:
global_pos = (mouse_event as InputEventMouseMotion).global_position
else:
return {"x": 0, "y": 0}
var element_rect = control.get_global_rect()
var local_x = global_pos.x - element_rect.position.x
var local_y = global_pos.y - element_rect.position.y
return {
"x": local_x,
"y": local_y
}
func _handle_mousemove_event(mouse_event: InputEventMouseMotion, subscription: EventSubscription) -> void:
# TODO: pass reference instead of hardcoded path
var body_container = Engine.get_main_loop().current_scene.website_container
@@ -1003,3 +1029,31 @@ func _handle_download_request(operation: Dictionary):
var main_node = Engine.get_main_loop().current_scene
main_node.download_manager.handle_download_request(download_data)
func _get_element_size_sync(result: Array, element_id: String):
var dom_node = dom_parser.parse_result.dom_nodes.get(element_id, null)
if dom_node and dom_node is Control:
var control = dom_node as Control
result[0] = control.size.x
result[1] = control.size.y
result[2] = true # completion flag
return
# Fallback
result[0] = 0.0
result[1] = 0.0
result[2] = true # completion flag
func _get_element_position_sync(result: Array, element_id: String):
var dom_node = dom_parser.parse_result.dom_nodes.get(element_id, null)
if dom_node and dom_node is Control:
var control = dom_node as Control
result[0] = control.position.x
result[1] = control.position.y
result[2] = true # completion flag
return
# Fallback
result[0] = 0.0
result[1] = 0.0
result[2] = true # completion flag

View File

@@ -1054,6 +1054,60 @@ static func _element_index_wrapper(vm: LuauVM) -> int:
# Fallback to true (visible by default)
vm.lua_pushboolean(true)
return 1
"size":
if lua_api:
vm.lua_getfield(1, "_element_id")
var element_id: String = vm.lua_tostring(-1)
vm.lua_pop(1)
var dom_node = lua_api.dom_parser.parse_result.dom_nodes.get(element_id, null)
if dom_node and dom_node is Control:
var result = [0.0, 0.0, false]
lua_api.call_deferred("_get_element_size_sync", result, element_id)
while not result[2]: # wait for completion flag
OS.delay_msec(1)
vm.lua_newtable()
vm.lua_pushnumber(result[0])
vm.lua_setfield(-2, "width")
vm.lua_pushnumber(result[1])
vm.lua_setfield(-2, "height")
return 1
# Fallback to zero size
vm.lua_newtable()
vm.lua_pushnumber(0)
vm.lua_setfield(-2, "width")
vm.lua_pushnumber(0)
vm.lua_setfield(-2, "height")
return 1
"position":
if lua_api:
vm.lua_getfield(1, "_element_id")
var element_id: String = vm.lua_tostring(-1)
vm.lua_pop(1)
var dom_node = lua_api.dom_parser.parse_result.dom_nodes.get(element_id, null)
if dom_node and dom_node is Control:
var result = [0.0, 0.0, false]
lua_api.call_deferred("_get_element_position_sync", result, element_id)
while not result[2]: # wait for completion flag
OS.delay_msec(1)
vm.lua_newtable()
vm.lua_pushnumber(result[0])
vm.lua_setfield(-2, "x")
vm.lua_pushnumber(result[1])
vm.lua_setfield(-2, "y")
return 1
# Fallback to zero position
vm.lua_newtable()
vm.lua_pushnumber(0)
vm.lua_setfield(-2, "x")
vm.lua_pushnumber(0)
vm.lua_setfield(-2, "y")
return 1
_:
# Check for DOM traversal properties first
if lua_api:

View File

@@ -17,7 +17,7 @@ static func connect_element_event(signal_node: Node, event_name: String, subscri
var wrapper = func():
LuaAudioUtils.mark_user_event()
LuaDownloadUtils.mark_user_event()
subscription.lua_api._on_event_triggered(subscription)
subscription.lua_api._execute_lua_callback(subscription, [{}])
signal_node.pressed.connect(wrapper)
subscription.connected_signal = "pressed"
subscription.connected_node = signal_node if signal_node != subscription.lua_api.get_dom_node(signal_node.get_parent(), "signal") else null