]> Untitled Git - wolf-seeking-sheep.git/blob - addons/dialogic/Modules/Settings/event_setting.gd
Squashed commit of the following:
[wolf-seeking-sheep.git] / addons / dialogic / Modules / Settings / event_setting.gd
1 @tool
2 class_name DialogicSettingEvent
3 extends DialogicEvent
4
5 ## Event that allows changing a specific setting.
6
7
8 ### Settings
9
10 enum Modes {SET, RESET, RESET_ALL}
11 enum SettingValueType {
12         STRING,
13         NUMBER,
14         VARIABLE,
15         EXPRESSION
16 }
17
18 ## The name of the setting to save to.
19 var name := ""
20 var _value_type := 0 :
21         get:
22                 return _value_type
23         set(_value):
24                 _value_type = _value
25                 if not _suppress_default_value:
26                         match _value_type:
27                                 SettingValueType.STRING, SettingValueType.VARIABLE, SettingValueType.EXPRESSION:
28                                         value = ""
29                                 SettingValueType.NUMBER:
30                                         value = 0
31                         ui_update_needed.emit()
32
33 var value: Variant = ""
34
35 var mode := Modes.SET
36
37 ## Used to suppress _value_type from overwriting value with a default value when the type changes
38 ## This is only used when initializing the event_variable.
39 var _suppress_default_value: bool = false
40
41 ################################################################################
42 ##                                              INITIALIZE
43 ################################################################################
44
45 func _execute() -> void:
46         if mode == Modes.RESET or mode == Modes.RESET_ALL:
47                 if !name.is_empty() and mode != Modes.RESET_ALL:
48                         dialogic.Settings.reset_setting(name)
49                 else:
50                         dialogic.Settings.reset_all()
51         else:
52                 match _value_type:
53                         SettingValueType.STRING:
54                                 dialogic.Settings.set(name, value)
55                         SettingValueType.NUMBER:
56                                 dialogic.Settings.set(name, float(value))
57                         SettingValueType.VARIABLE:
58                                 if dialogic.has_subsystem('VAR'):
59                                         dialogic.Settings.set(name, dialogic.VAR.get_variable('{'+value+'}'))
60                         SettingValueType.EXPRESSION:
61                                 if dialogic.has_subsystem('VAR'):
62                                         dialogic.Settings.set(name, dialogic.VAR.get_variable(value))
63         finish()
64
65
66 ################################################################################
67 ##                                              INITIALIZE
68 ################################################################################
69
70 func _init() -> void:
71         event_name = "Setting"
72         set_default_color('Color9')
73         event_category = "Helpers"
74         event_sorting_index = 2
75
76
77 func _get_icon() -> Resource:
78         return load(self.get_script().get_path().get_base_dir().path_join('icon.svg'))
79
80
81 ################################################################################
82 ##                                              SAVING/LOADING
83 ################################################################################
84
85 func to_text() -> String:
86         var string := "setting "
87         if mode != Modes.SET:
88                 string += "reset "
89
90         if !name.is_empty() and mode != Modes.RESET_ALL:
91                 string += '"' + name + '"'
92
93         if mode == Modes.SET:
94                 string += " = "
95                 value = str(value)
96                 match _value_type:
97                         SettingValueType.STRING: # String
98                                 string += '"'+value.replace('"', '\\"')+'"'
99                         SettingValueType.NUMBER,SettingValueType.EXPRESSION: # Float or Expression
100                                 string += str(value)
101                         SettingValueType.VARIABLE: # Variable
102                                 string += '{'+value+'}'
103
104         return string
105
106
107 func from_text(string:String) -> void:
108         var reg := RegEx.new()
109         reg.compile('setting (?<reset>reset)? *("(?<name>[^=+\\-*\\/]*)")?( *= *(?<value>.*))?')
110         var result := reg.search(string)
111         if !result:
112                 return
113
114         if result.get_string('reset'):
115                 mode = Modes.RESET
116
117         name = result.get_string('name').strip_edges()
118
119         if name.is_empty() and mode == Modes.RESET:
120                 mode = Modes.RESET_ALL
121
122         if result.get_string('value'):
123                 _suppress_default_value = true
124                 value = result.get_string('value').strip_edges()
125                 if value.begins_with('"') and value.ends_with('"') and value.count('"')-value.count('\\"') == 2:
126                         value = result.get_string('value').strip_edges().replace('"', '')
127                         _value_type = SettingValueType.STRING
128                 elif value.begins_with('{') and value.ends_with('}') and value.count('{') == 1:
129                         value = result.get_string('value').strip_edges().trim_suffix('}').trim_prefix('{')
130                         _value_type = SettingValueType.VARIABLE
131                 else:
132                         value = result.get_string('value').strip_edges()
133                         if value.is_valid_float():
134                                 _value_type = SettingValueType.NUMBER
135                         else:
136                                 _value_type = SettingValueType.EXPRESSION
137                 _suppress_default_value = false
138
139
140 func is_valid_event(string:String) -> bool:
141         return string.begins_with('setting')
142
143
144 ################################################################################
145 ##                                              EDITOR REPRESENTATION
146 ################################################################################
147
148 func build_event_editor() -> void:
149         add_header_edit('mode', ValueType.FIXED_OPTIONS, {
150                 'options': [{
151                                 'label': 'Set',
152                                 'value': Modes.SET,
153                                 'icon': load("res://addons/dialogic/Editor/Images/Dropdown/default.svg")
154                         },{
155                                 'label': 'Reset',
156                                 'value': Modes.RESET,
157                                 'icon': load("res://addons/dialogic/Editor/Images/Dropdown/update.svg")
158                         },{
159                                 'label': 'Reset All',
160                                 'value': Modes.RESET_ALL,
161                                 'icon': load("res://addons/dialogic/Editor/Images/Dropdown/update.svg")
162                         },
163                         ]})
164
165         add_header_edit('name', ValueType.DYNAMIC_OPTIONS, {'placeholder':'Type setting', 'suggestions_func':get_settings_suggestions}, 'mode != Modes.RESET_ALL')
166         add_header_edit('_value_type', ValueType.FIXED_OPTIONS, {'left_text':'to',
167                 'options': [
168                         {
169                                 'label': 'String',
170                                 'icon': ["String", "EditorIcons"],
171                                 'value': SettingValueType.STRING
172                         },{
173                                 'label': 'Number',
174                                 'icon': ["float", "EditorIcons"],
175                                 'value': SettingValueType.NUMBER
176                         },{
177                                 'label': 'Variable',
178                                 'icon': ["ClassList", "EditorIcons"],
179                                 'value': SettingValueType.VARIABLE
180                         },{
181                                 'label': 'Expression',
182                                 'icon': ["Variant", "EditorIcons"],
183                                 'value': SettingValueType.EXPRESSION
184                         }],
185                 'symbol_only':true},
186                 '!name.is_empty() and mode == Modes.SET')
187         add_header_edit('value', ValueType.SINGLELINE_TEXT, {}, '!name.is_empty() and (_value_type == SettingValueType.STRING or _value_type == SettingValueType.EXPRESSION) and mode == Modes.SET')
188         add_header_edit('value', ValueType.NUMBER, {}, '!name.is_empty()  and _value_type == SettingValueType.NUMBER and mode == Modes.SET')
189         add_header_edit('value', ValueType.DYNAMIC_OPTIONS,
190                         {'suggestions_func' : get_value_suggestions, 'placeholder':'Select Variable'},
191                         '!name.is_empty() and _value_type == SettingValueType.VARIABLE and mode == Modes.SET')
192
193
194 func get_settings_suggestions(filter:String) -> Dictionary:
195         var suggestions := {filter:{'value':filter, 'editor_icon':["GDScriptInternal", "EditorIcons"]}}
196
197         for prop in ProjectSettings.get_property_list():
198                 if prop.name.begins_with('dialogic/settings/'):
199                         suggestions[prop.name.trim_prefix('dialogic/settings/')] = {'value':prop.name.trim_prefix('dialogic/settings/'), 'editor_icon':["GDScript", "EditorIcons"]}
200         return suggestions
201
202
203 func get_value_suggestions(_filter:String) -> Dictionary:
204         var suggestions := {}
205
206         var vars: Dictionary = ProjectSettings.get_setting('dialogic/variables', {})
207         for var_path in DialogicUtil.list_variables(vars):
208                 suggestions[var_path] = {'value':var_path, 'editor_icon':["ClassList", "EditorIcons"]}
209         return suggestions
210
211
212
213 ####################### CODE COMPLETION ########################################
214 ################################################################################
215
216 func _get_code_completion(CodeCompletionHelper:Node, TextNode:TextEdit, line:String, _word:String, symbol:String) -> void:
217         if symbol == " " and !"reset" in line and !'=' in line and !'"' in line:
218                 TextNode.add_code_completion_option(CodeEdit.KIND_MEMBER, "reset", "reset ", event_color.lerp(TextNode.syntax_highlighter.normal_color, 0.5), TextNode.get_theme_icon("RotateLeft", "EditorIcons"))
219                 TextNode.add_code_completion_option(CodeEdit.KIND_MEMBER, "reset all", "reset \n", event_color.lerp(TextNode.syntax_highlighter.normal_color, 0.5), TextNode.get_theme_icon("ToolRotate", "EditorIcons"))
220
221         if (symbol == " " or symbol == '"') and !"=" in line and CodeCompletionHelper.get_line_untill_caret(line).count('"') != 2:
222                 for i in get_settings_suggestions(''):
223                         if i.is_empty():
224                                 continue
225                         if symbol == '"':
226                                 TextNode.add_code_completion_option(CodeEdit.KIND_MEMBER, i, i, event_color.lerp(TextNode.syntax_highlighter.normal_color, 0.5), TextNode.get_theme_icon("GDScript", "EditorIcons"), '"')
227                         else:
228                                 TextNode.add_code_completion_option(CodeEdit.KIND_MEMBER, i, '"'+i, event_color.lerp(TextNode.syntax_highlighter.normal_color, 0.5), TextNode.get_theme_icon("GDScript", "EditorIcons"), '"')
229
230
231 func _get_start_code_completion(_CodeCompletionHelper:Node, TextNode:TextEdit) -> void:
232         TextNode.add_code_completion_option(CodeEdit.KIND_PLAIN_TEXT, 'setting', 'setting ', event_color)
233
234 #################### SYNTAX HIGHLIGHTING #######################################
235 ################################################################################
236
237 func _get_syntax_highlighting(Highlighter:SyntaxHighlighter, dict:Dictionary, line:String) -> Dictionary:
238         dict[line.find('setting')] = {"color":event_color}
239         dict[line.find('setting')+7] = {"color":Highlighter.normal_color}
240         dict = Highlighter.color_word(dict, event_color, line, 'reset')
241         dict = Highlighter.color_region(dict, Highlighter.string_color, line, '"', '"')
242         dict = Highlighter.color_region(dict, Highlighter.variable_color, line, '{', '}')
243         return dict