lua: select, log, body, on, get_text, set_text, subscribtions, events (keyup, keydown, keypress, mouseover, mouseup, mousedown, mouseenter, mouseexit, click, focusin, focusout)
This commit is contained in:
@@ -43,12 +43,19 @@ class HTMLElement:
|
||||
func is_inline_element() -> bool:
|
||||
return tag_name in ["b", "i", "u", "small", "mark", "code", "span", "a", "input"]
|
||||
|
||||
class HTMLBody extends HTMLElement:
|
||||
var body_node: Node = null
|
||||
|
||||
func _init():
|
||||
super._init("body")
|
||||
|
||||
class ParseResult:
|
||||
var root: HTMLElement
|
||||
var all_elements: Array[HTMLElement] = []
|
||||
var errors: Array[String] = []
|
||||
var css_parser: CSSParser = null
|
||||
var inline_styles: Dictionary = {}
|
||||
var dom_nodes: Dictionary = {}
|
||||
|
||||
func _init():
|
||||
root = HTMLElement.new("document")
|
||||
@@ -271,6 +278,11 @@ func find_by_id(element_id: String) -> HTMLElement:
|
||||
|
||||
return null
|
||||
|
||||
func register_dom_node(element: HTMLElement, node: Control) -> void:
|
||||
var element_id = element.get_id()
|
||||
if element_id.length() > 0:
|
||||
parse_result.dom_nodes[element_id] = node
|
||||
|
||||
func find_first(tag: String, attribute: String = "") -> HTMLElement:
|
||||
var results = find_all(tag, attribute)
|
||||
return results[0] if results.size() > 0 else null
|
||||
@@ -334,6 +346,24 @@ func get_all_images() -> Array[String]:
|
||||
func get_all_scripts() -> Array[String]:
|
||||
return get_attribute_values("script", "src")
|
||||
|
||||
func process_scripts(lua_api: LuaAPI, lua_vm) -> void:
|
||||
if not lua_api or not lua_vm:
|
||||
print("Warning: Lua API or VM not available for script processing")
|
||||
return
|
||||
|
||||
lua_api.dom_parser = self
|
||||
|
||||
for script_element in find_all("script"):
|
||||
var src = script_element.get_attribute("src")
|
||||
var inline_code = script_element.text_content.strip_edges()
|
||||
|
||||
if not src.is_empty():
|
||||
# TODO: add support for external Lua script
|
||||
print("External script found: ", src)
|
||||
elif not inline_code.is_empty():
|
||||
print("Executing inline Lua script")
|
||||
lua_api.execute_lua_script(inline_code, lua_vm)
|
||||
|
||||
func get_all_stylesheets() -> Array[String]:
|
||||
return get_attribute_values("style", "src")
|
||||
|
||||
|
||||
371
flumi/Scripts/B9/Lua.gd
Normal file
371
flumi/Scripts/B9/Lua.gd
Normal file
@@ -0,0 +1,371 @@
|
||||
class_name LuaAPI
|
||||
extends Node
|
||||
|
||||
class EventSubscription:
|
||||
var id: int
|
||||
var element_id: String
|
||||
var event_name: String
|
||||
var callback_ref: int
|
||||
var vm: LuauVM
|
||||
var lua_api: LuaAPI
|
||||
var connected_signal: String = ""
|
||||
var connected_node: Node = null
|
||||
|
||||
var dom_parser: HTMLParser
|
||||
var event_subscriptions: Dictionary = {}
|
||||
var next_subscription_id: int = 1
|
||||
var next_callback_ref: int = 1
|
||||
|
||||
func _gurt_select_handler(vm: LuauVM) -> int:
|
||||
var selector: String = vm.luaL_checkstring(1)
|
||||
|
||||
var element_id = ""
|
||||
if selector.begins_with("#"):
|
||||
element_id = selector.substr(1)
|
||||
else:
|
||||
vm.lua_pushnil()
|
||||
return 1
|
||||
|
||||
var dom_node = dom_parser.parse_result.dom_nodes.get(element_id, null)
|
||||
if not dom_node:
|
||||
vm.lua_pushnil()
|
||||
return 1
|
||||
|
||||
vm.lua_newtable()
|
||||
vm.lua_pushstring(element_id)
|
||||
vm.lua_setfield(-2, "_element_id")
|
||||
|
||||
add_element_methods(vm)
|
||||
return 1
|
||||
|
||||
func add_element_methods(vm: LuauVM) -> void:
|
||||
vm.lua_pushcallable(_element_set_text_handler, "element.set_text")
|
||||
vm.lua_setfield(-2, "set_text")
|
||||
|
||||
vm.lua_pushcallable(_element_get_text_handler, "element.get_text")
|
||||
vm.lua_setfield(-2, "get_text")
|
||||
|
||||
vm.lua_pushcallable(_element_on_event_handler, "element.on")
|
||||
vm.lua_setfield(-2, "on")
|
||||
|
||||
# Element manipulation handlers
|
||||
func _element_set_text_handler(vm: LuauVM) -> int:
|
||||
vm.luaL_checktype(1, vm.LUA_TTABLE)
|
||||
var text: String = vm.luaL_checkstring(2)
|
||||
|
||||
vm.lua_getfield(1, "_element_id")
|
||||
var element_id: String = vm.lua_tostring(-1)
|
||||
vm.lua_pop(1)
|
||||
|
||||
var dom_node = dom_parser.parse_result.dom_nodes.get(element_id, null)
|
||||
var text_node = get_dom_node(dom_node, "text")
|
||||
if text_node:
|
||||
text_node.text = text
|
||||
return 0
|
||||
|
||||
func _element_get_text_handler(vm: LuauVM) -> int:
|
||||
vm.luaL_checktype(1, vm.LUA_TTABLE)
|
||||
|
||||
vm.lua_getfield(1, "_element_id")
|
||||
var element_id: String = vm.lua_tostring(-1)
|
||||
vm.lua_pop(1)
|
||||
|
||||
var dom_node = dom_parser.parse_result.dom_nodes.get(element_id, null)
|
||||
var text = ""
|
||||
|
||||
var text_node = get_dom_node(dom_node, "text")
|
||||
if text_node:
|
||||
if text_node.has_method("get_text"):
|
||||
text = text_node.get_text()
|
||||
else:
|
||||
text = text_node.text
|
||||
|
||||
vm.lua_pushstring(text)
|
||||
return 1
|
||||
|
||||
# Event system handlers
|
||||
func _element_on_event_handler(vm: LuauVM) -> int:
|
||||
vm.luaL_checktype(1, vm.LUA_TTABLE)
|
||||
var event_name: String = vm.luaL_checkstring(2)
|
||||
vm.luaL_checktype(3, vm.LUA_TFUNCTION)
|
||||
|
||||
vm.lua_getfield(1, "_element_id")
|
||||
var element_id: String = vm.lua_tostring(-1)
|
||||
vm.lua_pop(1)
|
||||
|
||||
var dom_node = dom_parser.parse_result.dom_nodes.get(element_id, null)
|
||||
if not dom_node:
|
||||
vm.lua_pushnil()
|
||||
return 1
|
||||
|
||||
var subscription = _create_subscription(vm, element_id, event_name)
|
||||
event_subscriptions[subscription.id] = subscription
|
||||
|
||||
var signal_node = get_dom_node(dom_node, "signal")
|
||||
var success = LuaEventUtils.connect_element_event(signal_node, event_name, subscription)
|
||||
|
||||
return _handle_subscription_result(vm, subscription, success)
|
||||
|
||||
func _body_on_event_handler(vm: LuauVM) -> int:
|
||||
vm.luaL_checktype(1, vm.LUA_TTABLE)
|
||||
var event_name: String = vm.luaL_checkstring(2)
|
||||
vm.luaL_checktype(3, vm.LUA_TFUNCTION)
|
||||
|
||||
var subscription = _create_subscription(vm, "body", event_name)
|
||||
event_subscriptions[subscription.id] = subscription
|
||||
|
||||
var success = LuaEventUtils.connect_body_event(event_name, subscription, self)
|
||||
|
||||
return _handle_subscription_result(vm, subscription, success)
|
||||
|
||||
func _subscription_unsubscribe_handler(vm: LuauVM) -> int:
|
||||
vm.luaL_checktype(1, vm.LUA_TTABLE)
|
||||
|
||||
vm.lua_getfield(1, "_subscription_id")
|
||||
var subscription_id: int = vm.lua_tointeger(-1)
|
||||
vm.lua_pop(1)
|
||||
|
||||
var subscription = event_subscriptions.get(subscription_id, null)
|
||||
if subscription:
|
||||
LuaEventUtils.disconnect_subscription(subscription, self)
|
||||
event_subscriptions.erase(subscription_id)
|
||||
vm.lua_pushnil()
|
||||
vm.lua_rawseti(vm.LUA_REGISTRYINDEX, subscription.callback_ref)
|
||||
|
||||
return 0
|
||||
|
||||
# Subscription management
|
||||
func _create_subscription(vm: LuauVM, element_id: String, event_name: String) -> EventSubscription:
|
||||
var subscription_id = next_subscription_id
|
||||
next_subscription_id += 1
|
||||
var callback_ref = next_callback_ref
|
||||
next_callback_ref += 1
|
||||
|
||||
vm.lua_pushvalue(3)
|
||||
vm.lua_rawseti(vm.LUA_REGISTRYINDEX, callback_ref)
|
||||
|
||||
var subscription = EventSubscription.new()
|
||||
subscription.id = subscription_id
|
||||
subscription.element_id = element_id
|
||||
subscription.event_name = event_name
|
||||
subscription.callback_ref = callback_ref
|
||||
subscription.vm = vm
|
||||
subscription.lua_api = self
|
||||
|
||||
return subscription
|
||||
|
||||
func _handle_subscription_result(vm: LuauVM, subscription: EventSubscription, success: bool) -> int:
|
||||
if success:
|
||||
vm.lua_newtable()
|
||||
vm.lua_pushinteger(subscription.id)
|
||||
vm.lua_setfield(-2, "_subscription_id")
|
||||
|
||||
vm.lua_pushcallable(_subscription_unsubscribe_handler, "subscription.unsubscribe")
|
||||
vm.lua_setfield(-2, "unsubscribe")
|
||||
|
||||
return 1
|
||||
else:
|
||||
vm.lua_pushnil()
|
||||
vm.lua_rawseti(vm.LUA_REGISTRYINDEX, subscription.callback_ref)
|
||||
event_subscriptions.erase(subscription.id)
|
||||
vm.lua_pushnil()
|
||||
return 1
|
||||
|
||||
# Event callbacks
|
||||
func _on_event_triggered(subscription: EventSubscription) -> void:
|
||||
if not event_subscriptions.has(subscription.id):
|
||||
return
|
||||
|
||||
subscription.vm.lua_rawgeti(subscription.vm.LUA_REGISTRYINDEX, subscription.callback_ref)
|
||||
if subscription.vm.lua_isfunction(-1):
|
||||
if subscription.vm.lua_pcall(0, 0, 0) != subscription.vm.LUA_OK:
|
||||
print("GURT ERROR in event callback: ", subscription.vm.lua_tostring(-1))
|
||||
subscription.vm.lua_pop(1)
|
||||
else:
|
||||
subscription.vm.lua_pop(1)
|
||||
|
||||
func _on_gui_input_click(event: InputEvent, subscription: EventSubscription) -> void:
|
||||
if not event_subscriptions.has(subscription.id):
|
||||
return
|
||||
|
||||
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)
|
||||
|
||||
func _on_gui_input_mouse_universal(event: InputEvent, signal_node: Node) -> void:
|
||||
if event is InputEventMouseButton:
|
||||
var mouse_event = event as InputEventMouseButton
|
||||
if mouse_event.button_index == MOUSE_BUTTON_LEFT:
|
||||
# Find all subscriptions for this node with mouse events
|
||||
for subscription_id in event_subscriptions:
|
||||
var subscription = event_subscriptions[subscription_id]
|
||||
if subscription.connected_node == signal_node and subscription.connected_signal == "gui_input_mouse":
|
||||
var should_trigger = false
|
||||
if subscription.event_name == "mousedown" and mouse_event.pressed:
|
||||
should_trigger = true
|
||||
elif subscription.event_name == "mouseup" and not mouse_event.pressed:
|
||||
should_trigger = true
|
||||
|
||||
if should_trigger:
|
||||
_execute_lua_callback(subscription)
|
||||
|
||||
# Event callback handlers
|
||||
func _on_gui_input_mousemove(event: InputEvent, subscription: EventSubscription) -> void:
|
||||
if not event_subscriptions.has(subscription.id):
|
||||
return
|
||||
|
||||
if event is InputEventMouseMotion:
|
||||
var mouse_event = event as InputEventMouseMotion
|
||||
_handle_mousemove_event(mouse_event, subscription)
|
||||
|
||||
func _on_focus_gui_input(event: InputEvent, subscription: EventSubscription) -> void:
|
||||
if not event_subscriptions.has(subscription.id):
|
||||
return
|
||||
|
||||
if event is InputEventMouseButton:
|
||||
var mouse_event = event as InputEventMouseButton
|
||||
if mouse_event.button_index == MOUSE_BUTTON_LEFT and mouse_event.pressed:
|
||||
if subscription.event_name == "focusin":
|
||||
_execute_lua_callback(subscription)
|
||||
|
||||
func _on_body_mouse_enter(subscription: EventSubscription) -> void:
|
||||
if not event_subscriptions.has(subscription.id):
|
||||
return
|
||||
|
||||
if subscription.event_name == "mouseenter":
|
||||
_execute_lua_callback(subscription)
|
||||
|
||||
func _on_body_mouse_exit(subscription: EventSubscription) -> void:
|
||||
if not event_subscriptions.has(subscription.id):
|
||||
return
|
||||
|
||||
if subscription.event_name == "mouseexit":
|
||||
_execute_lua_callback(subscription)
|
||||
|
||||
func _execute_lua_callback(subscription: EventSubscription, args: Array = []) -> void:
|
||||
subscription.vm.lua_rawgeti(subscription.vm.LUA_REGISTRYINDEX, subscription.callback_ref)
|
||||
if subscription.vm.lua_isfunction(-1):
|
||||
for arg in args:
|
||||
subscription.vm.lua_pushvariant(arg)
|
||||
|
||||
if subscription.vm.lua_pcall(args.size(), 0, 0) != subscription.vm.LUA_OK:
|
||||
print("GURT ERROR in callback: ", subscription.vm.lua_tostring(-1))
|
||||
subscription.vm.lua_pop(1)
|
||||
else:
|
||||
subscription.vm.lua_pop(1)
|
||||
|
||||
# Global input processing
|
||||
func _input(event: InputEvent) -> void:
|
||||
if event is InputEventKey:
|
||||
var key_event = event as InputEventKey
|
||||
for subscription_id in event_subscriptions:
|
||||
var subscription = event_subscriptions[subscription_id]
|
||||
if subscription.element_id == "body" and subscription.connected_signal == "input":
|
||||
var should_trigger = false
|
||||
match subscription.event_name:
|
||||
"keydown":
|
||||
should_trigger = key_event.pressed
|
||||
"keyup":
|
||||
should_trigger = not key_event.pressed
|
||||
"keypress":
|
||||
should_trigger = key_event.pressed
|
||||
|
||||
if should_trigger:
|
||||
var key_info = {
|
||||
"key": OS.get_keycode_string(key_event.keycode),
|
||||
"keycode": key_event.keycode,
|
||||
"ctrl": key_event.ctrl_pressed,
|
||||
"shift": key_event.shift_pressed,
|
||||
"alt": key_event.alt_pressed
|
||||
}
|
||||
_execute_lua_callback(subscription, [key_info])
|
||||
|
||||
elif event is InputEventMouseMotion:
|
||||
var mouse_event = event as InputEventMouseMotion
|
||||
for subscription_id in event_subscriptions:
|
||||
var subscription = event_subscriptions[subscription_id]
|
||||
if subscription.element_id == "body" and subscription.connected_signal == "input_mousemove":
|
||||
if subscription.event_name == "mousemove":
|
||||
_handle_mousemove_event(mouse_event, subscription)
|
||||
|
||||
func _handle_mousemove_event(mouse_event: InputEventMouseMotion, subscription: EventSubscription) -> void:
|
||||
# TODO: pass reference instead of hardcoded path
|
||||
var body_container = get_node("/root/Main").website_container
|
||||
|
||||
if body_container.get_parent() is MarginContainer:
|
||||
body_container = body_container.get_parent()
|
||||
|
||||
if not body_container:
|
||||
return
|
||||
|
||||
var container_rect = body_container.get_global_rect()
|
||||
var local_x = mouse_event.global_position.x - container_rect.position.x
|
||||
var local_y = mouse_event.global_position.y - container_rect.position.y
|
||||
|
||||
# Only provide coordinates if mouse is within the container bounds
|
||||
if local_x >= 0 and local_y >= 0 and local_x <= container_rect.size.x and local_y <= container_rect.size.y:
|
||||
var mouse_info = {
|
||||
"x": local_x,
|
||||
"y": local_y,
|
||||
"deltaX": mouse_event.relative.x,
|
||||
"deltaY": mouse_event.relative.y
|
||||
}
|
||||
_execute_lua_callback(subscription, [mouse_info])
|
||||
|
||||
# DOM node utilities
|
||||
func get_dom_node(node: Node, purpose: String = "general") -> Node:
|
||||
if not node:
|
||||
return null
|
||||
|
||||
if node is MarginContainer:
|
||||
node = node.get_child(0)
|
||||
|
||||
match purpose:
|
||||
"signal":
|
||||
if node is HTMLButton:
|
||||
return node.get_node_or_null("ButtonNode")
|
||||
elif node is RichTextLabel:
|
||||
return node
|
||||
elif node.has_method("get") and node.get("rich_text_label"):
|
||||
return node.get("rich_text_label")
|
||||
elif node.get_node_or_null("RichTextLabel"):
|
||||
return node.get_node_or_null("RichTextLabel")
|
||||
else:
|
||||
return node
|
||||
"text":
|
||||
if node.has_method("set_text") and node.has_method("get_text"):
|
||||
return node
|
||||
elif node is RichTextLabel:
|
||||
return node
|
||||
elif node.has_method("get") and node.get("rich_text_label"):
|
||||
return node.get("rich_text_label")
|
||||
elif node.get_node_or_null("RichTextLabel"):
|
||||
return node.get_node_or_null("RichTextLabel")
|
||||
else:
|
||||
if "text" in node:
|
||||
return node
|
||||
return null
|
||||
"general":
|
||||
if node is HTMLButton:
|
||||
return node.get_node_or_null("ButtonNode")
|
||||
elif node is RichTextLabel:
|
||||
return node
|
||||
elif node.get_node_or_null("RichTextLabel"):
|
||||
return node.get_node_or_null("RichTextLabel")
|
||||
else:
|
||||
return node
|
||||
|
||||
return node
|
||||
|
||||
# Main execution function
|
||||
func execute_lua_script(code: String, vm: LuauVM):
|
||||
vm.open_libraries([vm.LUA_BASE_LIB, vm.LUA_BIT32_LIB,
|
||||
vm.LUA_COROUTINE_LIB, vm.LUA_MATH_LIB, vm.LUA_UTF8_LIB,
|
||||
vm.LUA_TABLE_LIB, vm.LUA_STRING_LIB, vm.LUA_VECTOR_LIB])
|
||||
|
||||
LuaFunctionUtils.setup_gurt_api(vm, self, dom_parser)
|
||||
|
||||
if vm.lua_dostring(code) != vm.LUA_OK:
|
||||
print("LUA ERROR: ", vm.lua_tostring(-1))
|
||||
vm.lua_pop(1)
|
||||
1
flumi/Scripts/B9/Lua.gd.uid
Normal file
1
flumi/Scripts/B9/Lua.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://biv2ch1mi3lnn
|
||||
@@ -100,7 +100,7 @@ var HTML_CONTENT2 = """<head>
|
||||
|
||||
</body>
|
||||
""".to_utf8_buffer()
|
||||
var HTML_CONTENT = """<head>
|
||||
var HTML_CONTENTbv = """<head>
|
||||
<title>My cool web</title>
|
||||
<icon src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/c/c1/Google_%22G%22_logo.svg/768px-Google_%22G%22_logo.svg.png\">
|
||||
|
||||
@@ -111,7 +111,6 @@ var HTML_CONTENT = """<head>
|
||||
|
||||
<style>
|
||||
h1 { text-[#ff0000] font-italic hover:text-[#00ff00] }
|
||||
p { text-[#333333] text-2xl }
|
||||
button { hover:bg-[#FF6B35] hover:text-[#FFFFFF] active:bg-[#CC5429] active:text-[#F0F0F0] }
|
||||
</style>
|
||||
<style src=\"styles.css\">
|
||||
@@ -416,17 +415,17 @@ var HTML_CONTENT_S = """<head>
|
||||
a[href^="https"] { text-[#008000] font-bold }
|
||||
button[disabled] { bg-[#888888] text-[#cccccc] }
|
||||
input[placeholder*="email"] { border-2 border-[#0066cc] bg-[#ffffff] }
|
||||
div[class$="special"] { bg-[#ffffaa] }
|
||||
div[style$="special"] { bg-[#ffffaa] }
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>CSS Selector Test Page</h1>
|
||||
<p>This paragraph should be red and bold (h1 + p)</p>
|
||||
<p class="second-p">This paragraph should be blue (h1 ~ p)</p>
|
||||
<p style="second-p">This paragraph should be blue (h1 ~ p)</p>
|
||||
|
||||
<h2>Descendant vs Child Selectors</h2>
|
||||
<div class="outer-div">
|
||||
<div style="outer-div">
|
||||
<p>This paragraph should be purple and bold (div p and .outer-div > p)</p>
|
||||
<div>
|
||||
<p>This paragraph should be purple but not bold (div p only)</p>
|
||||
@@ -452,20 +451,20 @@ var HTML_CONTENT_S = """<head>
|
||||
<span>This span should have light red bg (h3 ~ span)</span>
|
||||
<span>This span should also have light red bg (h3 ~ span)</span>
|
||||
|
||||
<div class="container">
|
||||
<div style="container">
|
||||
<span>This span should have yellow bg (.container span)</span>
|
||||
<p>Regular paragraph in container</p>
|
||||
</div>
|
||||
|
||||
<div class="parent">
|
||||
<div style="parent">
|
||||
<button>This button should be green (.parent > button)</button>
|
||||
<div>
|
||||
<button>This button should be normal (not direct child)</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="item-special">This div should have yellow bg (class ends with 'special')</div>
|
||||
<div class="special-item">This div should be normal</div>
|
||||
<div style="item-special">This div should have yellow bg (class ends with 'special')</div>
|
||||
<div style="special-item">This div should be normal</div>
|
||||
</body>
|
||||
""".to_utf8_buffer()
|
||||
|
||||
@@ -590,3 +589,97 @@ var HTML_CONTENT3 = """<head>
|
||||
|
||||
</body>
|
||||
""".to_utf8_buffer()
|
||||
|
||||
var HTML_CONTENT = """<head>
|
||||
<title>Lua API Demo</title>
|
||||
<icon src="https://upload.wikimedia.org/wikipedia/commons/thumb/c/cf/Lua-Logo.svg/256px-Lua-Logo.svg.png">
|
||||
<meta name="theme-color" content="#000080">
|
||||
<meta name="description" content="Demonstrating the GURT Lua API">
|
||||
|
||||
<style>
|
||||
body { bg-[#f8f9fa] p-6 }
|
||||
h1 { text-[#2563eb] text-4xl font-bold }
|
||||
.container { bg-[#ffffff] p-4 rounded-lg shadow-lg }
|
||||
.demo-button { bg-[#3b82f6] text-white px-4 py-2 rounded hover:bg-[#2563eb] }
|
||||
</style>
|
||||
|
||||
<script>
|
||||
local typing = gurt.select('#type')
|
||||
local mouse = gurt.select('#mouse')
|
||||
local btnmouse = gurt.select('#btnmouse')
|
||||
|
||||
gurt.log('Starting Lua script execution...')
|
||||
|
||||
gurt.body:on('keypress', function(el)
|
||||
typing:set_text(table.tostring(el))
|
||||
end)
|
||||
|
||||
gurt.body:on('mousemove', function(el)
|
||||
mouse:set_text(table.tostring(el))
|
||||
end)
|
||||
|
||||
-- Test element selection and manipulation
|
||||
local heading = gurt.select('#main-heading')
|
||||
heading:set_text('Welcome to the New Web!')
|
||||
|
||||
local button = gurt.select('#demo-button')
|
||||
local event_log = gurt.select('#event-log')
|
||||
|
||||
button:on('mousedown', function()
|
||||
print('Mouse down')
|
||||
end)
|
||||
|
||||
button:on('mouseup', function()
|
||||
print('Mouse up')
|
||||
end)
|
||||
|
||||
button:on('mouseenter', function()
|
||||
print('Mouse enter')
|
||||
end)
|
||||
|
||||
button:on('mouseexit', function()
|
||||
print('Mouse exit')
|
||||
end)
|
||||
|
||||
button:on('mousemove', function(el)
|
||||
btnmouse:set_text(table.tostring(el))
|
||||
end)
|
||||
|
||||
if button and event_log then
|
||||
local click_count = 0
|
||||
|
||||
local subscription = button:on('click', function()
|
||||
click_count = click_count + 1
|
||||
local new_text = 'Button clicked ' .. click_count .. ' time(s)!'
|
||||
event_log:set_text(new_text)
|
||||
end)
|
||||
|
||||
heading:on('focusin', function()
|
||||
print('oh u flck')
|
||||
subscription:unsubscribe()
|
||||
end)
|
||||
|
||||
gurt.log('Event listener attached to button with subscription ID')
|
||||
else
|
||||
gurt.log('Could not find button or event log element')
|
||||
end
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1 id="main-heading">Welcome to GURT Lua API Demo</h1>
|
||||
|
||||
<div style="container">
|
||||
<p>This page demonstrates the GURT Lua API in action.</p>
|
||||
<div id="demo-button" style="w-40 h-40 bg-red-500 p-4 rounded-lg">Click me to see Lua in action!</div>
|
||||
</div>
|
||||
|
||||
<p id="event-log" style="mt-4 p-4 bg-[#f3f4f6] rounded min-h-24">Click the button</p>
|
||||
|
||||
<p id="mouse" style="mt-4 p-4 bg-[#f3f4f6] rounded min-h-24">Move your mouse</p>
|
||||
|
||||
<p id="btnmouse" style="mt-4 p-4 bg-[#f3f4f6] rounded min-h-24">Move mouse over Button</p>
|
||||
|
||||
<p id="type" style="mt-4 p-4 bg-[#f3f4f6] rounded min-h-24">Type something</p>
|
||||
</body>
|
||||
""".to_utf8_buffer()
|
||||
|
||||
161
flumi/Scripts/Utils/Lua/Event.gd
Normal file
161
flumi/Scripts/Utils/Lua/Event.gd
Normal file
@@ -0,0 +1,161 @@
|
||||
class_name LuaEventUtils
|
||||
extends RefCounted
|
||||
|
||||
static func connect_element_event(signal_node: Node, event_name: String, subscription) -> bool:
|
||||
if not signal_node:
|
||||
return false
|
||||
|
||||
match event_name:
|
||||
"click":
|
||||
if signal_node.has_signal("pressed"):
|
||||
signal_node.pressed.connect(subscription.lua_api._on_event_triggered.bind(subscription))
|
||||
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
|
||||
return true
|
||||
elif signal_node is Control:
|
||||
signal_node.gui_input.connect(subscription.lua_api._on_gui_input_click.bind(subscription))
|
||||
subscription.connected_signal = "gui_input"
|
||||
subscription.connected_node = signal_node
|
||||
return true
|
||||
"mousedown", "mouseup":
|
||||
if signal_node is Control:
|
||||
# Check if we already have a mouse handler connected to this node
|
||||
var already_connected = false
|
||||
for existing_id in subscription.lua_api.event_subscriptions:
|
||||
var existing_sub = subscription.lua_api.event_subscriptions[existing_id]
|
||||
if existing_sub.connected_node == signal_node and existing_sub.connected_signal == "gui_input_mouse":
|
||||
already_connected = true
|
||||
break
|
||||
|
||||
if not already_connected:
|
||||
signal_node.gui_input.connect(subscription.lua_api._on_gui_input_mouse_universal.bind(signal_node))
|
||||
|
||||
subscription.connected_signal = "gui_input_mouse"
|
||||
subscription.connected_node = signal_node
|
||||
return true
|
||||
"mousemove":
|
||||
if signal_node is Control:
|
||||
signal_node.gui_input.connect(subscription.lua_api._on_gui_input_mousemove.bind(subscription))
|
||||
subscription.connected_signal = "gui_input_mousemove"
|
||||
subscription.connected_node = signal_node
|
||||
return true
|
||||
"mouseenter":
|
||||
if signal_node is Control and signal_node.has_signal("mouse_entered"):
|
||||
signal_node.mouse_entered.connect(subscription.lua_api._on_event_triggered.bind(subscription))
|
||||
subscription.connected_signal = "mouse_entered"
|
||||
subscription.connected_node = signal_node
|
||||
return true
|
||||
"mouseexit":
|
||||
if signal_node is Control and signal_node.has_signal("mouse_exited"):
|
||||
signal_node.mouse_exited.connect(subscription.lua_api._on_event_triggered.bind(subscription))
|
||||
subscription.connected_signal = "mouse_exited"
|
||||
subscription.connected_node = signal_node
|
||||
return true
|
||||
"focusin":
|
||||
if signal_node is Control:
|
||||
signal_node.focus_mode = Control.FOCUS_ALL
|
||||
if signal_node.has_signal("focus_entered"):
|
||||
signal_node.focus_entered.connect(subscription.lua_api._on_event_triggered.bind(subscription))
|
||||
subscription.connected_signal = "focus_entered"
|
||||
subscription.connected_node = signal_node
|
||||
return true
|
||||
else:
|
||||
signal_node.gui_input.connect(subscription.lua_api._on_focus_gui_input.bind(subscription))
|
||||
subscription.connected_signal = "gui_input_focus"
|
||||
subscription.connected_node = signal_node
|
||||
return true
|
||||
"focusout":
|
||||
if signal_node is Control and signal_node.has_signal("focus_exited"):
|
||||
signal_node.focus_exited.connect(subscription.lua_api._on_event_triggered.bind(subscription))
|
||||
subscription.connected_signal = "focus_exited"
|
||||
subscription.connected_node = signal_node
|
||||
return true
|
||||
|
||||
return false
|
||||
|
||||
static func connect_body_event(event_name: String, subscription, lua_api) -> bool:
|
||||
match event_name:
|
||||
"keydown", "keypress", "keyup":
|
||||
lua_api.set_process_input(true)
|
||||
subscription.connected_signal = "input"
|
||||
subscription.connected_node = lua_api
|
||||
return true
|
||||
"mousemove":
|
||||
lua_api.set_process_input(true)
|
||||
subscription.connected_signal = "input_mousemove"
|
||||
subscription.connected_node = lua_api
|
||||
return true
|
||||
"mouseenter", "mouseexit":
|
||||
var main_container = lua_api.dom_parser.parse_result.dom_nodes.get("body", null)
|
||||
if main_container:
|
||||
if event_name == "mouseenter":
|
||||
main_container.mouse_entered.connect(lua_api._on_body_mouse_enter.bind(subscription))
|
||||
subscription.connected_signal = "mouse_entered"
|
||||
elif event_name == "mouseexit":
|
||||
main_container.mouse_exited.connect(lua_api._on_body_mouse_exit.bind(subscription))
|
||||
subscription.connected_signal = "mouse_exited"
|
||||
subscription.connected_node = main_container
|
||||
return true
|
||||
"focusin", "focusout":
|
||||
subscription.connected_signal = "focus_events"
|
||||
subscription.connected_node = lua_api
|
||||
return true
|
||||
|
||||
return false
|
||||
|
||||
static func _count_active_input_subscriptions(lua_api) -> int:
|
||||
var count = 0
|
||||
for sub_id in lua_api.event_subscriptions:
|
||||
var sub = lua_api.event_subscriptions[sub_id]
|
||||
if sub.connected_signal in ["input", "input_mousemove"]:
|
||||
count += 1
|
||||
return count
|
||||
|
||||
static func disconnect_subscription(subscription, lua_api) -> void:
|
||||
var target_node = subscription.connected_node if subscription.connected_node else lua_api.dom_parser.parse_result.dom_nodes.get(subscription.element_id, null)
|
||||
|
||||
if target_node and subscription.connected_signal:
|
||||
match subscription.connected_signal:
|
||||
"pressed":
|
||||
if target_node.has_signal("pressed"):
|
||||
target_node.pressed.disconnect(lua_api._on_event_triggered.bind(subscription))
|
||||
"gui_input":
|
||||
if target_node.has_signal("gui_input"):
|
||||
target_node.gui_input.disconnect(lua_api._on_gui_input_click.bind(subscription))
|
||||
"gui_input_mouse":
|
||||
if target_node.has_signal("gui_input"):
|
||||
target_node.gui_input.disconnect(lua_api._on_gui_input_mouse_universal.bind(target_node))
|
||||
"gui_input_mousemove":
|
||||
if target_node.has_signal("gui_input"):
|
||||
target_node.gui_input.disconnect(lua_api._on_gui_input_mousemove.bind(subscription))
|
||||
"gui_input_focus":
|
||||
if target_node.has_signal("gui_input"):
|
||||
target_node.gui_input.disconnect(lua_api._on_focus_gui_input.bind(subscription))
|
||||
"mouse_entered":
|
||||
if target_node.has_signal("mouse_entered"):
|
||||
# Check if this is a body event or element event
|
||||
if subscription.element_id == "body":
|
||||
target_node.mouse_entered.disconnect(lua_api._on_body_mouse_enter.bind(subscription))
|
||||
else:
|
||||
target_node.mouse_entered.disconnect(lua_api._on_event_triggered.bind(subscription))
|
||||
"mouse_exited":
|
||||
if target_node.has_signal("mouse_exited"):
|
||||
# Check if this is a body event or element event
|
||||
if subscription.element_id == "body":
|
||||
target_node.mouse_exited.disconnect(lua_api._on_body_mouse_exit.bind(subscription))
|
||||
else:
|
||||
target_node.mouse_exited.disconnect(lua_api._on_event_triggered.bind(subscription))
|
||||
"focus_entered":
|
||||
if target_node.has_signal("focus_entered"):
|
||||
target_node.focus_entered.disconnect(lua_api._on_event_triggered.bind(subscription))
|
||||
"focus_exited":
|
||||
if target_node.has_signal("focus_exited"):
|
||||
target_node.focus_exited.disconnect(lua_api._on_event_triggered.bind(subscription))
|
||||
"input":
|
||||
# Only disable input processing if no other input subscriptions remain
|
||||
if _count_active_input_subscriptions(lua_api) <= 1:
|
||||
lua_api.set_process_input(false)
|
||||
"input_mousemove":
|
||||
# Only disable input processing if no other input subscriptions remain
|
||||
if _count_active_input_subscriptions(lua_api) <= 1:
|
||||
lua_api.set_process_input(false)
|
||||
1
flumi/Scripts/Utils/Lua/Event.gd.uid
Normal file
1
flumi/Scripts/Utils/Lua/Event.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://b7bck02xxt0u6
|
||||
57
flumi/Scripts/Utils/Lua/Function.gd
Normal file
57
flumi/Scripts/Utils/Lua/Function.gd
Normal file
@@ -0,0 +1,57 @@
|
||||
class_name LuaFunctionUtils
|
||||
extends RefCounted
|
||||
|
||||
# Core Lua handler functions that extend Lua functionality
|
||||
|
||||
static func table_tostring_handler(vm: LuauVM) -> int:
|
||||
vm.luaL_checktype(1, vm.LUA_TTABLE)
|
||||
var table_string = LuaPrintUtils.table_to_string(vm, 1)
|
||||
vm.lua_pushstring(table_string)
|
||||
return 1
|
||||
|
||||
static func setup_gurt_api(vm: LuauVM, lua_api, dom_parser: HTMLParser) -> void:
|
||||
# override global print
|
||||
# This makes print() behave like gurt.log()
|
||||
vm.lua_pushcallable(LuaPrintUtils.lua_print, "print")
|
||||
vm.lua_setglobal("print")
|
||||
|
||||
# Add table.tostring utility
|
||||
vm.lua_getglobal("table")
|
||||
if vm.lua_isnil(-1):
|
||||
vm.lua_pop(1)
|
||||
vm.lua_newtable()
|
||||
vm.lua_setglobal("table")
|
||||
vm.lua_getglobal("table")
|
||||
|
||||
vm.lua_pushcallable(LuaFunctionUtils.table_tostring_handler, "table.tostring")
|
||||
vm.lua_setfield(-2, "tostring")
|
||||
vm.lua_pop(1) # Pop table from stack
|
||||
|
||||
vm.lua_newtable()
|
||||
|
||||
vm.lua_pushcallable(LuaPrintUtils.lua_print, "gurt.log")
|
||||
vm.lua_setfield(-2, "log")
|
||||
|
||||
vm.lua_pushcallable(lua_api._gurt_select_handler, "gurt.select")
|
||||
vm.lua_setfield(-2, "select")
|
||||
|
||||
# Add body element access
|
||||
var body_element = dom_parser.find_first("body")
|
||||
if body_element:
|
||||
vm.lua_newtable()
|
||||
vm.lua_pushstring("body")
|
||||
vm.lua_setfield(-2, "_element_id")
|
||||
|
||||
# NOTE: same code as add_element_methods, but lazy to handle body.xxxx prop
|
||||
vm.lua_pushcallable(lua_api._element_set_text_handler, "body.set_text")
|
||||
vm.lua_setfield(-2, "set_text")
|
||||
|
||||
vm.lua_pushcallable(lua_api._element_get_text_handler, "body.get_text")
|
||||
vm.lua_setfield(-2, "get_text")
|
||||
|
||||
vm.lua_pushcallable(lua_api._body_on_event_handler, "body.on")
|
||||
vm.lua_setfield(-2, "on")
|
||||
|
||||
vm.lua_setfield(-2, "body")
|
||||
|
||||
vm.lua_setglobal("gurt")
|
||||
1
flumi/Scripts/Utils/Lua/Function.gd.uid
Normal file
1
flumi/Scripts/Utils/Lua/Function.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://dbsrdfnhv4h16
|
||||
87
flumi/Scripts/Utils/Lua/Print.gd
Normal file
87
flumi/Scripts/Utils/Lua/Print.gd
Normal file
@@ -0,0 +1,87 @@
|
||||
class_name LuaPrintUtils
|
||||
extends RefCounted
|
||||
|
||||
static func lua_print(vm: LuauVM) -> int:
|
||||
var message_parts: Array[String] = []
|
||||
var num_args: int = vm.lua_gettop()
|
||||
|
||||
for i in range(1, num_args + 1):
|
||||
var value_str = lua_value_to_string(vm, i)
|
||||
message_parts.append(value_str)
|
||||
|
||||
var final_message = "\t".join(message_parts)
|
||||
print("GURT LOG: ", final_message)
|
||||
return 0
|
||||
|
||||
static func lua_value_to_string(vm: LuauVM, index: int) -> String:
|
||||
var lua_type = vm.lua_type(index)
|
||||
|
||||
match lua_type:
|
||||
vm.LUA_TNIL:
|
||||
return "nil"
|
||||
vm.LUA_TBOOLEAN:
|
||||
return "true" if vm.lua_toboolean(index) else "false"
|
||||
vm.LUA_TNUMBER:
|
||||
return str(vm.lua_tonumber(index))
|
||||
vm.LUA_TSTRING:
|
||||
return vm.lua_tostring(index)
|
||||
vm.LUA_TTABLE:
|
||||
return table_to_string(vm, index)
|
||||
vm.LUA_TFUNCTION:
|
||||
return "[function]"
|
||||
vm.LUA_TUSERDATA:
|
||||
return "[userdata]"
|
||||
vm.LUA_TVECTOR:
|
||||
var vec = vm.lua_tovector(index)
|
||||
return "vector(" + str(vec.x) + ", " + str(vec.y) + ", " + str(vec.z) + ", " + str(vec.w) + ")"
|
||||
_:
|
||||
return "[" + vm.lua_typename(lua_type) + "]"
|
||||
|
||||
static func table_to_string(vm: LuauVM, index: int, max_depth: int = 3, current_depth: int = 0) -> String:
|
||||
if current_depth >= max_depth:
|
||||
return "{...}"
|
||||
|
||||
var result = "{"
|
||||
var first = true
|
||||
var count = 0
|
||||
var max_items = 10
|
||||
|
||||
# Convert negative index to positive
|
||||
if index < 0:
|
||||
index = vm.lua_gettop() + index + 1
|
||||
|
||||
# Iterate through table
|
||||
vm.lua_pushnil() # First key
|
||||
while vm.lua_next(index):
|
||||
if count >= max_items:
|
||||
# We need to pop the value and key before breaking
|
||||
vm.lua_pop(2) # Remove value and key
|
||||
break
|
||||
|
||||
if not first:
|
||||
result += ", "
|
||||
first = false
|
||||
|
||||
# Get key
|
||||
var key_str = lua_value_to_string(vm, -2)
|
||||
# Get value
|
||||
var value_str = ""
|
||||
if vm.lua_type(-1) == vm.LUA_TTABLE:
|
||||
value_str = table_to_string(vm, -1, max_depth, current_depth + 1)
|
||||
else:
|
||||
value_str = lua_value_to_string(vm, -1)
|
||||
|
||||
# Check if key is a valid identifier (for shorthand)
|
||||
if key_str.is_valid_identifier():
|
||||
result += key_str + ": " + value_str
|
||||
else:
|
||||
result += "[" + key_str + "]: " + value_str
|
||||
|
||||
vm.lua_pop(1) # Remove value, keep key for next iteration
|
||||
count += 1
|
||||
|
||||
if count >= max_items:
|
||||
result += ", ..."
|
||||
|
||||
result += "}"
|
||||
return result
|
||||
1
flumi/Scripts/Utils/Lua/Print.gd.uid
Normal file
1
flumi/Scripts/Utils/Lua/Print.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://dvdnveday3ev1
|
||||
1
flumi/Scripts/Utils/LuaEventUtils.gd.uid
Normal file
1
flumi/Scripts/Utils/LuaEventUtils.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://bt0njoa0olpb7
|
||||
1
flumi/Scripts/Utils/LuaFunctionUtils.gd.uid
Normal file
1
flumi/Scripts/Utils/LuaFunctionUtils.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://dxti5hc236dcp
|
||||
1
flumi/Scripts/Utils/LuaPrintUtils.gd.uid
Normal file
1
flumi/Scripts/Utils/LuaPrintUtils.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://bwbbe8r7u10ov
|
||||
@@ -99,7 +99,18 @@ func render() -> void:
|
||||
|
||||
if body:
|
||||
StyleManager.apply_body_styles(body, parser, website_container, website_background)
|
||||
|
||||
parser.register_dom_node(body, website_container)
|
||||
|
||||
var scripts = parser.find_all("script")
|
||||
var lua_vm = null
|
||||
var lua_api = null
|
||||
if scripts.size() > 0:
|
||||
lua_vm = LuauVM.new()
|
||||
lua_api = LuaAPI.new()
|
||||
add_child(lua_vm)
|
||||
add_child(lua_api)
|
||||
|
||||
var i = 0
|
||||
while i < body.children.size():
|
||||
var element: HTMLParser.HTMLElement = body.children[i]
|
||||
@@ -118,6 +129,8 @@ func render() -> void:
|
||||
for inline_element in inline_elements:
|
||||
var inline_node = await create_element_node(inline_element, parser)
|
||||
if inline_node:
|
||||
parser.register_dom_node(inline_element, inline_node)
|
||||
|
||||
safe_add_child(hbox, inline_node)
|
||||
# Handle hyperlinks for all inline elements
|
||||
if contains_hyperlink(inline_element) and inline_node is RichTextLabel:
|
||||
@@ -130,6 +143,8 @@ func render() -> void:
|
||||
|
||||
var element_node = await create_element_node(element, parser)
|
||||
if element_node:
|
||||
parser.register_dom_node(element, element_node)
|
||||
|
||||
# ul/ol handle their own adding
|
||||
if element.tag_name != "ul" and element.tag_name != "ol":
|
||||
safe_add_child(website_container, element_node)
|
||||
@@ -144,6 +159,9 @@ func render() -> void:
|
||||
print("Couldn't parse unsupported HTML tag \"%s\"" % element.tag_name)
|
||||
|
||||
i += 1
|
||||
|
||||
if scripts.size() > 0 and lua_vm and lua_api:
|
||||
parser.process_scripts(lua_api, lua_vm)
|
||||
|
||||
static func safe_add_child(parent: Node, child: Node) -> void:
|
||||
if child.get_parent():
|
||||
@@ -232,7 +250,15 @@ func create_element_node(element: HTMLParser.HTMLElement, parser: HTMLParser) ->
|
||||
|
||||
# Apply flex CONTAINER properties if it's a flex container
|
||||
if is_flex_container:
|
||||
StyleManager.apply_flex_container_properties(final_node, styles)
|
||||
var flex_container_node = final_node
|
||||
# If the node was wrapped in a MarginContainer, get the inner FlexContainer
|
||||
if final_node is MarginContainer and final_node.get_child_count() > 0:
|
||||
var first_child = final_node.get_child(0)
|
||||
if first_child is FlexContainer:
|
||||
flex_container_node = first_child
|
||||
|
||||
if flex_container_node is FlexContainer:
|
||||
StyleManager.apply_flex_container_properties(flex_container_node, styles)
|
||||
|
||||
# Apply flex ITEM properties
|
||||
StyleManager.apply_flex_item_properties(final_node, styles)
|
||||
@@ -252,6 +278,7 @@ func create_element_node(element: HTMLParser.HTMLElement, parser: HTMLParser) ->
|
||||
if not child_element.is_inline_element() or is_flex_container:
|
||||
var child_node = await create_element_node(child_element, parser)
|
||||
if child_node and is_instance_valid(container_for_children):
|
||||
parser.register_dom_node(child_element, child_node)
|
||||
safe_add_child(container_for_children, child_node)
|
||||
|
||||
return final_node
|
||||
@@ -340,7 +367,7 @@ func create_element_node_internal(element: HTMLParser.HTMLElement, parser: HTMLP
|
||||
node = BackgroundUtils.create_panel_container_with_background(styles, hover_styles)
|
||||
else:
|
||||
node = DIV.instantiate()
|
||||
node.init(element, parser)
|
||||
node.init(element)
|
||||
|
||||
var has_only_text = is_text_only_element(element)
|
||||
|
||||
|
||||
21
flumi/addons/gdluau/LICENSE
Normal file
21
flumi/addons/gdluau/LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2023 Tigran Mamedov
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
0
flumi/addons/gdluau/bin/linux/.gitkeep
Normal file
0
flumi/addons/gdluau/bin/linux/.gitkeep
Normal file
Binary file not shown.
Binary file not shown.
0
flumi/addons/gdluau/bin/macos/.gitkeep
Normal file
0
flumi/addons/gdluau/bin/macos/.gitkeep
Normal file
Binary file not shown.
Binary file not shown.
0
flumi/addons/gdluau/bin/windows/.gitkeep
Normal file
0
flumi/addons/gdluau/bin/windows/.gitkeep
Normal file
Binary file not shown.
Binary file not shown.
BIN
flumi/addons/gdluau/bin/windows/libgcc_s_seh-1.dll
Normal file
BIN
flumi/addons/gdluau/bin/windows/libgcc_s_seh-1.dll
Normal file
Binary file not shown.
BIN
flumi/addons/gdluau/bin/windows/libstdc++-6.dll
Normal file
BIN
flumi/addons/gdluau/bin/windows/libstdc++-6.dll
Normal file
Binary file not shown.
BIN
flumi/addons/gdluau/bin/windows/libwinpthread-1.dll
Normal file
BIN
flumi/addons/gdluau/bin/windows/libwinpthread-1.dll
Normal file
Binary file not shown.
Binary file not shown.
13
flumi/addons/gdluau/gdluau.gdextension
Normal file
13
flumi/addons/gdluau/gdluau.gdextension
Normal file
@@ -0,0 +1,13 @@
|
||||
[configuration]
|
||||
|
||||
entry_symbol = "gdluau_library_init"
|
||||
compatibility_minimum = "4.2"
|
||||
|
||||
[libraries]
|
||||
|
||||
windows.debug.x86_64 = "res://addons/gdluau/bin/windows/gdluau.windows.template_debug.x86_64.dll"
|
||||
windows.release.x86_64 = "res://addons/gdluau/bin/windows/gdluau.windows.template_release.x86_64.dll"
|
||||
linux.debug.x86_64 = "res://addons/gdluau/bin/linux/libgdluau.linux.template_debug.x86_64.so"
|
||||
linux.release.x86_64 = "res://addons/gdluau/bin/linux/libgdluau.linux.template_release.x86_64.so"
|
||||
macos.debug = "res://addons/gdluau/bin/macos/macos.framework/libgdluau.macos.template_debug"
|
||||
macos.release = "res://addons/gdluau/bin/macos/macos.framework/libgdluau.macos.template_release"
|
||||
1
flumi/addons/gdluau/gdluau.gdextension.uid
Normal file
1
flumi/addons/gdluau/gdluau.gdextension.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://c4jyopuvj0sq1
|
||||
Binary file not shown.
Reference in New Issue
Block a user