You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
407 lines
17 KiB
407 lines
17 KiB
@tool
|
|
extends DialogicSettingsPage
|
|
|
|
|
|
func _get_title() -> String:
|
|
return "Modules"
|
|
|
|
func _get_priority() -> int:
|
|
return 0
|
|
|
|
func _is_feature_tab() -> bool:
|
|
return true
|
|
|
|
|
|
func _ready() -> void:
|
|
if get_parent() is SubViewport:
|
|
return
|
|
%Refresh.icon = get_theme_icon("Loop", "EditorIcons")
|
|
%Search.right_icon = get_theme_icon("Search", "EditorIcons")
|
|
|
|
%Filter_Events.icon = get_theme_icon("Favorites", "EditorIcons")
|
|
%Filter_Subsystems.icon = get_theme_icon("Callable", "EditorIcons")
|
|
%Filter_Styles.icon = get_theme_icon("PopupMenu", "EditorIcons")
|
|
%Filter_EffectsAndModifiers.icon = get_theme_icon("RichTextEffect", "EditorIcons")
|
|
%Filter_Editors.icon = get_theme_icon("ConfirmationDialog", "EditorIcons")
|
|
%Filter_Settings.icon = get_theme_icon("PluginScript", "EditorIcons")
|
|
%Collapse.icon = get_theme_icon("CollapseTree", "EditorIcons")
|
|
|
|
%EventDefaultsPanel.add_theme_stylebox_override('panel', get_theme_stylebox("Background", "EditorStyles"))
|
|
|
|
%ExternalLink.icon = get_theme_icon("Help", "EditorIcons")
|
|
|
|
|
|
func _refresh() -> void:
|
|
%EventDefaultsPanel.hide()
|
|
load_modules_tree()
|
|
|
|
|
|
func _on_refresh_pressed() -> void:
|
|
load_modules_tree()
|
|
|
|
|
|
func filters_updated(fake_arg:Variant) -> void:
|
|
load_modules_tree()
|
|
|
|
|
|
func _on_collapse_toggled(button_pressed:bool) -> void:
|
|
for item in %Tree.get_root().get_children():
|
|
item.collapsed = button_pressed
|
|
|
|
if button_pressed:
|
|
%Collapse.icon = get_theme_icon("ExpandTree", "EditorIcons")
|
|
%Collapse.tooltip_text = "Expand All"
|
|
else:
|
|
%Collapse.icon = get_theme_icon("CollapseTree", "EditorIcons")
|
|
%Collapse.tooltip_text = "Collapse All"
|
|
|
|
|
|
func _on_search_text_changed(new_text:String) -> void:
|
|
for filter in [%Filter_Events, %Filter_Subsystems, %Filter_Editors, %Filter_EffectsAndModifiers, %Filter_Settings, %Filter_Styles]:
|
|
filter.text = ""
|
|
filter.set_meta("counter", 0)
|
|
|
|
var hidden_events :Array= DialogicUtil.get_editor_setting('hidden_event_buttons', [])
|
|
|
|
for child in %Tree.get_root().get_children():
|
|
if new_text.to_lower() in child.get_text(0).to_lower() or new_text.is_empty():
|
|
for sub_child in child.get_children():
|
|
sub_child.visible = sub_child.get_meta('filter_button').button_pressed
|
|
sub_child.get_meta('filter_button').set_meta('counter', sub_child.get_meta('filter_button').get_meta('counter')+1)
|
|
sub_child.get_meta('filter_button').text = str(sub_child.get_meta('filter_button').get_meta('counter'))
|
|
child.visible = true
|
|
else:
|
|
for sub_child in child.get_children():
|
|
sub_child.visible = sub_child.get_meta('filter_button').button_pressed and new_text.to_lower() in sub_child.get_text(0).to_lower()
|
|
|
|
if new_text.to_lower() in sub_child.get_text(0).to_lower():
|
|
sub_child.get_meta('filter_button').set_meta('counter', sub_child.get_meta('filter_button').get_meta('counter')+1)
|
|
sub_child.get_meta('filter_button').text = str(sub_child.get_meta('filter_button').get_meta('counter'))
|
|
|
|
for i in range(child.get_button_count(0)):
|
|
child.erase_button(0, child.get_button_count(0)-1)
|
|
var any_visible := false
|
|
var counter := 0
|
|
for sub_child in child.get_children():
|
|
if sub_child.visible:
|
|
child.add_button(0, sub_child.get_icon(0), counter, false, sub_child.get_text(0))
|
|
if sub_child.get_metadata(0) and sub_child.get_metadata(0)['type'] == 'Event' and sub_child.get_metadata(0)['hidden']:
|
|
var color : Color = sub_child.get_icon_modulate(0)
|
|
color.a = 0.5
|
|
child.set_button_color(0, counter, color)
|
|
else:
|
|
child.set_button_color(0, counter, sub_child.get_icon_modulate(0))
|
|
counter += 1
|
|
any_visible = true
|
|
child.visible = any_visible
|
|
|
|
|
|
|
|
func load_modules_tree() -> void:
|
|
%Tree.clear()
|
|
var root :TreeItem = %Tree.create_item()
|
|
var cached_events := DialogicResourceUtil.get_event_cache()
|
|
var hidden_events: Array = DialogicUtil.get_editor_setting('hidden_event_buttons', [])
|
|
var indexers := DialogicUtil.get_indexers()
|
|
for i in indexers:
|
|
var module_item :TreeItem = %Tree.create_item(root)
|
|
module_item.set_text(0, i.get_script().resource_path.trim_suffix('/index.gd').get_file())
|
|
module_item.set_metadata(0, {'type':'Module'})
|
|
|
|
# Events
|
|
for ev in i._get_events():
|
|
if not ResourceLoader.exists(ev):
|
|
continue
|
|
var event_item : TreeItem = %Tree.create_item(module_item)
|
|
event_item.set_icon(0, get_theme_icon("Favorites", "EditorIcons"))
|
|
for cached_event in cached_events:
|
|
if cached_event.get_script().resource_path == ev:
|
|
event_item.set_text(0, cached_event.event_name + " Event")
|
|
event_item.set_icon_modulate(0, cached_event.event_color)
|
|
var hidden :bool = cached_event.event_name in hidden_events
|
|
event_item.set_metadata(0, {'type':'Event', 'event':cached_event, 'hidden':hidden})
|
|
event_item.add_button(0, get_theme_icon("GuiVisibilityVisible", "EditorIcons"), 0, false, "Toggle Event Button Visibility")
|
|
if hidden:
|
|
event_item.set_button(0, 0, get_theme_icon("GuiVisibilityHidden", "EditorIcons"))
|
|
event_item.set_meta('filter_button', %Filter_Events)
|
|
event_item.visible = %Filter_Events.button_pressed
|
|
|
|
# Subsystems
|
|
for subsys in i._get_subsystems():
|
|
var subsys_item : TreeItem = %Tree.create_item(module_item)
|
|
subsys_item.set_icon(0, get_theme_icon("Callable", "EditorIcons"))
|
|
subsys_item.set_text(0, subsys.name + " Subsystem")
|
|
subsys_item.set_icon_modulate(0, get_theme_color("readonly_color", "Editor"))
|
|
subsys_item.set_metadata(0, {'type':'Subsystem', 'info':subsys})
|
|
subsys_item.set_meta('filter_button', %Filter_Subsystems)
|
|
subsys_item.visible = %Filter_Subsystems.button_pressed
|
|
|
|
# Style scenes
|
|
for style in i._get_layout_parts():
|
|
var style_item : TreeItem = %Tree.create_item(module_item)
|
|
style_item.set_icon(0, get_theme_icon("PopupMenu", "EditorIcons"))
|
|
style_item.set_text(0, style.name)
|
|
style_item.set_icon_modulate(0, get_theme_color("property_color_x", "Editor"))
|
|
style_item.set_metadata(0, {'type':'Style', 'info':style})
|
|
style_item.set_meta('filter_button', %Filter_Styles)
|
|
style_item.visible = %Filter_Styles.button_pressed
|
|
|
|
# Text Effects
|
|
for effect in i._get_text_effects():
|
|
var effect_item : TreeItem = %Tree.create_item(module_item)
|
|
effect_item.set_icon(0, get_theme_icon("RichTextEffect", "EditorIcons"))
|
|
effect_item.set_text(0, "Text effect ["+effect.command+"]")
|
|
effect_item.set_icon_modulate(0, get_theme_color("property_color_z", "Editor"))
|
|
effect_item.set_metadata(0, {'type':'Effect', 'info':effect})
|
|
effect_item.set_meta('filter_button', %Filter_EffectsAndModifiers)
|
|
effect_item.visible = %Filter_EffectsAndModifiers.button_pressed
|
|
|
|
# Text Modifiers
|
|
for mod in i._get_text_modifiers():
|
|
var mod_item : TreeItem = %Tree.create_item(module_item)
|
|
mod_item.set_icon(0, get_theme_icon("RichTextEffect", "EditorIcons"))
|
|
mod_item.set_text(0, mod.method.capitalize())
|
|
mod_item.set_icon_modulate(0, get_theme_color("property_color_z", "Editor"))
|
|
mod_item.set_metadata(0, {'type':'Modifier', 'info':mod})
|
|
mod_item.set_meta('filter_button', %Filter_EffectsAndModifiers)
|
|
mod_item.visible = %Filter_EffectsAndModifiers.button_pressed
|
|
|
|
# Settings
|
|
for settings in i._get_settings_pages():
|
|
var settings_item : TreeItem = %Tree.create_item(module_item)
|
|
settings_item.set_icon(0, get_theme_icon("PluginScript", "EditorIcons"))
|
|
settings_item.set_text(0, module_item.get_text(0) + " Settings")
|
|
settings_item.set_icon_modulate(0, get_theme_color("readonly_color", "Editor"))
|
|
settings_item.set_metadata(0, {'type':'Settings', 'info':settings})
|
|
settings_item.set_meta('filter_button', %Filter_Settings)
|
|
settings_item.visible = %Filter_Settings.button_pressed
|
|
|
|
# Editors
|
|
for editor in i._get_editors():
|
|
var editor_item : TreeItem = %Tree.create_item(module_item)
|
|
editor_item.set_icon(0, get_theme_icon("ConfirmationDialog", "EditorIcons"))
|
|
editor_item.set_text(0, editor.get_file().trim_suffix('.tscn').capitalize())
|
|
editor_item.set_icon_modulate(0, get_theme_color("readonly_color", "Editor"))
|
|
editor_item.set_metadata(0, {'type':'Editor', 'info':editor})
|
|
editor_item.set_meta('filter_button', %Filter_Editors)
|
|
editor_item.visible = %Filter_Editors.button_pressed
|
|
|
|
module_item.collapsed = %Collapse.button_pressed
|
|
|
|
_on_search_text_changed(%Search.text)
|
|
if %Tree.get_root().get_child_count(): %Tree.set_selected(%Tree.get_root().get_child(0), 0)
|
|
|
|
|
|
func _on_tree_button_clicked(item:TreeItem, column:int, id:int, mouse_button_index:int) -> void:
|
|
match item.get_metadata(0)['type']:
|
|
'Module':
|
|
item.collapsed = false
|
|
%Tree.set_selected(item.get_child(id), 0)
|
|
'Event':
|
|
# Visibility item clicked
|
|
if id == 0:
|
|
var meta :Dictionary= item.get_metadata(0)
|
|
if meta['hidden']:
|
|
item.set_button(0, 0, get_theme_icon("GuiVisibilityVisible", "EditorIcons"))
|
|
item.get_parent().set_button_color(0, item.get_index(), item.get_icon_modulate(0))
|
|
if item == %Tree.get_selected():
|
|
%VisibilityToggle.button_pressed = true
|
|
else:
|
|
item.set_button(0, 0, get_theme_icon("GuiVisibilityHidden", "EditorIcons"))
|
|
var color : Color = item.get_icon_modulate(0)
|
|
color.a = 0.5
|
|
item.get_parent().set_button_color(0, item.get_index(), color)
|
|
if item == %Tree.get_selected():
|
|
%VisibilityToggle.button_pressed = false
|
|
meta['hidden'] = !meta['hidden']
|
|
item.set_metadata(0, meta)
|
|
change_event_visibility(meta['event'], !meta['hidden'])
|
|
|
|
|
|
func _on_tree_item_selected() -> void:
|
|
var selected_item :TreeItem = %Tree.get_selected()
|
|
|
|
var metadata :Variant = selected_item.get_metadata(0)
|
|
|
|
%Title.text = selected_item.get_text(0)
|
|
%EventDefaultsPanel.hide()
|
|
%Icon.texture = null
|
|
%ExternalLink.hide()
|
|
%VisibilityToggle.hide()
|
|
|
|
if metadata is Dictionary:
|
|
match metadata.type:
|
|
'Event':
|
|
%GeneralInfo.text = "Events can be used in timelines and do all kinds of things. They often interact with subsystems and dialogic nodes."
|
|
|
|
load_event_settings(metadata.event)
|
|
if %EventDefaults.get_child_count():
|
|
%EventDefaultsPanel.show()
|
|
|
|
if metadata.event.help_page_path:
|
|
%ExternalLink.show()
|
|
%ExternalLink.set_meta('url', metadata.event.help_page_path)
|
|
%Icon.texture = metadata.event._get_icon()
|
|
if !metadata.event.disable_editor_button:
|
|
%VisibilityToggle.show()
|
|
%VisibilityToggle.button_pressed = !metadata.event.event_name in DialogicUtil.get_editor_setting('hidden_event_buttons', [])
|
|
if %VisibilityToggle.button_pressed:
|
|
%VisibilityToggle.icon = get_theme_icon("GuiVisibilityVisible", "EditorIcons")
|
|
else:
|
|
%VisibilityToggle.icon = get_theme_icon("GuiVisibilityHidden", "EditorIcons")
|
|
# -------------------------------------------------
|
|
'Subsystem':
|
|
%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()."
|
|
# -------------------------------------------------
|
|
'Effect':
|
|
%GeneralInfo.text = "Text effects can be used in text events. They will be executed once reached and can take a single argument."
|
|
# -------------------------------------------------
|
|
'Modifier':
|
|
%GeneralInfo.text = "Modifiers can modify text from text events before it is shown."
|
|
# -------------------------------------------------
|
|
'Style':
|
|
%GeneralInfo.text = "Style presets can be activated and modified in the Styles editor. They provide the design of the dialog interface in your game."
|
|
# -------------------------------------------------
|
|
'Editor':
|
|
%GeneralInfo.text = "Editors provide a user interface for editing dialogic data."
|
|
# -------------------------------------------------
|
|
'Settings':
|
|
%GeneralInfo.text = "Settings pages provide settings that are usually used by subsystems, events and dialogic nodes."
|
|
# -------------------------------------------------
|
|
'_':
|
|
%GeneralInfo.text = ""
|
|
|
|
|
|
func _on_external_link_pressed():
|
|
if %ExternalLink.has_meta('url'):
|
|
OS.shell_open(%ExternalLink.get_meta('url'))
|
|
|
|
|
|
func change_event_visibility(event:DialogicEvent, visibility:bool) -> void:
|
|
if event:
|
|
var list :Array= DialogicUtil.get_editor_setting('hidden_event_buttons', [])
|
|
if visibility:
|
|
list.erase(event.event_name)
|
|
else:
|
|
list.append(event.event_name)
|
|
DialogicUtil.set_editor_setting('hidden_event_buttons', list)
|
|
force_event_button_list_update()
|
|
|
|
|
|
func _on_visibility_toggle_toggled(button_pressed:bool) -> void:
|
|
change_event_visibility(%Tree.get_selected().get_metadata(0).event, button_pressed)
|
|
|
|
if button_pressed:
|
|
%VisibilityToggle.icon = get_theme_icon("GuiVisibilityVisible", "EditorIcons")
|
|
%Tree.get_selected().set_button(0, 0, get_theme_icon("GuiVisibilityVisible", "EditorIcons"))
|
|
%Tree.get_selected().get_parent().set_button_color(0, %Tree.get_selected().get_index(), %Tree.get_selected().get_icon_modulate(0))
|
|
else:
|
|
%VisibilityToggle.icon = get_theme_icon("GuiVisibilityHidden", "EditorIcons")
|
|
%Tree.get_selected().set_button(0, 0, get_theme_icon("GuiVisibilityHidden", "EditorIcons"))
|
|
var color : Color = %Tree.get_selected().get_icon_modulate(0)
|
|
color.a = 0.5
|
|
%Tree.get_selected().get_parent().set_button_color(0, %Tree.get_selected().get_index(), color)
|
|
|
|
|
|
|
|
func force_event_button_list_update() -> void:
|
|
find_parent('EditorsManager').editors['Timeline'].node.get_node('%VisualEditor').load_event_buttons()
|
|
|
|
################################################################################
|
|
## EVENT DEFAULT SETTINGS
|
|
################################################################################
|
|
func load_event_settings(event:DialogicEvent) -> void:
|
|
for child in %EventDefaults.get_children():
|
|
child.queue_free()
|
|
|
|
var event_default_overrides :Dictionary = ProjectSettings.get_setting('dialogic/event_default_overrides', {})
|
|
|
|
var params := event.get_shortcode_parameters()
|
|
for prop in params:
|
|
# Label
|
|
var label := Label.new()
|
|
label.text = prop.capitalize()
|
|
%EventDefaults.add_child(label)
|
|
|
|
# Editing field
|
|
var editor_node :Node = null
|
|
var current_value :Variant = params[prop].default
|
|
if event_default_overrides.get(event.event_name, {}).has(params[prop].property):
|
|
current_value = event_default_overrides.get(event.event_name, {}).get(params[prop].property)
|
|
|
|
match typeof(event.get(params[prop].property)):
|
|
TYPE_STRING:
|
|
editor_node = LineEdit.new()
|
|
editor_node.custom_minimum_size.x = 150
|
|
editor_node.text = str(current_value)
|
|
editor_node.text_changed.connect(_on_event_default_string_submitted.bind(params[prop].property))
|
|
TYPE_INT, TYPE_FLOAT:
|
|
if params[prop].has('suggestions'):
|
|
editor_node = OptionButton.new()
|
|
for i in params[prop].suggestions.call():
|
|
editor_node.add_item(i, int(params[prop].suggestions.call()[i].value))
|
|
editor_node.select(int(current_value))
|
|
editor_node.item_selected.connect(_on_event_default_option_selected.bind(editor_node, params[prop].property))
|
|
else:
|
|
editor_node = SpinBox.new()
|
|
|
|
editor_node.allow_greater = true
|
|
editor_node.allow_lesser = true
|
|
if typeof(event.get(params[prop].property)) == TYPE_INT:
|
|
editor_node.step = 1
|
|
else:
|
|
editor_node.step = 0.001
|
|
|
|
editor_node.value = float(current_value)
|
|
editor_node.value_changed.connect(_on_event_default_number_changed.bind(params[prop].property))
|
|
|
|
TYPE_VECTOR2:
|
|
editor_node = load("res://addons/dialogic/Editor/Events/Fields/Vector2.tscn").instantiate()
|
|
editor_node.set_value(current_value)
|
|
editor_node.property_name = params[prop].property
|
|
editor_node.value_changed.connect(_on_event_default_value_changed)
|
|
|
|
TYPE_BOOL:
|
|
editor_node = CheckBox.new()
|
|
editor_node.button_pressed = bool(current_value)
|
|
editor_node.toggled.connect(_on_event_default_bool_toggled.bind(params[prop].property))
|
|
|
|
TYPE_ARRAY:
|
|
editor_node = load("res://addons/dialogic/Editor/Events/Fields/Array.tscn").instantiate()
|
|
editor_node.set_value(current_value)
|
|
editor_node.property_name = params[prop].property
|
|
editor_node.value_changed.connect(_on_event_default_value_changed)
|
|
|
|
%EventDefaults.add_child(editor_node)
|
|
|
|
|
|
func set_event_default_override(prop:String, value:Variant) -> void:
|
|
var event_default_overrides :Dictionary = ProjectSettings.get_setting('dialogic/event_default_overrides', {})
|
|
var event :DialogicEvent = %Tree.get_selected().get_metadata(0).event
|
|
|
|
if not event_default_overrides.has(event.event_name):
|
|
event_default_overrides[event.event_name] = {}
|
|
|
|
event_default_overrides[event.event_name][prop] = value
|
|
|
|
ProjectSettings.set_setting('dialogic/event_default_overrides', event_default_overrides)
|
|
|
|
|
|
|
|
|
|
func _on_event_default_string_submitted(text:String, prop:String) -> void:
|
|
set_event_default_override(prop, text)
|
|
|
|
func _on_event_default_option_selected(index:int, option_button:OptionButton, prop:String) -> void:
|
|
set_event_default_override(prop, option_button.get_item_id(index))
|
|
|
|
func _on_event_default_number_changed(value:float, prop:String) -> void:
|
|
set_event_default_override(prop, value)
|
|
|
|
func _on_event_default_value_changed(prop:String, value:Vector2) -> void:
|
|
set_event_default_override(prop, value)
|
|
|
|
func _on_event_default_bool_toggled(value:bool, prop:String) -> void:
|
|
set_event_default_override(prop, value)
|
|
|