add focus event
This commit is contained in:
parent
ca294d3d88
commit
93c82f1790
43
README.md
43
README.md
|
@ -95,36 +95,33 @@ In case that an event of a specific node has to be reacted on, use the `Clickabl
|
||||||
|
|
||||||
It is also possible to bubble up information by returning a dictionary from a function like `_on_click`.
|
It is also possible to bubble up information by returning a dictionary from a function like `_on_click`.
|
||||||
|
|
||||||
```python
|
|
||||||
InteractionEvent {
|
|
||||||
"controller": XRController3D, # The controller that triggered the event
|
|
||||||
"ray": RayCast3D, # The ray-cast that triggered the event
|
|
||||||
"target": Node3D, # The node that was hit by the ray-cast
|
|
||||||
}
|
|
||||||
|
|
||||||
KeyEvent {
|
|
||||||
"key": String, # The key that was pressed
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
| Function called | Args | Description |
|
| Function called | Args | Description |
|
||||||
| -- | -- | -- |
|
| -- | -- | -- |
|
||||||
| `_on_click` | `[event: InteractionEvent]` | The back trigger button has been pressed and released |
|
| `_on_click` | `[event: EventRay]` | The back trigger button has been pressed and released |
|
||||||
| `_on_press_down` | `[event: InteractionEvent]` | The back trigger button has been pressed down |
|
| `_on_press_down` | `[event: EventRay]` | The back trigger button has been pressed down |
|
||||||
| `_on_press_move` | `[event: InteractionEvent]` | The back trigger button has been moved while pressed down |
|
| `_on_press_move` | `[event: EventRay]` | The back trigger button has been moved while pressed down |
|
||||||
| `_on_press_up` | `[event: InteractionEvent]` | The back trigger button has been released |
|
| `_on_press_up` | `[event: EventRay]` | The back trigger button has been released |
|
||||||
| `_on_grab_down` | `[event: InteractionEvent]` | The side grab button been pressed down |
|
| `_on_grab_down` | `[event: EventRay]` | The side grab button been pressed down |
|
||||||
| `_on_grab_move` | `[event: InteractionEvent]` | The side grab button been pressed down |
|
| `_on_grab_move` | `[event: EventRay]` | The side grab button been pressed down |
|
||||||
| `_on_grab_up` | `[event: InteractionEvent]` | The side grab button been released |
|
| `_on_grab_up` | `[event: EventRay]` | The side grab button been released |
|
||||||
| `_on_ray_enter` | `[event: InteractionEvent]` | The ray-cast enters the the collision body |
|
| `_on_ray_enter` | `[event: EventRay]` | The ray-cast enters the the collision body |
|
||||||
| `_on_ray_leave` | `[event: InteractionEvent]` | The ray-cast leaves the the collision body |
|
| `_on_ray_leave` | `[event: EventRay]` | The ray-cast leaves the the collision body |
|
||||||
| `_on_key_down` | `[event: KeyEvent]` | The ray-cast leaves the the collision body |
|
| `_on_key_down` | `[event: EventKey]` | The ray-cast leaves the the collision body |
|
||||||
| `_on_key_up` | `[event: KeyEvent]` | The ray-cast leaves the the collision body |
|
| `_on_key_up` | `[event: EventKey]` | The ray-cast leaves the the collision body |
|
||||||
|
| `_on_focus_in` | `[event: EventFocus]` | The node is got focused |
|
||||||
|
| `_on_focus_out` | `[event: EventFocus]` | The node lost focus |
|
||||||
|
|
||||||
After considering using the build in godot event system, I've decided that it would be better to use a custom event system.
|
After considering using the build in godot event system, I've decided that it would be better to use a custom event system.
|
||||||
The reason being that we would have to check each tick if the event matches the desired one which seems very inefficient compared to using signals like the browser does.
|
The reason being that we would have to check each tick if the event matches the desired one which seems very inefficient compared to using signals like the browser does.
|
||||||
Thus I've decided to use a custom event system that is similar to the one used in the browser.
|
Thus I've decided to use a custom event system that is similar to the one used in the browser.
|
||||||
|
|
||||||
|
### UI Groups
|
||||||
|
|
||||||
|
| Group | Description |
|
||||||
|
| -- | -- |
|
||||||
|
| `ui_focus` | The element can be focused |
|
||||||
|
|
||||||
|
|
||||||
### Functions
|
### Functions
|
||||||
|
|
||||||
In order to implement generic features, a set of functions is available to be used in the project.
|
In order to implement generic features, a set of functions is available to be used in the project.
|
||||||
|
|
|
@ -81,7 +81,7 @@ _data = {
|
||||||
"down": SubResource("Animation_iu2ed")
|
"down": SubResource("Animation_iu2ed")
|
||||||
}
|
}
|
||||||
|
|
||||||
[node name="Button" type="StaticBody3D"]
|
[node name="Button" type="StaticBody3D" groups=["ui_focus"]]
|
||||||
script = ExtResource("1_74x7g")
|
script = ExtResource("1_74x7g")
|
||||||
|
|
||||||
[node name="MeshInstance3D" type="MeshInstance3D" parent="."]
|
[node name="MeshInstance3D" type="MeshInstance3D" parent="."]
|
||||||
|
|
5
lib/events/event_focus.gd
Normal file
5
lib/events/event_focus.gd
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
extends Event
|
||||||
|
class_name EventFocus
|
||||||
|
|
||||||
|
var target: Node
|
||||||
|
var previous_target: Node
|
|
@ -17,16 +17,39 @@ signal on_ray_leave(event: EventRay)
|
||||||
signal on_key_down(event: EventKey)
|
signal on_key_down(event: EventKey)
|
||||||
signal on_key_up(event: EventKey)
|
signal on_key_up(event: EventKey)
|
||||||
|
|
||||||
|
signal on_focus_in(event: EventFocus)
|
||||||
|
signal on_focus_out(event: EventFocus)
|
||||||
|
|
||||||
|
var active_node: Node = null
|
||||||
|
|
||||||
func emit(type: String, event: Event):
|
func emit(type: String, event: Event):
|
||||||
if event is EventBubble:
|
if event is EventBubble:
|
||||||
_bubble_call(type, event.target, event)
|
_bubble_call(type, event.target, event)
|
||||||
|
if event.target.is_in_group("ui_focus"):
|
||||||
|
_handle_focus(event.target)
|
||||||
|
else:
|
||||||
|
_handle_focus(null)
|
||||||
else:
|
else:
|
||||||
_root_call(type, event)
|
_root_call(type, event)
|
||||||
|
|
||||||
|
func _handle_focus(node: Node):
|
||||||
|
var event = EventFocus.new()
|
||||||
|
event.previous_target = active_node
|
||||||
|
event.target = node
|
||||||
|
|
||||||
|
if active_node != null && active_node.has_method(FN_PREFIX + "focus_in"):
|
||||||
|
active_node.call(FN_PREFIX + "focus_out", event)
|
||||||
|
on_focus_out.emit(event)
|
||||||
|
|
||||||
|
active_node = node
|
||||||
|
|
||||||
|
if active_node != null:
|
||||||
|
active_node.call(FN_PREFIX + "focus_in", event)
|
||||||
|
on_focus_in.emit(event)
|
||||||
|
|
||||||
func _bubble_call(type: String, target: Variant, event: EventBubble):
|
func _bubble_call(type: String, target: Variant, event: EventBubble):
|
||||||
if target == null:
|
if target == null:
|
||||||
return
|
return false
|
||||||
|
|
||||||
if target.has_method(FN_PREFIX + type):
|
if target.has_method(FN_PREFIX + type):
|
||||||
var updated_event = target.call(FN_PREFIX + type, event)
|
var updated_event = target.call(FN_PREFIX + type, event)
|
||||||
|
@ -36,7 +59,7 @@ func _bubble_call(type: String, target: Variant, event: EventBubble):
|
||||||
event = updated_event
|
event = updated_event
|
||||||
|
|
||||||
if event.bubbling == false:
|
if event.bubbling == false:
|
||||||
return
|
return false
|
||||||
|
|
||||||
for child in target.get_children():
|
for child in target.get_children():
|
||||||
if child is Function && child.has_method(FN_PREFIX + type):
|
if child is Function && child.has_method(FN_PREFIX + type):
|
||||||
|
@ -50,6 +73,8 @@ func _bubble_call(type: String, target: Variant, event: EventBubble):
|
||||||
# in case the top has been reached
|
# in case the top has been reached
|
||||||
_root_call(type, event)
|
_root_call(type, event)
|
||||||
|
|
||||||
|
return true
|
||||||
|
|
||||||
|
|
||||||
func _root_call(type: String, event: Event):
|
func _root_call(type: String, event: Event):
|
||||||
get(SIGNAL_PREFIX + type).emit(event)
|
get(SIGNAL_PREFIX + type).emit(event)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user