diff --git a/addons/dialogic/Editor/CharacterEditor/character_editor.gd b/addons/dialogic/Editor/CharacterEditor/character_editor.gd index 89e9d7605..48183dbf6 100644 --- a/addons/dialogic/Editor/CharacterEditor/character_editor.gd +++ b/addons/dialogic/Editor/CharacterEditor/character_editor.gd @@ -13,6 +13,7 @@ enum PreviewModes {Full, Real} # Current state var current_preview_mode = PreviewModes.Full var loading = false +var current_previewed_scene = null # References var selected_item: TreeItem @@ -43,7 +44,7 @@ func _register() -> void: # Called when a character is opened somehow func _open_resource(resource:Resource) -> void: # update resource - current_resource = resource + current_resource = (resource as DialogicCharacter) # make sure changes in the ui won't trigger saving loading = true @@ -52,6 +53,13 @@ func _open_resource(resource:Resource) -> void: for main_edit in %MainEditTabs.get_children(): main_edit._load_character(current_resource) + %DefaultPortraitPicker.set_value(resource.default_portrait) + + %MainScale.value = 100*resource.scale + %MainOffsetX.value = resource.offset.x + %MainOffsetY.value = resource.offset.y + %MainMirror.button_pressed = resource.mirror + # Portrait section %PortraitSearch.text = "" load_portrait_tree() @@ -64,8 +72,22 @@ func _save_resource() -> void: if ! visible or not current_resource: return + # Portrait list current_resource.portraits = get_updated_portrait_dict() + # Portrait settings + if %DefaultPortraitPicker.current_value in current_resource.portraits.keys(): + current_resource.default_portrait = %DefaultPortraitPicker.current_value + elif !current_resource.portraits.is_empty(): + current_resource.default_portrait = current_resource.portraits.keys()[0] + else: + current_resource.default_portrait = "" + + current_resource.scale = %MainScale.value/100.0 + current_resource.offset = Vector2(%MainOffsetX.value, %MainOffsetY.value) + current_resource.mirror = %MainMirror.button_pressed + + # Main tabs for main_edit in %MainEditTabs.get_children(): current_resource = main_edit._save_changes(current_resource) @@ -76,7 +98,7 @@ func _save_resource() -> void: # Saves a new empty character to the given path func new_character(path: String) -> void: - var resource = DialogicCharacter.new() + var resource := DialogicCharacter.new() resource.resource_path = path resource.display_name = path.get_file().trim_suffix("."+path.get_extension()) resource.color = Color(1,1,1,1) @@ -91,16 +113,9 @@ func new_character(path: String) -> void: ############################################################################## func _ready() -> void: - ## Portrait section styling/connections - %AddPortraitButton.icon = get_theme_icon("Add", "EditorIcons") - %AddPortraitButton.pressed.connect(add_portrait) - %ImportPortraitsButton.icon = get_theme_icon("Folder", "EditorIcons") - %ImportPortraitsButton.pressed.connect(open_portrait_folder_select) - %PortraitSearch.right_icon = get_theme_icon("Search", "EditorIcons") - %PortraitSearch.text_changed.connect(filter_portrait_list) + setup_portrait_list_tab() - %PortraitTree.item_selected.connect(load_selected_portrait) - %PortraitTree.item_edited.connect(_on_item_edited) + setup_portrait_settings_tab() %PreviewMode.item_selected.connect(_on_PreviewMode_item_selected) %PreviewMode.select(DialogicUtil.get_project_setting('dialogic/editor/character_preview_mode', 0)) @@ -158,13 +173,29 @@ func add_main_tab(scene_path:String) -> void: func something_changed(fake_argument = "", fake_arg2 = null) -> void: if not loading: current_resource_state = ResourceStates.Unsaved -# _save_resource() TODO, should this happen? + editors_manager.save_current_resource() #TODO, should this happen? ############################################################################## ## PORTRAIT SECTION ############################################################################## +func setup_portrait_list_tab() -> void: + %PortraitTree.editor = self + + ## Portrait section styling/connections + %AddPortraitButton.icon = get_theme_icon("Add", "EditorIcons") + %AddPortraitButton.pressed.connect(add_portrait) + %AddPortraitGroupButton.icon = get_theme_icon("Groups", "EditorIcons") + %AddPortraitGroupButton.pressed.connect(add_portrait_group) + %ImportPortraitsButton.icon = get_theme_icon("Folder", "EditorIcons") + %ImportPortraitsButton.pressed.connect(open_portrait_folder_select) + %PortraitSearch.right_icon = get_theme_icon("Search", "EditorIcons") + %PortraitSearch.text_changed.connect(filter_portrait_list) + + %PortraitTree.item_selected.connect(load_selected_portrait) + %PortraitTree.item_edited.connect(_on_item_edited) + func open_portrait_folder_select() -> void: find_parent("EditorView").godot_file_dialog( import_portraits_from_folder, "*", @@ -172,6 +203,10 @@ func open_portrait_folder_select() -> void: func import_portraits_from_folder(path:String) -> void: + var parent: TreeItem = %PortraitTree.get_root() + if %PortraitTree.get_selected() and %PortraitTree.get_selected().get_metadata(0).has('group'): + parent = %PortraitTree.get_selected() + var dir := DirAccess.open(path) dir.list_dir_begin() var file_name :String = dir.get_next() @@ -181,57 +216,82 @@ func import_portraits_from_folder(path:String) -> void: if '.svg' in file_lower or '.png' in file_lower: if not '.import' in file_lower: var final_name: String= path+ "/" + file_name - add_portrait(file_name.trim_suffix('.'+file_name.get_extension()), - {'scene':"",'image':final_name, 'scale':1, 'offset':Vector2(), 'mirror':false}) + %PortraitTree.add_portrait_item(file_name.trim_suffix('.'+file_name.get_extension()), + {'scene':"",'image':final_name, 'scale':1, 'offset':Vector2(), 'mirror':false}, parent) file_name = dir.get_next() + something_changed() func add_portrait(portrait_name:String='New portrait', portrait_data:Dictionary={'scene':"", 'image':'', 'scale':1, 'offset':Vector2(), 'mirror':false}) -> void: - var root: TreeItem = %PortraitTree.get_root() - add_portrait_item(portrait_name, portrait_data, root).select(0) + var parent: TreeItem = %PortraitTree.get_root() + if %PortraitTree.get_selected(): + if %PortraitTree.get_selected().get_metadata(0).has('group'): + parent = %PortraitTree.get_selected() + else: + parent = %PortraitTree.get_selected().get_parent() + %PortraitTree.add_portrait_item(portrait_name, portrait_data, parent).select(0) something_changed() +func add_portrait_group() -> void: + var parent_item :TreeItem = %PortraitTree.get_root() + if %PortraitTree.get_selected() and %PortraitTree.get_selected().get_metadata(0).has('group'): + parent_item = %PortraitTree.get_selected() + %PortraitTree.add_portrait_group("Group", parent_item) + + func load_portrait_tree() -> void: - %PortraitTree.clear() + %PortraitTree.clear_tree() var root:TreeItem = %PortraitTree.create_item() for portrait in current_resource.portraits.keys(): - add_portrait_item(portrait, current_resource.portraits[portrait], root) + var portrait_label = portrait + var parent = %PortraitTree.get_root() + if '/' in portrait: + parent = %PortraitTree.create_necessary_group_items(portrait) + portrait_label = portrait.split('/')[-1] + + %PortraitTree.add_portrait_item(portrait_label, current_resource.portraits[portrait], parent) + + update_default_portrait_star(current_resource.default_portrait) if root.get_child_count(): root.get_first_child().select(0) - + else: + # Call anyways to clear preview and hide portrait settings section + load_selected_portrait() func filter_portrait_list(filter_term:String = '') -> void: - var item : TreeItem = %PortraitTree.get_root().get_first_child() - while true: - item.visible = filter_term.is_empty() or filter_term.to_lower() in item.get_text(0).to_lower() - item = item.get_next() - if !item: - break + filter_branch(%PortraitTree.get_root(), filter_term) + + +func filter_branch(parent:TreeItem, filter_term:String) -> bool: + var anything_visible := false + for item in parent.get_children(): + if item.get_metadata(0).has('group'): + item.visible = filter_branch(item, filter_term) + anything_visible = item.visible + elif filter_term.is_empty() or filter_term.to_lower() in item.get_text(0).to_lower(): + item.visible = true + anything_visible = true + else: + item.visible = false + return anything_visible # this is used to save the portrait data func get_updated_portrait_dict() -> Dictionary: - var dict : Dictionary = {} - var item : TreeItem = %PortraitTree.get_root().get_first_child() - while item: - dict[item.get_text(0)] = item.get_metadata(0) - item = item.get_next() - return dict + return list_portraits(%PortraitTree.get_root().get_children()) -func add_portrait_item(portrait_name:String, portrait_data:Dictionary, parent_item:TreeItem) -> TreeItem: - var item :TreeItem = %PortraitTree.create_item(parent_item) - item.set_text(0, portrait_name) - item.set_metadata(0, portrait_data) - if portrait_name == current_resource.default_portrait: - item.add_button(0, get_theme_icon('Favorites', 'EditorIcons'), 2, true, 'Default') - item.add_button(0, get_theme_icon('Duplicate', 'EditorIcons'), 3, false, 'Duplicate') - item.add_button(0, get_theme_icon('Remove', 'EditorIcons'), 1, false, 'Remove') - return item +func list_portraits(tree_items:Array[TreeItem], dict:Dictionary = {}, path_prefix = "") -> Dictionary: + for item in tree_items: + if item.get_metadata(0).has('group'): + dict = list_portraits(item.get_children(), dict, path_prefix+item.get_text(0)+"/") + else: + dict[path_prefix +item.get_text(0)] = item.get_metadata(0) + return dict func load_selected_portrait(): @@ -240,10 +300,11 @@ func load_selected_portrait(): selected_item = %PortraitTree.get_selected() - if selected_item: - + + if selected_item and !selected_item.get_metadata(0).has('group'): + %PortraitSettingsSection.show() var current_portrait_data :Dictionary = selected_item.get_metadata(0) - portrait_selected.emit(selected_item.get_text(0), current_portrait_data) + portrait_selected.emit(%PortraitTree.get_full_item_name(selected_item), current_portrait_data) update_preview() @@ -254,6 +315,20 @@ func load_selected_portrait(): tab.selected_item = selected_item tab._load_portrait_data(current_portrait_data) + # switch tabs if the current one is hidden (until the next not hidden tab) + for i in range(%PortraitSettingsSection.get_tab_count()): + if %PortraitSettingsSection.is_tab_hidden(%PortraitSettingsSection.current_tab): + if %PortraitSettingsSection.current_tab == %PortraitSettingsSection.get_tab_count()-1: + %PortraitSettingsSection.current_tab = 0 + else: + %PortraitSettingsSection.current_tab += 1 + else: + break + else: + %PortraitSettingsSection.hide() + update_preview() + + if selected_item: await get_tree().create_timer(0.01).timeout selected_item.set_editable(0, true) @@ -264,7 +339,7 @@ func delete_portrait_item(item:TreeItem) -> void: func duplicate_item(item:TreeItem) -> void: - add_portrait_item(item.get_text(0)+'_duplicated', item.get_metadata(0), item.get_parent()).select(0) + %PortraitTree.add_portrait_item(item.get_text(0)+'_duplicated', item.get_metadata(0), item.get_parent()).select(0) func _on_portrait_tree_button_clicked(item:TreeItem, column:int, id:int, mouse_button_index:int): @@ -276,35 +351,120 @@ func _on_portrait_tree_button_clicked(item:TreeItem, column:int, id:int, mouse_b duplicate_item(item) +# this removes/and adds the DEFAULT star on the portrait list +func update_default_portrait_star(default_portrait_name:String) -> void: + var item_list : Array = %PortraitTree.get_root().get_children() + while true: + var item = item_list.pop_back() + if item.get_button_by_id(0, 2) != -1: + item.erase_button(0, item.get_button_by_id(0, 2)) + if %PortraitTree.get_full_item_name(item) == default_portrait_name: + item.erase_button(0, item.get_button_by_id(0, 1)) + item.erase_button(0, item.get_button_by_id(0, 3)) + item.add_button(0, get_theme_icon('Favorites', 'EditorIcons'), 2, true, 'Default') + item.add_button(0, get_theme_icon('Duplicate', 'EditorIcons'), 3, false, 'Duplicate') + item.add_button(0, get_theme_icon('Remove', 'EditorIcons'), 1, false, 'Remove') + item_list.append_array(item.get_children()) + + if item_list.is_empty(): + break + + +func _on_item_edited(): + selected_item = %PortraitTree.get_selected() + something_changed() + if selected_item: + if %PreviewLabel.text.trim_prefix('Preview of "').trim_suffix('"') == current_resource.default_portrait: + current_resource.default_portrait = %PortraitTree.get_full_item_name(selected_item) + update_preview() + + + +############################################################################## +## PORTRAIT SETTINGS TAB +############################################################################## + +func setup_portrait_settings_tab() -> void: + %DefaultPortraitPicker.value_changed.connect(default_portrait_changed) + %MainScale.value_changed.connect(main_portrait_settings_update) + %MainOffsetX.value_changed.connect(main_portrait_settings_update) + %MainOffsetY.value_changed.connect(main_portrait_settings_update) + %MainMirror.toggled.connect(main_portrait_settings_update) + + # Setting up Default Portrait Picker + %DefaultPortraitPicker.resource_icon = load("res://addons/dialogic/Editor/Images/Resources/portrait.svg") + %DefaultPortraitPicker.get_suggestions_func = suggest_portraits + %DefaultPortraitPicker.set_left_text("") + + +# Make sure preview get's updated when portrait settings change +func main_portrait_settings_update(value = null) -> void: + current_resource.scale = %MainScale.value/100.0 + current_resource.offset = Vector2(%MainOffsetX.value, %MainOffsetY.value) + current_resource.mirror = %MainMirror.button_pressed + update_preview() + something_changed() + + +func default_portrait_changed(property:String, value:String) -> void: + current_resource.default_portrait = value + update_default_portrait_star(value) + + +# Get suggestions for DefaultPortraitPicker +func suggest_portraits(search:String) -> Dictionary: + var suggestions := {} + for portrait in get_updated_portrait_dict().keys(): + suggestions[portrait] = {'value':portrait} + return suggestions + + +############################################################################## +## PREVIEW +############################################################################## + func update_preview() -> void: - for node in %RealPreviewPivot.get_children(): - node.queue_free() %ScenePreviewWarning.hide() - if selected_item and is_instance_valid(selected_item): - %PreviewLabel.text = 'Preview of "'+selected_item.get_text(0)+'"' + if selected_item and is_instance_valid(selected_item) and !selected_item.get_metadata(0).has('group'): + %PreviewLabel.text = 'Preview of "'+%PortraitTree.get_full_item_name(selected_item)+'"' var current_portrait_data: Dictionary = selected_item.get_metadata(0) var mirror:bool = current_portrait_data.get('mirror', false) != current_resource.mirror var scale:float = current_portrait_data.get('scale', 1) * current_resource.scale var offset:Vector2 =current_portrait_data.get('offset', Vector2()) + current_resource.offset - var scene = null - if current_portrait_data.get('scene', '').is_empty(): - scene = load("res://addons/dialogic/Events/Character/default_portrait.tscn") + if current_previewed_scene != null \ + and current_previewed_scene.get_meta('path', null) == current_portrait_data.get('scene') \ + and current_previewed_scene.has_method('_should_do_portrait_update') \ + and is_instance_valid(current_previewed_scene.get_script()) \ + and current_previewed_scene._should_do_portrait_update(current_resource, selected_item.get_text(0)): + pass # we keep the same scene else: - scene = load(current_portrait_data.get('scene')) - - if scene: - scene = scene.instantiate() + for node in %RealPreviewPivot.get_children(): + node.queue_free() + current_previewed_scene = null + if current_portrait_data.get('scene', '').is_empty(): + if FileAccess.file_exists("res://addons/dialogic/Events/Character/default_portrait.tscn"): + current_previewed_scene = load("res://addons/dialogic/Events/Character/default_portrait.tscn").instantiate() + current_previewed_scene.set_meta('path', '') + else: + if FileAccess.file_exists(current_portrait_data.get('scene')): + current_previewed_scene = load(current_portrait_data.get('scene')).instantiate() + current_previewed_scene.set_meta('path', current_portrait_data.get('scene')) + if current_previewed_scene: + %RealPreviewPivot.add_child(current_previewed_scene) + + if current_previewed_scene != null: + var scene = current_previewed_scene scene.show_behind_parent = true - %RealPreviewPivot.add_child(scene) + for prop in current_portrait_data.get('export_overrides', {}).keys(): + scene.set(prop, str_to_var(current_portrait_data['export_overrides'][prop])) if is_instance_valid(scene.get_script()) and scene.script.is_tool(): if scene.has_method('_update_portrait'): - scene._update_portrait(current_resource, selected_item.get_text(0)) + scene._update_portrait(current_resource, %PortraitTree.get_full_item_name(selected_item)) if scene.has_method('_set_mirror'): scene._set_mirror(mirror) - if current_preview_mode == PreviewModes.Real: scene.position = Vector2() + offset @@ -324,32 +484,12 @@ func update_preview() -> void: %PreviewRealRect.texture = null %PreviewFullRect.texture = null %PreviewLabel.text = 'Nothing to preview' - - -# this removes/and adds the DEFAULT star on the portrait list -func update_default_portrait_star(default_portrait_name:String) -> void: - var item : TreeItem = %PortraitTree.get_root().get_first_child() - while true: - if item.get_button_by_id(0, 2) != -1: - item.erase_button(0, item.get_button_by_id(0, 2)) - if item.get_text(0) == default_portrait_name: - item.erase_button(0, item.get_button_by_id(0, 1)) - item.erase_button(0, item.get_button_by_id(0, 3)) - item.add_button(0, get_theme_icon('Favorites', 'EditorIcons'), 2, true, 'Default') - item.add_button(0, get_theme_icon('Duplicate', 'EditorIcons'), 3, false, 'Duplicate') - item.add_button(0, get_theme_icon('Remove', 'EditorIcons'), 1, false, 'Remove') - item = item.get_next() - if !item: - break - - -func _on_item_edited(): - selected_item = %PortraitTree.get_selected() - something_changed() - if selected_item: - if %PreviewLabel.text.trim_prefix('Preview of "').trim_suffix('"') == current_resource.default_portrait: - current_resource.default_portrait = selected_item.get_text(0) - update_preview() + + else: + %PreviewLabel.text = 'No portrait to preview.' + for node in %RealPreviewPivot.get_children(): + node.queue_free() + current_previewed_scene = null func _on_PreviewMode_item_selected(index:int) -> void: @@ -365,11 +505,7 @@ func _on_PreviewMode_item_selected(index:int) -> void: ProjectSettings.save() -func main_portrait_settings_update(value = null) -> void: - update_preview() - something_changed() - - func _on_full_preview_available_rect_resized(): if current_preview_mode == PreviewModes.Full: update_preview() + diff --git a/addons/dialogic/Editor/CharacterEditor/character_editor.tscn b/addons/dialogic/Editor/CharacterEditor/character_editor.tscn index 702a2d7fe..489e5bf36 100644 --- a/addons/dialogic/Editor/CharacterEditor/character_editor.tscn +++ b/addons/dialogic/Editor/CharacterEditor/character_editor.tscn @@ -1,12 +1,15 @@ -[gd_scene load_steps=11 format=3 uid="uid://dxt0c6mx24nxo"] +[gd_scene load_steps=15 format=3 uid="uid://dlskc36c5hrwv"] [ext_resource type="Script" path="res://addons/dialogic/Editor/CharacterEditor/character_editor.gd" id="2"] +[ext_resource type="PackedScene" uid="uid://dpwhshre1n4t6" path="res://addons/dialogic/Editor/Events/Fields/ComplexPicker.tscn" id="2_01va3"] [ext_resource type="Script" path="res://addons/dialogic/Editor/CharacterEditor/character_editor_ptab_image.gd" id="2_cusvj"] +[ext_resource type="Script" path="res://addons/dialogic/Editor/CharacterEditor/character_editor_portrait_tree.gd" id="2_vad0i"] [ext_resource type="Script" path="res://addons/dialogic/Editor/CharacterEditor/character_editor_ptab_scene.gd" id="4_6tltp"] [ext_resource type="PackedScene" uid="uid://7mvxuaulctcq" path="res://addons/dialogic/Editor/Events/Fields/FilePicker.tscn" id="4_a4bcu"] [ext_resource type="Script" path="res://addons/dialogic/Editor/CharacterEditor/character_editor_ptab_layout.gd" id="5_eicvp"] +[ext_resource type="Script" path="res://addons/dialogic/Editor/CharacterEditor/character_editor_ptab_exports.gd" id="7_4enie"] -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_cf78c"] +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_kxihh"] content_margin_left = 10.0 content_margin_top = 4.0 content_margin_right = 10.0 @@ -16,7 +19,7 @@ border_width_top = 2 border_color = Color(1, 1, 1, 0.75) corner_detail = 1 -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_l8t00"] +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_1pdx5"] content_margin_left = 7.5 content_margin_top = 7.5 content_margin_right = 7.5 @@ -27,7 +30,7 @@ corner_radius_top_right = 3 corner_radius_bottom_right = 3 corner_radius_bottom_left = 3 -[sub_resource type="Image" id="Image_fyuk7"] +[sub_resource type="Image" id="Image_8q5e2"] data = { "data": PackedByteArray(255, 255, 255, 0, 255, 255, 255, 0, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 131, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 131, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 131, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 231, 255, 93, 93, 55, 255, 97, 97, 58, 255, 93, 93, 233, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 231, 255, 94, 94, 54, 255, 94, 94, 57, 255, 93, 93, 233, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 93, 93, 233, 255, 93, 93, 232, 255, 93, 93, 41, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 93, 93, 233, 255, 93, 93, 232, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 97, 97, 42, 255, 255, 255, 0, 255, 97, 97, 42, 255, 97, 97, 42, 255, 255, 255, 0, 255, 98, 98, 47, 255, 97, 97, 42, 255, 255, 255, 0, 255, 97, 97, 42, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 235, 255, 93, 93, 233, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 94, 94, 46, 255, 93, 93, 236, 255, 93, 93, 233, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 235, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 233, 255, 95, 95, 59, 255, 96, 96, 61, 255, 93, 93, 235, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 233, 255, 95, 95, 59, 255, 96, 96, 61, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0), "format": "RGBA8", @@ -36,13 +39,25 @@ data = { "width": 16 } -[sub_resource type="ImageTexture" id="ImageTexture_asiy6"] -image = SubResource("Image_fyuk7") +[sub_resource type="ImageTexture" id="ImageTexture_uf4x7"] +image = SubResource("Image_8q5e2") [sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_4xgdx"] +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_81xk6"] +content_margin_left = 4.0 +content_margin_top = 4.0 +content_margin_right = 4.0 +content_margin_bottom = 4.0 +bg_color = Color(1, 0.365, 0.365, 1) +draw_center = false +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +corner_detail = 1 + [node name="CharacterEditor" type="MarginContainer"] -visible = false self_modulate = Color(0, 0, 0, 1) anchors_preset = 15 anchor_right = 1.0 @@ -57,24 +72,16 @@ script = ExtResource("2") [node name="Split" type="HSplitContainer" parent="."] layout_mode = 2 -offset_right = 1152.0 -offset_bottom = 648.0 size_flags_horizontal = 3 size_flags_vertical = 3 [node name="Editor" type="VSplitContainer" parent="Split"] layout_mode = 2 -offset_right = 454.0 -offset_bottom = 648.0 -grow_horizontal = 2 -grow_vertical = 2 size_flags_horizontal = 3 size_flags_vertical = 11 [node name="EditorScroll" type="ScrollContainer" parent="Split/Editor"] layout_mode = 2 -offset_right = 454.0 -offset_bottom = 54.0 size_flags_horizontal = 3 size_flags_stretch_ratio = 0.0 vertical_scroll_mode = 0 @@ -82,93 +89,138 @@ vertical_scroll_mode = 0 [node name="MainEditTabs" type="TabContainer" parent="Split/Editor/EditorScroll"] unique_name_in_owner = true layout_mode = 2 -offset_right = 454.0 -offset_bottom = 54.0 size_flags_horizontal = 3 size_flags_vertical = 3 theme_override_constants/side_margin = 5 -theme_override_styles/tab_selected = SubResource("StyleBoxFlat_cf78c") -theme_override_styles/panel = SubResource("StyleBoxFlat_l8t00") +theme_override_styles/tab_selected = SubResource("StyleBoxFlat_kxihh") +theme_override_styles/panel = SubResource("StyleBoxFlat_1pdx5") [node name="PortraitListSection" type="TabContainer" parent="Split/Editor"] unique_name_in_owner = true layout_mode = 2 -offset_top = 66.0 -offset_right = 454.0 -offset_bottom = 648.0 theme_override_constants/side_margin = 5 -theme_override_styles/tab_selected = SubResource("StyleBoxFlat_cf78c") -theme_override_styles/panel = SubResource("StyleBoxFlat_l8t00") +theme_override_styles/tab_selected = SubResource("StyleBoxFlat_kxihh") +theme_override_styles/panel = SubResource("StyleBoxFlat_1pdx5") [node name="Portraits" type="VBoxContainer" parent="Split/Editor/PortraitListSection"] layout_mode = 2 -anchors_preset = 15 -anchor_right = 1.0 -anchor_bottom = 1.0 -offset_left = 7.5 -offset_top = 38.5 -offset_right = -7.5 -offset_bottom = -7.5 -grow_horizontal = 2 -grow_vertical = 2 [node name="PortraitListTools" type="HBoxContainer" parent="Split/Editor/PortraitListSection/Portraits"] layout_mode = 2 -offset_right = 439.0 -offset_bottom = 31.0 [node name="AddPortraitButton" type="Button" parent="Split/Editor/PortraitListSection/Portraits/PortraitListTools"] unique_name_in_owner = true layout_mode = 2 -offset_right = 24.0 -offset_bottom = 31.0 -icon = SubResource("ImageTexture_asiy6") +tooltip_text = "Add portrait" +icon = SubResource("ImageTexture_uf4x7") + +[node name="AddPortraitGroupButton" type="Button" parent="Split/Editor/PortraitListSection/Portraits/PortraitListTools"] +unique_name_in_owner = true +layout_mode = 2 +tooltip_text = "Add Group" +icon = SubResource("ImageTexture_uf4x7") [node name="ImportPortraitsButton" type="Button" parent="Split/Editor/PortraitListSection/Portraits/PortraitListTools"] unique_name_in_owner = true layout_mode = 2 -offset_left = 28.0 -offset_right = 52.0 -offset_bottom = 31.0 -icon = SubResource("ImageTexture_asiy6") +tooltip_text = "Import images from folder" +icon = SubResource("ImageTexture_uf4x7") [node name="PortraitSearch" type="LineEdit" parent="Split/Editor/PortraitListSection/Portraits/PortraitListTools"] unique_name_in_owner = true layout_mode = 2 -offset_left = 56.0 -offset_right = 439.0 -offset_bottom = 31.0 size_flags_horizontal = 3 size_flags_vertical = 4 placeholder_text = "Search" expand_to_text_length = true clear_button_enabled = true -right_icon = SubResource("ImageTexture_asiy6") +right_icon = SubResource("ImageTexture_uf4x7") caret_blink = true caret_blink_interval = 0.5 [node name="Panel" type="PanelContainer" parent="Split/Editor/PortraitListSection/Portraits"] layout_mode = 2 -offset_top = 35.0 -offset_right = 439.0 -offset_bottom = 314.0 size_flags_vertical = 3 theme_override_styles/panel = SubResource("StyleBoxEmpty_4xgdx") [node name="PortraitTree" type="Tree" parent="Split/Editor/PortraitListSection/Portraits/Panel"] unique_name_in_owner = true layout_mode = 2 -offset_right = 439.0 -offset_bottom = 279.0 allow_rmb_select = true -hide_folding = true hide_root = true +drop_mode_flags = 1 +script = ExtResource("2_vad0i") + +[node name="P Settings" type="VBoxContainer" parent="Split/Editor/PortraitListSection"] +visible = false +layout_mode = 2 + +[node name="DefaultPortrait" type="HBoxContainer" parent="Split/Editor/PortraitListSection/P Settings"] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="Label5" type="Label" parent="Split/Editor/PortraitListSection/P Settings/DefaultPortrait"] +layout_mode = 2 +text = "Default:" + +[node name="DefaultPortraitPicker" parent="Split/Editor/PortraitListSection/P Settings/DefaultPortrait" instance=ExtResource("2_01va3")] +unique_name_in_owner = true +layout_mode = 2 +size_flags_horizontal = 3 +placeholder_text = "Select Portrait" + +[node name="HSeparator" type="HSeparator" parent="Split/Editor/PortraitListSection/P Settings"] +layout_mode = 2 + +[node name="PortraitMainSettings" type="HFlowContainer" parent="Split/Editor/PortraitListSection/P Settings"] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="Label" type="Label" parent="Split/Editor/PortraitListSection/P Settings/PortraitMainSettings"] +layout_mode = 2 +text = "Scale" + +[node name="MainScale" type="SpinBox" parent="Split/Editor/PortraitListSection/P Settings/PortraitMainSettings"] +unique_name_in_owner = true +layout_mode = 2 +value = 100.0 +allow_greater = true +suffix = "%" + +[node name="Offset" type="HBoxContainer" parent="Split/Editor/PortraitListSection/P Settings/PortraitMainSettings"] +layout_mode = 2 + +[node name="Label2" type="Label" parent="Split/Editor/PortraitListSection/P Settings/PortraitMainSettings/Offset"] +layout_mode = 2 +text = "Offset" + +[node name="MainOffsetX" type="SpinBox" parent="Split/Editor/PortraitListSection/P Settings/PortraitMainSettings/Offset"] +unique_name_in_owner = true +layout_mode = 2 +allow_greater = true +allow_lesser = true +suffix = "X" + +[node name="MainOffsetY" type="SpinBox" parent="Split/Editor/PortraitListSection/P Settings/PortraitMainSettings/Offset"] +unique_name_in_owner = true +layout_mode = 2 +allow_greater = true +allow_lesser = true +suffix = "Y" + +[node name="MirrorOption" type="HBoxContainer" parent="Split/Editor/PortraitListSection/P Settings/PortraitMainSettings"] +layout_mode = 2 + +[node name="Label" type="Label" parent="Split/Editor/PortraitListSection/P Settings/PortraitMainSettings/MirrorOption"] +layout_mode = 2 +text = "Mirror" + +[node name="MainMirror" type="CheckBox" parent="Split/Editor/PortraitListSection/P Settings/PortraitMainSettings/MirrorOption"] +unique_name_in_owner = true +layout_mode = 2 [node name="RightSection" type="VSplitContainer" parent="Split"] layout_mode = 2 -offset_left = 466.0 -offset_right = 1152.0 -offset_bottom = 648.0 size_flags_horizontal = 3 size_flags_vertical = 3 size_flags_stretch_ratio = 1.5 @@ -177,19 +229,17 @@ size_flags_stretch_ratio = 1.5 unique_name_in_owner = true clip_contents = true layout_mode = 2 -offset_right = 686.0 -offset_bottom = 492.0 size_flags_horizontal = 3 size_flags_vertical = 3 -theme_override_styles/panel = SubResource("StyleBoxFlat_l8t00") +theme_override_styles/panel = SubResource("StyleBoxFlat_1pdx5") [node name="Node2D" type="Node2D" parent="Split/RightSection/PortraitPreviewSection"] position = Vector2(13, 17) [node name="RealPreviewPivot" type="Sprite2D" parent="Split/RightSection/PortraitPreviewSection/Node2D"] unique_name_in_owner = true -position = Vector2(289, 362) -texture = SubResource("ImageTexture_asiy6") +position = Vector2(330, 405) +texture = SubResource("ImageTexture_uf4x7") [node name="ScenePreviewWarning" type="Label" parent="Split/RightSection/PortraitPreviewSection"] unique_name_in_owner = true @@ -229,11 +279,6 @@ metadata/_edit_layout_mode = 1 [node name="Control" type="Control" parent="Split/RightSection/PortraitPreviewSection/PreviewReal"] layout_mode = 2 -anchors_preset = 0 -offset_left = 302.0 -offset_top = 69.0 -offset_right = 302.0 -offset_bottom = 69.0 [node name="RealSizeRemotePivotTransform" type="RemoteTransform2D" parent="Split/RightSection/PortraitPreviewSection/PreviewReal/Control"] unique_name_in_owner = true @@ -261,7 +306,7 @@ unique_name_in_owner = true layout_mode = 0 offset_right = 40.0 offset_bottom = 23.0 -text = "Preview" +text = "No portrait to preview." [node name="PreviewMode" type="OptionButton" parent="Split/RightSection/PortraitPreviewSection"] unique_name_in_owner = true @@ -291,188 +336,115 @@ offset_bottom = -12.0 [node name="PortraitSettingsSection" type="TabContainer" parent="Split/RightSection"] unique_name_in_owner = true layout_mode = 2 -offset_top = 504.0 -offset_right = 686.0 -offset_bottom = 648.0 size_flags_vertical = 3 size_flags_stretch_ratio = 0.3 theme_override_constants/side_margin = 5 -theme_override_styles/tab_selected = SubResource("StyleBoxFlat_cf78c") -theme_override_styles/panel = SubResource("StyleBoxFlat_l8t00") +theme_override_styles/tab_selected = SubResource("StyleBoxFlat_kxihh") +theme_override_styles/panel = SubResource("StyleBoxFlat_1pdx5") [node name="Image" type="ScrollContainer" parent="Split/RightSection/PortraitSettingsSection"] custom_minimum_size = Vector2(0, 35) layout_mode = 2 -anchors_preset = 15 -anchor_right = 1.0 -anchor_bottom = 1.0 -offset_left = 7.5 -offset_top = 38.5 -offset_right = -7.5 -offset_bottom = -7.5 -grow_horizontal = 2 -grow_vertical = 2 horizontal_scroll_mode = 0 script = ExtResource("2_cusvj") [node name="Flow" type="HFlowContainer" parent="Split/RightSection/PortraitSettingsSection/Image"] layout_mode = 2 -offset_right = 671.0 -offset_bottom = 98.0 size_flags_horizontal = 3 size_flags_vertical = 3 [node name="GridContainer" type="GridContainer" parent="Split/RightSection/PortraitSettingsSection/Image/Flow"] layout_mode = 2 -offset_right = 671.0 -offset_bottom = 38.0 size_flags_horizontal = 3 size_flags_vertical = 3 columns = 2 [node name="Label" type="Label" parent="Split/RightSection/PortraitSettingsSection/Image/Flow/GridContainer"] layout_mode = 2 -offset_top = 6.0 -offset_right = 57.0 -offset_bottom = 32.0 text = "Image: " [node name="ImagePicker" parent="Split/RightSection/PortraitSettingsSection/Image/Flow/GridContainer" instance=ExtResource("4_a4bcu")] unique_name_in_owner = true layout_mode = 2 -offset_left = 61.0 -offset_right = 671.0 -offset_bottom = 38.0 size_flags_horizontal = 3 file_filter = "*.png, *.svg" -resource_icon = SubResource("ImageTexture_asiy6") +resource_icon = SubResource("ImageTexture_uf4x7") [node name="Scene" type="ScrollContainer" parent="Split/RightSection/PortraitSettingsSection"] visible = false custom_minimum_size = Vector2(0, 35) layout_mode = 2 -anchors_preset = 15 -anchor_right = 1.0 -anchor_bottom = 1.0 -offset_left = 10.0 -offset_top = 41.0 -offset_right = -10.0 -offset_bottom = -10.0 -grow_horizontal = 2 -grow_vertical = 2 horizontal_scroll_mode = 0 script = ExtResource("4_6tltp") [node name="Flow" type="HFlowContainer" parent="Split/RightSection/PortraitSettingsSection/Scene"] unique_name_in_owner = true layout_mode = 2 -offset_right = 666.0 -offset_bottom = 93.0 size_flags_horizontal = 3 size_flags_vertical = 3 [node name="GridContainer" type="GridContainer" parent="Split/RightSection/PortraitSettingsSection/Scene/Flow"] layout_mode = 2 -offset_right = 584.0 -offset_bottom = 63.0 size_flags_horizontal = 3 size_flags_vertical = 3 columns = 2 [node name="Label" type="Label" parent="Split/RightSection/PortraitSettingsSection/Scene/Flow/GridContainer"] layout_mode = 2 -offset_top = 3.0 -offset_right = 102.0 -offset_bottom = 29.0 text = "Scene: " [node name="ScenePicker" parent="Split/RightSection/PortraitSettingsSection/Scene/Flow/GridContainer" instance=ExtResource("4_a4bcu")] unique_name_in_owner = true layout_mode = 2 -offset_left = 106.0 -offset_right = 584.0 -offset_bottom = 33.0 size_flags_horizontal = 3 file_filter = "*.tscn" placeholder = "Default scene" -resource_icon = SubResource("ImageTexture_asiy6") +resource_icon = SubResource("ImageTexture_uf4x7") [node name="Label2" type="Label" parent="Split/RightSection/PortraitSettingsSection/Scene/Flow/GridContainer"] layout_mode = 2 -offset_top = 37.0 -offset_right = 102.0 -offset_bottom = 63.0 text = "Ignore scale: " [node name="IgnoreScale" type="CheckBox" parent="Split/RightSection/PortraitSettingsSection/Scene/Flow/GridContainer"] unique_name_in_owner = true layout_mode = 2 -offset_left = 106.0 -offset_top = 37.0 -offset_right = 584.0 -offset_bottom = 63.0 [node name="Layout" type="ScrollContainer" parent="Split/RightSection/PortraitSettingsSection"] visible = false custom_minimum_size = Vector2(0, 35) layout_mode = 2 -anchors_preset = 15 -anchor_right = 1.0 -anchor_bottom = 1.0 -offset_top = 31.0 -grow_horizontal = 2 -grow_vertical = 2 horizontal_scroll_mode = 0 script = ExtResource("5_eicvp") [node name="Flow" type="HFlowContainer" parent="Split/RightSection/PortraitSettingsSection/Layout"] layout_mode = 2 -offset_right = 686.0 -offset_bottom = 113.0 size_flags_horizontal = 3 size_flags_vertical = 3 [node name="HBoxContainer" type="HBoxContainer" parent="Split/RightSection/PortraitSettingsSection/Layout/Flow"] layout_mode = 2 -offset_right = 150.0 -offset_bottom = 33.0 [node name="Label" type="Label" parent="Split/RightSection/PortraitSettingsSection/Layout/Flow/HBoxContainer"] layout_mode = 2 -offset_top = 3.0 -offset_right = 40.0 -offset_bottom = 29.0 text = "Scale:" [node name="PortraitScale" type="SpinBox" parent="Split/RightSection/PortraitSettingsSection/Layout/Flow/HBoxContainer"] unique_name_in_owner = true layout_mode = 2 -offset_left = 44.0 -offset_right = 150.0 -offset_bottom = 33.0 value = 100.0 allow_greater = true suffix = "%" [node name="HBoxContainer2" type="HBoxContainer" parent="Split/RightSection/PortraitSettingsSection/Layout/Flow"] layout_mode = 2 -offset_top = 37.0 -offset_right = 268.0 -offset_bottom = 70.0 [node name="Label2" type="Label" parent="Split/RightSection/PortraitSettingsSection/Layout/Flow/HBoxContainer2"] layout_mode = 2 -offset_top = 3.0 -offset_right = 48.0 -offset_bottom = 29.0 text = "Offset:" [node name="PortraitOffsetX" type="SpinBox" parent="Split/RightSection/PortraitSettingsSection/Layout/Flow/HBoxContainer2"] unique_name_in_owner = true layout_mode = 2 -offset_left = 52.0 -offset_right = 158.0 -offset_bottom = 33.0 allow_greater = true allow_lesser = true suffix = "X" @@ -480,33 +452,35 @@ suffix = "X" [node name="PortraitOffsetY" type="SpinBox" parent="Split/RightSection/PortraitSettingsSection/Layout/Flow/HBoxContainer2"] unique_name_in_owner = true layout_mode = 2 -offset_left = 162.0 -offset_right = 268.0 -offset_bottom = 33.0 allow_greater = true allow_lesser = true suffix = "Y" [node name="MirrorOption" type="HBoxContainer" parent="Split/RightSection/PortraitSettingsSection/Layout/Flow"] layout_mode = 2 -offset_left = 272.0 -offset_top = 37.0 -offset_right = 350.0 -offset_bottom = 70.0 [node name="Label" type="Label" parent="Split/RightSection/PortraitSettingsSection/Layout/Flow/MirrorOption"] layout_mode = 2 -offset_top = 3.0 -offset_right = 50.0 -offset_bottom = 29.0 text = "Mirror:" [node name="PortraitMirror" type="CheckBox" parent="Split/RightSection/PortraitSettingsSection/Layout/Flow/MirrorOption"] unique_name_in_owner = true layout_mode = 2 -offset_left = 54.0 -offset_right = 78.0 -offset_bottom = 33.0 + +[node name="Exports" type="ScrollContainer" parent="Split/RightSection/PortraitSettingsSection"] +visible = false +custom_minimum_size = Vector2(0, 35) +layout_mode = 2 +theme_override_styles/panel = SubResource("StyleBoxFlat_81xk6") +horizontal_scroll_mode = 0 +script = ExtResource("7_4enie") + +[node name="Grid" type="GridContainer" parent="Split/RightSection/PortraitSettingsSection/Exports"] +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 3 +theme_override_constants/h_separation = 10 +columns = 2 [connection signal="button_clicked" from="Split/Editor/PortraitListSection/Portraits/Panel/PortraitTree" to="." method="_on_portrait_tree_button_clicked"] [connection signal="resized" from="Split/RightSection/PortraitPreviewSection/FullPreviewAvailableRect" to="." method="_on_full_preview_available_rect_resized"] diff --git a/addons/dialogic/Editor/CharacterEditor/character_editor_portrait_settings_tab.gd b/addons/dialogic/Editor/CharacterEditor/character_editor_portrait_settings_tab.gd index 4874e8da5..5570a62dd 100644 --- a/addons/dialogic/Editor/CharacterEditor/character_editor_portrait_settings_tab.gd +++ b/addons/dialogic/Editor/CharacterEditor/character_editor_portrait_settings_tab.gd @@ -12,5 +12,5 @@ var character_editor:Control var selected_item :TreeItem = null -func _load_portrait(data:Dictionary) -> void: +func _load_portrait_data(data:Dictionary) -> void: pass diff --git a/addons/dialogic/Editor/CharacterEditor/character_editor_portrait_tree.gd b/addons/dialogic/Editor/CharacterEditor/character_editor_portrait_tree.gd new file mode 100644 index 000000000..37cc5ec7e --- /dev/null +++ b/addons/dialogic/Editor/CharacterEditor/character_editor_portrait_tree.gd @@ -0,0 +1,115 @@ +@tool +extends Tree + +## Tree that displays the portrait list as a hirarchy + +var editor := find_parent('Character Editor') +var current_group_nodes := {} + + +func clear_tree() -> void: + clear() + current_group_nodes = {} + + +func add_portrait_item(portrait_name:String, portrait_data:Dictionary, parent_item:TreeItem) -> TreeItem: + var item :TreeItem = %PortraitTree.create_item(parent_item) + item.set_text(0, portrait_name) + item.set_metadata(0, portrait_data) + if portrait_name == editor.current_resource.default_portrait: + item.add_button(0, get_theme_icon('Favorites', 'EditorIcons'), 2, true, 'Default') + item.add_button(0, get_theme_icon('Duplicate', 'EditorIcons'), 3, false, 'Duplicate') + item.add_button(0, get_theme_icon('Remove', 'EditorIcons'), 1, false, 'Remove') + return item + + +func add_portrait_group(goup_name:String = "Group", parent_item:TreeItem = get_root()): + var item :TreeItem = %PortraitTree.create_item(parent_item) + item.set_icon(0, get_theme_icon("Groups", "EditorIcons")) + item.set_text(0, goup_name) + item.set_metadata(0, {'group':true}) + item.add_button(0, get_theme_icon('Remove', 'EditorIcons'), 1, false, 'Remove') + return item + + +func get_full_item_name(item:TreeItem) -> String: + var item_name := item.get_text(0) + while item.get_parent() != get_root() and item != get_root(): + item_name = item.get_parent().get_text(0)+"/"+item_name + item = item.get_parent() + return item_name + + +# Will create all not yet existing folders in the given path. +# Returns the last folder (the parent of the portrait item of this path). +func create_necessary_group_items(path:String) -> void: + var last_item := get_root() + var item_path := "" + + for i in Array(path.split('/')).slice(0, -1): + item_path += "/"+i + item_path = item_path.trim_prefix('/') + if current_group_nodes.has(item_path+"/"+i): + last_item = current_group_nodes[item_path+"/"+i] + else: + var new_item := add_portrait_group(i, last_item) + current_group_nodes[item_path+"/"+i] = new_item + last_item = new_item + return last_item + + +################################################################################ +## DRAG AND DROP +################################################################################ + +func _get_drag_data(position:Vector2) -> Variant: + set_drop_mode_flags(DROP_MODE_ON_ITEM) + + var preview := Label.new() + preview.text = " "+get_selected().get_text(0) + preview.add_theme_stylebox_override('normal', get_theme_stylebox("Background", "EditorStyles")) + set_drag_preview(preview) + + return get_selected() + + +func _can_drop_data(position:Vector2, data:Variant) -> bool: + return data is TreeItem + + +func _drop_data(position:Vector2, item:Variant) -> void: + var to_item := get_item_at_position(position) + if to_item: + var test_item:= to_item + while true: + if test_item == item: + return + test_item = test_item.get_parent() + if test_item == get_root(): + break + + var parent := get_root() + if to_item: + parent = to_item.get_parent() + + if to_item and to_item.get_metadata(0).has('group'): + parent = to_item + + var new_item := copy_branch_or_item(item, parent) + + if to_item and !to_item.get_metadata(0).has('group'): + new_item.move_after(to_item) + + item.free() + + +func copy_branch_or_item(item:TreeItem, new_parent:TreeItem) -> TreeItem: + var new_item :TreeItem = null + if item.get_metadata(0).has('group'): + new_item = add_portrait_group(item.get_text(0), new_parent) + else: + new_item = add_portrait_item(item.get_text(0), item.get_metadata(0), new_parent) + + for child in item.get_children(): + copy_branch_or_item(child, new_item) + return new_item diff --git a/addons/dialogic/Editor/CharacterEditor/character_editor_ptab_exports.gd b/addons/dialogic/Editor/CharacterEditor/character_editor_ptab_exports.gd new file mode 100644 index 000000000..883aaf3f4 --- /dev/null +++ b/addons/dialogic/Editor/CharacterEditor/character_editor_ptab_exports.gd @@ -0,0 +1,102 @@ +@tool +extends DialogicCharacterEditorPortraitSettingsTab + +## Tab that allows setting values of exported scene variables +## for custom portrait scenes + +var current_portrait_data := {} + +func _ready() -> void: + get_parent().set_tab_icon(get_index(), get_theme_icon("EditInternal", "EditorIcons")) + add_theme_stylebox_override('panel', get_theme_stylebox("Background", "EditorStyles")) + +func _load_portrait_data(data:Dictionary) -> void: + if data.get('scene', '').is_empty(): + get_parent().set_tab_hidden(get_index(), true) + else: + get_parent().set_tab_hidden(get_index(), false) + + current_portrait_data = data + load_portrait_scene_export_variables() + +func load_portrait_scene_export_variables(): + var scene = null + if !current_portrait_data.get('scene', '').is_empty(): + scene = load(current_portrait_data.get('scene')) + + if !scene: + return + + for child in $Grid.get_children(): + child.queue_free() + + scene = scene.instantiate() + for i in scene.script.get_script_property_list(): + if i['usage'] & PROPERTY_USAGE_EDITOR: + var label = Label.new() + label.text = i['name'] + label.add_theme_stylebox_override('normal', get_theme_stylebox("CanvasItemInfoOverlay", "EditorStyles")) + label.size_flags_horizontal = SIZE_EXPAND_FILL + $Grid.add_child(label) + + + var input = null + var current_value :String = "" + if current_portrait_data.has('export_overrides') and current_portrait_data['export_overrides'].has(i['name']): + current_value = current_portrait_data['export_overrides'][i['name']] + match typeof(scene.get(i['name'])): + TYPE_BOOL: + input = CheckBox.new() + if current_value: + input.button_pressed = current_value == "true" + input.toggled.connect(_on_export_bool_submitted.bind(i['name'])) + TYPE_COLOR: + input = ColorPickerButton.new() + if current_value: + input.color = str_to_var(current_value) + input.color_changed.connect(_on_export_color_submitted.bind(i['name'])) + input.custom_minimum_size.x = DialogicUtil.get_editor_scale()*50 + TYPE_INT: + if i['hint'] & PROPERTY_HINT_ENUM: + input = OptionButton.new() + for x in i['hint_string'].split(','): + input.add_item(x) + input.item_selected.connect(_on_export_int_enum_submitted.bind(i['name'])) + _: + input = LineEdit.new() + if current_value: + input.text = current_value + input.text_submitted.connect(_on_export_input_text_submitted.bind(i['name'])) + input.size_flags_horizontal = SIZE_EXPAND_FILL + $Grid.add_child(input) + if i['usage'] & PROPERTY_USAGE_GROUP: + var title := Label.new() + title.text = i['name'] + title.add_theme_stylebox_override('normal', get_theme_stylebox("ContextualToolbar", "EditorStyles")) + $Grid.add_child(title) + $Grid.add_child(Control.new()) + +func set_export_override(property_name:String, value:String = "") -> void: + var data:Dictionary = selected_item.get_metadata(0) + if !data.has('export_overrides'): + data['export_overrides'] = {} + + if !value.is_empty(): + data['export_overrides'][property_name] = value + else: + data['export_overrides'].erase(property_name) + + changed.emit() + update_preview.emit() + +func _on_export_input_text_submitted(text:String, property_name:String) -> void: + set_export_override(property_name, var_to_str(text)) + +func _on_export_bool_submitted(value:bool, property_name:String) -> void: + set_export_override(property_name, var_to_str(value)) + +func _on_export_color_submitted(color:Color, property_name:String) -> void: + set_export_override(property_name, var_to_str(color)) + +func _on_export_int_enum_submitted(item:int, property_name:String) -> void: + set_export_override(property_name, var_to_str(item)) diff --git a/addons/dialogic/Editor/CharacterEditor/character_editor_ptab_image.gd b/addons/dialogic/Editor/CharacterEditor/character_editor_ptab_image.gd index b3d8cde8d..bec8e40a3 100644 --- a/addons/dialogic/Editor/CharacterEditor/character_editor_ptab_image.gd +++ b/addons/dialogic/Editor/CharacterEditor/character_editor_ptab_image.gd @@ -13,12 +13,7 @@ func _ready() -> void: func _load_portrait_data(data:Dictionary) -> void: # hides/shows this tab based on the scene value of this portrait # (only shown if the default scene is used) - if !data.get('scene', '').is_empty(): - get_parent().set_tab_hidden(get_index(), true) - while get_parent().is_tab_hidden(get_parent().current_tab): - get_parent().current_tab = (get_parent().current_tab+1)%get_parent().get_tab_count() - else: - get_parent().set_tab_hidden(get_index(), false) + get_parent().set_tab_hidden(get_index(), !data.get('scene', '').is_empty()) %ImagePicker.set_value(data.get('image', '')) diff --git a/addons/dialogic/Editor/CharacterEditor/character_editor_tab_general.gd b/addons/dialogic/Editor/CharacterEditor/character_editor_tab_general.gd index 36f56855b..4aa3fec9c 100644 --- a/addons/dialogic/Editor/CharacterEditor/character_editor_tab_general.gd +++ b/addons/dialogic/Editor/CharacterEditor/character_editor_tab_general.gd @@ -10,16 +10,6 @@ func _ready() -> void: %DisplayNameLineEdit.text_changed.connect(character_editor.something_changed) %NicknameLineEdit.text_changed.connect(character_editor.something_changed) %DescriptionTextEdit.text_changed.connect(character_editor.something_changed) - %DefaultPortraitPicker.value_changed.connect(default_portrait_changed) - %MainScale.value_changed.connect(main_portrait_settings_update) - %MainOffsetX.value_changed.connect(main_portrait_settings_update) - %MainOffsetY.value_changed.connect(main_portrait_settings_update) - %MainMirror.toggled.connect(main_portrait_settings_update) - - # Setting up Default Portrait Picker - %DefaultPortraitPicker.resource_icon = load("res://addons/dialogic/Editor/Images/Resources/portrait.svg") - %DefaultPortraitPicker.get_suggestions_func = suggest_portraits - %DefaultPortraitPicker.set_left_text("") func _load_character(resource:DialogicCharacter) -> void: @@ -32,12 +22,6 @@ func _load_character(resource:DialogicCharacter) -> void: %NicknameLineEdit.text = %NicknameLineEdit.text.trim_suffix(', ') %DescriptionTextEdit.text = resource.description - %DefaultPortraitPicker.set_value(resource.default_portrait) - - %MainScale.value = 100*resource.scale - %MainOffsetX.value = resource.offset.x - %MainOffsetY.value = resource.offset.y - %MainMirror.button_pressed = resource.mirror func _save_changes(resource:DialogicCharacter) -> DialogicCharacter: @@ -49,37 +33,4 @@ func _save_changes(resource:DialogicCharacter) -> DialogicCharacter: resource.nicknames = nicknames resource.description = %DescriptionTextEdit.text - if $'%DefaultPortraitPicker'.current_value in resource.portraits.keys(): - resource.default_portrait = $'%DefaultPortraitPicker'.current_value - elif !resource.portraits.is_empty(): - resource.default_portrait = resource.portraits.keys()[0] - else: - resource.default_portrait = "" - - resource.scale = %MainScale.value/100.0 - resource.offset = Vector2(%MainOffsetX.value, %MainOffsetY.value) - resource.mirror = %MainMirror.button_pressed - return resource - - -# Get suggestions for DefaultPortraitPicker -func suggest_portraits(search:String) -> Dictionary: - var suggestions := {} - for portrait in character_editor.get_updated_portrait_dict().keys(): - suggestions[portrait] = {'value':portrait} - return suggestions - - -# Make sure preview get's updated when portrait settings change -func main_portrait_settings_update(value = null) -> void: - character_editor.current_resource.scale = %MainScale.value/100.0 - character_editor.current_resource.offset = Vector2(%MainOffsetX.value, %MainOffsetY.value) - character_editor.current_resource.mirror = %MainMirror.button_pressed - character_editor.update_preview() - character_editor.something_changed() - -func default_portrait_changed(property:String, value:String) -> void: - character_editor.current_resource.default_portrait = value - character_editor.update_default_portrait_star(value) - diff --git a/addons/dialogic/Editor/CharacterEditor/character_editor_tab_general.tscn b/addons/dialogic/Editor/CharacterEditor/character_editor_tab_general.tscn index 98cea1dd7..326e06187 100644 --- a/addons/dialogic/Editor/CharacterEditor/character_editor_tab_general.tscn +++ b/addons/dialogic/Editor/CharacterEditor/character_editor_tab_general.tscn @@ -1,6 +1,5 @@ -[gd_scene load_steps=3 format=3 uid="uid://de5kj4vd0we1w"] +[gd_scene load_steps=2 format=3 uid="uid://de5kj4vd0we1w"] -[ext_resource type="PackedScene" uid="uid://dpwhshre1n4t6" path="res://addons/dialogic/Editor/Events/Fields/ComplexPicker.tscn" id="1_3b04d"] [ext_resource type="Script" path="res://addons/dialogic/Editor/CharacterEditor/character_editor_tab_general.gd" id="1_3e1i1"] [node name="General" type="GridContainer"] @@ -20,27 +19,16 @@ script = ExtResource("1_3e1i1") [node name="Label2" type="Label" parent="."] layout_mode = 2 -offset_right = 131.0 -offset_bottom = 26.0 -size_flags_vertical = 0 text = "Display Name: " [node name="DisplayName" type="HBoxContainer" parent="."] layout_mode = 2 -offset_left = 132.0 -offset_right = 1137.0 -offset_bottom = 31.0 size_flags_horizontal = 3 -[node name="CheckBox" type="CheckBox" parent="DisplayName"] -visible = false -layout_mode = 2 - [node name="DisplayNameLineEdit" type="LineEdit" parent="DisplayName"] unique_name_in_owner = true layout_mode = 2 -offset_right = 67.0 -offset_bottom = 31.0 +tooltip_text = "This name will be displayed on the name label. You can use a dialogic variable. E.g. :{Player.name}" expand_to_text_length = true caret_blink = true caret_blink_interval = 0.5 @@ -49,173 +37,31 @@ caret_blink_interval = 0.5 unique_name_in_owner = true custom_minimum_size = Vector2(30, 0) layout_mode = 2 -offset_left = 71.0 -offset_right = 101.0 -offset_bottom = 31.0 +tooltip_text = "This color can be used on the name label and for occurences of the characters name in text (autocolor names)." color = Color(1, 1, 1, 1) edit_alpha = false [node name="Label3" type="Label" parent="."] layout_mode = 2 -offset_top = 37.0 -offset_right = 131.0 -offset_bottom = 63.0 -size_flags_vertical = 0 text = "Nicknames:" -[node name="DisplayNickname" type="HBoxContainer" parent="."] -layout_mode = 2 -offset_left = 132.0 -offset_top = 37.0 -offset_right = 1137.0 -offset_bottom = 68.0 -size_flags_horizontal = 3 - -[node name="NicknameLineEdit" type="LineEdit" parent="DisplayNickname"] +[node name="NicknameLineEdit" type="LineEdit" parent="."] unique_name_in_owner = true layout_mode = 2 -offset_right = 1005.0 -offset_bottom = 31.0 size_flags_horizontal = 3 +tooltip_text = "If autocolor names is enabled, these will be colored in the characters color as well." caret_blink = true caret_blink_interval = 0.5 [node name="Label4" type="Label" parent="."] layout_mode = 2 -offset_top = 74.0 -offset_right = 131.0 -offset_bottom = 100.0 size_flags_vertical = 0 text = "Description:" -[node name="Description" type="HBoxContainer" parent="."] -layout_mode = 2 -offset_left = 132.0 -offset_top = 74.0 -offset_right = 1137.0 -offset_bottom = 109.0 -size_flags_horizontal = 3 - -[node name="DescriptionTextEdit" type="TextEdit" parent="Description"] +[node name="DescriptionTextEdit" type="TextEdit" parent="."] unique_name_in_owner = true layout_mode = 2 -offset_right = 1005.0 -offset_bottom = 35.0 size_flags_horizontal = 3 +tooltip_text = "No effect, just for you." wrap_mode = 1 scroll_fit_content_height = true - -[node name="Label5" type="Label" parent="."] -layout_mode = 2 -offset_top = 115.0 -offset_right = 131.0 -offset_bottom = 141.0 -size_flags_vertical = 0 -text = "Default Portrait:" - -[node name="DefaultPortrait" type="HBoxContainer" parent="."] -layout_mode = 2 -offset_left = 132.0 -offset_top = 115.0 -offset_right = 1137.0 -offset_bottom = 150.0 -size_flags_horizontal = 3 - -[node name="DefaultPortraitPicker" parent="DefaultPortrait" instance=ExtResource("1_3b04d")] -unique_name_in_owner = true -layout_mode = 2 -anchors_preset = 0 -anchor_right = 0.0 -anchor_bottom = 0.0 -offset_left = 0.0 -offset_top = 0.0 -offset_right = 180.0 -offset_bottom = 35.0 -grow_horizontal = 1 -grow_vertical = 1 - -[node name="Label6" type="Label" parent="."] -layout_mode = 2 -offset_top = 156.0 -offset_right = 131.0 -offset_bottom = 182.0 -size_flags_vertical = 0 -text = "Portrait Settings:" - -[node name="PortraitMainSettings" type="HFlowContainer" parent="."] -layout_mode = 2 -offset_left = 132.0 -offset_top = 156.0 -offset_right = 1137.0 -offset_bottom = 187.0 -size_flags_horizontal = 3 - -[node name="Label" type="Label" parent="PortraitMainSettings"] -layout_mode = 2 -offset_top = 2.0 -offset_right = 40.0 -offset_bottom = 28.0 -text = "Scale" - -[node name="MainScale" type="SpinBox" parent="PortraitMainSettings"] -unique_name_in_owner = true -layout_mode = 2 -offset_left = 44.0 -offset_right = 127.0 -offset_bottom = 31.0 -value = 100.0 -allow_greater = true -suffix = "%" - -[node name="Offset" type="HBoxContainer" parent="PortraitMainSettings"] -layout_mode = 2 -offset_left = 131.0 -offset_right = 353.0 -offset_bottom = 31.0 - -[node name="Label2" type="Label" parent="PortraitMainSettings/Offset"] -layout_mode = 2 -offset_top = 2.0 -offset_right = 48.0 -offset_bottom = 28.0 -text = "Offset" - -[node name="MainOffsetX" type="SpinBox" parent="PortraitMainSettings/Offset"] -unique_name_in_owner = true -layout_mode = 2 -offset_left = 52.0 -offset_right = 135.0 -offset_bottom = 31.0 -allow_greater = true -allow_lesser = true -suffix = "X" - -[node name="MainOffsetY" type="SpinBox" parent="PortraitMainSettings/Offset"] -unique_name_in_owner = true -layout_mode = 2 -offset_left = 139.0 -offset_right = 222.0 -offset_bottom = 31.0 -allow_greater = true -allow_lesser = true -suffix = "Y" - -[node name="MirrorOption" type="HBoxContainer" parent="PortraitMainSettings"] -layout_mode = 2 -offset_left = 357.0 -offset_right = 435.0 -offset_bottom = 31.0 - -[node name="Label" type="Label" parent="PortraitMainSettings/MirrorOption"] -layout_mode = 2 -offset_top = 2.0 -offset_right = 50.0 -offset_bottom = 28.0 -text = "Mirror" - -[node name="MainMirror" type="CheckBox" parent="PortraitMainSettings/MirrorOption"] -unique_name_in_owner = true -layout_mode = 2 -offset_left = 54.0 -offset_right = 78.0 -offset_bottom = 31.0 diff --git a/addons/dialogic/Events/Character/default_portrait.gd b/addons/dialogic/Events/Character/default_portrait.gd index e14d17856..bd18289fb 100644 --- a/addons/dialogic/Events/Character/default_portrait.gd +++ b/addons/dialogic/Events/Character/default_portrait.gd @@ -22,7 +22,7 @@ func _should_do_portrait_update(character:DialogicCharacter, portrait:String) -> ## If the custom portrait accepts a change, then accept it here func _update_portrait(passed_character:DialogicCharacter, passed_portrait:String) -> void: - if passed_portrait == "": + if passed_portrait == "" or not passed_portrait in passed_character.portraits.keys(): passed_portrait = passed_character['default_portrait'] portrait = passed_portrait if passed_character != null: @@ -43,4 +43,6 @@ func _set_mirror(mirror:bool) -> void: ## If implemented, this is used by the editor for the "full view" mode func _get_covered_rect() -> Rect2: + if $Portrait.texture == null: + return Rect2() return Rect2($Portrait.position, $Portrait.get_rect().size) diff --git a/addons/dialogic/Events/Character/default_portrait.tscn b/addons/dialogic/Events/Character/default_portrait.tscn index 9f0e0edb0..073d111ec 100644 --- a/addons/dialogic/Events/Character/default_portrait.tscn +++ b/addons/dialogic/Events/Character/default_portrait.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=3 format=3] +[gd_scene load_steps=3 format=3 uid="uid://c4yp65n7ju1br"] [ext_resource type="Script" path="res://addons/dialogic/Events/Character/default_portrait.gd" id="1_wn77n"] diff --git a/addons/dialogic/Events/Character/subsystem_portraits.gd b/addons/dialogic/Events/Character/subsystem_portraits.gd index c20392b46..a102d7576 100644 --- a/addons/dialogic/Events/Character/subsystem_portraits.gd +++ b/addons/dialogic/Events/Character/subsystem_portraits.gd @@ -130,6 +130,10 @@ func change_portrait(character:DialogicCharacter, portrait:String, mirrored:bool portrait_node.scale = Vector2(1,1)*character.scale * character.portraits[portrait].get('scale', 1) else: portrait_node.scale = Vector2(1,1)*character.portraits[portrait].get('scale', 1) + + for property in character.portraits[portrait].get('export_overrides', {}).keys(): + portrait_node.set(property, str_to_var(character.portraits[portrait]['export_overrides'][property])) + if portrait_node.has_method('_update_portrait'): portrait_node._update_portrait(character, portrait) if portrait_node.has_method('_set_mirror'): diff --git a/addons/dialogic/Events/Text/character_settings/ui_mood_item.tscn b/addons/dialogic/Events/Text/character_settings/ui_mood_item.tscn index 38bb0e2e1..f7a715c2f 100644 --- a/addons/dialogic/Events/Text/character_settings/ui_mood_item.tscn +++ b/addons/dialogic/Events/Text/character_settings/ui_mood_item.tscn @@ -1,14 +1,14 @@ -[gd_scene load_steps=6 format=3] +[gd_scene load_steps=6 format=3 uid="uid://x8alx74fnm10"] [ext_resource type="Script" path="res://addons/dialogic/Events/Text/character_settings/ui_mood_item.gd" id="2"] [ext_resource type="Script" path="res://addons/dialogic/Events/Text/node_type_sound.gd" id="3"] -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_h1p4u"] +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_rsmy0"] content_margin_left = 4.0 content_margin_top = 4.0 content_margin_right = 4.0 content_margin_bottom = 4.0 -bg_color = Color(0.147, 0.168, 0.203, 1) +bg_color = Color(1, 0.365, 0.365, 1) draw_center = false border_width_left = 2 border_width_top = 2 @@ -16,7 +16,7 @@ border_width_right = 2 border_width_bottom = 2 corner_detail = 1 -[sub_resource type="Image" id="Image_7wswg"] +[sub_resource type="Image" id="Image_uegt4"] data = { "data": PackedByteArray(255, 255, 255, 0, 255, 255, 255, 0, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 131, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 131, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 131, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 231, 255, 93, 93, 55, 255, 97, 97, 58, 255, 93, 93, 233, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 231, 255, 94, 94, 54, 255, 94, 94, 57, 255, 93, 93, 233, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 93, 93, 233, 255, 93, 93, 232, 255, 93, 93, 41, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 93, 93, 233, 255, 93, 93, 232, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 97, 97, 42, 255, 255, 255, 0, 255, 97, 97, 42, 255, 97, 97, 42, 255, 255, 255, 0, 255, 98, 98, 47, 255, 97, 97, 42, 255, 255, 255, 0, 255, 97, 97, 42, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 235, 255, 93, 93, 233, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 94, 94, 46, 255, 93, 93, 236, 255, 93, 93, 233, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 235, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 233, 255, 95, 95, 59, 255, 96, 96, 61, 255, 93, 93, 235, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 233, 255, 95, 95, 59, 255, 96, 96, 61, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0), "format": "RGBA8", @@ -25,163 +25,123 @@ data = { "width": 16 } -[sub_resource type="ImageTexture" id="ImageTexture_o5mle"] -image = SubResource("Image_7wswg") +[sub_resource type="ImageTexture" id="ImageTexture_osvex"] +image = SubResource("Image_uegt4") [node name="MoodItem" type="PanelContainer"] size_flags_horizontal = 3 -theme_override_styles/panel = SubResource("StyleBoxFlat_h1p4u") +theme_override_styles/panel = SubResource("StyleBoxFlat_rsmy0") script = ExtResource("2") [node name="VBox" type="VBoxContainer" parent="."] -offset_left = 4.0 -offset_top = 4.0 -offset_right = 241.0 -offset_bottom = 135.0 +layout_mode = 2 [node name="General" type="HBoxContainer" parent="VBox"] -offset_right = 237.0 -offset_bottom = 31.0 +layout_mode = 2 [node name="Name" type="LineEdit" parent="VBox/General"] unique_name_in_owner = true -offset_right = 125.0 -offset_bottom = 31.0 +layout_mode = 2 size_flags_horizontal = 3 -hint_tooltip = "Mood name" +tooltip_text = "Mood name" caret_blink = true -caret_blink_speed = 0.5 [node name="Play" type="Button" parent="VBox/General"] unique_name_in_owner = true -offset_left = 129.0 -offset_right = 153.0 -offset_bottom = 31.0 -hint_tooltip = "Preview" -icon = SubResource("ImageTexture_o5mle") +layout_mode = 2 +tooltip_text = "Preview" +icon = SubResource("ImageTexture_osvex") [node name="Duplicate" type="Button" parent="VBox/General"] unique_name_in_owner = true -offset_left = 157.0 -offset_right = 181.0 -offset_bottom = 31.0 -hint_tooltip = "Duplicate" -icon = SubResource("ImageTexture_o5mle") +layout_mode = 2 +tooltip_text = "Duplicate" +icon = SubResource("ImageTexture_osvex") [node name="Delete" type="Button" parent="VBox/General"] unique_name_in_owner = true -offset_left = 185.0 -offset_right = 209.0 -offset_bottom = 31.0 -hint_tooltip = "Delete" -icon = SubResource("ImageTexture_o5mle") +layout_mode = 2 +tooltip_text = "Delete" +icon = SubResource("ImageTexture_osvex") [node name="Fold" type="Button" parent="VBox/General"] unique_name_in_owner = true -offset_left = 213.0 -offset_right = 237.0 -offset_bottom = 31.0 -hint_tooltip = "Fold/Unfold" +layout_mode = 2 +tooltip_text = "Fold/Unfold" toggle_mode = true button_pressed = true -icon = SubResource("ImageTexture_o5mle") +icon = SubResource("ImageTexture_osvex") [node name="Content" type="HBoxContainer" parent="VBox"] unique_name_in_owner = true -offset_top = 35.0 -offset_right = 237.0 -offset_bottom = 131.0 +visible = false +layout_mode = 2 [node name="Control" type="Control" parent="VBox/Content"] -offset_bottom = 96.0 +layout_mode = 2 [node name="Content" type="VBoxContainer" parent="VBox/Content"] -offset_left = 4.0 -offset_right = 237.0 -offset_bottom = 96.0 +layout_mode = 2 size_flags_horizontal = 3 [node name="SoundFolderSect" type="HBoxContainer" parent="VBox/Content/Content"] -offset_right = 233.0 -offset_bottom = 26.0 +layout_mode = 2 [node name="Label" type="Label" parent="VBox/Content/Content/SoundFolderSect"] -offset_right = 107.0 -offset_bottom = 26.0 +layout_mode = 2 size_flags_horizontal = 3 text = "Sounds folder" [node name="SoundFolder" type="Label" parent="VBox/Content/Content/SoundFolderSect"] unique_name_in_owner = true -offset_left = 111.0 -offset_top = 1.0 -offset_right = 205.0 -offset_bottom = 24.0 +layout_mode = 2 size_flags_horizontal = 3 horizontal_alignment = 2 [node name="ChangeSoundFolderButton" type="Button" parent="VBox/Content/Content/SoundFolderSect"] unique_name_in_owner = true -offset_left = 209.0 -offset_right = 233.0 -offset_bottom = 26.0 -hint_tooltip = "Change sounds folder" -icon = SubResource("ImageTexture_o5mle") +layout_mode = 2 +tooltip_text = "Change sounds folder" +icon = SubResource("ImageTexture_osvex") [node name="Pitch" type="HBoxContainer" parent="VBox/Content/Content"] -offset_top = 30.0 -offset_right = 233.0 -offset_bottom = 61.0 +layout_mode = 2 [node name="Label2" type="Label" parent="VBox/Content/Content/Pitch"] -offset_top = 2.0 -offset_right = 59.0 -offset_bottom = 28.0 +layout_mode = 2 size_flags_horizontal = 3 text = "Pitch" [node name="PitchBase" type="SpinBox" parent="VBox/Content/Content/Pitch"] unique_name_in_owner = true -offset_left = 63.0 -offset_right = 146.0 -offset_bottom = 31.0 +layout_mode = 2 step = 0.001 value = 1.0 [node name="PitchVariance" type="SpinBox" parent="VBox/Content/Content/Pitch"] unique_name_in_owner = true -offset_left = 150.0 -offset_right = 233.0 -offset_bottom = 31.0 +layout_mode = 2 step = 0.001 prefix = "+/-" [node name="Volume" type="HBoxContainer" parent="VBox/Content/Content"] -offset_top = 65.0 -offset_right = 233.0 -offset_bottom = 96.0 +layout_mode = 2 [node name="Label3" type="Label" parent="VBox/Content/Content/Volume"] -offset_top = 2.0 -offset_right = 59.0 -offset_bottom = 28.0 +layout_mode = 2 size_flags_horizontal = 3 text = "Volume" [node name="VolumeBase" type="SpinBox" parent="VBox/Content/Content/Volume"] unique_name_in_owner = true -offset_left = 63.0 -offset_right = 146.0 -offset_bottom = 31.0 +layout_mode = 2 min_value = -80.0 step = 0.001 suffix = "db" [node name="VolumeVariance" type="SpinBox" parent="VBox/Content/Content/Volume"] unique_name_in_owner = true -offset_left = 150.0 -offset_right = 233.0 -offset_bottom = 31.0 +layout_mode = 2 step = 0.001 prefix = "+/-" diff --git a/addons/dialogic/Events/Text/node_type_sound.gd b/addons/dialogic/Events/Text/node_type_sound.gd index 89b6a57b3..19a629a0b 100644 --- a/addons/dialogic/Events/Text/node_type_sound.gd +++ b/addons/dialogic/Events/Text/node_type_sound.gd @@ -76,7 +76,7 @@ func _on_continued_revealing_text(new_character) -> void: stream = current_overwrite_data.get('sounds', sounds)[RNG.randi_range(0, sounds.size() - 1)] #choose a random pitch and volume - pitch_scale = current_overwrite_data.get('pitch_base', base_pitch) + current_overwrite_data.get('pitch_variance', pitch_variance) * RNG.randf_range(-1.0, 1.0) + pitch_scale = max(0, current_overwrite_data.get('pitch_base', base_pitch) + current_overwrite_data.get('pitch_variance', pitch_variance) * RNG.randf_range(-1.0, 1.0)) volume_db = current_overwrite_data.get('volume_base', base_volume) + current_overwrite_data.get('volume_variance',volume_variance) * RNG.randf_range(-1.0, 1.0) #play the sound diff --git a/addons/dialogic/plugin.gd b/addons/dialogic/plugin.gd index 6d5bccc1a..ae61b378d 100644 --- a/addons/dialogic/plugin.gd +++ b/addons/dialogic/plugin.gd @@ -14,8 +14,8 @@ const MainPanel := preload("res://addons/dialogic/Editor/editor_main.tscn") var editor_view: Control # multiple editor compononents/helper classes -var _parts_inspector : EditorInspectorPlugin -var _export_plugin : EditorExportPlugin +#var _parts_inspector : EditorInspectorPlugin # TODO remove +#var _export_plugin : EditorExportPlugin # TODO remove var editor_interface : EditorInterface # emitted if godot wants us to save @@ -56,8 +56,8 @@ func _exit_tree() -> void: if editor_view: remove_control_from_bottom_panel(editor_view) editor_view.queue_free() - remove_inspector_plugin(_parts_inspector) - remove_export_plugin(_export_plugin) +# remove_inspector_plugin(_parts_inspector) +# remove_export_plugin(_export_plugin) func _has_main_screen() -> bool: