immersive-home/lib/globals/event_system.gd

107 lines
2.8 KiB
GDScript3
Raw Normal View History

2023-11-22 02:44:07 +02:00
extends Node
const FN_PREFIX = "_on_"
const SIGNAL_PREFIX = "on_"
# Interaction Events
2023-11-27 01:23:19 +02:00
signal on_click(event: EventPointer)
signal on_press_down(event: EventPointer)
signal on_press_move(event: EventPointer)
signal on_press_up(event: EventPointer)
signal on_grab_down(event: EventPointer)
signal on_grab_move(event: EventPointer)
signal on_grab_up(event: EventPointer)
signal on_ray_enter(event: EventPointer)
signal on_ray_leave(event: EventPointer)
2023-11-22 02:44:07 +02:00
signal on_key_down(event: EventKey)
signal on_key_up(event: EventKey)
2023-11-22 18:35:54 +02:00
signal on_focus_in(event: EventFocus)
signal on_focus_out(event: EventFocus)
2023-11-28 00:46:05 +02:00
signal on_touch_enter(event: EventTouch)
signal on_touch_move(event: EventTouch)
signal on_touch_leave(event: EventTouch)
2023-12-13 23:22:52 +02:00
signal on_notify(event: EventNotify)
var _active_node: Node = null
2023-11-22 18:35:54 +02:00
2023-11-22 02:44:07 +02:00
func emit(type: String, event: Event):
if event is EventBubble:
_bubble_call(type, event.target, event)
else:
_root_call(type, event)
2023-12-13 23:22:52 +02:00
func notify(message: String, type := EventNotify.Type.INFO):
var event = EventNotify.new()
event.message = message
event.type = type
emit("notify", event)
func is_focused(node: Node):
return _active_node == node
2023-11-22 18:35:54 +02:00
2023-11-28 15:20:38 +02:00
func _handle_focus(target: Variant, event: EventBubble):
if target != null:
if target.is_in_group("ui_focus_skip"):
return false
if target.is_in_group("ui_focus_stop"):
return true
2023-11-22 18:35:54 +02:00
var event_focus = EventFocus.new()
event_focus.previous_target = _active_node
2023-11-28 00:46:05 +02:00
event_focus.target = target
2023-11-22 18:35:54 +02:00
if _active_node != null && _active_node.has_method(FN_PREFIX + "focus_out"):
_active_node.call(FN_PREFIX + "focus_out", event_focus)
on_focus_out.emit(event_focus)
2023-11-28 00:46:05 +02:00
if target == null || target.is_in_group("ui_focus") == false:
_active_node = null
2023-11-28 15:20:38 +02:00
return false
2023-11-28 00:46:05 +02:00
_active_node = target
if _active_node != null && _active_node.has_method(FN_PREFIX + "focus_in"):
_active_node.call(FN_PREFIX + "focus_in", event_focus)
on_focus_in.emit(event_focus)
2023-11-22 02:44:07 +02:00
2023-11-28 15:20:38 +02:00
return true
func _bubble_call(type: String, target: Variant, event: EventBubble, focused = false):
2023-11-22 02:44:07 +02:00
if target == null:
2023-11-22 18:35:54 +02:00
return false
2023-11-22 02:44:07 +02:00
if target.has_method(FN_PREFIX + type):
var updated_event = target.call(FN_PREFIX + type, event)
if updated_event is EventBubble:
updated_event.merge(event)
event = updated_event
if event.bubbling == false:
2023-11-22 18:35:54 +02:00
return false
2023-11-22 02:44:07 +02:00
2023-11-28 15:20:38 +02:00
if (type == "press_down" || type == "touch_enter") && focused == false:
focused = _handle_focus(target, event)
2023-11-28 00:46:05 +02:00
2023-11-22 02:44:07 +02:00
for child in target.get_children():
if child is Function && child.has_method(FN_PREFIX + type):
child.call(FN_PREFIX + type, event)
var parent = target.get_parent()
if parent != null && parent is Node:
2023-11-28 15:20:38 +02:00
_bubble_call(type, parent, event, focused)
2023-11-22 02:44:07 +02:00
else:
# in case the top has been reached
_root_call(type, event)
2023-11-22 18:35:54 +02:00
return true
2023-11-22 02:44:07 +02:00
func _root_call(type: String, event: Event):
get(SIGNAL_PREFIX + type).emit(event)