2 extends DialogicVisualEditorField
4 ## Event block field for displaying conditions in either a simple or complex way.
6 var _current_value1: Variant = ""
7 var _current_value2: Variant = ""
10 ################################################################################
12 func _set_value(value:Variant) -> void:
13 var too_complex := is_too_complex(value)
14 %ToggleComplex.disabled = too_complex
15 %ToggleComplex.button_pressed = too_complex
16 %ComplexEditor.visible = too_complex
17 %SimpleEditor.visible = !too_complex
18 %ComplexEditor.text = value
20 load_simple_editor(value)
24 func _autofocus() -> void:
25 %Value1Variable.grab_focus()
29 func _ready() -> void:
30 for i in [%Value1Type, %Value2Type]:
33 'icon': ["String", "EditorIcons"],
37 'icon': ["float", "EditorIcons"],
41 'icon': load("res://addons/dialogic/Editor/Images/Pieces/variable.svg"),
45 'icon': ["bool", "EditorIcons"],
48 'label': 'Expression',
49 'icon': ["Variant", "EditorIcons"],
53 i.value_changed.connect(value_type_changed.bind(i.name))
54 i.value_changed.connect(something_changed)
55 i.tooltip_text = "Change type"
58 for i in [%Value1Variable, %Value2Variable]:
59 i.get_suggestions_func = get_variable_suggestions
60 i.value_changed.connect(something_changed)
62 %Value1Number.value_changed.connect(something_changed)
63 %Value2Number.value_changed.connect(something_changed)
64 %Value1Text.value_changed.connect(something_changed)
65 %Value2Text.value_changed.connect(something_changed)
66 %Value1Bool.value_changed.connect(something_changed)
67 %Value2Bool.value_changed.connect(something_changed)
69 %ToggleComplex.icon = get_theme_icon("Enum", "EditorIcons")
71 %Operator.value_changed.connect(something_changed)
73 {'label': '==', 'value': '=='},
74 {'label': '>', 'value': '>'},
75 {'label': '<', 'value': '<'},
76 {'label': '<=', 'value': '<='},
77 {'label': '>=', 'value': '>='},
78 {'label': '!=', 'value': '!='}
82 func load_simple_editor(condition_string:String) -> void:
83 var data := complex2simple(condition_string)
84 %Value1Type.set_value(get_value_type(data[0], 2))
85 _current_value1 = data[0]
86 value_type_changed('', get_value_type(data[0], 2), 'Value1')
87 %Operator.set_value(data[1].strip_edges())
88 %Value2Type.set_value(get_value_type(data[2], 0))
89 _current_value2 = data[2]
90 value_type_changed('', get_value_type(data[2], 0), 'Value2')
93 func value_type_changed(property:String, value_type:int, value_name:String) -> void:
94 value_name = value_name.trim_suffix('Type')
95 get_node('%'+value_name+'Variable').hide()
96 get_node('%'+value_name+'Text').hide()
97 get_node('%'+value_name+'Number').hide()
98 get_node('%'+value_name+'Bool').hide()
99 var current_val: Variant = ""
100 if '1' in value_name:
101 current_val = _current_value1
103 current_val = _current_value2
106 get_node('%'+value_name+'Text').show()
107 get_node('%'+value_name+'Text').set_value(trim_value(current_val, value_type))
109 get_node('%'+value_name+'Number').show()
110 get_node('%'+value_name+'Number').set_value(float(current_val.strip_edges()))
112 get_node('%'+value_name+'Variable').show()
113 get_node('%'+value_name+'Variable').set_value(trim_value(current_val, value_type))
115 get_node('%'+value_name+'Bool').show()
116 get_node('%'+value_name+'Bool').set_value(trim_value(current_val, value_type))
118 get_node('%'+value_name+'Text').show()
119 get_node('%'+value_name+'Text').set_value(str(current_val))
122 func get_value_type(value:String, default:int) -> int:
123 value = value.strip_edges()
124 if value.begins_with('"') and value.ends_with('"') and value.count('"')-value.count('\\"') == 2:
126 elif value.begins_with('{') and value.ends_with('}') and value.count('{') == 1:
128 elif value == "true" or value == "false":
133 if value.is_valid_float():
139 func prep_value(value:Variant, value_type:int) -> String:
140 if value != null: value = str(value)
142 value = value.strip_edges()
144 0: return '"'+value.replace('"', '\\"')+'"'
145 2: return '{'+value+'}'
149 func trim_value(value:Variant, value_type:int) -> String:
150 value = value.strip_edges()
152 0: return value.trim_prefix('"').trim_suffix('"').replace('\\"', '"')
153 2: return value.trim_prefix('{').trim_suffix('}')
155 if value == "true" or (value and (typeof(value) != TYPE_STRING or value != "false")):
162 func something_changed(fake_arg1=null, fake_arg2 = null):
163 if %ComplexEditor.visible:
164 value_changed.emit(property_name, %ComplexEditor.text)
168 match %Value1Type.current_value:
169 0: _current_value1 = prep_value(%Value1Text.text, %Value1Type.current_value)
170 1: _current_value1 = str(%Value1Number.get_value())
171 2: _current_value1 = prep_value(%Value1Variable.current_value, %Value1Type.current_value)
172 3: _current_value1 = prep_value(%Value1Bool.button_pressed, %Value1Type.current_value)
173 _: _current_value1 = prep_value(%Value1Text.text, %Value1Type.current_value)
175 match %Value2Type.current_value:
176 0: _current_value2 = prep_value(%Value2Text.text, %Value2Type.current_value)
177 1: _current_value2 = str(%Value2Number.get_value())
178 2: _current_value2 = prep_value(%Value2Variable.current_value, %Value2Type.current_value)
179 3: _current_value2 = prep_value(%Value2Bool.button_pressed, %Value2Type.current_value)
180 _: _current_value2 = prep_value(%Value2Text.text, %Value2Type.current_value)
183 if not %Operator.text in ['==', '!='] and get_value_type(_current_value2, 0) in [0, 3]:
184 event_resource.ui_update_warning.emit("This operator doesn't work with strings and booleans.")
186 event_resource.ui_update_warning.emit("")
188 value_changed.emit(property_name, get_simple_condition())
191 func is_too_complex(condition:String) -> bool:
192 if condition.strip_edges().is_empty():
195 var comparison_count: int = 0
196 for i in ['==', '!=', '<=', '<', '>', '>=']:
197 comparison_count += condition.count(i)
198 if comparison_count == 1:
204 ## Combines the info from the simple editor fields into a string condition
205 func get_simple_condition() -> String:
206 return _current_value1 +" "+ %Operator.text +" "+ _current_value2
209 func complex2simple(condition:String) -> Array:
210 if is_too_complex(condition) or condition.strip_edges().is_empty():
213 for i in ['==', '!=', '<=', '<', '>', '>=']:
215 var cond_split := Array(condition.split(i, false))
216 return [cond_split[0], i, cond_split[1]]
221 func _on_toggle_complex_toggled(button_pressed:bool) -> void:
223 %ComplexEditor.show()
225 %ComplexEditor.text = get_simple_condition()
227 if !is_too_complex(%ComplexEditor.text):
228 %ComplexEditor.hide()
230 load_simple_editor(%ComplexEditor.text)
233 func _on_complex_editor_text_changed(new_text:String) -> void:
234 %ToggleComplex.disabled = is_too_complex(%ComplexEditor.text)
238 func get_variable_suggestions(filter:String) -> Dictionary:
239 var suggestions := {}
240 var vars: Dictionary = ProjectSettings.get_setting('dialogic/variables', {})
241 for var_path in DialogicUtil.list_variables(vars):
242 suggestions[var_path] = {'value':var_path, 'editor_icon':["ClassList", "EditorIcons"]}
246 func _on_value_1_variable_value_changed(property_name: Variant, value: Variant) -> void:
247 var type := DialogicUtil.get_variable_type(value)
249 DialogicUtil.VarTypes.BOOL:
250 if not %Operator.text in ["==", "!="]:
251 %Operator.text = "=="
252 if get_value_type(_current_value2, 3) in [0, 1]:
253 %Value2Type.insert_options()
254 %Value2Type.index_pressed(3)
255 DialogicUtil.VarTypes.STRING:
256 if not %Operator.text in ["==", "!="]:
257 %Operator.text = "=="
258 if get_value_type(_current_value2, 0) in [1, 3]:
259 %Value2Type.insert_options()
260 %Value2Type.index_pressed(0)
261 DialogicUtil.VarTypes.FLOAT, DialogicUtil.VarTypes.INT:
262 if get_value_type(_current_value2, 1) in [0,3]:
263 %Value2Type.insert_options()
264 %Value2Type.index_pressed(1)