]> Untitled Git - wolf-seeking-sheep.git/blob - addons/dialogic/Editor/Settings/settings_modules.gd
Updated export config options
[wolf-seeking-sheep.git] / addons / dialogic / Editor / Settings / settings_modules.gd
1 @tool
2 extends DialogicSettingsPage
3
4
5 func _get_title() -> String:
6         return "Modules"
7
8 func _get_priority() -> int:
9         return 0
10
11 func _is_feature_tab() -> bool:
12         return true
13
14
15 func _ready() -> void:
16         if get_parent() is SubViewport:
17                 return
18         %Refresh.icon = get_theme_icon("Loop", "EditorIcons")
19         %Search.right_icon = get_theme_icon("Search", "EditorIcons")
20
21         %Filter_Events.icon = get_theme_icon("Favorites", "EditorIcons")
22         %Filter_Subsystems.icon = get_theme_icon("Callable", "EditorIcons")
23         %Filter_Styles.icon = get_theme_icon("PopupMenu", "EditorIcons")
24         %Filter_EffectsAndModifiers.icon = get_theme_icon("RichTextEffect", "EditorIcons")
25         %Filter_Editors.icon = get_theme_icon("ConfirmationDialog", "EditorIcons")
26         %Filter_Settings.icon = get_theme_icon("PluginScript", "EditorIcons")
27         %Collapse.icon = get_theme_icon("CollapseTree", "EditorIcons")
28
29         %EventDefaultsPanel.add_theme_stylebox_override('panel', get_theme_stylebox("Background", "EditorStyles"))
30
31         %ExternalLink.icon = get_theme_icon("Help", "EditorIcons")
32
33
34 func _refresh() -> void:
35         %EventDefaultsPanel.hide()
36         load_modules_tree()
37
38
39 func _on_refresh_pressed() -> void:
40         DialogicUtil.get_indexers(true, true)
41         DialogicResourceUtil.update_event_cache()
42         load_modules_tree()
43
44
45 func filters_updated(fake_arg:Variant) -> void:
46         load_modules_tree()
47
48
49 func _on_collapse_toggled(button_pressed:bool) -> void:
50         for item in %Tree.get_root().get_children():
51                 item.collapsed = button_pressed
52
53         if button_pressed:
54                 %Collapse.icon = get_theme_icon("ExpandTree", "EditorIcons")
55                 %Collapse.tooltip_text = "Expand All"
56         else:
57                 %Collapse.icon = get_theme_icon("CollapseTree", "EditorIcons")
58                 %Collapse.tooltip_text = "Collapse All"
59
60
61 func _on_search_text_changed(new_text:String) -> void:
62         for filter in [%Filter_Events, %Filter_Subsystems, %Filter_Editors, %Filter_EffectsAndModifiers, %Filter_Settings, %Filter_Styles]:
63                 filter.text = ""
64                 filter.set_meta("counter", 0)
65
66         var hidden_events: Array = DialogicUtil.get_editor_setting('hidden_event_buttons', [])
67
68         for child in %Tree.get_root().get_children():
69                 if new_text.to_lower() in child.get_text(0).to_lower() or new_text.is_empty():
70                         for sub_child in child.get_children():
71                                 sub_child.visible = sub_child.get_meta('filter_button').button_pressed
72                                 sub_child.get_meta('filter_button').set_meta('counter', sub_child.get_meta('filter_button').get_meta('counter')+1)
73                                 sub_child.get_meta('filter_button').text = str(sub_child.get_meta('filter_button').get_meta('counter'))
74                         child.visible = true
75                 else:
76                         for sub_child in child.get_children():
77                                 sub_child.visible = sub_child.get_meta('filter_button').button_pressed and new_text.to_lower() in sub_child.get_text(0).to_lower()
78
79                                 if new_text.to_lower() in sub_child.get_text(0).to_lower():
80                                         sub_child.get_meta('filter_button').set_meta('counter', sub_child.get_meta('filter_button').get_meta('counter')+1)
81                                         sub_child.get_meta('filter_button').text = str(sub_child.get_meta('filter_button').get_meta('counter'))
82
83                 for i in range(child.get_button_count(0)):
84                         child.erase_button(0, child.get_button_count(0)-1)
85                 var any_visible := false
86                 var counter := 0
87                 for sub_child in child.get_children():
88                         if sub_child.visible:
89                                 child.add_button(0, sub_child.get_icon(0), counter, false, sub_child.get_text(0))
90                                 if sub_child.get_metadata(0) and sub_child.get_metadata(0)['type'] == 'Event' and sub_child.get_metadata(0)['hidden']:
91                                         var color: Color = sub_child.get_icon_modulate(0)
92                                         color.a = 0.5
93                                         child.set_button_color(0, counter, color)
94                                 else:
95                                         child.set_button_color(0, counter, sub_child.get_icon_modulate(0))
96                                 counter += 1
97                                 any_visible = true
98                 child.visible = any_visible
99
100
101
102 func load_modules_tree() -> void:
103         %Tree.clear()
104         var root: TreeItem = %Tree.create_item()
105         var cached_events := DialogicResourceUtil.get_event_cache()
106         var hidden_events: Array = DialogicUtil.get_editor_setting('hidden_event_buttons', [])
107         var indexers := DialogicUtil.get_indexers()
108         for i in indexers:
109                 var module_item: TreeItem = %Tree.create_item(root)
110                 module_item.set_text(0, i.get_script().resource_path.trim_suffix('/index.gd').get_file())
111                 module_item.set_metadata(0, {'type':'Module'})
112
113                 # Events
114                 for ev in i._get_events():
115                         if not ResourceLoader.exists(ev):
116                                 continue
117                         var event_item: TreeItem = %Tree.create_item(module_item)
118                         event_item.set_icon(0, get_theme_icon("Favorites", "EditorIcons"))
119                         for cached_event in cached_events:
120                                 if cached_event.get_script().resource_path == ev:
121                                         event_item.set_text(0, cached_event.event_name + " Event")
122                                         event_item.set_icon_modulate(0, cached_event.event_color)
123                                         var hidden: bool = cached_event.event_name in hidden_events
124                                         event_item.set_metadata(0, {'type':'Event', 'event':cached_event, 'hidden':hidden})
125                                         event_item.add_button(0, get_theme_icon("GuiVisibilityVisible", "EditorIcons"), 0, false, "Toggle Event Button Visibility")
126                                         if hidden:
127                                                 event_item.set_button(0, 0, get_theme_icon("GuiVisibilityHidden", "EditorIcons"))
128                         event_item.set_meta('filter_button', %Filter_Events)
129                         event_item.visible = %Filter_Events.button_pressed
130
131                 # Subsystems
132                 for subsys in i._get_subsystems():
133                         var subsys_item: TreeItem = %Tree.create_item(module_item)
134                         subsys_item.set_icon(0, get_theme_icon("Callable", "EditorIcons"))
135                         subsys_item.set_text(0, subsys.name + " Subsystem")
136                         subsys_item.set_icon_modulate(0, get_theme_color("readonly_color", "Editor"))
137                         subsys_item.set_metadata(0, {'type':'Subsystem', 'info':subsys})
138                         subsys_item.set_meta('filter_button', %Filter_Subsystems)
139                         subsys_item.visible = %Filter_Subsystems.button_pressed
140
141                 # Style scenes
142                 for style in i._get_layout_parts():
143                         var style_item: TreeItem = %Tree.create_item(module_item)
144                         style_item.set_icon(0, get_theme_icon("PopupMenu", "EditorIcons"))
145                         style_item.set_text(0, style.name)
146                         style_item.set_icon_modulate(0, get_theme_color("property_color_x", "Editor"))
147                         style_item.set_metadata(0, {'type':'Style', 'info':style})
148                         style_item.set_meta('filter_button', %Filter_Styles)
149                         style_item.visible = %Filter_Styles.button_pressed
150
151                 # Text Effects
152                 for effect in i._get_text_effects():
153                         var effect_item: TreeItem = %Tree.create_item(module_item)
154                         effect_item.set_icon(0, get_theme_icon("RichTextEffect", "EditorIcons"))
155                         effect_item.set_text(0, "Text effect ["+effect.command+"]")
156                         effect_item.set_icon_modulate(0, get_theme_color("property_color_z", "Editor"))
157                         effect_item.set_metadata(0, {'type':'Effect', 'info':effect})
158                         effect_item.set_meta('filter_button', %Filter_EffectsAndModifiers)
159                         effect_item.visible = %Filter_EffectsAndModifiers.button_pressed
160
161                 # Text Modifiers
162                 for mod in i._get_text_modifiers():
163                         var mod_item: TreeItem = %Tree.create_item(module_item)
164                         mod_item.set_icon(0, get_theme_icon("RichTextEffect", "EditorIcons"))
165                         mod_item.set_text(0, mod.method.capitalize())
166                         mod_item.set_icon_modulate(0, get_theme_color("property_color_z", "Editor"))
167                         mod_item.set_metadata(0, {'type':'Modifier', 'info':mod})
168                         mod_item.set_meta('filter_button', %Filter_EffectsAndModifiers)
169                         mod_item.visible = %Filter_EffectsAndModifiers.button_pressed
170
171                 # Settings
172                 for settings in i._get_settings_pages():
173                         var settings_item: TreeItem = %Tree.create_item(module_item)
174                         settings_item.set_icon(0, get_theme_icon("PluginScript", "EditorIcons"))
175                         settings_item.set_text(0, module_item.get_text(0) + " Settings")
176                         settings_item.set_icon_modulate(0, get_theme_color("readonly_color", "Editor"))
177                         settings_item.set_metadata(0, {'type':'Settings', 'info':settings})
178                         settings_item.set_meta('filter_button', %Filter_Settings)
179                         settings_item.visible = %Filter_Settings.button_pressed
180
181                 # Editors
182                 for editor in i._get_editors():
183                         var editor_item: TreeItem = %Tree.create_item(module_item)
184                         editor_item.set_icon(0, get_theme_icon("ConfirmationDialog", "EditorIcons"))
185                         editor_item.set_text(0, editor.get_file().trim_suffix('.tscn').capitalize())
186                         editor_item.set_icon_modulate(0, get_theme_color("readonly_color", "Editor"))
187                         editor_item.set_metadata(0, {'type':'Editor', 'info':editor})
188                         editor_item.set_meta('filter_button', %Filter_Editors)
189                         editor_item.visible = %Filter_Editors.button_pressed
190
191                 module_item.collapsed = %Collapse.button_pressed
192
193         _on_search_text_changed(%Search.text)
194         if %Tree.get_root().get_child_count(): %Tree.set_selected(%Tree.get_root().get_child(0), 0)
195
196
197 func _on_tree_button_clicked(item:TreeItem, column:int, id:int, mouse_button_index:int) -> void:
198         match item.get_metadata(0)['type']:
199                 'Module':
200                         item.collapsed = false
201                         %Tree.set_selected(item.get_child(id), 0)
202                 'Event':
203                         # Visibility item clicked
204                         if id == 0:
205                                 var meta: Dictionary= item.get_metadata(0)
206                                 if meta['hidden']:
207                                         item.set_button(0, 0, get_theme_icon("GuiVisibilityVisible", "EditorIcons"))
208                                         item.get_parent().set_button_color(0, item.get_index(), item.get_icon_modulate(0))
209                                         if item == %Tree.get_selected():
210                                                 %VisibilityToggle.button_pressed = true
211                                 else:
212                                         item.set_button(0, 0, get_theme_icon("GuiVisibilityHidden", "EditorIcons"))
213                                         var color: Color = item.get_icon_modulate(0)
214                                         color.a = 0.5
215                                         item.get_parent().set_button_color(0, item.get_index(), color)
216                                         if item == %Tree.get_selected():
217                                                 %VisibilityToggle.button_pressed = false
218                                 meta['hidden'] = !meta['hidden']
219                                 item.set_metadata(0, meta)
220                                 change_event_visibility(meta['event'], !meta['hidden'])
221
222
223 func _on_tree_item_selected() -> void:
224         var selected_item: TreeItem = %Tree.get_selected()
225
226         var metadata: Variant = selected_item.get_metadata(0)
227
228         %Title.text = selected_item.get_text(0)
229         %EventDefaultsPanel.hide()
230         %Icon.texture = null
231         %ExternalLink.hide()
232         %VisibilityToggle.hide()
233
234         if metadata is Dictionary:
235                 match metadata.type:
236                         'Event':
237                                 %GeneralInfo.text = "Events can be used in timelines and do all kinds of things. They often interact with subsystems and dialogic nodes."
238
239                                 load_event_settings(metadata.event)
240                                 if %EventDefaults.get_child_count():
241                                         %EventDefaultsPanel.show()
242
243                                 if metadata.event.help_page_path:
244                                         %ExternalLink.show()
245                                         %ExternalLink.set_meta('url', metadata.event.help_page_path)
246                                 %Icon.texture = metadata.event._get_icon()
247                                 if !metadata.event.disable_editor_button:
248                                         %VisibilityToggle.show()
249                                         %VisibilityToggle.button_pressed = !metadata.event.event_name in DialogicUtil.get_editor_setting('hidden_event_buttons', [])
250                                         if %VisibilityToggle.button_pressed:
251                                                 %VisibilityToggle.icon = get_theme_icon("GuiVisibilityVisible", "EditorIcons")
252                                         else:
253                                                 %VisibilityToggle.icon = get_theme_icon("GuiVisibilityHidden", "EditorIcons")
254                         # -------------------------------------------------
255                         'Subsystem':
256                                 %GeneralInfo.text = "Subsystems hold specialized functionality. They mostly manage communication between events and dialogic nodes. Often they provide handy methods that can be accessed by the user like this: Dialogic.Subsystem.a_method()."
257                         # -------------------------------------------------
258                         'Effect':
259                                 %GeneralInfo.text = "Text effects can be used in text events. They will be executed once reached and can take a single argument."
260                         # -------------------------------------------------
261                         'Modifier':
262                                 %GeneralInfo.text = "Modifiers can modify text from text events before it is shown."
263                         # -------------------------------------------------
264                         'Style':
265                                 %GeneralInfo.text = "Style presets can be activated and modified in the Styles editor. They provide the design of the dialog interface in your game."
266                         # -------------------------------------------------
267                         'Editor':
268                                 %GeneralInfo.text = "Editors provide a user interface for editing dialogic data."
269                         # -------------------------------------------------
270                         'Settings':
271                                 %GeneralInfo.text = "Settings pages provide settings that are usually used by subsystems, events and dialogic nodes."
272                         # -------------------------------------------------
273                         '_':
274                                 %GeneralInfo.text = ""
275
276
277 func _on_external_link_pressed() -> void:
278         if %ExternalLink.has_meta('url'):
279                 OS.shell_open(%ExternalLink.get_meta('url'))
280
281
282 func change_event_visibility(event:DialogicEvent, visibility:bool) -> void:
283         if event:
284                 var list: Array= DialogicUtil.get_editor_setting('hidden_event_buttons', [])
285                 if visibility:
286                         list.erase(event.event_name)
287                 else:
288                         list.append(event.event_name)
289                 DialogicUtil.set_editor_setting('hidden_event_buttons', list)
290                 force_event_button_list_update()
291
292
293 func _on_visibility_toggle_toggled(button_pressed:bool) -> void:
294         change_event_visibility(%Tree.get_selected().get_metadata(0).event, button_pressed)
295
296         if button_pressed:
297                 %VisibilityToggle.icon = get_theme_icon("GuiVisibilityVisible", "EditorIcons")
298                 %Tree.get_selected().set_button(0, 0, get_theme_icon("GuiVisibilityVisible", "EditorIcons"))
299                 %Tree.get_selected().get_parent().set_button_color(0, %Tree.get_selected().get_index(), %Tree.get_selected().get_icon_modulate(0))
300         else:
301                 %VisibilityToggle.icon = get_theme_icon("GuiVisibilityHidden", "EditorIcons")
302                 %Tree.get_selected().set_button(0, 0, get_theme_icon("GuiVisibilityHidden", "EditorIcons"))
303                 var color: Color = %Tree.get_selected().get_icon_modulate(0)
304                 color.a = 0.5
305                 %Tree.get_selected().get_parent().set_button_color(0, %Tree.get_selected().get_index(), color)
306
307
308
309 func force_event_button_list_update() -> void:
310         find_parent('EditorsManager').editors['Timeline'].node.get_node('%VisualEditor').load_event_buttons()
311
312 ################################################################################
313 ##                                              EVENT DEFAULT SETTINGS
314 ################################################################################
315 func load_event_settings(event:DialogicEvent) -> void:
316         for child in %EventDefaults.get_children():
317                 child.queue_free()
318
319         var event_default_overrides: Dictionary = ProjectSettings.get_setting('dialogic/event_default_overrides', {})
320
321         var params := event.get_shortcode_parameters()
322         for prop in params:
323                 var current_value: Variant = params[prop].default
324                 if event_default_overrides.get(event.event_name, {}).has(params[prop].property):
325                         current_value = event_default_overrides.get(event.event_name, {}).get(params[prop].property)
326
327                 # Label
328                 var label := Label.new()
329                 label.text = prop.capitalize()
330                 %EventDefaults.add_child(label)
331
332                 var reset := Button.new()
333                 reset.icon = get_theme_icon("Clear", "EditorIcons")
334                 reset.flat = true
335
336                 %EventDefaults.add_child(reset)
337
338                 # Editing field
339                 var editor_node: Node = null
340                 match typeof(event.get(params[prop].property)):
341                         TYPE_STRING:
342                                 editor_node = LineEdit.new()
343                                 editor_node.custom_minimum_size.x = 150
344                                 editor_node.text = str(current_value)
345                                 editor_node.text_changed.connect(_on_event_default_string_submitted.bind(params[prop].property))
346                         TYPE_INT, TYPE_FLOAT:
347                                 if params[prop].has('suggestions'):
348                                         editor_node = OptionButton.new()
349                                         for i in params[prop].suggestions.call():
350                                                 editor_node.add_item(i, int(params[prop].suggestions.call()[i].value))
351                                         editor_node.select(int(current_value))
352                                         editor_node.item_selected.connect(_on_event_default_option_selected.bind(editor_node, params[prop].property))
353                                 else:
354                                         editor_node = SpinBox.new()
355
356                                         editor_node.allow_greater = true
357                                         editor_node.allow_lesser = true
358                                         if typeof(event.get(params[prop].property)) == TYPE_INT:
359                                                 editor_node.step = 1
360                                         else:
361                                                 editor_node.step = 0.001
362
363                                         editor_node.value = float(current_value)
364                                         editor_node.value_changed.connect(_on_event_default_number_changed.bind(params[prop].property))
365
366                         TYPE_VECTOR2:
367                                 editor_node = load("res://addons/dialogic/Editor/Events/Fields/field_vector2.tscn").instantiate()
368                                 editor_node.set_value(current_value)
369                                 editor_node.property_name = params[prop].property
370                                 editor_node.value_changed.connect(_on_event_default_value_changed)
371
372                         TYPE_BOOL:
373                                 editor_node = CheckBox.new()
374                                 editor_node.button_pressed = bool(current_value)
375                                 editor_node.toggled.connect(_on_event_default_bool_toggled.bind(params[prop].property))
376
377                         TYPE_ARRAY:
378                                 editor_node = load("res://addons/dialogic/Editor/Events/Fields/field_array.tscn").instantiate()
379                                 editor_node.set_value(current_value)
380                                 editor_node.property_name = params[prop].property
381                                 editor_node.value_changed.connect(_on_event_default_value_changed)
382
383                         TYPE_DICTIONARY:
384                                 editor_node = load("res://addons/dialogic/Editor/Events/Fields/field_dictionary.tscn").instantiate()
385                                 editor_node.set_value(current_value)
386                                 editor_node.property_name = params[prop].property
387                                 editor_node.value_changed.connect(_on_event_default_value_changed)
388                 %EventDefaults.add_child(editor_node)
389                 reset.pressed.connect(reset_event_default_override.bind(prop, editor_node, params[prop].default))
390
391
392 func set_event_default_override(prop:String, value:Variant) -> void:
393         var event_default_overrides: Dictionary = ProjectSettings.get_setting('dialogic/event_default_overrides', {})
394         var event: DialogicEvent = %Tree.get_selected().get_metadata(0).event
395
396         if not event_default_overrides.has(event.event_name):
397                 event_default_overrides[event.event_name] = {}
398
399         event_default_overrides[event.event_name][prop] = value
400
401         ProjectSettings.set_setting('dialogic/event_default_overrides', event_default_overrides)
402
403
404 func reset_event_default_override(prop:String, node:Node, default:Variant) -> void:
405         var event_default_overrides: Dictionary = ProjectSettings.get_setting('dialogic/event_default_overrides', {})
406         var event: DialogicEvent = %Tree.get_selected().get_metadata(0).event
407
408         if not event_default_overrides.has(event.event_name):
409                 return
410
411         event_default_overrides[event.event_name].erase(prop)
412
413         ProjectSettings.set_setting('dialogic/event_default_overrides', event_default_overrides)
414
415         if node is CheckBox:
416                 node.button_pressed = default
417         elif node is LineEdit:
418                 node.text = default
419         elif node.has_method('set_value'):
420                 node.set_value(default)
421         elif node is ColorPickerButton:
422                 node.color = default
423         elif node is OptionButton:
424                 node.select(default)
425         elif node is SpinBox:
426                 node.value = default
427
428
429 func _on_event_default_string_submitted(text:String, prop:String) -> void:
430         set_event_default_override(prop, text)
431
432 func _on_event_default_option_selected(index:int, option_button:OptionButton, prop:String) -> void:
433         set_event_default_override(prop, option_button.get_item_id(index))
434
435 func _on_event_default_number_changed(value:float, prop:String) -> void:
436         set_event_default_override(prop, value)
437
438 func _on_event_default_value_changed(prop:String, value:Variant) -> void:
439         set_event_default_override(prop, value)
440
441 func _on_event_default_bool_toggled(value:bool, prop:String) -> void:
442         set_event_default_override(prop, value)
443