]> Untitled Git - wolf-seeking-sheep.git/blob - addons/dialogic/Editor/Events/Fields/field_number.gd
Squashed commit of the following:
[wolf-seeking-sheep.git] / addons / dialogic / Editor / Events / Fields / field_number.gd
1 @tool
2 class_name DialogicVisualEditorFieldNumber
3 extends DialogicVisualEditorField
4
5 ## Event block field for integers and floats. Improved version of the native spinbox.
6
7 @export var allow_string: bool = false
8 @export var step: float = 0.1
9 @export var enforce_step: bool = true
10 @export var min: float = -INF
11 @export var max: float = INF
12 @export var value = 0.0
13 @export var prefix: String = ""
14 @export var suffix: String = ""
15
16 var _is_holding_button: bool = false #For handling incrementing while holding key or click
17
18 #region MAIN METHODS
19 ################################################################################
20
21 func _ready() -> void:
22         if %Value.text.is_empty():
23                 set_value(value)
24
25         update_prefix(prefix)
26         update_suffix(suffix)
27
28
29 func _load_display_info(info: Dictionary) -> void:
30         match info.get('mode', 0):
31                 0: #FLOAT
32                         use_float_mode(info.get('step', 0.1))
33                 1: #INT
34                         use_int_mode(info.get('step', 1))
35                 2: #DECIBLE:
36                         use_decibel_mode(info.get('step', step))
37
38         for option in info.keys():
39                 match option:
40                         'min': min = info[option]
41                         'max': max = info[option]
42                         'prefix': update_prefix(info[option])
43                         'suffix': update_suffix(info[option])
44                         'step':
45                                 enforce_step = true
46                                 step = info[option]
47                         'hide_step_button': %Spin.hide()
48
49
50 func _set_value(new_value: Variant) -> void:
51         _on_value_text_submitted(str(new_value), true)
52         %Value.tooltip_text = tooltip_text
53
54
55 func _autofocus() -> void:
56         %Value.grab_focus()
57
58
59 func get_value() -> float:
60         return value
61
62
63 func use_float_mode(value_step: float = 0.1) -> void:
64         step = value_step
65         update_suffix("")
66         enforce_step = false
67
68
69 func use_int_mode(value_step: float = 1) -> void:
70         step = value_step
71         update_suffix("")
72         enforce_step = true
73
74
75 func use_decibel_mode(value_step: float = step) -> void:
76         max = 6
77         update_suffix("dB")
78         min = -80
79
80 #endregion
81
82 #region UI FUNCTIONALITY
83 ################################################################################
84 var _stop_button_holding: Callable = func(button: BaseButton) -> void:
85         _is_holding_button = false
86         if button.button_up.get_connections().find(_stop_button_holding):
87                 button.button_up.disconnect(_stop_button_holding)
88         if button.focus_exited.get_connections().find(_stop_button_holding):
89                 button.focus_exited.disconnect(_stop_button_holding)
90         if button.mouse_exited.get_connections().find(_stop_button_holding):
91                 button.mouse_exited.disconnect(_stop_button_holding)
92
93
94 func _holding_button(value_direction: int, button: BaseButton) -> void:
95         if _is_holding_button:
96                 return
97         if _stop_button_holding.get_bound_arguments_count() > 0:
98                 _stop_button_holding.unbind(0)
99
100         _is_holding_button = true
101
102         #Ensure removal of our value changing routine when it shouldn't run anymore
103         button.button_up.connect(_stop_button_holding.bind(button))
104         button.focus_exited.connect(_stop_button_holding.bind(button))
105         button.mouse_exited.connect(_stop_button_holding.bind(button))
106
107         var scene_tree: SceneTree = get_tree()
108         var delay_timer_ms: int = 600
109
110         #Instead of awaiting for the duration, await per-frame so we can catch any changes in _is_holding_button and exit completely
111         while(delay_timer_ms > 0):
112                 if _is_holding_button == false:
113                         return
114                 var pre_time: int = Time.get_ticks_msec()
115                 await scene_tree.process_frame
116                 delay_timer_ms -= Time.get_ticks_msec() - pre_time
117
118         var change_speed: float = 0.25
119
120         while(_is_holding_button == true):
121                 await scene_tree.create_timer(change_speed).timeout
122                 change_speed = maxf(0.05, change_speed - 0.01)
123                 _on_value_text_submitted(str(value+(step * value_direction)))
124
125
126 func update_prefix(to_prefix: String) -> void:
127         prefix = to_prefix
128         %Prefix.visible = to_prefix != null and to_prefix != ""
129         %Prefix.text = prefix
130
131
132 func update_suffix(to_suffix: String) -> void:
133         suffix = to_suffix
134         %Suffix.visible = to_suffix != null and to_suffix != ""
135         %Suffix.text = suffix
136
137 #endregion
138
139 #region SIGNAL METHODS
140 ################################################################################
141 func _on_gui_input(event: InputEvent) -> void:
142         if event.is_action('ui_up') and event.get_action_strength('ui_up') > 0.5:
143                 _on_value_text_submitted(str(value+step))
144         elif event.is_action('ui_down') and event.get_action_strength('ui_down') > 0.5:
145                 _on_value_text_submitted(str(value-step))
146
147
148 func _on_increment_button_down(button: NodePath) -> void:
149         _on_value_text_submitted(str(value+step))
150         _holding_button(1.0, get_node(button) as BaseButton)
151
152
153 func _on_decrement_button_down(button: NodePath) -> void:
154         _on_value_text_submitted(str(value-step))
155         _holding_button(-1.0, get_node(button) as BaseButton)
156
157
158 func _on_value_text_submitted(new_text: String, no_signal:= false) -> void:
159         if new_text.is_empty() and not allow_string:
160                 new_text = "0.0"
161         if new_text.is_valid_float():
162                 var temp: float = min(max(new_text.to_float(), min), max)
163                 if !enforce_step:
164                         value = temp
165                 else:
166                         value = snapped(temp, step)
167         elif allow_string:
168                 value = new_text
169         %Value.text = str(value).pad_decimals(len(str(float(step)-floorf(step)))-2)
170         if not no_signal:
171                 value_changed.emit(property_name, value)
172         # Visually disable Up or Down arrow when limit is reached to better indicate a limit has been hit
173         %Spin/Decrement.disabled = value <= min
174         %Spin/Increment.disabled = value >= max
175
176
177 # If prefix or suffix was clicked, select the actual value box instead and move the caret to the closest side.
178 func _on_sublabel_clicked(event: InputEvent) -> void:
179         if event is InputEventMouseButton and event.pressed and event.button_index == MOUSE_BUTTON_LEFT:
180                 var mousePos: Vector2 = get_global_mouse_position()
181                 mousePos.x -= get_minimum_size().x / 2
182                 if mousePos.x > global_position.x:
183                         (%Value as LineEdit).caret_column = (%Value as LineEdit).text.length()
184                 else:
185                         (%Value as LineEdit).caret_column = 0
186                 (%Value as LineEdit).grab_focus()
187
188
189 func _on_value_focus_exited() -> void:
190         _on_value_text_submitted(%Value.text)
191         $Value_Panel.add_theme_stylebox_override('panel', get_theme_stylebox('panel', 'DialogicEventEdit'))
192
193
194 func _on_value_focus_entered() -> void:
195         $Value_Panel.add_theme_stylebox_override('panel', get_theme_stylebox('focus', 'DialogicEventEdit'))
196         %Value.select_all.call_deferred()
197
198 #endregion
199