RapidGameFramework
Reusable Godot managers for data-driven small games
Loading...
Searching...
No Matches
ui_flow_manager.gd
Go to the documentation of this file.
1extends RefCounted
2
3
6
7
8
9func focus_first(root:Node) -> Control:
10 var control = find_first_focusable(root)
11 if control != null and control.is_inside_tree():
12 control.grab_focus()
13 return control
14
15
16
17func focus_named(root:Node, node_name:String, fallback_to_first:bool = true) -> Control:
18 if root == null:
19 return null
20 var target = root.find_child(node_name, true, false)
21 if target is Control and target.visible and target.focus_mode != Control.FOCUS_NONE:
22 if not (target is BaseButton) or not target.disabled:
23 if target.is_inside_tree():
24 target.grab_focus()
25 return target
26 return focus_first(root) if fallback_to_first else null
27
28
29
30func focus_button_by_text(root:Node, labels:Array, fallback_to_first:bool = true) -> Control:
31 if root == null:
32 return null
33 var target = _find_button_by_text(root, labels)
34 if target != null:
35 if target.is_inside_tree():
36 target.grab_focus()
37 return target
38 return focus_first(root) if fallback_to_first else null
39
40
41
43func focus_first_on_navigation(root:Node, event:InputEvent) -> bool:
44 if root == null or event == null:
45 return false
46 if not _is_navigation_event(event):
47 return false
48 var viewport = root.get_viewport() if root is Control else null
49 if viewport != null and viewport.gui_get_focus_owner() != null:
50 return false
51 return focus_first(root) != null
52
53
54
55func find_first_focusable(root:Node) -> Control:
56 if root == null:
57 return null
58 for child in root.get_children():
59 if child is Control and child.visible and child.focus_mode != Control.FOCUS_NONE:
60 if not (child is BaseButton) or not child.disabled:
61 return child
62 var nested = find_first_focusable(child)
63 if nested != null:
64 return nested
65 return null
66
67
68
69func set_focus_mode_recursive(root:Node, mode:int) -> void:
70 if root == null:
71 return
72 if root is Control:
73 root.focus_mode = mode
74 for child in root.get_children():
75 set_focus_mode_recursive(child, mode)
76
77
78
79func show_screen(screen_id:String, screens:Dictionary, scroll:ScrollContainer = null) -> String:
80 for id in screens.keys():
81 var screen = screens[id]
82 if screen is Control:
83 screen.visible = str(id) == screen_id
84 if scroll != null:
85 call_deferred("_set_scroll_vertical_if_valid", scroll, 0)
86 return screen_id
87
88
89
90func shifted_id(current_id:String, ordered_ids:Array, delta:int) -> String:
91 if ordered_ids.is_empty():
92 return current_id
93 var index = ordered_ids.find(current_id)
94 if index < 0:
95 index = 0
96 return str(ordered_ids[posmod(index + delta, ordered_ids.size())])
97
98
99
100func visible_screen_id(screens:Dictionary, fallback:String = "") -> String:
101 for id in screens.keys():
102 var screen = screens[id]
103 if screen is Control and screen.visible:
104 return str(id)
105 return fallback
106
107
108
109func format_local_time(unix_time:float) -> String:
110 if unix_time <= 0.0:
111 return "Unknown"
112 var value = Time.get_datetime_string_from_unix_time(int(unix_time), true)
113 return value.replace("T", " ").substr(0, 16)
114
115
116
118func set_label_text_if_changed(label:Label, text:String) -> bool:
119 if label == null:
120 return false
121 if label.text == text:
122 return false
123 label.text = text
124 return true
125
126
127func _is_navigation_event(event:InputEvent) -> bool:
128 for action in ["ui_up", "ui_down", "ui_left", "ui_right"]:
129 if event.is_action_pressed(action):
130 return true
131 return false
132
133
134func _find_button_by_text(root:Node, labels:Array) -> Control:
135 for child in root.get_children():
136 if child is Button and child.visible and not child.disabled and labels.has(str(child.text)):
137 return child
138 var nested = _find_button_by_text(child, labels)
139 if nested != null:
140 return nested
141 return null
142
143
144func _set_scroll_vertical_if_valid(scroll:ScrollContainer, value:int) -> void:
145 if scroll != null and is_instance_valid(scroll):
146 scroll.scroll_vertical = value