diff --git a/addons/Todo_Manager/doc/images/Instruct1.png.import b/addons/Todo_Manager/doc/images/Instruct1.png.import index 98608c1a..ba6557dd 100644 --- a/addons/Todo_Manager/doc/images/Instruct1.png.import +++ b/addons/Todo_Manager/doc/images/Instruct1.png.import @@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/Instruct1.png-698c6faa3ef3ac4960807faa3e028bd compress/mode=0 compress/high_quality=false compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 compress/hdr_compression=1 compress/normal_map=0 compress/channel_pack=0 @@ -25,6 +27,10 @@ mipmaps/generate=false mipmaps/limit=-1 roughness/mode=0 roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 process/fix_alpha_border=true process/premult_alpha=false process/normal_map_invert_y=false diff --git a/addons/Todo_Manager/doc/images/Instruct2.png.import b/addons/Todo_Manager/doc/images/Instruct2.png.import index 18b26207..01b8f923 100644 --- a/addons/Todo_Manager/doc/images/Instruct2.png.import +++ b/addons/Todo_Manager/doc/images/Instruct2.png.import @@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/Instruct2.png-4e8664e49d00a397bbd539f7dee976f compress/mode=0 compress/high_quality=false compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 compress/hdr_compression=1 compress/normal_map=0 compress/channel_pack=0 @@ -25,6 +27,10 @@ mipmaps/generate=false mipmaps/limit=-1 roughness/mode=0 roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 process/fix_alpha_border=true process/premult_alpha=false process/normal_map_invert_y=false diff --git a/addons/Todo_Manager/doc/images/Instruct3.png.import b/addons/Todo_Manager/doc/images/Instruct3.png.import index e1ee1989..354d866e 100644 --- a/addons/Todo_Manager/doc/images/Instruct3.png.import +++ b/addons/Todo_Manager/doc/images/Instruct3.png.import @@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/Instruct3.png-3cc62ed99bf29d90b803cb8eb40881e compress/mode=0 compress/high_quality=false compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 compress/hdr_compression=1 compress/normal_map=0 compress/channel_pack=0 @@ -25,6 +27,10 @@ mipmaps/generate=false mipmaps/limit=-1 roughness/mode=0 roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 process/fix_alpha_border=true process/premult_alpha=false process/normal_map_invert_y=false diff --git a/addons/Todo_Manager/doc/images/Instruct4.png.import b/addons/Todo_Manager/doc/images/Instruct4.png.import index 309098ca..2270274b 100644 --- a/addons/Todo_Manager/doc/images/Instruct4.png.import +++ b/addons/Todo_Manager/doc/images/Instruct4.png.import @@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/Instruct4.png-bf5aa1cffc066175cecf9281b077480 compress/mode=0 compress/high_quality=false compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 compress/hdr_compression=1 compress/normal_map=0 compress/channel_pack=0 @@ -25,6 +27,10 @@ mipmaps/generate=false mipmaps/limit=-1 roughness/mode=0 roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 process/fix_alpha_border=true process/premult_alpha=false process/normal_map_invert_y=false diff --git a/addons/Todo_Manager/doc/images/Instruct5.png.import b/addons/Todo_Manager/doc/images/Instruct5.png.import index 99b31909..beaa777f 100644 --- a/addons/Todo_Manager/doc/images/Instruct5.png.import +++ b/addons/Todo_Manager/doc/images/Instruct5.png.import @@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/Instruct5.png-001538ed8b5682dcf232de08035aab3 compress/mode=0 compress/high_quality=false compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 compress/hdr_compression=1 compress/normal_map=0 compress/channel_pack=0 @@ -25,6 +27,10 @@ mipmaps/generate=false mipmaps/limit=-1 roughness/mode=0 roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 process/fix_alpha_border=true process/premult_alpha=false process/normal_map_invert_y=false diff --git a/addons/Todo_Manager/doc/images/TODO_Manager_Logo.png.import b/addons/Todo_Manager/doc/images/TODO_Manager_Logo.png.import index 75d1a2da..9da3bd92 100644 --- a/addons/Todo_Manager/doc/images/TODO_Manager_Logo.png.import +++ b/addons/Todo_Manager/doc/images/TODO_Manager_Logo.png.import @@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/TODO_Manager_Logo.png-e07d7ec75201c66b732ef87 compress/mode=0 compress/high_quality=false compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 compress/hdr_compression=1 compress/normal_map=0 compress/channel_pack=0 @@ -25,6 +27,10 @@ mipmaps/generate=false mipmaps/limit=-1 roughness/mode=0 roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 process/fix_alpha_border=true process/premult_alpha=false process/normal_map_invert_y=false diff --git a/addons/Todo_Manager/doc/images/example1.png.import b/addons/Todo_Manager/doc/images/example1.png.import index a88dd0c9..c792ce01 100644 --- a/addons/Todo_Manager/doc/images/example1.png.import +++ b/addons/Todo_Manager/doc/images/example1.png.import @@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/example1.png-6386c332ca46e1e62ea061b956a901cd compress/mode=0 compress/high_quality=false compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 compress/hdr_compression=1 compress/normal_map=0 compress/channel_pack=0 @@ -25,6 +27,10 @@ mipmaps/generate=false mipmaps/limit=-1 roughness/mode=0 roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 process/fix_alpha_border=true process/premult_alpha=false process/normal_map_invert_y=false diff --git a/addons/Todo_Manager/doc/images/example2.png.import b/addons/Todo_Manager/doc/images/example2.png.import index bb9a7bc1..05753d63 100644 --- a/addons/Todo_Manager/doc/images/example2.png.import +++ b/addons/Todo_Manager/doc/images/example2.png.import @@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/example2.png-2e3a8f9cd1e178daf22b83dc0513f37a compress/mode=0 compress/high_quality=false compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 compress/hdr_compression=1 compress/normal_map=0 compress/channel_pack=0 @@ -25,6 +27,10 @@ mipmaps/generate=false mipmaps/limit=-1 roughness/mode=0 roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 process/fix_alpha_border=true process/premult_alpha=false process/normal_map_invert_y=false diff --git a/addons/beautify_code_on_save/plugin.cfg b/addons/beautify_code_on_save/plugin.cfg new file mode 100644 index 00000000..ac305754 --- /dev/null +++ b/addons/beautify_code_on_save/plugin.cfg @@ -0,0 +1,7 @@ +[plugin] + +name="Beautify Code on Save" +description="Automatically formats and lints GDScript files on save using gdformat and gdlint." +author="nuevocharrua" +version="1.1.1" +script="plugin.gd" diff --git a/addons/beautify_code_on_save/plugin.gd b/addons/beautify_code_on_save/plugin.gd new file mode 100644 index 00000000..8a951812 --- /dev/null +++ b/addons/beautify_code_on_save/plugin.gd @@ -0,0 +1,210 @@ +@tool +extends EditorPlugin + +const SUCCESS: int = 0 +const AUTO_RELOAD_SETTING = "text_editor/behavior/files/auto_reload_scripts_on_external_change" +const ENABLE_EXTERNAL_EDITOR = "text_editor/external/use_external_editor" +# Plugin custom settings +const GDFORMAT_PATH_SETTING = "beautify_code_on_save/paths/gdformat_path" +const GDLINT_PATH_SETTING = "beautify_code_on_save/paths/gdlint_path" + +var original_reload_setting: bool +var original_external_editor: bool + + +func _enter_tree() -> void: + var settings = get_editor_interface().get_editor_settings() + + # Save original settings + original_reload_setting = settings.get_setting(AUTO_RELOAD_SETTING) + original_external_editor = settings.get_setting(ENABLE_EXTERNAL_EDITOR) + + # Configure auto-reload and external editor + settings.set_setting(AUTO_RELOAD_SETTING, true) + settings.set_setting(ENABLE_EXTERNAL_EDITOR, false) + settings.set_initial_value(AUTO_RELOAD_SETTING, true, false) + settings.set_initial_value(ENABLE_EXTERNAL_EDITOR, false, false) + + # Register plugin settings + _setup_plugin_settings(settings) + + resource_saved.connect(_on_resource_saved_deferred) + + +func _exit_tree() -> void: + resource_saved.disconnect(_on_resource_saved_deferred) + + var settings = get_editor_interface().get_editor_settings() + settings.set_setting(AUTO_RELOAD_SETTING, original_reload_setting) + settings.set_setting(ENABLE_EXTERNAL_EDITOR, original_external_editor) + + +func _setup_plugin_settings(settings: EditorSettings) -> void: + # Detect default paths + var default_gdformat = _detect_default_path("gdformat") + var default_gdlint = _detect_default_path("gdlint") + + # Register settings + if not settings.has_setting(GDFORMAT_PATH_SETTING): + settings.set_setting(GDFORMAT_PATH_SETTING, default_gdformat) + if not settings.has_setting(GDLINT_PATH_SETTING): + settings.set_setting(GDLINT_PATH_SETTING, default_gdlint) + + # Configure settings metadata + ( + settings + .add_property_info( + { + "name": GDFORMAT_PATH_SETTING, + "type": TYPE_STRING, + "hint": PROPERTY_HINT_GLOBAL_FILE, + "hint_string": "", + } + ) + ) + ( + settings + .add_property_info( + { + "name": GDLINT_PATH_SETTING, + "type": TYPE_STRING, + "hint": PROPERTY_HINT_GLOBAL_FILE, + "hint_string": "", + } + ) + ) + + +func _detect_default_path(command: String) -> String: + # Try to detect command path using 'which' + var output = [] + var exit_code = OS.execute("which", [command], output, true) + + if exit_code == SUCCESS and not output.is_empty(): + return output[0].strip_edges() + + # Common paths as fallback + var common_paths = [ + "/usr/local/bin/" + command, + "/usr/bin/" + command, + OS.get_environment("HOME") + "/.local/bin/" + command + ] + + for path in common_paths: + if FileAccess.file_exists(path): + return path + + return "" + + +func _on_resource_saved_deferred(script: Resource) -> void: + call_deferred("_on_resource_saved", script) + + +func _on_resource_saved(script: Resource) -> void: + if not script is Script: + return + + var current_script = get_editor_interface().get_script_editor().get_current_script() + if current_script != script: + return + + var text_edit = ( + get_editor_interface().get_script_editor().get_current_editor().get_base_editor() + ) + var file_path = ProjectSettings.globalize_path(script.resource_path) + + # Get paths from settings + var settings = get_editor_interface().get_editor_settings() + var gdformat_path = settings.get_setting(GDFORMAT_PATH_SETTING) + var gdlint_path = settings.get_setting(GDLINT_PATH_SETTING) + + # Add date time + var date_time = Time.get_datetime_string_from_system() + print("\n%s" % date_time) + + # First run gdformat + if not gdformat_path or not FileAccess.file_exists(gdformat_path): + push_warning("❌ GDFormat not found. Please configure the path in Editor Settings.") + else: + var gdformat_output = [] + var gdformat_exit_code = OS.execute(gdformat_path, [file_path], gdformat_output, true) + + if gdformat_exit_code == SUCCESS: + await get_tree().process_frame + var formatted_source = FileAccess.get_file_as_string(script.resource_path) + _reload_script(text_edit, formatted_source) + print("✓ GDFormat: Successfully formatted: '%s'" % script.resource_path) + else: + push_error("❌ GDFormat Error: " + str(gdformat_output)) + return # If formatting fails, don't continue with linting + + # Then run gdlint on the formatted code + if not gdlint_path or not FileAccess.file_exists(gdlint_path): + push_warning("❌ GDLint not found. Please configure the path in Editor Settings.") + else: + var gdlint_output = [] + var gdlint_exit_code = OS.execute(gdlint_path, [file_path], gdlint_output, true) + + if gdlint_exit_code != SUCCESS: + _show_lint_errors(gdlint_output[0], file_path) + else: + print("✓ GDLint : Successfully linted : '%s'" % script.resource_path) + + +func _reload_script(text_edit: TextEdit, source_code: String) -> void: + # Save cursor and scroll position + var column = text_edit.get_caret_column() + var row = text_edit.get_caret_line() + var scroll_position_h = text_edit.scroll_horizontal + var scroll_position_v = text_edit.scroll_vertical + + # Update text + text_edit.text = source_code + + # Restore cursor and scroll position + + text_edit.set_caret_column(column) + text_edit.set_caret_line(row) + text_edit.scroll_horizontal = scroll_position_h + text_edit.scroll_vertical = scroll_position_v + + # Mark as saved + text_edit.tag_saved_version() + + +func _show_lint_errors(output: String, path: String) -> void: + print("\n⚠ GDLint found the following issues:") + print("File: %s" % _get_res_path(path)) + push_error("❌ GDLint Error: Please see output with more information.") + var lines = output.split("\n") + var error_count := 0 + + for line in lines: + if line.is_empty() or line.begins_with("Failure:"): + continue + + var error_parts = line.split(": Error: ") + if error_parts.size() >= 2: + error_count += 1 + var location = error_parts[0].get_file() + var line_number = ( + error_parts[0].split(":")[2] + if OS.get_name() == "Windows" + else error_parts[0].split(":")[1] + ) + var error_msg = error_parts[1] + + print("%d) Line %s: %s" % [error_count, line_number, error_msg]) + + print("\nTotal: %d issues found" % error_count) + + +func _get_res_path(absolute_path: String) -> String: + var project_root = ProjectSettings.globalize_path("res://") + if absolute_path.begins_with(project_root): + return "res://" + absolute_path.substr(project_root.length()) + var addons_pos = absolute_path.find("/addons/") + if addons_pos != -1: + return "res://" + absolute_path.substr(addons_pos + 1) + return absolute_path diff --git a/addons/beautify_code_on_save/plugin.gd.uid b/addons/beautify_code_on_save/plugin.gd.uid new file mode 100644 index 00000000..fb83ed2f --- /dev/null +++ b/addons/beautify_code_on_save/plugin.gd.uid @@ -0,0 +1 @@ +uid://bd1mkvvfjhvfr diff --git a/addons/dockable_container/LICENSE b/addons/dockable_container/LICENSE new file mode 100644 index 00000000..0e259d42 --- /dev/null +++ b/addons/dockable_container/LICENSE @@ -0,0 +1,121 @@ +Creative Commons Legal Code + +CC0 1.0 Universal + + CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE + LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN + ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS + INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES + REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS + PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM + THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED + HEREUNDER. + +Statement of Purpose + +The laws of most jurisdictions throughout the world automatically confer +exclusive Copyright and Related Rights (defined below) upon the creator +and subsequent owner(s) (each and all, an "owner") of an original work of +authorship and/or a database (each, a "Work"). + +Certain owners wish to permanently relinquish those rights to a Work for +the purpose of contributing to a commons of creative, cultural and +scientific works ("Commons") that the public can reliably and without fear +of later claims of infringement build upon, modify, incorporate in other +works, reuse and redistribute as freely as possible in any form whatsoever +and for any purposes, including without limitation commercial purposes. +These owners may contribute to the Commons to promote the ideal of a free +culture and the further production of creative, cultural and scientific +works, or to gain reputation or greater distribution for their Work in +part through the use and efforts of others. + +For these and/or other purposes and motivations, and without any +expectation of additional consideration or compensation, the person +associating CC0 with a Work (the "Affirmer"), to the extent that he or she +is an owner of Copyright and Related Rights in the Work, voluntarily +elects to apply CC0 to the Work and publicly distribute the Work under its +terms, with knowledge of his or her Copyright and Related Rights in the +Work and the meaning and intended legal effect of CC0 on those rights. + +1. Copyright and Related Rights. A Work made available under CC0 may be +protected by copyright and related or neighboring rights ("Copyright and +Related Rights"). Copyright and Related Rights include, but are not +limited to, the following: + + i. the right to reproduce, adapt, distribute, perform, display, + communicate, and translate a Work; + ii. moral rights retained by the original author(s) and/or performer(s); +iii. publicity and privacy rights pertaining to a person's image or + likeness depicted in a Work; + iv. rights protecting against unfair competition in regards to a Work, + subject to the limitations in paragraph 4(a), below; + v. rights protecting the extraction, dissemination, use and reuse of data + in a Work; + vi. database rights (such as those arising under Directive 96/9/EC of the + European Parliament and of the Council of 11 March 1996 on the legal + protection of databases, and under any national implementation + thereof, including any amended or successor version of such + directive); and +vii. other similar, equivalent or corresponding rights throughout the + world based on applicable law or treaty, and any national + implementations thereof. + +2. Waiver. To the greatest extent permitted by, but not in contravention +of, applicable law, Affirmer hereby overtly, fully, permanently, +irrevocably and unconditionally waives, abandons, and surrenders all of +Affirmer's Copyright and Related Rights and associated claims and causes +of action, whether now known or unknown (including existing as well as +future claims and causes of action), in the Work (i) in all territories +worldwide, (ii) for the maximum duration provided by applicable law or +treaty (including future time extensions), (iii) in any current or future +medium and for any number of copies, and (iv) for any purpose whatsoever, +including without limitation commercial, advertising or promotional +purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each +member of the public at large and to the detriment of Affirmer's heirs and +successors, fully intending that such Waiver shall not be subject to +revocation, rescission, cancellation, termination, or any other legal or +equitable action to disrupt the quiet enjoyment of the Work by the public +as contemplated by Affirmer's express Statement of Purpose. + +3. Public License Fallback. Should any part of the Waiver for any reason +be judged legally invalid or ineffective under applicable law, then the +Waiver shall be preserved to the maximum extent permitted taking into +account Affirmer's express Statement of Purpose. In addition, to the +extent the Waiver is so judged Affirmer hereby grants to each affected +person a royalty-free, non transferable, non sublicensable, non exclusive, +irrevocable and unconditional license to exercise Affirmer's Copyright and +Related Rights in the Work (i) in all territories worldwide, (ii) for the +maximum duration provided by applicable law or treaty (including future +time extensions), (iii) in any current or future medium and for any number +of copies, and (iv) for any purpose whatsoever, including without +limitation commercial, advertising or promotional purposes (the +"License"). The License shall be deemed effective as of the date CC0 was +applied by Affirmer to the Work. Should any part of the License for any +reason be judged legally invalid or ineffective under applicable law, such +partial invalidity or ineffectiveness shall not invalidate the remainder +of the License, and in such case Affirmer hereby affirms that he or she +will not (i) exercise any of his or her remaining Copyright and Related +Rights in the Work or (ii) assert any associated claims and causes of +action with respect to the Work, in either case contrary to Affirmer's +express Statement of Purpose. + +4. Limitations and Disclaimers. + + a. No trademark or patent rights held by Affirmer are waived, abandoned, + surrendered, licensed or otherwise affected by this document. + b. Affirmer offers the Work as-is and makes no representations or + warranties of any kind concerning the Work, express, implied, + statutory or otherwise, including without limitation warranties of + title, merchantability, fitness for a particular purpose, non + infringement, or the absence of latent or other defects, accuracy, or + the present or absence of errors, whether or not discoverable, all to + the greatest extent permissible under applicable law. + c. Affirmer disclaims responsibility for clearing rights of other persons + that may apply to the Work or any use thereof, including without + limitation any person's Copyright and Related Rights in the Work. + Further, Affirmer disclaims responsibility for obtaining any necessary + consents, permissions or other rights required for any use of the + Work. + d. Affirmer understands and acknowledges that Creative Commons is not a + party to this document and has no duty or obligation with respect to + this CC0 or use of the Work. diff --git a/addons/dockable_container/dockable_container.gd b/addons/dockable_container/dockable_container.gd new file mode 100644 index 00000000..cbb95c8c --- /dev/null +++ b/addons/dockable_container/dockable_container.gd @@ -0,0 +1,524 @@ +@tool +class_name DockableContainer +extends Container + +const SplitHandle := preload("split_handle.gd") +const DockablePanel := preload("dockable_panel.gd") +const DragNDropPanel := preload("drag_n_drop_panel.gd") + +@export var tab_alignment := TabBar.ALIGNMENT_CENTER: + get: + return _tab_align + set(value): + _tab_align = value + for i in range(1, _panel_container.get_child_count()): + var panel := _panel_container.get_child(i) as DockablePanel + panel.tab_alignment = value +@export var use_hidden_tabs_for_min_size := false: + get: + return _use_hidden_tabs_for_min_size + set(value): + _use_hidden_tabs_for_min_size = value + for i in range(1, _panel_container.get_child_count()): + var panel := _panel_container.get_child(i) as DockablePanel + panel.use_hidden_tabs_for_min_size = value +@export var tabs_visible := true: + get: + return _tabs_visible + set(value): + _tabs_visible = value + for i in range(1, _panel_container.get_child_count()): + var panel := _panel_container.get_child(i) as DockablePanel + panel.show_tabs = _tabs_visible +## If [code]true[/code] and a panel only has one tab, it keeps that tab hidden even if +## [member tabs_visible] is [code]true[/code]. +## Only takes effect is [member tabs_visible] is [code]true[/code]. +@export var hide_single_tab := false: + get: + return _hide_single_tab + set(value): + _hide_single_tab = value + for i in range(1, _panel_container.get_child_count()): + var panel := _panel_container.get_child(i) as DockablePanel + panel.hide_single_tab = _hide_single_tab + queue_sort() +@export var rearrange_group := 0 +@export var layout := DockableLayout.new(): + get: + return _layout + set(value): + set_layout(value) +## If `clone_layout_on_ready` is true, `layout` will be cloned checked `_ready`. +## This is useful for leaving layout Resources untouched in case you want to +## restore layout to its default later. +@export var clone_layout_on_ready := true + +var _layout := DockableLayout.new() +var _panel_container := Container.new() +var _windows_container := Container.new() +var _split_container := Container.new() +var _drag_n_drop_panel := DragNDropPanel.new() +var _drag_panel: DockablePanel +var _tab_align := TabBar.ALIGNMENT_CENTER +var _tabs_visible := true +var _use_hidden_tabs_for_min_size := false +var _hide_single_tab := false +var _current_panel_index := 0 +var _current_split_index := 0 +var _children_names := {} +var _layout_dirty := false + + +func _init() -> void: + child_entered_tree.connect(_child_entered_tree) + child_exiting_tree.connect(_child_exiting_tree) + + +func _ready() -> void: + set_process_input(false) + _panel_container.name = "_panel_container" + add_child(_panel_container) + move_child(_panel_container, 0) + _split_container.name = "_split_container" + _split_container.mouse_filter = MOUSE_FILTER_PASS + _panel_container.add_child(_split_container) + _windows_container.name = "_windows_container" + get_parent().call_deferred("add_child", _windows_container) + + _drag_n_drop_panel.name = "_drag_n_drop_panel" + _drag_n_drop_panel.mouse_filter = MOUSE_FILTER_PASS + _drag_n_drop_panel.visible = false + add_child(_drag_n_drop_panel) + + if not _layout: + set_layout(null) + elif clone_layout_on_ready and not Engine.is_editor_hint(): + set_layout(_layout.clone()) + + +func _notification(what: int) -> void: + if what == NOTIFICATION_SORT_CHILDREN: + _resort() + elif ( + what == NOTIFICATION_DRAG_BEGIN + and _can_handle_drag_data(get_viewport().gui_get_drag_data()) + ): + _drag_n_drop_panel.set_enabled(true, not _layout.root.is_empty()) + set_process_input(true) + elif what == NOTIFICATION_DRAG_END: + _drag_n_drop_panel.set_enabled(false) + set_process_input(false) + + +func _input(event: InputEvent) -> void: + assert(get_viewport().gui_is_dragging(), "FIXME: should only be called when dragging") + if event is InputEventMouseMotion: + var local_position := get_local_mouse_position() + var panel: DockablePanel + for i in range(1, _panel_container.get_child_count()): + var p := _panel_container.get_child(i) as DockablePanel + if p.get_rect().has_point(local_position): + panel = p + break + _drag_panel = panel + if not panel: + return + + var current_tab: DockableReferenceControl = panel.get_current_tab_control() + var tab_name: String = current_tab.reference_to.name + if tab_name.begins_with("_"): + return + + fit_child_in_rect(_drag_n_drop_panel, panel.get_child_rect()) + + +func _child_entered_tree(node: Node) -> void: + if node == _panel_container or node == _drag_n_drop_panel: + return + _drag_n_drop_panel.move_to_front() + _track_and_add_node(node) + + +func _child_exiting_tree(node: Node) -> void: + if node == _panel_container or node == _drag_n_drop_panel: + return + _untrack_node(node) + + +func _can_drop_data(_position: Vector2, data) -> bool: + return _can_handle_drag_data(data) + + +func _drop_data(_position: Vector2, data) -> void: + var from_node := get_node(data.from_path) + if from_node is TabBar: + from_node = from_node.get_parent() + if from_node == _drag_panel and _drag_panel.get_child_count() == 1: + return + var tab_index = data.tabc_element if data.has("tabc_element") else data.tab_index + var moved_tab = from_node.get_tab_control(tab_index) + if moved_tab is DockableReferenceControl: + moved_tab = moved_tab.reference_to + if not _is_managed_node(moved_tab): + moved_tab.get_parent().remove_child(moved_tab) + add_child(moved_tab) + + if _drag_panel != null: + var margin := _drag_n_drop_panel.get_hover_margin() + _layout.split_leaf_with_node(_drag_panel.leaf, moved_tab, margin) + + _layout_dirty = true + queue_sort() + + +func _add_floating_options(tab_container: DockablePanel) -> void: + var options := PopupMenu.new() + options.add_item("Make Floating") + options.id_pressed.connect(_toggle_floating.bind(tab_container)) + options.size.y = 0 + _windows_container.add_child(options) + tab_container.set_popup(options) + + +## Required when converting a window back to panel. +func _refresh_tabs_visible() -> void: + if tabs_visible: + tabs_visible = false + await get_tree().process_frame + await get_tree().process_frame + tabs_visible = true + + +func _toggle_floating(_id: int, tab_container: DockablePanel) -> void: + var node_name := tab_container.get_tab_title(tab_container.current_tab) + var node := get_node(node_name) + if is_instance_valid(node): + var tab_position := maxi(tab_container.leaf.find_child(node), 0) + _convert_to_window(node, {"tab_position": tab_position, "tab_container": tab_container}) + else: + print("Node ", node_name, " not found!") + + +## Converts a panel to floating window. +func _convert_to_window(content: Control, previous_data := {}) -> void: + var old_owner := content.owner + var data := {} + if content.name in layout.windows: + data = layout.windows[content.name] + var window := FloatingWindow.new(content, data) + _windows_container.add_child(window) + window.show() + _refresh_tabs_visible() + window.close_requested.connect(_convert_to_panel.bind(window, old_owner, previous_data)) + window.data_changed.connect(layout.save_window_properties) + + +## Converts a floating window into a panel. +func _convert_to_panel(window: FloatingWindow, old_owner: Node, previous_data := {}) -> void: + var content := window.window_content + window.remove_child(content) + window.destroy() + add_child(content) + content.owner = old_owner + if previous_data.has("tab_container") and is_instance_valid(previous_data["tab_container"]): + var tab_position := previous_data.get("tab_position", 0) as int + previous_data["tab_container"].leaf.insert_node(tab_position, content) + _refresh_tabs_visible() + + +func set_control_as_current_tab(control: Control) -> void: + assert( + control.get_parent_control() == self, + "Trying to focus a control not managed by this container" + ) + if is_control_hidden(control): + push_warning("Trying to focus a hidden control") + return + var leaf := _layout.get_leaf_for_node(control) + if not leaf: + return + var position_in_leaf := leaf.find_child(control) + if position_in_leaf < 0: + return + var panel: DockablePanel + for i in range(1, _panel_container.get_child_count()): + var p := _panel_container.get_child(i) as DockablePanel + if p.leaf == leaf: + panel = p + break + if not panel: + return + panel.current_tab = clampi(position_in_leaf, 0, panel.get_tab_count() - 1) + + +func set_layout(value: DockableLayout) -> void: + if value == null: + value = DockableLayout.new() + if value == _layout: + return + if _layout and _layout.changed.is_connected(queue_sort): + _layout.changed.disconnect(queue_sort) + _layout = value + _layout.changed.connect(queue_sort) + for window in _windows_container.get_children(): + if not window.name in _layout.windows and window is FloatingWindow: + window.prevent_data_erasure = true # We don't want to delete data. + window.close_requested.emit() # Removes the window. + continue + for window: String in _layout.windows.keys(): + var panel := find_child(window, false) + # Only those windows get created which were not previously created. + if panel: + _convert_to_window(panel) + _layout_dirty = true + queue_sort() + + +func set_use_hidden_tabs_for_min_size(value: bool) -> void: + _use_hidden_tabs_for_min_size = value + for i in range(1, _panel_container.get_child_count()): + var panel := _panel_container.get_child(i) as DockablePanel + panel.use_hidden_tabs_for_min_size = value + + +func get_use_hidden_tabs_for_min_size() -> bool: + return _use_hidden_tabs_for_min_size + + +func set_control_hidden(child: Control, is_hidden: bool) -> void: + _layout.set_node_hidden(child, is_hidden) + + +func is_control_hidden(child: Control) -> bool: + return _layout.is_node_hidden(child) + + +func get_tabs() -> Array[Control]: + var tabs: Array[Control] = [] + for i in get_child_count(): + var child := get_child(i) + if _is_managed_node(child): + tabs.append(child) + return tabs + + +func get_tab_count() -> int: + var count := 0 + for i in get_child_count(): + var child := get_child(i) + if _is_managed_node(child): + count += 1 + return count + + +func _can_handle_drag_data(data) -> bool: + if data is Dictionary and data.get("type") in ["tab_container_tab", "tabc_element"]: + var tabc := get_node_or_null(data.get("from_path")) + return ( + tabc + and tabc.has_method("get_tabs_rearrange_group") + and tabc.get_tabs_rearrange_group() == rearrange_group + ) + return false + + +func _is_managed_node(node: Node) -> bool: + return ( + node.get_parent() == self + and node != _panel_container + and node != _drag_n_drop_panel + and node is Control + and not node.top_level + ) + + +func _update_layout_with_children() -> void: + var names := PackedStringArray() + _children_names.clear() + for i in range(1, get_child_count() - 1): + var c := get_child(i) + if _track_node(c): + names.append(c.name) + _layout.update_nodes(names) + _layout_dirty = false + + +func _track_node(node: Node) -> bool: + if not _is_managed_node(node): + return false + _children_names[node] = node.name + _children_names[node.name] = node + if not node.renamed.is_connected(_on_child_renamed): + node.renamed.connect(_on_child_renamed.bind(node)) + if not node.tree_exiting.is_connected(_untrack_node): + node.tree_exiting.connect(_untrack_node.bind(node)) + return true + + +func _track_and_add_node(node: Node) -> void: + var tracked_name = _children_names.get(node) + if not _track_node(node): + return + if tracked_name and tracked_name != node.name: + _layout.rename_node(tracked_name, node.name) + _layout_dirty = true + + +func _untrack_node(node: Node) -> void: + _children_names.erase(node) + _children_names.erase(node.name) + if node.renamed.is_connected(_on_child_renamed): + node.renamed.disconnect(_on_child_renamed) + if node.tree_exiting.is_connected(_untrack_node): + node.tree_exiting.disconnect(_untrack_node) + _layout_dirty = true + + +func _resort() -> void: + assert(_panel_container, "FIXME: resorting without _panel_container") + if _panel_container.get_index() != 0: + move_child(_panel_container, 0) + if _drag_n_drop_panel.get_index() < get_child_count() - 1: + _drag_n_drop_panel.move_to_front() + + if _layout_dirty: + _update_layout_with_children() + + var rect := Rect2(Vector2.ZERO, size) + fit_child_in_rect(_panel_container, rect) + _panel_container.fit_child_in_rect(_split_container, rect) + + _current_panel_index = 1 + _current_split_index = 0 + + var children_list := [] + _calculate_panel_and_split_list(children_list, _layout.root) + _fit_panel_and_split_list_to_rect(children_list, rect) + + _untrack_children_after(_panel_container, _current_panel_index) + _untrack_children_after(_split_container, _current_split_index) + + +## Calculate DockablePanel and SplitHandle minimum sizes, skipping empty +## branches. +## +## Returns a DockablePanel checked non-empty leaves, a SplitHandle checked non-empty +## splits, `null` if the whole branch is empty and no space should be used. +## +## `result` will be filled with the non-empty nodes in this post-order tree +## traversal. +func _calculate_panel_and_split_list(result: Array, layout_node: DockableLayoutNode): + if layout_node is DockableLayoutPanel: + var nodes: Array[Control] = [] + for n in layout_node.names: + var node: Control = _children_names.get(n) + if node: + assert(node is Control, "FIXME: node is not a control %s" % node) + assert( + node.get_parent_control() == self, + "FIXME: node is not child of container %s" % node + ) + if is_control_hidden(node): + node.visible = false + else: + nodes.append(node) + if nodes.is_empty(): + return null + else: + var panel := _get_panel(_current_panel_index) + _current_panel_index += 1 + panel.track_nodes(nodes, layout_node) + result.append(panel) + return panel + elif layout_node is DockableLayoutSplit: + # by processing `second` before `first`, traversing `result` from back + # to front yields a nice pre-order tree traversal + var second_result = _calculate_panel_and_split_list(result, layout_node.second) + var first_result = _calculate_panel_and_split_list(result, layout_node.first) + if first_result and second_result: + var split := _get_split(_current_split_index) + _current_split_index += 1 + split.layout_split = layout_node + split.first_minimum_size = first_result.get_layout_minimum_size() + split.second_minimum_size = second_result.get_layout_minimum_size() + result.append(split) + return split + elif first_result: + return first_result + else: # NOTE: this returns null if `second_result` is null + return second_result + else: + push_warning("FIXME: invalid Resource, should be branch or leaf, found %s" % layout_node) + + +## Traverse list from back to front fitting controls where they belong. +## +## Be sure to call this with the result from `_calculate_split_minimum_sizes`. +func _fit_panel_and_split_list_to_rect(panel_and_split_list: Array, rect: Rect2) -> void: + var control = panel_and_split_list.pop_back() + if control is DockablePanel: + _panel_container.fit_child_in_rect(control, rect) + elif control is SplitHandle: + var split_rects = control.get_split_rects(rect) + _split_container.fit_child_in_rect(control, split_rects["self"]) + _fit_panel_and_split_list_to_rect(panel_and_split_list, split_rects["first"]) + _fit_panel_and_split_list_to_rect(panel_and_split_list, split_rects["second"]) + + +## Get the idx'th DockablePanel, reusing an instanced one if possible +func _get_panel(idx: int) -> DockablePanel: + assert(_panel_container, "FIXME: creating panel without _panel_container") + if idx < _panel_container.get_child_count(): + return _panel_container.get_child(idx) + var panel := DockablePanel.new() + panel.tab_alignment = _tab_align + panel.show_tabs = _tabs_visible + panel.hide_single_tab = _hide_single_tab + panel.use_hidden_tabs_for_min_size = _use_hidden_tabs_for_min_size + panel.set_tabs_rearrange_group(maxi(0, rearrange_group)) + _add_floating_options(panel) + _panel_container.add_child(panel) + panel.tab_layout_changed.connect(_on_panel_tab_layout_changed.bind(panel)) + return panel + + +## Get the idx'th SplitHandle, reusing an instanced one if possible +func _get_split(idx: int) -> SplitHandle: + assert(_split_container, "FIXME: creating split without _split_container") + if idx < _split_container.get_child_count(): + return _split_container.get_child(idx) + var split := SplitHandle.new() + _split_container.add_child(split) + return split + + +## Helper for removing and freeing all remaining children from node +func _untrack_children_after(node: Control, idx: int) -> void: + for i in range(idx, node.get_child_count()): + var child := node.get_child(idx) + node.remove_child(child) + child.queue_free() + + +## Handler for `DockablePanel.tab_layout_changed`, update its DockableLayoutPanel +func _on_panel_tab_layout_changed(tab: int, panel: DockablePanel) -> void: + _layout_dirty = true + var control := panel.get_tab_control(tab) + if control is DockableReferenceControl: + control = control.reference_to + if not _is_managed_node(control): + control.get_parent().remove_child(control) + add_child(control) + _layout.move_node_to_leaf(control, panel.leaf, tab) + queue_sort() + + +## Handler for `Node.renamed` signal, updates tracked name for node +func _on_child_renamed(child: Node) -> void: + var old_name: String = _children_names.get(child) + if old_name == str(child.name): + return + _children_names.erase(old_name) + _children_names[child] = child.name + _children_names[child.name] = child + _layout.rename_node(old_name, child.name) diff --git a/addons/dockable_container/dockable_container.gd.uid b/addons/dockable_container/dockable_container.gd.uid new file mode 100644 index 00000000..d3304fc5 --- /dev/null +++ b/addons/dockable_container/dockable_container.gd.uid @@ -0,0 +1 @@ +uid://k2o7qui1lr6l diff --git a/addons/dockable_container/dockable_panel.gd b/addons/dockable_container/dockable_panel.gd new file mode 100644 index 00000000..bd064113 --- /dev/null +++ b/addons/dockable_container/dockable_panel.gd @@ -0,0 +1,168 @@ +@tool +extends TabContainer + +signal tab_layout_changed(tab) + +var leaf: DockableLayoutPanel: + get: + return get_leaf() + set(value): + set_leaf(value) +var show_tabs := true: + get: + return _show_tabs + set(value): + _show_tabs = value + _handle_tab_visibility() +var hide_single_tab := false: + get: + return _hide_single_tab + set(value): + _hide_single_tab = value + _handle_tab_visibility() + +var _leaf: DockableLayoutPanel +var _show_tabs := true +var _hide_single_tab := false +var _have_focus := false + + +func _ready() -> void: + drag_to_rearrange_enabled = true + theme_type_variation = "EditorSection" + + _update_style() + + +func _enter_tree() -> void: + active_tab_rearranged.connect(_on_tab_changed) + tab_selected.connect(_on_tab_selected) + tab_changed.connect(_on_tab_changed) + + _update_style() + + +func _exit_tree() -> void: + active_tab_rearranged.disconnect(_on_tab_changed) + tab_selected.disconnect(_on_tab_selected) + tab_changed.disconnect(_on_tab_changed) + if is_instance_valid(get_popup()): + get_popup().queue_free() + + _update_style() + + +func track_nodes(nodes: Array[Control], new_leaf: DockableLayoutPanel) -> void: + _leaf = null # avoid using previous leaf in tab_changed signals + var min_size := mini(nodes.size(), get_child_count()) + # remove spare children + for i in range(min_size, get_child_count()): + var child := get_child(min_size) as DockableReferenceControl + child.reference_to = null + remove_child(child) + child.queue_free() + # add missing children + for i in range(min_size, nodes.size()): + var ref_control := DockableReferenceControl.new() + add_child(ref_control) + assert(nodes.size() == get_child_count(), "FIXME") + # setup children + for i in nodes.size(): + var ref_control := get_child(i) as DockableReferenceControl + ref_control.reference_to = nodes[i] + set_tab_title(i, nodes[i].name) + set_leaf(new_leaf) + _handle_tab_visibility() + + +func get_child_rect() -> Rect2: + var control := get_current_tab_control() + return Rect2(position + control.position, control.size) + + +func set_leaf(value: DockableLayoutPanel) -> void: + if get_tab_count() > 0 and value: + current_tab = clampi(value.current_tab, 0, get_tab_count() - 1) + _leaf = value + + _update_style() + + +func get_leaf() -> DockableLayoutPanel: + return _leaf + + +func get_layout_minimum_size() -> Vector2: + hide() + show() + return get_combined_minimum_size() + + +func _on_tab_selected(tab: int) -> void: + if _leaf: + _leaf.current_tab = tab + + +func _on_tab_changed(tab: int) -> void: + if not _leaf: + return + var control := get_tab_control(tab) + if not control: + return + var tab_name := control.name + var name_index_in_leaf := _leaf.find_name(tab_name) + if name_index_in_leaf != tab: # NOTE: this handles added tabs (index == -1) + tab_layout_changed.emit(tab) + + +func _handle_tab_visibility() -> void: + if _hide_single_tab and get_tab_count() == 1: + tabs_visible = false + else: + tabs_visible = _show_tabs + + if is_node_ready(): + _update_style() + + +func _update_style() -> void: + var mouse_hovering: bool = is_mouse_on_section() + + if leaf: + for name in leaf.get_names(): + if not name.begins_with("_"): + continue + tabs_visible = false + + var panel_style_name: String = "panel" + var tabbar_style_name: String = "tabbar_background" + _have_focus = mouse_hovering + if mouse_hovering: + panel_style_name += "_focus" + tabbar_style_name += "_focus" + else: + panel_style_name += "_unfocus" + tabbar_style_name += "_unfocus" + + if tabs_visible: + panel_style_name = "tab_" + panel_style_name + + add_theme_stylebox_override("panel", get_theme_stylebox(panel_style_name, "EditorSection")) + add_theme_stylebox_override( + "tabbar_background", get_theme_stylebox(tabbar_style_name, "EditorSection") + ) + + +func _input(event: InputEvent) -> void: + if event is InputEventMouseButton and event.is_pressed(): + _update_style() + + +func is_mouse_on_section() -> bool: + var local_mouse_pos: Vector2 = get_global_mouse_position() - global_position + return not ( + local_mouse_pos.x < 0 + or local_mouse_pos.y < 0 + or local_mouse_pos.x > size.x + or local_mouse_pos.y > size.y + ) diff --git a/addons/dockable_container/dockable_panel.gd.uid b/addons/dockable_container/dockable_panel.gd.uid new file mode 100644 index 00000000..aa5a5aff --- /dev/null +++ b/addons/dockable_container/dockable_panel.gd.uid @@ -0,0 +1 @@ +uid://dca5brtlainkk diff --git a/addons/dockable_container/dockable_panel_reference_control.gd b/addons/dockable_container/dockable_panel_reference_control.gd new file mode 100644 index 00000000..06dc11b9 --- /dev/null +++ b/addons/dockable_container/dockable_panel_reference_control.gd @@ -0,0 +1,49 @@ +@tool +class_name DockableReferenceControl +extends Container +## Control that mimics its own visibility and rect into another Control. + +var reference_to: Control: + get: + return _reference_to + set(control): + if _reference_to != control: + if is_instance_valid(_reference_to): + _reference_to.renamed.disconnect(_on_reference_to_renamed) + _reference_to.minimum_size_changed.disconnect(update_minimum_size) + _reference_to = control + + minimum_size_changed.emit() + if not is_instance_valid(_reference_to): + return + _reference_to.renamed.connect(_on_reference_to_renamed) + _reference_to.minimum_size_changed.connect(update_minimum_size) + _reference_to.visible = visible + _reposition_reference() + +var _reference_to: Control = null + + +func _ready() -> void: + mouse_filter = MOUSE_FILTER_IGNORE + set_notify_transform(true) + + +func _notification(what: int) -> void: + if what == NOTIFICATION_VISIBILITY_CHANGED and _reference_to: + _reference_to.visible = visible + elif what == NOTIFICATION_TRANSFORM_CHANGED and _reference_to: + _reposition_reference() + + +func _get_minimum_size() -> Vector2: + return _reference_to.get_combined_minimum_size() if _reference_to else Vector2.ZERO + + +func _reposition_reference() -> void: + _reference_to.global_position = global_position + _reference_to.size = size + + +func _on_reference_to_renamed() -> void: + name = _reference_to.name diff --git a/addons/dockable_container/dockable_panel_reference_control.gd.uid b/addons/dockable_container/dockable_panel_reference_control.gd.uid new file mode 100644 index 00000000..8ff02d12 --- /dev/null +++ b/addons/dockable_container/dockable_panel_reference_control.gd.uid @@ -0,0 +1 @@ +uid://8fcumdc7ut8 diff --git a/addons/dockable_container/drag_n_drop_panel.gd b/addons/dockable_container/drag_n_drop_panel.gd new file mode 100644 index 00000000..7e5d7714 --- /dev/null +++ b/addons/dockable_container/drag_n_drop_panel.gd @@ -0,0 +1,82 @@ +@tool +extends Control + +enum { MARGIN_LEFT, MARGIN_RIGHT, MARGIN_TOP, MARGIN_BOTTOM, MARGIN_CENTER } + +const DRAW_NOTHING := -1 +const DRAW_CENTERED := -2 +const MARGIN_NONE := -1 + +var _draw_margin := DRAW_NOTHING +var _should_split := false + + +func _notification(what: int) -> void: + if what == NOTIFICATION_MOUSE_EXIT: + _draw_margin = DRAW_NOTHING + queue_redraw() + elif what == NOTIFICATION_MOUSE_ENTER and not _should_split: + _draw_margin = DRAW_CENTERED + queue_redraw() + + +func _gui_input(event: InputEvent) -> void: + if _should_split and event is InputEventMouseMotion: + _draw_margin = _find_hover_margin(event.position) + queue_redraw() + + +func _draw() -> void: + var rect: Rect2 + if _draw_margin == DRAW_NOTHING: + return + elif _draw_margin == DRAW_CENTERED: + rect = Rect2(Vector2.ZERO, size) + elif _draw_margin == MARGIN_LEFT: + rect = Rect2(0, 0, size.x * 0.5, size.y) + elif _draw_margin == MARGIN_TOP: + rect = Rect2(0, 0, size.x, size.y * 0.5) + elif _draw_margin == MARGIN_RIGHT: + var half_width = size.x * 0.5 + rect = Rect2(half_width, 0, half_width, size.y) + elif _draw_margin == MARGIN_BOTTOM: + var half_height = size.y * 0.5 + rect = Rect2(0, half_height, size.x, half_height) + var stylebox := get_theme_stylebox("panel", "TooltipPanel") + draw_style_box(stylebox, rect) + + +func set_enabled(enabled: bool, should_split: bool = true) -> void: + visible = enabled + _should_split = should_split + if enabled: + _draw_margin = DRAW_NOTHING + queue_redraw() + + +func get_hover_margin() -> int: + return _draw_margin + + +func _find_hover_margin(point: Vector2) -> int: + var half_size := size * 0.5 + + var left := point.distance_squared_to(Vector2(0, half_size.y)) + var lesser := left + var lesser_margin := MARGIN_LEFT + + var top := point.distance_squared_to(Vector2(half_size.x, 0)) + if lesser > top: + lesser = top + lesser_margin = MARGIN_TOP + + var right := point.distance_squared_to(Vector2(size.x, half_size.y)) + if lesser > right: + lesser = right + lesser_margin = MARGIN_RIGHT + + var bottom := point.distance_squared_to(Vector2(half_size.x, size.y)) + if lesser > bottom: + #lesser = bottom # unused result + lesser_margin = MARGIN_BOTTOM + return lesser_margin diff --git a/addons/dockable_container/drag_n_drop_panel.gd.uid b/addons/dockable_container/drag_n_drop_panel.gd.uid new file mode 100644 index 00000000..535296f3 --- /dev/null +++ b/addons/dockable_container/drag_n_drop_panel.gd.uid @@ -0,0 +1 @@ +uid://btfkmp6r4s6kb diff --git a/addons/dockable_container/floating_window.gd b/addons/dockable_container/floating_window.gd new file mode 100644 index 00000000..99f5c7ca --- /dev/null +++ b/addons/dockable_container/floating_window.gd @@ -0,0 +1,81 @@ +class_name FloatingWindow +extends Window + +## Emitted when the window's position or size changes, or when it's closed. +signal data_changed + +var window_content: Control +var prevent_data_erasure := false +var _is_initialized := false + + +func _init(content: Control, data := {}) -> void: + hide() + window_content = content + title = window_content.name + name = window_content.name + min_size = window_content.get_minimum_size() + unresizable = false + wrap_controls = true + always_on_top = false + force_native = true + ready.connect(_deserialize.bind(data)) + + +func _ready() -> void: + set_deferred(&"size", Vector2(300, 300)) + current_screen = get_window().current_screen + await get_tree().process_frame + await get_tree().process_frame + # Enable always_on_top for all child windows, + # to fix a bug where the child windows of floating windows appear behind them. + # TODO: Remove the loop when this bug gets fixed in Godot's side. + # Probably when https://github.com/godotengine/godot/issues/92848 is closed. + for dialog_child in find_children("", "Window", true, false): + if dialog_child is Window: + dialog_child.always_on_top = always_on_top + + show() + + +func _input(event: InputEvent) -> void: + if event is InputEventMouse: + # Emit `data_changed` when the window is being moved. + if not window_content.get_rect().has_point(event.position) and _is_initialized: + data_changed.emit(name, serialize()) + + +func serialize() -> Dictionary: + return {"size": size, "position": position} + + +func _deserialize(data: Dictionary) -> void: + window_content.get_parent().remove_child(window_content) + window_content.visible = true + window_content.global_position = Vector2.ZERO + add_child(window_content) + size_changed.connect(window_size_changed) + if "position" in data: + await get_tree().process_frame + await get_tree().process_frame + position = data["position"] + if "size" in data: + set_deferred(&"size", data["size"]) + _is_initialized = true + + +func window_size_changed() -> void: + window_content.size = size + window_content.position = Vector2.ZERO + if _is_initialized: + data_changed.emit(name, serialize()) + + +func destroy() -> void: + size_changed.disconnect(window_size_changed) + queue_free() + + +func _exit_tree() -> void: + if _is_initialized and !prevent_data_erasure: + data_changed.emit(name, {}) diff --git a/addons/dockable_container/floating_window.gd.uid b/addons/dockable_container/floating_window.gd.uid new file mode 100644 index 00000000..ab69fc16 --- /dev/null +++ b/addons/dockable_container/floating_window.gd.uid @@ -0,0 +1 @@ +uid://bj1b6rdd8u8dy diff --git a/addons/dockable_container/icon.svg b/addons/dockable_container/icon.svg new file mode 100644 index 00000000..d87d598d --- /dev/null +++ b/addons/dockable_container/icon.svg @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/addons/dockable_container/icon.svg.import b/addons/dockable_container/icon.svg.import new file mode 100644 index 00000000..7ffd9942 --- /dev/null +++ b/addons/dockable_container/icon.svg.import @@ -0,0 +1,18 @@ +[remap] + +importer="svg" +type="DPITexture" +uid="uid://dy25danh2am23" +path="res://.godot/imported/icon.svg-35635e7bbda4487d4b2942da1d987df8.dpitex" + +[deps] + +source_file="res://addons/dockable_container/icon.svg" +dest_files=["res://.godot/imported/icon.svg-35635e7bbda4487d4b2942da1d987df8.dpitex"] + +[params] + +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/addons/dockable_container/inspector_plugin/editor_inspector_plugin.gd b/addons/dockable_container/inspector_plugin/editor_inspector_plugin.gd new file mode 100644 index 00000000..73d0372b --- /dev/null +++ b/addons/dockable_container/inspector_plugin/editor_inspector_plugin.gd @@ -0,0 +1,22 @@ +extends EditorInspectorPlugin + +const LayoutEditorProperty := preload("layout_editor_property.gd") + + +func _can_handle(object: Object) -> bool: + return object is DockableContainer + + +func _parse_property( + _object: Object, + _type: Variant.Type, + name: String, + _hint: PropertyHint, + _hint_text: String, + _usage: int, + _wide: bool +) -> bool: + if name == "layout": + var editor_property := LayoutEditorProperty.new() + add_property_editor("layout", editor_property) + return false diff --git a/addons/dockable_container/inspector_plugin/editor_inspector_plugin.gd.uid b/addons/dockable_container/inspector_plugin/editor_inspector_plugin.gd.uid new file mode 100644 index 00000000..db6dd318 --- /dev/null +++ b/addons/dockable_container/inspector_plugin/editor_inspector_plugin.gd.uid @@ -0,0 +1 @@ +uid://st877dcaad8x diff --git a/addons/dockable_container/inspector_plugin/layout_editor_property.gd b/addons/dockable_container/inspector_plugin/layout_editor_property.gd new file mode 100644 index 00000000..eb00134b --- /dev/null +++ b/addons/dockable_container/inspector_plugin/layout_editor_property.gd @@ -0,0 +1,71 @@ +extends EditorProperty + +var _container := DockableContainer.new() +var _hidden_menu_button := MenuButton.new() +var _hidden_menu_popup: PopupMenu +var _hidden_menu_list: PackedStringArray + + +func _ready() -> void: + custom_minimum_size = Vector2(128, 256) + + _hidden_menu_button.text = "Visible nodes" + add_child(_hidden_menu_button) + _hidden_menu_popup = _hidden_menu_button.get_popup() + _hidden_menu_popup.hide_on_checkable_item_selection = false + _hidden_menu_popup.about_to_popup.connect(_on_hidden_menu_popup_about_to_show) + _hidden_menu_popup.id_pressed.connect(_on_hidden_menu_popup_id_pressed) + + _container.clone_layout_on_ready = false + _container.custom_minimum_size = custom_minimum_size + + var value := _get_layout().clone() # The layout gets reset when selecting it without clone + for n in value.get_names(): + var child := _create_child_control(n) + _container.add_child(child) + _container.set(get_edited_property(), value) + add_child(_container) + set_bottom_editor(_container) + + +func _exit_tree() -> void: # Not sure if this is needed, but just to be sure + queue_free() + + +func _update_property() -> void: + var value := _get_layout() + _container.set(get_edited_property(), value) + + +func _get_layout() -> DockableLayout: + var original_container := get_edited_object() as DockableContainer + return original_container.get(get_edited_property()) + + +func _create_child_control(named: String) -> Label: + var new_control := Label.new() + new_control.name = named + new_control.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER + new_control.vertical_alignment = VERTICAL_ALIGNMENT_CENTER + new_control.clip_text = true + new_control.text = named + return new_control + + +func _on_hidden_menu_popup_about_to_show() -> void: + var layout := _get_layout().clone() + _hidden_menu_popup.clear() + _hidden_menu_list = layout.get_names() + for i in _hidden_menu_list.size(): + var tab_name := _hidden_menu_list[i] + _hidden_menu_popup.add_check_item(tab_name, i) + _hidden_menu_popup.set_item_checked(i, not layout.is_tab_hidden(tab_name)) + + +func _on_hidden_menu_popup_id_pressed(id: int) -> void: + var layout := _get_layout().clone() + var tab_name := _hidden_menu_list[id] + var new_hidden := not layout.is_tab_hidden(tab_name) + _get_layout().set_tab_hidden(tab_name, new_hidden) + _hidden_menu_popup.set_item_checked(id, not new_hidden) + emit_changed(get_edited_property(), _get_layout()) # This line may not be needed diff --git a/addons/dockable_container/inspector_plugin/layout_editor_property.gd.uid b/addons/dockable_container/inspector_plugin/layout_editor_property.gd.uid new file mode 100644 index 00000000..56aa173f --- /dev/null +++ b/addons/dockable_container/inspector_plugin/layout_editor_property.gd.uid @@ -0,0 +1 @@ +uid://b10vbk0p47buq diff --git a/addons/dockable_container/layout.gd b/addons/dockable_container/layout.gd new file mode 100644 index 00000000..b02df10f --- /dev/null +++ b/addons/dockable_container/layout.gd @@ -0,0 +1,260 @@ +@tool +class_name DockableLayout +extends Resource +## DockableLayout Resource definition, holding the root DockableLayoutNode and hidden tabs. +## +## DockableLayoutSplit are binary trees with nested DockableLayoutSplit subtrees +## and DockableLayoutPanel leaves. Both of them inherit from DockableLayoutNode to help with +## type annotation and define common functionality. +## +## Hidden tabs are marked in the `hidden_tabs` Dictionary by name. + +enum { MARGIN_LEFT, MARGIN_RIGHT, MARGIN_TOP, MARGIN_BOTTOM, MARGIN_CENTER } + +@export var root: DockableLayoutNode = DockableLayoutPanel.new(): + get: + return _root + set(value): + set_root(value) +@export var hidden_tabs := {}: + get: + return _hidden_tabs + set(value): + if value != _hidden_tabs: + _hidden_tabs = value + changed.emit() +## A [Dictionary] of [StringName] and [Dictionary], containing data such as position and size. +@export var windows := {}: + get: + return _windows + set(value): + if value != _windows: + _windows = value + changed.emit() + +var _changed_signal_queued := false +var _first_leaf: DockableLayoutPanel +var _hidden_tabs: Dictionary +var _windows: Dictionary +var _leaf_by_node_name: Dictionary +var _root: DockableLayoutNode = DockableLayoutPanel.new() + + +func _init() -> void: + resource_name = "Layout" + + +func set_root(value: DockableLayoutNode, should_emit_changed := true) -> void: + if not value: + value = DockableLayoutPanel.new() + if _root == value: + return + if _root and _root.changed.is_connected(_on_root_changed): + _root.changed.disconnect(_on_root_changed) + _root = value + _root.parent = null + _root.changed.connect(_on_root_changed) + if should_emit_changed: + _on_root_changed() + + +func get_root() -> DockableLayoutNode: + return _root + + +func clone() -> DockableLayout: + return duplicate(true) + + +func get_names() -> PackedStringArray: + return _root.get_names() + + +## Add missing nodes on first leaf and remove nodes outside indices from leaves. +## +## _leaf_by_node_name = { +## (string keys) = respective Leaf that holds the node name, +## } +func update_nodes(names: PackedStringArray) -> void: + _leaf_by_node_name.clear() + _first_leaf = null + var empty_leaves: Array[DockableLayoutPanel] = [] + _ensure_names_in_node(_root, names, empty_leaves) # Changes _leaf_by_node_name and empty_leaves + for l in empty_leaves: + _remove_leaf(l) + if not _first_leaf: + _first_leaf = DockableLayoutPanel.new() + set_root(_first_leaf) + for n in names: + if not _leaf_by_node_name.has(n): + _first_leaf.push_name(n) + _leaf_by_node_name[n] = _first_leaf + _on_root_changed() + + +func move_node_to_leaf(node: Node, leaf: DockableLayoutPanel, relative_position: int) -> void: + var node_name := node.name + var previous_leaf: DockableLayoutPanel = _leaf_by_node_name.get(node_name) + if previous_leaf: + previous_leaf.remove_node(node) + if previous_leaf.is_empty(): + _remove_leaf(previous_leaf) + + leaf.insert_node(relative_position, node) + _leaf_by_node_name[node_name] = leaf + _on_root_changed() + + +func get_leaf_for_node(node: Node) -> DockableLayoutPanel: + return _leaf_by_node_name.get(node.name) + + +func split_leaf_with_node(leaf: DockableLayoutPanel, node: Node, margin: int) -> void: + var root_branch := leaf.parent + var new_leaf := DockableLayoutPanel.new() + var new_branch := DockableLayoutSplit.new() + if margin == MARGIN_LEFT or margin == MARGIN_RIGHT: + new_branch.direction = DockableLayoutSplit.Direction.HORIZONTAL + else: + new_branch.direction = DockableLayoutSplit.Direction.VERTICAL + if margin == MARGIN_LEFT or margin == MARGIN_TOP: + new_branch.first = new_leaf + new_branch.second = leaf + else: + new_branch.first = leaf + new_branch.second = new_leaf + if _root == leaf: + set_root(new_branch, false) + elif root_branch: + if leaf == root_branch.first: + root_branch.first = new_branch + else: + root_branch.second = new_branch + + move_node_to_leaf(node, new_leaf, 0) + + +func add_node(node: Node) -> void: + var node_name := node.name + if _leaf_by_node_name.has(node_name): + return + _first_leaf.push_name(node_name) + _leaf_by_node_name[node_name] = _first_leaf + _on_root_changed() + + +func remove_node(node: Node) -> void: + var node_name := node.name + var leaf: DockableLayoutPanel = _leaf_by_node_name.get(node_name) + if not leaf: + return + leaf.remove_node(node) + _leaf_by_node_name.erase(node_name) + if leaf.is_empty(): + _remove_leaf(leaf) + _on_root_changed() + + +func rename_node(previous_name: String, new_name: String) -> void: + var leaf: DockableLayoutPanel = _leaf_by_node_name.get(previous_name) + if not leaf: + return + leaf.rename_node(previous_name, new_name) + _leaf_by_node_name.erase(previous_name) + _leaf_by_node_name[new_name] = leaf + _on_root_changed() + + +func set_tab_hidden(name: String, hidden: bool) -> void: + if not _leaf_by_node_name.has(name): + return + if hidden: + _hidden_tabs[name] = true + else: + _hidden_tabs.erase(name) + _on_root_changed() + + +func save_window_properties(window_name: StringName, data: Dictionary) -> void: + var new_windows = windows.duplicate(true) + if data.is_empty(): + new_windows.erase(window_name) + else: + new_windows[window_name] = data + windows = new_windows + + +func is_tab_hidden(name: String) -> bool: + return _hidden_tabs.get(name, false) + + +func set_node_hidden(node: Node, hidden: bool) -> void: + set_tab_hidden(node.name, hidden) + + +func is_node_hidden(node: Node) -> bool: + return is_tab_hidden(node.name) + + +func _on_root_changed() -> void: + if _changed_signal_queued: + return + _changed_signal_queued = true + set_deferred("_changed_signal_queued", false) + emit_changed.call_deferred() + + +func _ensure_names_in_node( + node: DockableLayoutNode, names: PackedStringArray, empty_leaves: Array[DockableLayoutPanel] +) -> void: + if node is DockableLayoutPanel: + node.update_nodes(names, _leaf_by_node_name) # This changes _leaf_by_node_name + if node.is_empty(): + empty_leaves.append(node) + if not _first_leaf: + _first_leaf = node + elif node is DockableLayoutSplit: + _ensure_names_in_node(node.first, names, empty_leaves) + _ensure_names_in_node(node.second, names, empty_leaves) + else: + assert(false, "Invalid Resource, should be branch or leaf, found %s" % node) + + +func _remove_leaf(leaf: DockableLayoutPanel) -> void: + assert(leaf.is_empty(), "FIXME: trying to remove_at a leaf with nodes") + if _root == leaf: + return + var collapsed_branch := leaf.parent + assert(collapsed_branch is DockableLayoutSplit, "FIXME: leaf is not a child of branch") + var kept_branch: DockableLayoutNode = ( + collapsed_branch.first if leaf == collapsed_branch.second else collapsed_branch.second + ) + var root_branch := collapsed_branch.parent #HERE + if collapsed_branch == _root: + set_root(kept_branch, true) + elif root_branch: + if collapsed_branch == root_branch.first: + root_branch.first = kept_branch + else: + root_branch.second = kept_branch + + +func _print_tree() -> void: + print("TREE") + _print_tree_step(_root, 0, 0) + print("") + + +func _print_tree_step(tree_or_leaf: DockableLayoutNode, level: int, idx: int) -> void: + if tree_or_leaf is DockableLayoutPanel: + print(" |".repeat(level), "- (%d) = " % idx, tree_or_leaf.names) + elif tree_or_leaf is DockableLayoutSplit: + print( + " |".repeat(level), + "-+ (%d) = " % idx, + tree_or_leaf.direction, + " ", + tree_or_leaf.percent + ) + _print_tree_step(tree_or_leaf.first, level + 1, 1) + _print_tree_step(tree_or_leaf.second, level + 1, 2) diff --git a/addons/dockable_container/layout.gd.uid b/addons/dockable_container/layout.gd.uid new file mode 100644 index 00000000..43f1ab21 --- /dev/null +++ b/addons/dockable_container/layout.gd.uid @@ -0,0 +1 @@ +uid://cylirj261q6ru diff --git a/addons/dockable_container/layout_node.gd b/addons/dockable_container/layout_node.gd new file mode 100644 index 00000000..ba3accb4 --- /dev/null +++ b/addons/dockable_container/layout_node.gd @@ -0,0 +1,29 @@ +@tool +class_name DockableLayoutNode +extends Resource +## Base class for DockableLayout tree nodes + +var parent: DockableLayoutSplit: + get: + return _parent_ref.get_ref() + set(value): + _parent_ref = weakref(value) + +var _parent_ref := WeakRef.new() + + +func emit_tree_changed() -> void: + var node := self + while node: + node.emit_changed() + node = node.parent + + +## Returns whether there are any nodes +func is_empty() -> bool: + return true + + +## Returns all tab names in this node +func get_names() -> PackedStringArray: + return PackedStringArray() diff --git a/addons/dockable_container/layout_node.gd.uid b/addons/dockable_container/layout_node.gd.uid new file mode 100644 index 00000000..1d581b5d --- /dev/null +++ b/addons/dockable_container/layout_node.gd.uid @@ -0,0 +1 @@ +uid://v07flmpq7k2r diff --git a/addons/dockable_container/layout_panel.gd b/addons/dockable_container/layout_panel.gd new file mode 100644 index 00000000..e15201b1 --- /dev/null +++ b/addons/dockable_container/layout_panel.gd @@ -0,0 +1,89 @@ +@tool +class_name DockableLayoutPanel +extends DockableLayoutNode +## DockableLayout leaf nodes, defining tabs + +@export var names: PackedStringArray: + get: + return get_names() + set(value): + _names = value + emit_tree_changed() +@export var current_tab: int: + get: + return int(clamp(_current_tab, 0, _names.size() - 1)) + set(value): + if value != _current_tab: + _current_tab = value + emit_tree_changed() + +var _names := PackedStringArray() +var _current_tab := 0 + + +func _init() -> void: + resource_name = "Tabs" + + +## Returns all tab names in this node +func get_names() -> PackedStringArray: + return _names + + +func push_name(name: String) -> void: + _names.append(name) + emit_tree_changed() + + +func insert_node(position: int, node: Node) -> void: + _names.insert(position, node.name) + emit_tree_changed() + + +func find_name(node_name: String) -> int: + for i in _names.size(): + if _names[i] == node_name: + return i + return -1 + + +func find_child(node: Node) -> int: + return find_name(node.name) + + +func remove_node(node: Node) -> void: + var i := find_child(node) + if i >= 0: + _names.remove_at(i) + emit_tree_changed() + else: + push_warning("Remove failed, node '%s' was not found" % node) + + +func rename_node(previous_name: String, new_name: String) -> void: + var i := find_name(previous_name) + if i >= 0: + _names.set(i, new_name) + emit_tree_changed() + else: + push_warning("Rename failed, name '%s' was not found" % previous_name) + + +## Returns whether there are any nodes +func is_empty() -> bool: + return _names.is_empty() + + +func update_nodes(node_names: PackedStringArray, data: Dictionary) -> void: + var i := 0 + var removed_any := false + while i < _names.size(): + var current := _names[i] + if not current in node_names or data.has(current): + _names.remove_at(i) + removed_any = true + else: + data[current] = self + i += 1 + if removed_any: + emit_tree_changed() diff --git a/addons/dockable_container/layout_panel.gd.uid b/addons/dockable_container/layout_panel.gd.uid new file mode 100644 index 00000000..1edb035a --- /dev/null +++ b/addons/dockable_container/layout_panel.gd.uid @@ -0,0 +1 @@ +uid://bh202gagkdkar diff --git a/addons/dockable_container/layout_split.gd b/addons/dockable_container/layout_split.gd new file mode 100644 index 00000000..45f1f78b --- /dev/null +++ b/addons/dockable_container/layout_split.gd @@ -0,0 +1,111 @@ +@tool +class_name DockableLayoutSplit +extends DockableLayoutNode +## DockableLayout binary tree nodes, defining subtrees and leaf panels + +enum Direction { HORIZONTAL, VERTICAL } + +@export var direction := Direction.HORIZONTAL: + get: + return get_direction() + set(value): + set_direction(value) +@export_range(0, 1) var percent := 0.5: + get = get_percent, + set = set_percent +@export var first: DockableLayoutNode = DockableLayoutPanel.new(): + get: + return get_first() + set(value): + set_first(value) +@export var second: DockableLayoutNode = DockableLayoutPanel.new(): + get: + return get_second() + set(value): + set_second(value) + +var _direction := Direction.HORIZONTAL +var _percent := 0.5 +var _first: DockableLayoutNode +var _second: DockableLayoutNode + + +func _init() -> void: + resource_name = "Split" + + +func set_first(value: DockableLayoutNode) -> void: + if value == null: + _first = DockableLayoutPanel.new() + else: + _first = value + _first.parent = self + emit_tree_changed() + + +func get_first() -> DockableLayoutNode: + return _first + + +func set_second(value: DockableLayoutNode) -> void: + if value == null: + _second = DockableLayoutPanel.new() + else: + _second = value + emit_tree_changed() + _second.parent = self + + +func get_second() -> DockableLayoutNode: + return _second + + +func set_direction(value: Direction) -> void: + if value != _direction: + _direction = value + emit_tree_changed() + + +func get_direction() -> Direction: + return _direction + + +func set_percent(value: float) -> void: + var clamped_value := clampf(value, 0, 1) + if not is_equal_approx(_percent, clamped_value): + _percent = clamped_value + emit_tree_changed() + + +func get_percent() -> float: + return _percent + + +func get_names() -> PackedStringArray: + var names := _first.get_names() + names.append_array(_second.get_names()) + return names + + +## Returns whether there are any nodes +func is_empty() -> bool: + return _first.is_empty() and _second.is_empty() + + +func is_horizontal() -> bool: + return _direction == Direction.HORIZONTAL + + +func is_vertical() -> bool: + return _direction == Direction.VERTICAL + + +func _is_draggable() -> bool: + for dl: DockableLayoutNode in [first, second]: + if dl is not DockableLayoutPanel: + continue + + for name in dl.get_names(): + if name.begins_with("_"): + return false + return true diff --git a/addons/dockable_container/layout_split.gd.uid b/addons/dockable_container/layout_split.gd.uid new file mode 100644 index 00000000..3b8363b3 --- /dev/null +++ b/addons/dockable_container/layout_split.gd.uid @@ -0,0 +1 @@ +uid://dos02hjhrf1ws diff --git a/addons/dockable_container/plugin.cfg b/addons/dockable_container/plugin.cfg new file mode 100644 index 00000000..b3595919 --- /dev/null +++ b/addons/dockable_container/plugin.cfg @@ -0,0 +1,13 @@ +[plugin] + +name="Dockable Container" +description="Container script that manages docking/tiling UI panels. + +Panels are composed of tabs that can be dragged around and dropped to split another panel or compose its tabs. + +Layout information is stored in Resource objects, so they can be saved/loaded from disk easily. + +This plugin also offers a replica of the Container layout to be edited directly in the inspector." +author="gilzoide" +version="1.1.2" +script="plugin.gd" diff --git a/addons/dockable_container/plugin.gd b/addons/dockable_container/plugin.gd new file mode 100644 index 00000000..e93e0101 --- /dev/null +++ b/addons/dockable_container/plugin.gd @@ -0,0 +1,19 @@ +@tool +extends EditorPlugin + +const LayoutInspectorPlugin := preload("inspector_plugin/editor_inspector_plugin.gd") +const Icon := preload("icon.svg") + +var _layout_inspector_plugin: LayoutInspectorPlugin + + +func _enter_tree() -> void: + _layout_inspector_plugin = LayoutInspectorPlugin.new() + add_custom_type("DockableContainer", "Container", DockableContainer, Icon) + add_inspector_plugin(_layout_inspector_plugin) + + +func _exit_tree() -> void: + remove_inspector_plugin(_layout_inspector_plugin) + remove_custom_type("DockableContainer") + _layout_inspector_plugin = null diff --git a/addons/dockable_container/plugin.gd.uid b/addons/dockable_container/plugin.gd.uid new file mode 100644 index 00000000..ca216da1 --- /dev/null +++ b/addons/dockable_container/plugin.gd.uid @@ -0,0 +1 @@ +uid://cfkem7gta5wke diff --git a/addons/dockable_container/samples/TestScene.gd b/addons/dockable_container/samples/TestScene.gd new file mode 100644 index 00000000..f94ac972 --- /dev/null +++ b/addons/dockable_container/samples/TestScene.gd @@ -0,0 +1,63 @@ +extends VBoxContainer + +const SAVED_LAYOUT_PATH := "user://layout.tres" + +@onready var _container := $DockableContainers/DockableContainer as DockableContainer +@onready var _clone_control := $HBoxContainer/ControlPrefab as ColorRect +@onready var _checkbox_container := $HBoxContainer as HBoxContainer + + +func _ready() -> void: + if not OS.is_userfs_persistent(): + $HBoxContainer/SaveLayoutButton.visible = false + $HBoxContainer/LoadLayoutButton.visible = false + + var tabs := _container.get_tabs() + for i in tabs.size(): + var checkbox := CheckBox.new() + checkbox.text = str(i) + checkbox.button_pressed = not _container.is_control_hidden(tabs[i]) + checkbox.toggled.connect(_on_CheckButton_toggled.bind(tabs[i])) + _checkbox_container.add_child(checkbox) + + +func _on_add_pressed() -> void: + var control := _clone_control.duplicate() + control.get_node("Buttons/Rename").pressed.connect( + _on_control_rename_button_pressed.bind(control) + ) + control.get_node("Buttons/Remove").pressed.connect( + _on_control_remove_button_pressed.bind(control) + ) + control.color = Color(randf(), randf(), randf()) + control.name = "Control0" + + _container.add_child(control, true) + await _container.sort_children + _container.set_control_as_current_tab(control) + + +func _on_save_pressed() -> void: + if ResourceSaver.save(_container.layout, SAVED_LAYOUT_PATH) != OK: + print("ERROR") + + +func _on_load_pressed() -> void: + var res = load(SAVED_LAYOUT_PATH) + if res: + _container.set_layout(res.clone()) + else: + print("Error") + + +func _on_control_rename_button_pressed(control: Control) -> void: + control.name = StringName(str(control.name) + " =D") + + +func _on_control_remove_button_pressed(control: Control) -> void: + control.get_parent().remove_child(control) + control.queue_free() + + +func _on_CheckButton_toggled(button_pressed: bool, tab: Control) -> void: + _container.set_control_hidden(tab, not button_pressed) diff --git a/addons/dockable_container/samples/TestScene.gd.uid b/addons/dockable_container/samples/TestScene.gd.uid new file mode 100644 index 00000000..a8525dc2 --- /dev/null +++ b/addons/dockable_container/samples/TestScene.gd.uid @@ -0,0 +1 @@ +uid://57n31bygo7cy diff --git a/addons/dockable_container/samples/TestScene.tscn b/addons/dockable_container/samples/TestScene.tscn new file mode 100644 index 00000000..311440da --- /dev/null +++ b/addons/dockable_container/samples/TestScene.tscn @@ -0,0 +1,181 @@ +[gd_scene load_steps=16 format=3 uid="uid://drlvhuchtk6if"] + +[ext_resource type="Script" path="res://addons/dockable_container/dockable_container.gd" id="1"] +[ext_resource type="Script" path="res://addons/dockable_container/layout.gd" id="2"] +[ext_resource type="Script" path="res://addons/dockable_container/samples/TestScene.gd" id="4"] +[ext_resource type="Script" path="res://addons/dockable_container/layout_split.gd" id="4_yhgfb"] +[ext_resource type="Script" path="res://addons/dockable_container/layout_panel.gd" id="5"] + +[sub_resource type="Resource" id="Resource_8aoc2"] +resource_name = "Tabs" +script = ExtResource("5") +names = PackedStringArray("Control0") +current_tab = 0 + +[sub_resource type="Resource" id="Resource_6kjom"] +resource_name = "Tabs" +script = ExtResource("5") +names = PackedStringArray("Control1", "Control2") +current_tab = 0 + +[sub_resource type="Resource" id="Resource_hl8y1"] +resource_name = "Split" +script = ExtResource("4_yhgfb") +direction = 1 +percent = 0.5 +first = SubResource("Resource_8aoc2") +second = SubResource("Resource_6kjom") + +[sub_resource type="Resource" id="Resource_ybwqe"] +resource_name = "Layout" +script = ExtResource("2") +root = SubResource("Resource_hl8y1") +hidden_tabs = {} +windows = {} +save_on_change = false + +[sub_resource type="Resource" id="Resource_ntwfj"] +resource_name = "Tabs" +script = ExtResource("5") +names = PackedStringArray("Control3") +current_tab = 0 + +[sub_resource type="Resource" id="Resource_dmyvf"] +resource_name = "Tabs" +script = ExtResource("5") +names = PackedStringArray("Control4") +current_tab = 0 + +[sub_resource type="Resource" id="Resource_vag66"] +resource_name = "Split" +script = ExtResource("4_yhgfb") +direction = 1 +percent = 0.281 +first = SubResource("Resource_ntwfj") +second = SubResource("Resource_dmyvf") + +[sub_resource type="Resource" id="Resource_4q660"] +resource_name = "Tabs" +script = ExtResource("5") +names = PackedStringArray("Control5") +current_tab = 0 + +[sub_resource type="Resource" id="Resource_jhibs"] +resource_name = "Split" +script = ExtResource("4_yhgfb") +direction = 0 +percent = 0.5 +first = SubResource("Resource_vag66") +second = SubResource("Resource_4q660") + +[sub_resource type="Resource" id="Resource_xhxpg"] +resource_name = "Layout" +script = ExtResource("2") +root = SubResource("Resource_jhibs") +hidden_tabs = {} +windows = {} +save_on_change = false + +[node name="SampleScene" type="VBoxContainer"] +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +script = ExtResource("4") + +[node name="HBoxContainer" type="HBoxContainer" parent="."] +layout_mode = 2 +alignment = 1 + +[node name="AddControlButton" type="Button" parent="HBoxContainer"] +layout_mode = 2 +size_flags_horizontal = 0 +size_flags_vertical = 4 +text = "(+) ADD CONTROL" + +[node name="SaveLayoutButton" type="Button" parent="HBoxContainer"] +layout_mode = 2 +size_flags_horizontal = 0 +size_flags_vertical = 4 +text = "Save Layout" + +[node name="LoadLayoutButton" type="Button" parent="HBoxContainer"] +layout_mode = 2 +size_flags_horizontal = 0 +size_flags_vertical = 4 +text = "Load Layout" + +[node name="ControlPrefab" type="ColorRect" parent="HBoxContainer"] +visible = false +layout_mode = 2 +color = Color(0.129412, 0.121569, 0.121569, 1) + +[node name="Buttons" type="VBoxContainer" parent="HBoxContainer/ControlPrefab"] +layout_mode = 0 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -65.5 +offset_top = -22.0 +offset_right = 65.5 +offset_bottom = 22.0 + +[node name="Rename" type="Button" parent="HBoxContainer/ControlPrefab/Buttons"] +layout_mode = 2 +text = "Rename" + +[node name="Remove" type="Button" parent="HBoxContainer/ControlPrefab/Buttons"] +layout_mode = 2 +text = "REMOVE" + +[node name="DockableContainers" type="HBoxContainer" parent="."] +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 3 + +[node name="DockableContainer" type="Container" parent="DockableContainers"] +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 3 +script = ExtResource("1") +layout = SubResource("Resource_ybwqe") + +[node name="Control0" type="ColorRect" parent="DockableContainers/DockableContainer"] +layout_mode = 2 + +[node name="Control1" type="ColorRect" parent="DockableContainers/DockableContainer"] +layout_mode = 2 +color = Color(0.141176, 0.0745098, 0.603922, 1) + +[node name="Control2" type="ColorRect" parent="DockableContainers/DockableContainer"] +visible = false +layout_mode = 2 +color = Color(0.533333, 0.380392, 0.380392, 1) + +[node name="Separator" type="ColorRect" parent="DockableContainers"] +custom_minimum_size = Vector2(50, 0) +layout_mode = 2 +color = Color(0, 0, 0, 1) + +[node name="DockableContainer2" type="Container" parent="DockableContainers"] +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 3 +script = ExtResource("1") +layout = SubResource("Resource_xhxpg") + +[node name="Control3" type="ColorRect" parent="DockableContainers/DockableContainer2"] +layout_mode = 2 +color = Color(0, 1, 0.905882, 1) + +[node name="Control4" type="ColorRect" parent="DockableContainers/DockableContainer2"] +layout_mode = 2 +color = Color(0, 0.698039, 0.0588235, 1) + +[node name="Control5" type="ColorRect" parent="DockableContainers/DockableContainer2"] +layout_mode = 2 +color = Color(1, 0.937255, 0, 1) + +[connection signal="pressed" from="HBoxContainer/AddControlButton" to="." method="_on_add_pressed"] +[connection signal="pressed" from="HBoxContainer/SaveLayoutButton" to="." method="_on_save_pressed"] +[connection signal="pressed" from="HBoxContainer/LoadLayoutButton" to="." method="_on_load_pressed"] diff --git a/addons/dockable_container/split_handle.gd b/addons/dockable_container/split_handle.gd new file mode 100644 index 00000000..2dfc6163 --- /dev/null +++ b/addons/dockable_container/split_handle.gd @@ -0,0 +1,127 @@ +@tool +extends Control + +const SPLIT_THEME_CLASS: PackedStringArray = [ + "HSplitContainer", # SPLIT_THEME_CLASS[DockableLayoutSplit.Direction.HORIZONTAL] + "VSplitContainer", # SPLIT_THEME_CLASS[DockableLayoutSplit.Direction.VERTICAL] +] + +const SPLIT_MOUSE_CURSOR_SHAPE: Array[Control.CursorShape] = [ + Control.CURSOR_HSPLIT, # SPLIT_MOUSE_CURSOR_SHAPE[DockableLayoutSplit.Direction.HORIZONTAL] + Control.CURSOR_VSPLIT, # SPLIT_MOUSE_CURSOR_SHAPE[DockableLayoutSplit.Direction.VERTICAL] +] + +var layout_split: DockableLayoutSplit +var first_minimum_size: Vector2 +var second_minimum_size: Vector2 + +var _parent_rect: Rect2 +var _mouse_hovering := false +var _dragging := false +var _draggable: bool: + get(): + return layout_split._is_draggable() + + +func _draw() -> void: + var theme_class := SPLIT_THEME_CLASS[layout_split.direction] + var icon := get_theme_icon("grabber", theme_class) + var autohide := bool(get_theme_constant("autohide", theme_class)) + if not icon or (autohide and not _mouse_hovering): + return + + draw_texture(icon, (size - icon.get_size()) * 0.5) + + +func _gui_input(event: InputEvent) -> void: + if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT and _draggable: + _dragging = event.is_pressed() + if event.double_click: + layout_split.percent = 0.5 + elif _dragging and event is InputEventMouseMotion and _draggable: + if not Input.is_mouse_button_pressed(MOUSE_BUTTON_LEFT): + _dragging = false + return + + var mouse_in_parent := get_parent_control().get_local_mouse_position() + if layout_split.is_horizontal(): + layout_split.percent = ( + (mouse_in_parent.x - _parent_rect.position.x) / _parent_rect.size.x + ) + else: + layout_split.percent = ( + (mouse_in_parent.y - _parent_rect.position.y) / _parent_rect.size.y + ) + + +func _notification(what: int) -> void: + if what == NOTIFICATION_MOUSE_ENTER: + _mouse_hovering = true + set_split_cursor(true) + if bool(get_theme_constant("autohide", SPLIT_THEME_CLASS[layout_split.direction])): + queue_redraw() + elif what == NOTIFICATION_MOUSE_EXIT: + _mouse_hovering = false + set_split_cursor(false) + if bool(get_theme_constant("autohide", SPLIT_THEME_CLASS[layout_split.direction])): + queue_redraw() + elif what == NOTIFICATION_FOCUS_EXIT: + _dragging = false + + +func get_layout_minimum_size() -> Vector2: + if not layout_split: + return Vector2.ZERO + var separation := get_theme_constant("separation", SPLIT_THEME_CLASS[layout_split.direction]) + if layout_split.is_horizontal(): + return Vector2( + first_minimum_size.x + separation + second_minimum_size.x, + maxf(first_minimum_size.y, second_minimum_size.y) + ) + else: + return Vector2( + maxf(first_minimum_size.x, second_minimum_size.x), + first_minimum_size.y + separation + second_minimum_size.y + ) + + +func set_split_cursor(value: bool) -> void: + if value and _draggable: + mouse_default_cursor_shape = SPLIT_MOUSE_CURSOR_SHAPE[layout_split.direction] + else: + mouse_default_cursor_shape = CURSOR_ARROW + + +func get_split_rects(rect: Rect2) -> Dictionary: + _parent_rect = rect + var separation := get_theme_constant("separation", SPLIT_THEME_CLASS[layout_split.direction]) + var origin := rect.position + var percent := layout_split.percent + if layout_split.is_horizontal(): + var split_offset := clampf( + rect.size.x * percent - separation * 0.5, + first_minimum_size.x, + rect.size.x - second_minimum_size.x - separation + ) + var second_width := rect.size.x - split_offset - separation + + return { + "first": Rect2(origin.x, origin.y, split_offset, rect.size.y), + "self": Rect2(origin.x + split_offset, origin.y, separation, rect.size.y), + "second": + Rect2(origin.x + split_offset + separation, origin.y, second_width, rect.size.y), + } + else: + var split_offset := clampf( + rect.size.y * percent - separation * 0.5, + first_minimum_size.y, + rect.size.y - second_minimum_size.y - separation + ) + var second_height := rect.size.y - split_offset - separation + + return { + "first": Rect2(origin.x, origin.y, rect.size.x, split_offset), + "self": Rect2(origin.x, origin.y + split_offset, rect.size.x, separation), + "second": + Rect2(origin.x, origin.y + split_offset + separation, rect.size.x, second_height), + } diff --git a/addons/dockable_container/split_handle.gd.uid b/addons/dockable_container/split_handle.gd.uid new file mode 100644 index 00000000..3bd28a98 --- /dev/null +++ b/addons/dockable_container/split_handle.gd.uid @@ -0,0 +1 @@ +uid://c3g628ohy6cus diff --git a/addons/gdUnit4/GdUnitRunner.cfg b/addons/gdUnit4/GdUnitRunner.cfg deleted file mode 100644 index b2caafaf..00000000 --- a/addons/gdUnit4/GdUnitRunner.cfg +++ /dev/null @@ -1,1060 +0,0 @@ -{ - "server_port": 31002, - "tests": [ - { - "@path": "res://addons/gdUnit4/src/core/discovery/GdUnitTestCase.gd", - "@subpath": "", - "assembly_location": "", - "attribute_index": -1, - "display_name": "test_from_dict", - "fully_qualified_name": "unit.test_action_node.test_from_dict", - "guid": "8b3a8d57-f923462-2be70e5-92fbd40cd2", - "line_number": 17, - "metadata": { - - }, - "require_godot_runtime": true, - "source_file": "res://unit/test_action_node.gd", - "suite_name": "test_action_node", - "test_name": "test_from_dict" - }, - { - "@path": "res://addons/gdUnit4/src/core/discovery/GdUnitTestCase.gd", - "@subpath": "", - "assembly_location": "", - "attribute_index": -1, - "display_name": "test_arguments_to_dict", - "fully_qualified_name": "unit.test_action_node.test_arguments_to_dict", - "guid": "4f7bdc24-4edf40f-e82ee0e-bdfda0cb23", - "line_number": 36, - "metadata": { - - }, - "require_godot_runtime": true, - "source_file": "res://unit/test_action_node.gd", - "suite_name": "test_action_node", - "test_name": "test_arguments_to_dict" - }, - { - "@path": "res://addons/gdUnit4/src/core/discovery/GdUnitTestCase.gd", - "@subpath": "", - "assembly_location": "", - "attribute_index": -1, - "display_name": "test_add_option", - "fully_qualified_name": "unit.test_choice_node.test_add_option", - "guid": "d68db92d-45f14f0-8bde5f8-d5183d84f9", - "line_number": 28, - "metadata": { - - }, - "require_godot_runtime": true, - "source_file": "res://unit/test_choice_node.gd", - "suite_name": "test_choice_node", - "test_name": "test_add_option" - }, - { - "@path": "res://addons/gdUnit4/src/core/discovery/GdUnitTestCase.gd", - "@subpath": "", - "assembly_location": "", - "attribute_index": -1, - "display_name": "test_to_fields", - "fully_qualified_name": "unit.test_choice_node.test_to_fields", - "guid": "091d9df9-b72849c-08391cd-1706aebafc", - "line_number": 50, - "metadata": { - - }, - "require_godot_runtime": true, - "source_file": "res://unit/test_choice_node.gd", - "suite_name": "test_choice_node", - "test_name": "test_to_fields" - }, - { - "@path": "res://addons/gdUnit4/src/core/discovery/GdUnitTestCase.gd", - "@subpath": "", - "assembly_location": "", - "attribute_index": -1, - "display_name": "test_language_integration", - "fully_qualified_name": "unit.test_choice_node.test_language_integration", - "guid": "27af2362-abfe447-fa035ff-b9634a8fbe", - "line_number": 62, - "metadata": { - - }, - "require_godot_runtime": true, - "source_file": "res://unit/test_choice_node.gd", - "suite_name": "test_choice_node", - "test_name": "test_language_integration" - }, - { - "@path": "res://addons/gdUnit4/src/core/discovery/GdUnitTestCase.gd", - "@subpath": "", - "assembly_location": "", - "attribute_index": -1, - "display_name": "test_restore_options", - "fully_qualified_name": "unit.test_choice_node.test_restore_options", - "guid": "a987c51b-b2c8494-58cfbcc-6d74538314", - "line_number": 102, - "metadata": { - - }, - "require_godot_runtime": true, - "source_file": "res://unit/test_choice_node.gd", - "suite_name": "test_choice_node", - "test_name": "test_restore_options" - }, - { - "@path": "res://addons/gdUnit4/src/core/discovery/GdUnitTestCase.gd", - "@subpath": "", - "assembly_location": "", - "attribute_index": -1, - "display_name": "test_update_parent", - "fully_qualified_name": "unit.test_choice_node.test_update_parent", - "guid": "3fd45d76-5b7e4dd-b99ae16-474e96f72d", - "line_number": 130, - "metadata": { - - }, - "require_godot_runtime": true, - "source_file": "res://unit/test_choice_node.gd", - "suite_name": "test_choice_node", - "test_name": "test_update_parent" - }, - { - "@path": "res://addons/gdUnit4/src/core/discovery/GdUnitTestCase.gd", - "@subpath": "", - "assembly_location": "", - "attribute_index": -1, - "display_name": "test_add_root", - "fully_qualified_name": "unit.test_graph_edit_switcher.test_add_root", - "guid": "179cd145-74104e6-d901e79-2e1c32869d", - "line_number": 15, - "metadata": { - - }, - "require_godot_runtime": true, - "source_file": "res://unit/test_graph_edit_switcher.gd", - "suite_name": "test_graph_edit_switcher", - "test_name": "test_add_root" - }, - { - "@path": "res://addons/gdUnit4/src/core/discovery/GdUnitTestCase.gd", - "@subpath": "", - "assembly_location": "", - "attribute_index": -1, - "display_name": "test_add_tab_first", - "fully_qualified_name": "unit.test_graph_edit_switcher.test_add_tab_first", - "guid": "4d6e51e7-6735474-9ae787f-1865f58e1a", - "line_number": 29, - "metadata": { - - }, - "require_godot_runtime": true, - "source_file": "res://unit/test_graph_edit_switcher.gd", - "suite_name": "test_graph_edit_switcher", - "test_name": "test_add_tab_first" - }, - { - "@path": "res://addons/gdUnit4/src/core/discovery/GdUnitTestCase.gd", - "@subpath": "", - "assembly_location": "", - "attribute_index": -1, - "display_name": "test_add_tab_with_previous", - "fully_qualified_name": "unit.test_graph_edit_switcher.test_add_tab_with_previous", - "guid": "927774e3-b0aa4bd-ab9f4f3-191e66193d", - "line_number": 35, - "metadata": { - - }, - "require_godot_runtime": true, - "source_file": "res://unit/test_graph_edit_switcher.gd", - "suite_name": "test_graph_edit_switcher", - "test_name": "test_add_tab_with_previous" - }, - { - "@path": "res://addons/gdUnit4/src/core/discovery/GdUnitTestCase.gd", - "@subpath": "", - "assembly_location": "", - "attribute_index": -1, - "display_name": "test_connect_side_panel", - "fully_qualified_name": "unit.test_graph_edit_switcher.test_connect_side_panel", - "guid": "53de68af-9cea454-4928262-9633a9fac5", - "line_number": 45, - "metadata": { - - }, - "require_godot_runtime": true, - "source_file": "res://unit/test_graph_edit_switcher.gd", - "suite_name": "test_graph_edit_switcher", - "test_name": "test_connect_side_panel" - }, - { - "@path": "res://addons/gdUnit4/src/core/discovery/GdUnitTestCase.gd", - "@subpath": "", - "assembly_location": "", - "attribute_index": -1, - "display_name": "test_commit_side_panel", - "fully_qualified_name": "unit.test_graph_edit_switcher.test_commit_side_panel", - "guid": "e5780596-18e5455-5838115-1e2246c817", - "line_number": 56, - "metadata": { - - }, - "require_godot_runtime": true, - "source_file": "res://unit/test_graph_edit_switcher.gd", - "suite_name": "test_graph_edit_switcher", - "test_name": "test_commit_side_panel" - }, - { - "@path": "res://addons/gdUnit4/src/core/discovery/GdUnitTestCase.gd", - "@subpath": "", - "assembly_location": "", - "attribute_index": -1, - "display_name": "test_get_current_graph_edit", - "fully_qualified_name": "unit.test_graph_edit_switcher.test_get_current_graph_edit", - "guid": "3d78084f-fa7f486-793e9d5-5bf1708199", - "line_number": 62, - "metadata": { - - }, - "require_godot_runtime": true, - "source_file": "res://unit/test_graph_edit_switcher.gd", - "suite_name": "test_graph_edit_switcher", - "test_name": "test_get_current_graph_edit" - }, - { - "@path": "res://addons/gdUnit4/src/core/discovery/GdUnitTestCase.gd", - "@subpath": "", - "assembly_location": "", - "attribute_index": -1, - "display_name": "test_is_file_opened_false", - "fully_qualified_name": "unit.test_graph_edit_switcher.test_is_file_opened_false", - "guid": "a1a8e4ff-2fed4cc-dabf680-90889f556b", - "line_number": 73, - "metadata": { - - }, - "require_godot_runtime": true, - "source_file": "res://unit/test_graph_edit_switcher.gd", - "suite_name": "test_graph_edit_switcher", - "test_name": "test_is_file_opened_false" - }, - { - "@path": "res://addons/gdUnit4/src/core/discovery/GdUnitTestCase.gd", - "@subpath": "", - "assembly_location": "", - "attribute_index": -1, - "display_name": "test_is_file_opened_true", - "fully_qualified_name": "unit.test_graph_edit_switcher.test_is_file_opened_true", - "guid": "11c8d58a-18c64a5-f83dd0a-adc73cd6b3", - "line_number": 77, - "metadata": { - - }, - "require_godot_runtime": true, - "source_file": "res://unit/test_graph_edit_switcher.gd", - "suite_name": "test_graph_edit_switcher", - "test_name": "test_is_file_opened_true" - }, - { - "@path": "res://addons/gdUnit4/src/core/discovery/GdUnitTestCase.gd", - "@subpath": "", - "assembly_location": "", - "attribute_index": -1, - "display_name": "test_new_graph_edit", - "fully_qualified_name": "unit.test_graph_edit_switcher.test_new_graph_edit", - "guid": "9e338c89-299c4ce-2809695-51fc5e117d", - "line_number": 84, - "metadata": { - - }, - "require_godot_runtime": true, - "source_file": "res://unit/test_graph_edit_switcher.gd", - "suite_name": "test_graph_edit_switcher", - "test_name": "test_new_graph_edit" - }, - { - "@path": "res://addons/gdUnit4/src/core/discovery/GdUnitTestCase.gd", - "@subpath": "", - "assembly_location": "", - "attribute_index": -1, - "display_name": "test_on_tab_close_pressed_saved", - "fully_qualified_name": "unit.test_graph_edit_switcher.test_on_tab_close_pressed_saved", - "guid": "0fe0c990-427a4b0-f9e5dcc-3ff12bfdc9", - "line_number": 93, - "metadata": { - - }, - "require_godot_runtime": true, - "source_file": "res://unit/test_graph_edit_switcher.gd", - "suite_name": "test_graph_edit_switcher", - "test_name": "test_on_tab_close_pressed_saved" - }, - { - "@path": "res://addons/gdUnit4/src/core/discovery/GdUnitTestCase.gd", - "@subpath": "", - "assembly_location": "", - "attribute_index": -1, - "display_name": "test_on_tab_close_pressed_unsaved", - "fully_qualified_name": "unit.test_graph_edit_switcher.test_on_tab_close_pressed_unsaved", - "guid": "0b07bd64-6b0d4d4-385c6ee-153ba92998", - "line_number": 102, - "metadata": { - - }, - "require_godot_runtime": true, - "source_file": "res://unit/test_graph_edit_switcher.gd", - "suite_name": "test_graph_edit_switcher", - "test_name": "test_on_tab_close_pressed_unsaved" - }, - { - "@path": "res://addons/gdUnit4/src/core/discovery/GdUnitTestCase.gd", - "@subpath": "", - "assembly_location": "", - "attribute_index": -1, - "display_name": "test_show_current_config", - "fully_qualified_name": "unit.test_graph_edit_switcher.test_show_current_config", - "guid": "92b08ef9-ac704f8-491345e-1c6221a481", - "line_number": 117, - "metadata": { - - }, - "require_godot_runtime": true, - "source_file": "res://unit/test_graph_edit_switcher.gd", - "suite_name": "test_graph_edit_switcher", - "test_name": "test_show_current_config" - }, - { - "@path": "res://addons/gdUnit4/src/core/discovery/GdUnitTestCase.gd", - "@subpath": "", - "assembly_location": "", - "attribute_index": -1, - "display_name": "test_update_save_state_saved", - "fully_qualified_name": "unit.test_graph_edit_switcher.test_update_save_state_saved", - "guid": "e7224d3f-6af64eb-5a28751-f66bef818c", - "line_number": 126, - "metadata": { - - }, - "require_godot_runtime": true, - "source_file": "res://unit/test_graph_edit_switcher.gd", - "suite_name": "test_graph_edit_switcher", - "test_name": "test_update_save_state_saved" - }, - { - "@path": "res://addons/gdUnit4/src/core/discovery/GdUnitTestCase.gd", - "@subpath": "", - "assembly_location": "", - "attribute_index": -1, - "display_name": "test_update_save_state_unsaved", - "fully_qualified_name": "unit.test_graph_edit_switcher.test_update_save_state_unsaved", - "guid": "638451a5-4f104ab-5ad66b0-74d936f397", - "line_number": 136, - "metadata": { - - }, - "require_godot_runtime": true, - "source_file": "res://unit/test_graph_edit_switcher.gd", - "suite_name": "test_graph_edit_switcher", - "test_name": "test_update_save_state_unsaved" - }, - { - "@path": "res://addons/gdUnit4/src/core/discovery/GdUnitTestCase.gd", - "@subpath": "", - "assembly_location": "", - "attribute_index": -1, - "display_name": "test_enable_picker_mode", - "fully_qualified_name": "unit.test_graph_node_picker.test_enable_picker_mode", - "guid": "47f84251-0be6447-2b42090-345eabfdb8", - "line_number": 4, - "metadata": { - - }, - "require_godot_runtime": true, - "source_file": "res://unit/test_graph_node_picker.gd", - "suite_name": "test_graph_node_picker", - "test_name": "test_enable_picker_mode" - }, - { - "@path": "res://addons/gdUnit4/src/core/discovery/GdUnitTestCase.gd", - "@subpath": "", - "assembly_location": "", - "attribute_index": -1, - "display_name": "test_enable_picker_mode_invalid_graph", - "fully_qualified_name": "unit.test_graph_node_picker.test_enable_picker_mode_invalid_graph", - "guid": "008f8541-9ff4415-9815729-0cf170ecd3", - "line_number": 27, - "metadata": { - - }, - "require_godot_runtime": true, - "source_file": "res://unit/test_graph_node_picker.gd", - "suite_name": "test_graph_node_picker", - "test_name": "test_enable_picker_mode_invalid_graph" - }, - { - "@path": "res://addons/gdUnit4/src/core/discovery/GdUnitTestCase.gd", - "@subpath": "", - "assembly_location": "", - "attribute_index": -1, - "display_name": "test_close", - "fully_qualified_name": "unit.test_graph_node_picker.test_close", - "guid": "cf67938e-d5cd4a3-b8694fd-2aa4d154f1", - "line_number": 37, - "metadata": { - - }, - "require_godot_runtime": true, - "source_file": "res://unit/test_graph_node_picker.gd", - "suite_name": "test_graph_node_picker", - "test_name": "test_close" - }, - { - "@path": "res://addons/gdUnit4/src/core/discovery/GdUnitTestCase.gd", - "@subpath": "", - "assembly_location": "", - "attribute_index": -1, - "display_name": "test_delete_language", - "fully_qualified_name": "unit.test_language_switcher.test_delete_language", - "guid": "cb0d9463-7253478-db8f6f7-832e5adb39", - "line_number": 13, - "metadata": { - - }, - "require_godot_runtime": true, - "source_file": "res://unit/test_language_switcher.gd", - "suite_name": "test_language_switcher", - "test_name": "test_delete_language" - }, - { - "@path": "res://addons/gdUnit4/src/core/discovery/GdUnitTestCase.gd", - "@subpath": "", - "assembly_location": "", - "attribute_index": -1, - "display_name": "test_delete_language_destroys_raw_data", - "fully_qualified_name": "unit.test_language_switcher.test_delete_language_destroys_raw_data", - "guid": "6d7cfb08-870e4aa-b8222aa-55377d0f6f", - "line_number": 24, - "metadata": { - - }, - "require_godot_runtime": true, - "source_file": "res://unit/test_language_switcher.gd", - "suite_name": "test_language_switcher", - "test_name": "test_delete_language_destroys_raw_data" - }, - { - "@path": "res://addons/gdUnit4/src/core/discovery/GdUnitTestCase.gd", - "@subpath": "", - "assembly_location": "", - "attribute_index": -1, - "display_name": "test_delete_language_undo_restores_data", - "fully_qualified_name": "unit.test_language_switcher.test_delete_language_undo_restores_data", - "guid": "5609cea3-f7c148a-bbe5f1a-bc4a4d3d38", - "line_number": 37, - "metadata": { - - }, - "require_godot_runtime": true, - "source_file": "res://unit/test_language_switcher.gd", - "suite_name": "test_language_switcher", - "test_name": "test_delete_language_undo_restores_data" - }, - { - "@path": "res://addons/gdUnit4/src/core/discovery/GdUnitTestCase.gd", - "@subpath": "", - "assembly_location": "", - "attribute_index": -1, - "display_name": "test_first_language_does_not_show_delete_button", - "fully_qualified_name": "unit.test_language_switcher.test_first_language_does_not_show_delete_button", - "guid": "eaf477a8-1762483-2931e83-12a56b0b70", - "line_number": 53, - "metadata": { - - }, - "require_godot_runtime": true, - "source_file": "res://unit/test_language_switcher.gd", - "suite_name": "test_language_switcher", - "test_name": "test_first_language_does_not_show_delete_button" - }, - { - "@path": "res://addons/gdUnit4/src/core/discovery/GdUnitTestCase.gd", - "@subpath": "", - "assembly_location": "", - "attribute_index": -1, - "display_name": "test_language_get_value_renamed", - "fully_qualified_name": "unit.test_language_switcher.test_language_get_value_renamed", - "guid": "33d52919-c6b84ae-c959c33-c83aa10e33", - "line_number": 63, - "metadata": { - - }, - "require_godot_runtime": true, - "source_file": "res://unit/test_language_switcher.gd", - "suite_name": "test_language_switcher", - "test_name": "test_language_get_value_renamed" - }, - { - "@path": "res://addons/gdUnit4/src/core/discovery/GdUnitTestCase.gd", - "@subpath": "", - "assembly_location": "", - "attribute_index": -1, - "display_name": "test_language_get_value_nonexist_after_switch", - "fully_qualified_name": "unit.test_language_switcher.test_language_get_value_nonexist_after_switch", - "guid": "7f24331f-17eb4bb-098e5b2-1b3c8e37ed", - "line_number": 72, - "metadata": { - - }, - "require_godot_runtime": true, - "source_file": "res://unit/test_language_switcher.gd", - "suite_name": "test_language_switcher", - "test_name": "test_language_get_value_nonexist_after_switch" - }, - { - "@path": "res://addons/gdUnit4/src/core/discovery/GdUnitTestCase.gd", - "@subpath": "", - "assembly_location": "", - "attribute_index": -1, - "display_name": "test_language_set_value_locale_dictionary", - "fully_qualified_name": "unit.test_language_switcher.test_language_set_value_locale_dictionary", - "guid": "33600f8a-29d94c0-2b849ac-b7a0eaa988", - "line_number": 81, - "metadata": { - - }, - "require_godot_runtime": true, - "source_file": "res://unit/test_language_switcher.gd", - "suite_name": "test_language_switcher", - "test_name": "test_language_set_value_locale_dictionary" - }, - { - "@path": "res://addons/gdUnit4/src/core/discovery/GdUnitTestCase.gd", - "@subpath": "", - "assembly_location": "", - "attribute_index": -1, - "display_name": "test_language_set_value_locale_dictionary_non_default", - "fully_qualified_name": "unit.test_language_switcher.test_language_set_value_locale_dictionary_non_default", - "guid": "14bc24e9-48b6468-5b306fe-2f10570ab9", - "line_number": 90, - "metadata": { - - }, - "require_godot_runtime": true, - "source_file": "res://unit/test_language_switcher.gd", - "suite_name": "test_language_switcher", - "test_name": "test_language_set_value_locale_dictionary_non_default" - }, - { - "@path": "res://addons/gdUnit4/src/core/discovery/GdUnitTestCase.gd", - "@subpath": "", - "assembly_location": "", - "attribute_index": -1, - "display_name": "test_language_set_value_string", - "fully_qualified_name": "unit.test_language_switcher.test_language_set_value_string", - "guid": "4b8f1e19-91e8463-7880654-b5e8091b9e", - "line_number": 98, - "metadata": { - - }, - "require_godot_runtime": true, - "source_file": "res://unit/test_language_switcher.gd", - "suite_name": "test_language_switcher", - "test_name": "test_language_set_value_string" - }, - { - "@path": "res://addons/gdUnit4/src/core/discovery/GdUnitTestCase.gd", - "@subpath": "", - "assembly_location": "", - "attribute_index": -1, - "display_name": "test_language_set_value_and_switch_locales", - "fully_qualified_name": "unit.test_language_switcher.test_language_set_value_and_switch_locales", - "guid": "931f554e-402b4bd-bb05c39-f39d9ca090", - "line_number": 104, - "metadata": { - - }, - "require_godot_runtime": true, - "source_file": "res://unit/test_language_switcher.gd", - "suite_name": "test_language_switcher", - "test_name": "test_language_set_value_and_switch_locales" - }, - { - "@path": "res://addons/gdUnit4/src/core/discovery/GdUnitTestCase.gd", - "@subpath": "", - "assembly_location": "", - "attribute_index": -1, - "display_name": "test_load_languages", - "fully_qualified_name": "unit.test_language_switcher.test_load_languages", - "guid": "2f5c634f-483e43d-0a7ed37-4bd8e75b9a", - "line_number": 124, - "metadata": { - - }, - "require_godot_runtime": true, - "source_file": "res://unit/test_language_switcher.gd", - "suite_name": "test_language_switcher", - "test_name": "test_load_languages" - }, - { - "@path": "res://addons/gdUnit4/src/core/discovery/GdUnitTestCase.gd", - "@subpath": "", - "assembly_location": "", - "attribute_index": -1, - "display_name": "test_load_languages_duplicate", - "fully_qualified_name": "unit.test_language_switcher.test_load_languages_duplicate", - "guid": "5b463b9b-9b3d4b9-592b40a-21442a6eb1", - "line_number": 132, - "metadata": { - - }, - "require_godot_runtime": true, - "source_file": "res://unit/test_language_switcher.gd", - "suite_name": "test_language_switcher", - "test_name": "test_load_languages_duplicate" - }, - { - "@path": "res://addons/gdUnit4/src/core/discovery/GdUnitTestCase.gd", - "@subpath": "", - "assembly_location": "", - "attribute_index": -1, - "display_name": "test_to_dict", - "fully_qualified_name": "unit.test_option_node.test_to_dict", - "guid": "76edd481-52fc4ce-4ade2ab-83a0c7e2b5", - "line_number": 4, - "metadata": { - - }, - "require_godot_runtime": true, - "source_file": "res://unit/test_option_node.gd", - "suite_name": "test_option_node", - "test_name": "test_to_dict" - }, - { - "@path": "res://addons/gdUnit4/src/core/discovery/GdUnitTestCase.gd", - "@subpath": "", - "assembly_location": "", - "attribute_index": -1, - "display_name": "test_from_dict_v2", - "fully_qualified_name": "unit.test_option_node.test_from_dict_v2", - "guid": "562978a7-dba945f-680a83f-6839cf6e2a", - "line_number": 20, - "metadata": { - - }, - "require_godot_runtime": true, - "source_file": "res://unit/test_option_node.gd", - "suite_name": "test_option_node", - "test_name": "test_from_dict_v2" - }, - { - "@path": "res://addons/gdUnit4/src/core/discovery/GdUnitTestCase.gd", - "@subpath": "", - "assembly_location": "", - "attribute_index": -1, - "display_name": "test_from_dict_v3", - "fully_qualified_name": "unit.test_option_node.test_from_dict_v3", - "guid": "fb9dc20c-84f4432-5920b31-d07ed25118", - "line_number": 40, - "metadata": { - - }, - "require_godot_runtime": true, - "source_file": "res://unit/test_option_node.gd", - "suite_name": "test_option_node", - "test_name": "test_from_dict_v3" - }, - { - "@path": "res://addons/gdUnit4/src/core/discovery/GdUnitTestCase.gd", - "@subpath": "", - "assembly_location": "", - "attribute_index": 0, - "display_name": "test_absolute_to_relative_linux:0 ('/home/mrsharpener/Pen/w/b/20/ac.mp3', 'w/b/20/ac.mp3')", - "fully_qualified_name": "unit.test_path.test_absolute_to_relative_linux.test_absolute_to_relative_linux:0 ('/home/mrsharpener/Pen/w/b/20/ac.mp3', 'w/b/20/ac.mp3')", - "guid": "392e4080-e447468-c84de6b-0ec208648b", - "line_number": 29, - "metadata": { - - }, - "require_godot_runtime": true, - "source_file": "res://unit/test_path.gd", - "suite_name": "test_path", - "test_name": "test_absolute_to_relative_linux" - }, - { - "@path": "res://addons/gdUnit4/src/core/discovery/GdUnitTestCase.gd", - "@subpath": "", - "assembly_location": "", - "attribute_index": 1, - "display_name": "test_absolute_to_relative_linux:1 ('/home/mrsharpener/Pen/1.txt', '1.txt')", - "fully_qualified_name": "unit.test_path.test_absolute_to_relative_linux.test_absolute_to_relative_linux:1 ('/home/mrsharpener/Pen/1.txt', '1.txt')", - "guid": "a3b19b01-b2a74d3-0b2875a-92e4609a26", - "line_number": 29, - "metadata": { - - }, - "require_godot_runtime": true, - "source_file": "res://unit/test_path.gd", - "suite_name": "test_path", - "test_name": "test_absolute_to_relative_linux" - }, - { - "@path": "res://addons/gdUnit4/src/core/discovery/GdUnitTestCase.gd", - "@subpath": "", - "assembly_location": "", - "attribute_index": 2, - "display_name": "test_absolute_to_relative_linux:2 ('/home/missyeraser/K/y.o.u', '../../missyeraser/K/y.o.u')", - "fully_qualified_name": "unit.test_path.test_absolute_to_relative_linux.test_absolute_to_relative_linux:2 ('/home/missyeraser/K/y.o.u', '../../missyeraser/K/y.o.u')", - "guid": "f639d195-2a6349b-18caa33-11b71fa0a0", - "line_number": 29, - "metadata": { - - }, - "require_godot_runtime": true, - "source_file": "res://unit/test_path.gd", - "suite_name": "test_path", - "test_name": "test_absolute_to_relative_linux" - }, - { - "@path": "res://addons/gdUnit4/src/core/discovery/GdUnitTestCase.gd", - "@subpath": "", - "assembly_location": "", - "attribute_index": 3, - "display_name": "test_absolute_to_relative_linux:3 ('/opt/x/1/bro', '/opt/x/1/bro')", - "fully_qualified_name": "unit.test_path.test_absolute_to_relative_linux.test_absolute_to_relative_linux:3 ('/opt/x/1/bro', '/opt/x/1/bro')", - "guid": "82e7695e-f29745c-48cefb6-41c107abe8", - "line_number": 29, - "metadata": { - - }, - "require_godot_runtime": true, - "source_file": "res://unit/test_path.gd", - "suite_name": "test_path", - "test_name": "test_absolute_to_relative_linux" - }, - { - "@path": "res://addons/gdUnit4/src/core/discovery/GdUnitTestCase.gd", - "@subpath": "", - "assembly_location": "", - "attribute_index": 0, - "display_name": "test_absolute_to_relative_windows:0 ('C:\\\\Users\\\\MrSharpener\\\\Pen\\\\w\\\\b\\\\20\\\\ac.mp3', 'w/b/20/ac.mp3')", - "fully_qualified_name": "unit.test_path.test_absolute_to_relative_windows.test_absolute_to_relative_windows:0 ('C:\\\\Users\\\\MrSharpener\\\\Pen\\\\w\\\\b\\\\20\\\\ac.mp3', 'w/b/20/ac.mp3')", - "guid": "aff013d2-f15a419-5a7089b-d6faaefd1b", - "line_number": 36, - "metadata": { - - }, - "require_godot_runtime": true, - "source_file": "res://unit/test_path.gd", - "suite_name": "test_path", - "test_name": "test_absolute_to_relative_windows" - }, - { - "@path": "res://addons/gdUnit4/src/core/discovery/GdUnitTestCase.gd", - "@subpath": "", - "assembly_location": "", - "attribute_index": 1, - "display_name": "test_absolute_to_relative_windows:1 ('C:\\\\Users\\\\MrSharpener\\\\Pen\\\\1.txt', '1.txt')", - "fully_qualified_name": "unit.test_path.test_absolute_to_relative_windows.test_absolute_to_relative_windows:1 ('C:\\\\Users\\\\MrSharpener\\\\Pen\\\\1.txt', '1.txt')", - "guid": "56ff097e-4f3747a-4af3a0b-e94e09acf4", - "line_number": 36, - "metadata": { - - }, - "require_godot_runtime": true, - "source_file": "res://unit/test_path.gd", - "suite_name": "test_path", - "test_name": "test_absolute_to_relative_windows" - }, - { - "@path": "res://addons/gdUnit4/src/core/discovery/GdUnitTestCase.gd", - "@subpath": "", - "assembly_location": "", - "attribute_index": 2, - "display_name": "test_absolute_to_relative_windows:2 ('C:\\\\Users\\\\MissyEraser\\\\K\\\\y.o.u', '../../MissyEraser/K/y.o.u')", - "fully_qualified_name": "unit.test_path.test_absolute_to_relative_windows.test_absolute_to_relative_windows:2 ('C:\\\\Users\\\\MissyEraser\\\\K\\\\y.o.u', '../../MissyEraser/K/y.o.u')", - "guid": "af373b44-44f5418-7acb838-0e1952e4f4", - "line_number": 36, - "metadata": { - - }, - "require_godot_runtime": true, - "source_file": "res://unit/test_path.gd", - "suite_name": "test_path", - "test_name": "test_absolute_to_relative_windows" - }, - { - "@path": "res://addons/gdUnit4/src/core/discovery/GdUnitTestCase.gd", - "@subpath": "", - "assembly_location": "", - "attribute_index": 3, - "display_name": "test_absolute_to_relative_windows:3 ('E:\\\\10. __World\\\\g1d a', 'E:\\\\10. __World\\\\g1d a')", - "fully_qualified_name": "unit.test_path.test_absolute_to_relative_windows.test_absolute_to_relative_windows:3 ('E:\\\\10. __World\\\\g1d a', 'E:\\\\10. __World\\\\g1d a')", - "guid": "c513260a-bdd84c2-8847b21-000cfe33e4", - "line_number": 36, - "metadata": { - - }, - "require_godot_runtime": true, - "source_file": "res://unit/test_path.gd", - "suite_name": "test_path", - "test_name": "test_absolute_to_relative_windows" - }, - { - "@path": "res://addons/gdUnit4/src/core/discovery/GdUnitTestCase.gd", - "@subpath": "", - "assembly_location": "", - "attribute_index": 0, - "display_name": "test_relative_to_absolute_linux:0 ('w/b/20/ac.mp3', '/home/mrsharpener/Pen/w/b/20/ac.mp3')", - "fully_qualified_name": "unit.test_path.test_relative_to_absolute_linux.test_relative_to_absolute_linux:0 ('w/b/20/ac.mp3', '/home/mrsharpener/Pen/w/b/20/ac.mp3')", - "guid": "0af2839a-497b4bb-6b4d2d5-559d969dfd", - "line_number": 45, - "metadata": { - - }, - "require_godot_runtime": true, - "source_file": "res://unit/test_path.gd", - "suite_name": "test_path", - "test_name": "test_relative_to_absolute_linux" - }, - { - "@path": "res://addons/gdUnit4/src/core/discovery/GdUnitTestCase.gd", - "@subpath": "", - "assembly_location": "", - "attribute_index": 1, - "display_name": "test_relative_to_absolute_linux:1 ('1.txt', '/home/mrsharpener/Pen/1.txt')", - "fully_qualified_name": "unit.test_path.test_relative_to_absolute_linux.test_relative_to_absolute_linux:1 ('1.txt', '/home/mrsharpener/Pen/1.txt')", - "guid": "33322afb-3bee47b-aa39375-2655ff8c36", - "line_number": 45, - "metadata": { - - }, - "require_godot_runtime": true, - "source_file": "res://unit/test_path.gd", - "suite_name": "test_path", - "test_name": "test_relative_to_absolute_linux" - }, - { - "@path": "res://addons/gdUnit4/src/core/discovery/GdUnitTestCase.gd", - "@subpath": "", - "assembly_location": "", - "attribute_index": 2, - "display_name": "test_relative_to_absolute_linux:2 ('../../missyeraser/K/y.o.u', '/home/missyeraser/K/y.o.u')", - "fully_qualified_name": "unit.test_path.test_relative_to_absolute_linux.test_relative_to_absolute_linux:2 ('../../missyeraser/K/y.o.u', '/home/missyeraser/K/y.o.u')", - "guid": "64d6e013-8ae9425-693a675-ff724a8564", - "line_number": 45, - "metadata": { - - }, - "require_godot_runtime": true, - "source_file": "res://unit/test_path.gd", - "suite_name": "test_path", - "test_name": "test_relative_to_absolute_linux" - }, - { - "@path": "res://addons/gdUnit4/src/core/discovery/GdUnitTestCase.gd", - "@subpath": "", - "assembly_location": "", - "attribute_index": 3, - "display_name": "test_relative_to_absolute_linux:3 ('/opt/x/1/bro', '/opt/x/1/bro')", - "fully_qualified_name": "unit.test_path.test_relative_to_absolute_linux.test_relative_to_absolute_linux:3 ('/opt/x/1/bro', '/opt/x/1/bro')", - "guid": "c6976c5f-7a944a9-dbc0515-14eaba95de", - "line_number": 45, - "metadata": { - - }, - "require_godot_runtime": true, - "source_file": "res://unit/test_path.gd", - "suite_name": "test_path", - "test_name": "test_relative_to_absolute_linux" - }, - { - "@path": "res://addons/gdUnit4/src/core/discovery/GdUnitTestCase.gd", - "@subpath": "", - "assembly_location": "", - "attribute_index": 0, - "display_name": "test_relative_to_absolute_windows:0 ('w/b/20/ac.mp3', 'C:/Users/MrSharpener/Pen/w/b/20/ac.mp3')", - "fully_qualified_name": "unit.test_path.test_relative_to_absolute_windows.test_relative_to_absolute_windows:0 ('w/b/20/ac.mp3', 'C:/Users/MrSharpener/Pen/w/b/20/ac.mp3')", - "guid": "c51d8e5d-4436449-aa3130b-485161d13f", - "line_number": 54, - "metadata": { - - }, - "require_godot_runtime": true, - "source_file": "res://unit/test_path.gd", - "suite_name": "test_path", - "test_name": "test_relative_to_absolute_windows" - }, - { - "@path": "res://addons/gdUnit4/src/core/discovery/GdUnitTestCase.gd", - "@subpath": "", - "assembly_location": "", - "attribute_index": 1, - "display_name": "test_relative_to_absolute_windows:1 ('1.txt', 'C:/Users/MrSharpener/Pen/1.txt')", - "fully_qualified_name": "unit.test_path.test_relative_to_absolute_windows.test_relative_to_absolute_windows:1 ('1.txt', 'C:/Users/MrSharpener/Pen/1.txt')", - "guid": "29bc0f6c-3514484-08e1b53-7b289515a7", - "line_number": 54, - "metadata": { - - }, - "require_godot_runtime": true, - "source_file": "res://unit/test_path.gd", - "suite_name": "test_path", - "test_name": "test_relative_to_absolute_windows" - }, - { - "@path": "res://addons/gdUnit4/src/core/discovery/GdUnitTestCase.gd", - "@subpath": "", - "assembly_location": "", - "attribute_index": 2, - "display_name": "test_relative_to_absolute_windows:2 ('../../MissyEraser/K/y.o.u', 'C:/Users/MissyEraser/K/y.o.u')", - "fully_qualified_name": "unit.test_path.test_relative_to_absolute_windows.test_relative_to_absolute_windows:2 ('../../MissyEraser/K/y.o.u', 'C:/Users/MissyEraser/K/y.o.u')", - "guid": "13f4983f-5047424-ea8054c-b0dde53a81", - "line_number": 54, - "metadata": { - - }, - "require_godot_runtime": true, - "source_file": "res://unit/test_path.gd", - "suite_name": "test_path", - "test_name": "test_relative_to_absolute_windows" - }, - { - "@path": "res://addons/gdUnit4/src/core/discovery/GdUnitTestCase.gd", - "@subpath": "", - "assembly_location": "", - "attribute_index": 3, - "display_name": "test_relative_to_absolute_windows:3 ('E:/10. __World/g1d a', 'E:/10. __World/g1d a')", - "fully_qualified_name": "unit.test_path.test_relative_to_absolute_windows.test_relative_to_absolute_windows:3 ('E:/10. __World/g1d a', 'E:/10. __World/g1d a')", - "guid": "5c2e662c-33ae461-180a014-56fb771303", - "line_number": 54, - "metadata": { - - }, - "require_godot_runtime": true, - "source_file": "res://unit/test_path.gd", - "suite_name": "test_path", - "test_name": "test_relative_to_absolute_windows" - }, - { - "@path": "res://addons/gdUnit4/src/core/discovery/GdUnitTestCase.gd", - "@subpath": "", - "assembly_location": "", - "attribute_index": -1, - "display_name": "test_add_from_empty", - "fully_qualified_name": "unit.test_recent_file_container.test_add_from_empty", - "guid": "a2ff69d6-c4184b3-48b4ce9-0c48b5b0b3", - "line_number": 16, - "metadata": { - - }, - "require_godot_runtime": true, - "source_file": "res://unit/test_recent_file_container.gd", - "suite_name": "test_recent_file_container", - "test_name": "test_add_from_empty" - }, - { - "@path": "res://addons/gdUnit4/src/core/discovery/GdUnitTestCase.gd", - "@subpath": "", - "assembly_location": "", - "attribute_index": -1, - "display_name": "test_add_override", - "fully_qualified_name": "unit.test_recent_file_container.test_add_override", - "guid": "e4eeea69-7e7043b-4a1a3bd-e1d9d2ceec", - "line_number": 22, - "metadata": { - - }, - "require_godot_runtime": true, - "source_file": "res://unit/test_recent_file_container.gd", - "suite_name": "test_recent_file_container", - "test_name": "test_add_override" - }, - { - "@path": "res://addons/gdUnit4/src/core/discovery/GdUnitTestCase.gd", - "@subpath": "", - "assembly_location": "", - "attribute_index": -1, - "display_name": "test_create_file", - "fully_qualified_name": "unit.test_recent_file_container.test_create_file", - "guid": "66b76b2f-1514457-19863c7-07ce2f667c", - "line_number": 34, - "metadata": { - - }, - "require_godot_runtime": true, - "source_file": "res://unit/test_recent_file_container.gd", - "suite_name": "test_recent_file_container", - "test_name": "test_create_file" - }, - { - "@path": "res://addons/gdUnit4/src/core/discovery/GdUnitTestCase.gd", - "@subpath": "", - "assembly_location": "", - "attribute_index": -1, - "display_name": "test_load_file_empty", - "fully_qualified_name": "unit.test_recent_file_container.test_load_file_empty", - "guid": "ff1a3d15-7aff44e-38fc6f9-a57397bdfb", - "line_number": 40, - "metadata": { - - }, - "require_godot_runtime": true, - "source_file": "res://unit/test_recent_file_container.gd", - "suite_name": "test_recent_file_container", - "test_name": "test_load_file_empty" - }, - { - "@path": "res://addons/gdUnit4/src/core/discovery/GdUnitTestCase.gd", - "@subpath": "", - "assembly_location": "", - "attribute_index": -1, - "display_name": "test_load_file_exclude_not_exist", - "fully_qualified_name": "unit.test_recent_file_container.test_load_file_exclude_not_exist", - "guid": "ee1a90e2-075e4d4-c8f9e94-27ec9bb350", - "line_number": 45, - "metadata": { - - }, - "require_godot_runtime": true, - "source_file": "res://unit/test_recent_file_container.gd", - "suite_name": "test_recent_file_container", - "test_name": "test_load_file_exclude_not_exist" - }, - { - "@path": "res://addons/gdUnit4/src/core/discovery/GdUnitTestCase.gd", - "@subpath": "", - "assembly_location": "", - "attribute_index": -1, - "display_name": "test_load_file_existing", - "fully_qualified_name": "unit.test_recent_file_container.test_load_file_existing", - "guid": "ed732e73-3f79405-2abdf63-9c5148005a", - "line_number": 57, - "metadata": { - - }, - "require_godot_runtime": true, - "source_file": "res://unit/test_recent_file_container.gd", - "suite_name": "test_recent_file_container", - "test_name": "test_load_file_existing" - }, - { - "@path": "res://addons/gdUnit4/src/core/discovery/GdUnitTestCase.gd", - "@subpath": "", - "assembly_location": "", - "attribute_index": -1, - "display_name": "test_backwards_compatibility", - "fully_qualified_name": "unit.test_sentence_node.test_backwards_compatibility", - "guid": "2e03e022-65954f3-989932f-d198ecced7", - "line_number": 4, - "metadata": { - - }, - "require_godot_runtime": true, - "source_file": "res://unit/test_sentence_node.gd", - "suite_name": "test_sentence_node", - "test_name": "test_backwards_compatibility" - } - ], - "version": "5.0" -} \ No newline at end of file diff --git a/addons/gdUnit4/bin/GdUnitCmdTool.gd.uid b/addons/gdUnit4/bin/GdUnitCmdTool.gd.uid index 94633f65..8a081abb 100644 --- a/addons/gdUnit4/bin/GdUnitCmdTool.gd.uid +++ b/addons/gdUnit4/bin/GdUnitCmdTool.gd.uid @@ -1 +1 @@ -uid://p88p3dkvm32r +uid://bj5p2b3mmvpv2 diff --git a/addons/gdUnit4/bin/GdUnitCopyLog.gd.uid b/addons/gdUnit4/bin/GdUnitCopyLog.gd.uid index 33c3e3f6..b2d5e762 100644 --- a/addons/gdUnit4/bin/GdUnitCopyLog.gd.uid +++ b/addons/gdUnit4/bin/GdUnitCopyLog.gd.uid @@ -1 +1 @@ -uid://qnmevknqtkcr +uid://du3e4ltm5exyw diff --git a/addons/gdUnit4/plugin.cfg b/addons/gdUnit4/plugin.cfg index 45d0af55..4b3cf178 100644 --- a/addons/gdUnit4/plugin.cfg +++ b/addons/gdUnit4/plugin.cfg @@ -3,5 +3,5 @@ name="gdUnit4" description="Unit Testing Framework for Godot Scripts" author="Mike Schulze" -version="5.0.0" +version="5.0.5" script="plugin.gd" diff --git a/addons/gdUnit4/plugin.gd b/addons/gdUnit4/plugin.gd index cefdc412..1a52ef3c 100644 --- a/addons/gdUnit4/plugin.gd +++ b/addons/gdUnit4/plugin.gd @@ -30,8 +30,10 @@ func _enter_tree() -> void: var control := add_control_to_bottom_panel(_gd_console, "gdUnitConsole") @warning_ignore("unsafe_method_access") await _gd_console.setup_update_notification(control) - if GdUnit4CSharpApiLoader.is_dotnet_supported(): + if GdUnit4CSharpApiLoader.is_api_loaded(): prints("GdUnit4Net version '%s' loaded." % GdUnit4CSharpApiLoader.version()) + else: + prints("No GdUnit4Net found.") # Connect to be notified for script changes to be able to discover new tests GdUnitTestDiscoverGuard.instance() @warning_ignore("return_value_discarded") diff --git a/addons/gdUnit4/plugin.gd.uid b/addons/gdUnit4/plugin.gd.uid index cf0dbb04..c83a8417 100644 --- a/addons/gdUnit4/plugin.gd.uid +++ b/addons/gdUnit4/plugin.gd.uid @@ -1 +1 @@ -uid://bjat85epf7ofm +uid://do7vudxbo4hhc diff --git a/addons/gdUnit4/src/Comparator.gd.uid b/addons/gdUnit4/src/Comparator.gd.uid index e941641d..66137723 100644 --- a/addons/gdUnit4/src/Comparator.gd.uid +++ b/addons/gdUnit4/src/Comparator.gd.uid @@ -1 +1 @@ -uid://cm41y6w7wthm4 +uid://fmchogf6bdf8 diff --git a/addons/gdUnit4/src/Fuzzers.gd.uid b/addons/gdUnit4/src/Fuzzers.gd.uid index c16cd4aa..f48b919c 100644 --- a/addons/gdUnit4/src/Fuzzers.gd.uid +++ b/addons/gdUnit4/src/Fuzzers.gd.uid @@ -1 +1 @@ -uid://p6pp3cntrnd +uid://dut2wofegoono diff --git a/addons/gdUnit4/src/GdUnitArrayAssert.gd.uid b/addons/gdUnit4/src/GdUnitArrayAssert.gd.uid index 532347e8..ab4f79db 100644 --- a/addons/gdUnit4/src/GdUnitArrayAssert.gd.uid +++ b/addons/gdUnit4/src/GdUnitArrayAssert.gd.uid @@ -1 +1 @@ -uid://cqcsax3mfwcio +uid://cffjqveit84v4 diff --git a/addons/gdUnit4/src/GdUnitAssert.gd.uid b/addons/gdUnit4/src/GdUnitAssert.gd.uid index 2d716408..ecde72d7 100644 --- a/addons/gdUnit4/src/GdUnitAssert.gd.uid +++ b/addons/gdUnit4/src/GdUnitAssert.gd.uid @@ -1 +1 @@ -uid://b2rci48lrkstq +uid://dichuec7mryel diff --git a/addons/gdUnit4/src/GdUnitAwaiter.gd.uid b/addons/gdUnit4/src/GdUnitAwaiter.gd.uid index 32ad46eb..42ce6ae7 100644 --- a/addons/gdUnit4/src/GdUnitAwaiter.gd.uid +++ b/addons/gdUnit4/src/GdUnitAwaiter.gd.uid @@ -1 +1 @@ -uid://dmw2wrfn6hq88 +uid://c0f57re4e7dk2 diff --git a/addons/gdUnit4/src/GdUnitBoolAssert.gd.uid b/addons/gdUnit4/src/GdUnitBoolAssert.gd.uid index e29a69d4..003f37ef 100644 --- a/addons/gdUnit4/src/GdUnitBoolAssert.gd.uid +++ b/addons/gdUnit4/src/GdUnitBoolAssert.gd.uid @@ -1 +1 @@ -uid://ba4be0xfbtnmf +uid://dquqkxy1o024t diff --git a/addons/gdUnit4/src/GdUnitConstants.gd.uid b/addons/gdUnit4/src/GdUnitConstants.gd.uid index 456b802b..60811fa4 100644 --- a/addons/gdUnit4/src/GdUnitConstants.gd.uid +++ b/addons/gdUnit4/src/GdUnitConstants.gd.uid @@ -1 +1 @@ -uid://dsfw4040i5wdo +uid://d066hnl6xhys diff --git a/addons/gdUnit4/src/GdUnitDictionaryAssert.gd.uid b/addons/gdUnit4/src/GdUnitDictionaryAssert.gd.uid index bfac4d80..742a07a0 100644 --- a/addons/gdUnit4/src/GdUnitDictionaryAssert.gd.uid +++ b/addons/gdUnit4/src/GdUnitDictionaryAssert.gd.uid @@ -1 +1 @@ -uid://difkcajov8fkg +uid://bq1gcsupvqo21 diff --git a/addons/gdUnit4/src/GdUnitFailureAssert.gd.uid b/addons/gdUnit4/src/GdUnitFailureAssert.gd.uid index 9d50f843..766bcf15 100644 --- a/addons/gdUnit4/src/GdUnitFailureAssert.gd.uid +++ b/addons/gdUnit4/src/GdUnitFailureAssert.gd.uid @@ -1 +1 @@ -uid://qtqlkea47sy2 +uid://c0ug13vv0w60v diff --git a/addons/gdUnit4/src/GdUnitFileAssert.gd.uid b/addons/gdUnit4/src/GdUnitFileAssert.gd.uid index 7ee6da68..5f5f9340 100644 --- a/addons/gdUnit4/src/GdUnitFileAssert.gd.uid +++ b/addons/gdUnit4/src/GdUnitFileAssert.gd.uid @@ -1 +1 @@ -uid://cpangqu3iagtj +uid://ccdvwlsp8gun0 diff --git a/addons/gdUnit4/src/GdUnitFloatAssert.gd.uid b/addons/gdUnit4/src/GdUnitFloatAssert.gd.uid index 9c3983d7..607523bf 100644 --- a/addons/gdUnit4/src/GdUnitFloatAssert.gd.uid +++ b/addons/gdUnit4/src/GdUnitFloatAssert.gd.uid @@ -1 +1 @@ -uid://cii6rn31jx3al +uid://bpmnnby4vuhk8 diff --git a/addons/gdUnit4/src/GdUnitFuncAssert.gd.uid b/addons/gdUnit4/src/GdUnitFuncAssert.gd.uid index 87e1e06b..6023a015 100644 --- a/addons/gdUnit4/src/GdUnitFuncAssert.gd.uid +++ b/addons/gdUnit4/src/GdUnitFuncAssert.gd.uid @@ -1 +1 @@ -uid://c5xibgs8ux5xy +uid://bkt4ihw5hsa5u diff --git a/addons/gdUnit4/src/GdUnitGodotErrorAssert.gd.uid b/addons/gdUnit4/src/GdUnitGodotErrorAssert.gd.uid index 7a59443c..b948b8d3 100644 --- a/addons/gdUnit4/src/GdUnitGodotErrorAssert.gd.uid +++ b/addons/gdUnit4/src/GdUnitGodotErrorAssert.gd.uid @@ -1 +1 @@ -uid://co2g8c7py1k3e +uid://dfqi0y7vrgj10 diff --git a/addons/gdUnit4/src/GdUnitIntAssert.gd.uid b/addons/gdUnit4/src/GdUnitIntAssert.gd.uid index 17e2b81e..ae2ed11d 100644 --- a/addons/gdUnit4/src/GdUnitIntAssert.gd.uid +++ b/addons/gdUnit4/src/GdUnitIntAssert.gd.uid @@ -1 +1 @@ -uid://bpfhi1eheni4h +uid://cue1n5kbfpf62 diff --git a/addons/gdUnit4/src/GdUnitObjectAssert.gd.uid b/addons/gdUnit4/src/GdUnitObjectAssert.gd.uid index e86bd11b..ac399915 100644 --- a/addons/gdUnit4/src/GdUnitObjectAssert.gd.uid +++ b/addons/gdUnit4/src/GdUnitObjectAssert.gd.uid @@ -1 +1 @@ -uid://d2d3bkxt1wcx7 +uid://c5wxapigqmk5q diff --git a/addons/gdUnit4/src/GdUnitResultAssert.gd.uid b/addons/gdUnit4/src/GdUnitResultAssert.gd.uid index eb8143b2..f690de84 100644 --- a/addons/gdUnit4/src/GdUnitResultAssert.gd.uid +++ b/addons/gdUnit4/src/GdUnitResultAssert.gd.uid @@ -1 +1 @@ -uid://4cgv3ss1mryp +uid://dnip2ya5y8ycw diff --git a/addons/gdUnit4/src/GdUnitSceneRunner.gd.uid b/addons/gdUnit4/src/GdUnitSceneRunner.gd.uid index 4457aaa1..513dc150 100644 --- a/addons/gdUnit4/src/GdUnitSceneRunner.gd.uid +++ b/addons/gdUnit4/src/GdUnitSceneRunner.gd.uid @@ -1 +1 @@ -uid://dhdbg6m7ygvou +uid://b3vx3wiljpn0f diff --git a/addons/gdUnit4/src/GdUnitSignalAssert.gd.uid b/addons/gdUnit4/src/GdUnitSignalAssert.gd.uid index f09743f6..7d5da055 100644 --- a/addons/gdUnit4/src/GdUnitSignalAssert.gd.uid +++ b/addons/gdUnit4/src/GdUnitSignalAssert.gd.uid @@ -1 +1 @@ -uid://nqq3ony261ch +uid://baq28tquvfpvx diff --git a/addons/gdUnit4/src/GdUnitStringAssert.gd.uid b/addons/gdUnit4/src/GdUnitStringAssert.gd.uid index b90e3a81..03331917 100644 --- a/addons/gdUnit4/src/GdUnitStringAssert.gd.uid +++ b/addons/gdUnit4/src/GdUnitStringAssert.gd.uid @@ -1 +1 @@ -uid://dcbgythmvh6g4 +uid://hcqrn03qu1e4 diff --git a/addons/gdUnit4/src/GdUnitTestSuite.gd.uid b/addons/gdUnit4/src/GdUnitTestSuite.gd.uid index faaa948b..a8db01ab 100644 --- a/addons/gdUnit4/src/GdUnitTestSuite.gd.uid +++ b/addons/gdUnit4/src/GdUnitTestSuite.gd.uid @@ -1 +1 @@ -uid://d27xn7ceg8ta1 +uid://c0yh28xahuiht diff --git a/addons/gdUnit4/src/GdUnitTuple.gd.uid b/addons/gdUnit4/src/GdUnitTuple.gd.uid index 9eb02219..4fcd08d7 100644 --- a/addons/gdUnit4/src/GdUnitTuple.gd.uid +++ b/addons/gdUnit4/src/GdUnitTuple.gd.uid @@ -1 +1 @@ -uid://4soxgauogw4g +uid://c16ujl1btfyyb diff --git a/addons/gdUnit4/src/GdUnitValueExtractor.gd.uid b/addons/gdUnit4/src/GdUnitValueExtractor.gd.uid index 9b4d3ee6..6e1921af 100644 --- a/addons/gdUnit4/src/GdUnitValueExtractor.gd.uid +++ b/addons/gdUnit4/src/GdUnitValueExtractor.gd.uid @@ -1 +1 @@ -uid://dus26afrslc7c +uid://4epm64nfbmhg diff --git a/addons/gdUnit4/src/GdUnitVectorAssert.gd.uid b/addons/gdUnit4/src/GdUnitVectorAssert.gd.uid index 7222e571..bb440ddd 100644 --- a/addons/gdUnit4/src/GdUnitVectorAssert.gd.uid +++ b/addons/gdUnit4/src/GdUnitVectorAssert.gd.uid @@ -1 +1 @@ -uid://61ct1w1pqjnk +uid://bkmgw6fy1aohx diff --git a/addons/gdUnit4/src/asserts/CallBackValueProvider.gd.uid b/addons/gdUnit4/src/asserts/CallBackValueProvider.gd.uid index 1a3409a7..995cf47d 100644 --- a/addons/gdUnit4/src/asserts/CallBackValueProvider.gd.uid +++ b/addons/gdUnit4/src/asserts/CallBackValueProvider.gd.uid @@ -1 +1 @@ -uid://d3a4ypfxdkmru +uid://caw2mwxk4y02a diff --git a/addons/gdUnit4/src/asserts/DefaultValueProvider.gd.uid b/addons/gdUnit4/src/asserts/DefaultValueProvider.gd.uid index 727b98e6..6aad89f3 100644 --- a/addons/gdUnit4/src/asserts/DefaultValueProvider.gd.uid +++ b/addons/gdUnit4/src/asserts/DefaultValueProvider.gd.uid @@ -1 +1 @@ -uid://bd0yn1rsh6307 +uid://ceuddy0hobjye diff --git a/addons/gdUnit4/src/asserts/GdAssertMessages.gd.uid b/addons/gdUnit4/src/asserts/GdAssertMessages.gd.uid index a22e8bef..2bb50832 100644 --- a/addons/gdUnit4/src/asserts/GdAssertMessages.gd.uid +++ b/addons/gdUnit4/src/asserts/GdAssertMessages.gd.uid @@ -1 +1 @@ -uid://cc3hdk43hh47 +uid://cce0evdm20w7c diff --git a/addons/gdUnit4/src/asserts/GdAssertReports.gd.uid b/addons/gdUnit4/src/asserts/GdAssertReports.gd.uid index 8660da2b..ce68dea3 100644 --- a/addons/gdUnit4/src/asserts/GdAssertReports.gd.uid +++ b/addons/gdUnit4/src/asserts/GdAssertReports.gd.uid @@ -1 +1 @@ -uid://6kr4lpvi1qwq +uid://cj58yddbde7p8 diff --git a/addons/gdUnit4/src/asserts/GdUnitArrayAssertImpl.gd.uid b/addons/gdUnit4/src/asserts/GdUnitArrayAssertImpl.gd.uid index 8fa7f5a1..4bf5edd5 100644 --- a/addons/gdUnit4/src/asserts/GdUnitArrayAssertImpl.gd.uid +++ b/addons/gdUnit4/src/asserts/GdUnitArrayAssertImpl.gd.uid @@ -1 +1 @@ -uid://e04hjp5huh74 +uid://blnx4jsud6upv diff --git a/addons/gdUnit4/src/asserts/GdUnitAssertImpl.gd.uid b/addons/gdUnit4/src/asserts/GdUnitAssertImpl.gd.uid index 974376c9..80a27b41 100644 --- a/addons/gdUnit4/src/asserts/GdUnitAssertImpl.gd.uid +++ b/addons/gdUnit4/src/asserts/GdUnitAssertImpl.gd.uid @@ -1 +1 @@ -uid://ciwobc7f6h46r +uid://b8p4grxo0smkx diff --git a/addons/gdUnit4/src/asserts/GdUnitAssertions.gd.uid b/addons/gdUnit4/src/asserts/GdUnitAssertions.gd.uid index 009718e3..39df948c 100644 --- a/addons/gdUnit4/src/asserts/GdUnitAssertions.gd.uid +++ b/addons/gdUnit4/src/asserts/GdUnitAssertions.gd.uid @@ -1 +1 @@ -uid://mdemt0sdcelx +uid://bvacky1evj2jv diff --git a/addons/gdUnit4/src/asserts/GdUnitBoolAssertImpl.gd.uid b/addons/gdUnit4/src/asserts/GdUnitBoolAssertImpl.gd.uid index 7b1d3294..6b773f41 100644 --- a/addons/gdUnit4/src/asserts/GdUnitBoolAssertImpl.gd.uid +++ b/addons/gdUnit4/src/asserts/GdUnitBoolAssertImpl.gd.uid @@ -1 +1 @@ -uid://cuu0go0gd1ul7 +uid://bmktyrxj0k8p2 diff --git a/addons/gdUnit4/src/asserts/GdUnitDictionaryAssertImpl.gd.uid b/addons/gdUnit4/src/asserts/GdUnitDictionaryAssertImpl.gd.uid index dd8adbfa..9c1a50e7 100644 --- a/addons/gdUnit4/src/asserts/GdUnitDictionaryAssertImpl.gd.uid +++ b/addons/gdUnit4/src/asserts/GdUnitDictionaryAssertImpl.gd.uid @@ -1 +1 @@ -uid://bwrof6ds0dpxt +uid://dqw4e41njp2l8 diff --git a/addons/gdUnit4/src/asserts/GdUnitFailureAssertImpl.gd.uid b/addons/gdUnit4/src/asserts/GdUnitFailureAssertImpl.gd.uid index c0ba7bb3..a4866565 100644 --- a/addons/gdUnit4/src/asserts/GdUnitFailureAssertImpl.gd.uid +++ b/addons/gdUnit4/src/asserts/GdUnitFailureAssertImpl.gd.uid @@ -1 +1 @@ -uid://4v5w8jahhm04 +uid://bkh5pmbre7kam diff --git a/addons/gdUnit4/src/asserts/GdUnitFileAssertImpl.gd.uid b/addons/gdUnit4/src/asserts/GdUnitFileAssertImpl.gd.uid index feea0235..c0e39fc3 100644 --- a/addons/gdUnit4/src/asserts/GdUnitFileAssertImpl.gd.uid +++ b/addons/gdUnit4/src/asserts/GdUnitFileAssertImpl.gd.uid @@ -1 +1 @@ -uid://cmm7sbdnq6ynv +uid://b0p0dpxafixwg diff --git a/addons/gdUnit4/src/asserts/GdUnitFloatAssertImpl.gd.uid b/addons/gdUnit4/src/asserts/GdUnitFloatAssertImpl.gd.uid index a9047db4..f4eb1521 100644 --- a/addons/gdUnit4/src/asserts/GdUnitFloatAssertImpl.gd.uid +++ b/addons/gdUnit4/src/asserts/GdUnitFloatAssertImpl.gd.uid @@ -1 +1 @@ -uid://ce0tctonwex1f +uid://cfmvglkttiixi diff --git a/addons/gdUnit4/src/asserts/GdUnitFuncAssertImpl.gd.uid b/addons/gdUnit4/src/asserts/GdUnitFuncAssertImpl.gd.uid index 05dc97c0..7e6295f9 100644 --- a/addons/gdUnit4/src/asserts/GdUnitFuncAssertImpl.gd.uid +++ b/addons/gdUnit4/src/asserts/GdUnitFuncAssertImpl.gd.uid @@ -1 +1 @@ -uid://d0blnbdubapl2 +uid://dyj6mpqnx8fqh diff --git a/addons/gdUnit4/src/asserts/GdUnitGodotErrorAssertImpl.gd.uid b/addons/gdUnit4/src/asserts/GdUnitGodotErrorAssertImpl.gd.uid index 9481101a..7553986f 100644 --- a/addons/gdUnit4/src/asserts/GdUnitGodotErrorAssertImpl.gd.uid +++ b/addons/gdUnit4/src/asserts/GdUnitGodotErrorAssertImpl.gd.uid @@ -1 +1 @@ -uid://csgwjvp1srw01 +uid://b28gwfs6x5d3c diff --git a/addons/gdUnit4/src/asserts/GdUnitIntAssertImpl.gd.uid b/addons/gdUnit4/src/asserts/GdUnitIntAssertImpl.gd.uid index ea042aa2..d361034e 100644 --- a/addons/gdUnit4/src/asserts/GdUnitIntAssertImpl.gd.uid +++ b/addons/gdUnit4/src/asserts/GdUnitIntAssertImpl.gd.uid @@ -1 +1 @@ -uid://b4wyced4y202u +uid://co0vsefhtjvly diff --git a/addons/gdUnit4/src/asserts/GdUnitObjectAssertImpl.gd.uid b/addons/gdUnit4/src/asserts/GdUnitObjectAssertImpl.gd.uid index 2fc264a6..e12163f3 100644 --- a/addons/gdUnit4/src/asserts/GdUnitObjectAssertImpl.gd.uid +++ b/addons/gdUnit4/src/asserts/GdUnitObjectAssertImpl.gd.uid @@ -1 +1 @@ -uid://boiiakwr5lbqu +uid://dmg376u3xqyi2 diff --git a/addons/gdUnit4/src/asserts/GdUnitResultAssertImpl.gd.uid b/addons/gdUnit4/src/asserts/GdUnitResultAssertImpl.gd.uid index af6b7313..b090c457 100644 --- a/addons/gdUnit4/src/asserts/GdUnitResultAssertImpl.gd.uid +++ b/addons/gdUnit4/src/asserts/GdUnitResultAssertImpl.gd.uid @@ -1 +1 @@ -uid://dbe4cfms6j7tf +uid://bg88ekxp3v4hh diff --git a/addons/gdUnit4/src/asserts/GdUnitSignalAssertImpl.gd.uid b/addons/gdUnit4/src/asserts/GdUnitSignalAssertImpl.gd.uid index 13d71b9c..e3faa0e8 100644 --- a/addons/gdUnit4/src/asserts/GdUnitSignalAssertImpl.gd.uid +++ b/addons/gdUnit4/src/asserts/GdUnitSignalAssertImpl.gd.uid @@ -1 +1 @@ -uid://dc0nxf3g1q6hg +uid://yqt80k0iet10 diff --git a/addons/gdUnit4/src/asserts/GdUnitStringAssertImpl.gd.uid b/addons/gdUnit4/src/asserts/GdUnitStringAssertImpl.gd.uid index 454ba1dd..9ee32442 100644 --- a/addons/gdUnit4/src/asserts/GdUnitStringAssertImpl.gd.uid +++ b/addons/gdUnit4/src/asserts/GdUnitStringAssertImpl.gd.uid @@ -1 +1 @@ -uid://cgc45q2bbnw6h +uid://cnurg4dsh2j51 diff --git a/addons/gdUnit4/src/asserts/GdUnitVectorAssertImpl.gd.uid b/addons/gdUnit4/src/asserts/GdUnitVectorAssertImpl.gd.uid index 8d5800d4..6e929720 100644 --- a/addons/gdUnit4/src/asserts/GdUnitVectorAssertImpl.gd.uid +++ b/addons/gdUnit4/src/asserts/GdUnitVectorAssertImpl.gd.uid @@ -1 +1 @@ -uid://c8prlu08lq4pw +uid://cb76021730n1g diff --git a/addons/gdUnit4/src/asserts/ValueProvider.gd.uid b/addons/gdUnit4/src/asserts/ValueProvider.gd.uid index 44144cf3..053887b5 100644 --- a/addons/gdUnit4/src/asserts/ValueProvider.gd.uid +++ b/addons/gdUnit4/src/asserts/ValueProvider.gd.uid @@ -1 +1 @@ -uid://dmrnx0ievdw00 +uid://bwqax8vnkbk0t diff --git a/addons/gdUnit4/src/cmd/CmdArgumentParser.gd.uid b/addons/gdUnit4/src/cmd/CmdArgumentParser.gd.uid index d711c4d4..66421f50 100644 --- a/addons/gdUnit4/src/cmd/CmdArgumentParser.gd.uid +++ b/addons/gdUnit4/src/cmd/CmdArgumentParser.gd.uid @@ -1 +1 @@ -uid://dytw8hhfjgrfo +uid://b4lwihq3wr0tw diff --git a/addons/gdUnit4/src/cmd/CmdCommand.gd.uid b/addons/gdUnit4/src/cmd/CmdCommand.gd.uid index 401b3521..e49d6370 100644 --- a/addons/gdUnit4/src/cmd/CmdCommand.gd.uid +++ b/addons/gdUnit4/src/cmd/CmdCommand.gd.uid @@ -1 +1 @@ -uid://c3bmxrdyb2s7c +uid://o40bgvtisayg diff --git a/addons/gdUnit4/src/cmd/CmdCommandHandler.gd.uid b/addons/gdUnit4/src/cmd/CmdCommandHandler.gd.uid index e394020c..28b1f385 100644 --- a/addons/gdUnit4/src/cmd/CmdCommandHandler.gd.uid +++ b/addons/gdUnit4/src/cmd/CmdCommandHandler.gd.uid @@ -1 +1 @@ -uid://bv18vku5wy8dh +uid://dlkcvw2algkqo diff --git a/addons/gdUnit4/src/cmd/CmdOption.gd.uid b/addons/gdUnit4/src/cmd/CmdOption.gd.uid index a6e08ca7..8475e700 100644 --- a/addons/gdUnit4/src/cmd/CmdOption.gd.uid +++ b/addons/gdUnit4/src/cmd/CmdOption.gd.uid @@ -1 +1 @@ -uid://docx18wjoc50t +uid://dnagtjbx1bcqu diff --git a/addons/gdUnit4/src/cmd/CmdOptions.gd.uid b/addons/gdUnit4/src/cmd/CmdOptions.gd.uid index 5efaea1b..60be7c9d 100644 --- a/addons/gdUnit4/src/cmd/CmdOptions.gd.uid +++ b/addons/gdUnit4/src/cmd/CmdOptions.gd.uid @@ -1 +1 @@ -uid://d1rr3hrhxwpcx +uid://w2jlsroiofho diff --git a/addons/gdUnit4/src/core/GdArrayTools.gd.uid b/addons/gdUnit4/src/core/GdArrayTools.gd.uid index d31fe723..6ae859ac 100644 --- a/addons/gdUnit4/src/core/GdArrayTools.gd.uid +++ b/addons/gdUnit4/src/core/GdArrayTools.gd.uid @@ -1 +1 @@ -uid://dysbpliok4jy3 +uid://d30x6br7de16j diff --git a/addons/gdUnit4/src/core/GdDiffTool.gd.uid b/addons/gdUnit4/src/core/GdDiffTool.gd.uid index 39495dfb..4ad8196e 100644 --- a/addons/gdUnit4/src/core/GdDiffTool.gd.uid +++ b/addons/gdUnit4/src/core/GdDiffTool.gd.uid @@ -1 +1 @@ -uid://b15cajmjouv4w +uid://c0lieuv0eejrw diff --git a/addons/gdUnit4/src/core/GdObjects.gd.uid b/addons/gdUnit4/src/core/GdObjects.gd.uid index fb2475d9..aaa94f44 100644 --- a/addons/gdUnit4/src/core/GdObjects.gd.uid +++ b/addons/gdUnit4/src/core/GdObjects.gd.uid @@ -1 +1 @@ -uid://sdoq2leo0wh7 +uid://cbkqqtijh636g diff --git a/addons/gdUnit4/src/core/GdUnit4Version.gd.uid b/addons/gdUnit4/src/core/GdUnit4Version.gd.uid index 597caf56..641370b7 100644 --- a/addons/gdUnit4/src/core/GdUnit4Version.gd.uid +++ b/addons/gdUnit4/src/core/GdUnit4Version.gd.uid @@ -1 +1 @@ -uid://db2lxsj6mco0s +uid://dkxn7forlqv0d diff --git a/addons/gdUnit4/src/core/GdUnitFileAccess.gd.uid b/addons/gdUnit4/src/core/GdUnitFileAccess.gd.uid index 678e5c13..dd714bfd 100644 --- a/addons/gdUnit4/src/core/GdUnitFileAccess.gd.uid +++ b/addons/gdUnit4/src/core/GdUnitFileAccess.gd.uid @@ -1 +1 @@ -uid://c3frtlg7eexve +uid://ctippg01yi8cg diff --git a/addons/gdUnit4/src/core/GdUnitProperty.gd b/addons/gdUnit4/src/core/GdUnitProperty.gd index 138dd9f7..48de036b 100644 --- a/addons/gdUnit4/src/core/GdUnitProperty.gd +++ b/addons/gdUnit4/src/core/GdUnitProperty.gd @@ -31,6 +31,9 @@ func value() -> Variant: return _value +func int_value() -> int: + return _value + func value_as_string() -> String: return _value diff --git a/addons/gdUnit4/src/core/GdUnitProperty.gd.uid b/addons/gdUnit4/src/core/GdUnitProperty.gd.uid index a1ea4b8c..703740de 100644 --- a/addons/gdUnit4/src/core/GdUnitProperty.gd.uid +++ b/addons/gdUnit4/src/core/GdUnitProperty.gd.uid @@ -1 +1 @@ -uid://bvcue10yckc55 +uid://dhuger7fnp4o5 diff --git a/addons/gdUnit4/src/core/GdUnitResult.gd.uid b/addons/gdUnit4/src/core/GdUnitResult.gd.uid index 985e9878..1f77d27f 100644 --- a/addons/gdUnit4/src/core/GdUnitResult.gd.uid +++ b/addons/gdUnit4/src/core/GdUnitResult.gd.uid @@ -1 +1 @@ -uid://diw4j3mxoow71 +uid://bbsofx7xfmyb5 diff --git a/addons/gdUnit4/src/core/GdUnitRunnerConfig.gd b/addons/gdUnit4/src/core/GdUnitRunnerConfig.gd index 149893f2..9f36354d 100644 --- a/addons/gdUnit4/src/core/GdUnitRunnerConfig.gd +++ b/addons/gdUnit4/src/core/GdUnitRunnerConfig.gd @@ -70,7 +70,7 @@ func save_config(path: String = CONFIG_FILE) -> GdUnitResult: func load_config(path: String = CONFIG_FILE) -> GdUnitResult: if not FileAccess.file_exists(path): - return GdUnitResult.error("Can't find test runner configuration '%s'! Please select a test to run." % path) + return GdUnitResult.warn("Can't find test runner configuration '%s'! Please select a test to run." % path) var file := FileAccess.open(path, FileAccess.READ) if file == null: var error := FileAccess.get_open_error() diff --git a/addons/gdUnit4/src/core/GdUnitRunnerConfig.gd.uid b/addons/gdUnit4/src/core/GdUnitRunnerConfig.gd.uid index 3c0608d7..816ec711 100644 --- a/addons/gdUnit4/src/core/GdUnitRunnerConfig.gd.uid +++ b/addons/gdUnit4/src/core/GdUnitRunnerConfig.gd.uid @@ -1 +1 @@ -uid://8t4ughvls7x4 +uid://chlwqcs7smmml diff --git a/addons/gdUnit4/src/core/GdUnitSceneRunnerImpl.gd b/addons/gdUnit4/src/core/GdUnitSceneRunnerImpl.gd index c70be022..b8f1c82d 100644 --- a/addons/gdUnit4/src/core/GdUnitSceneRunnerImpl.gd +++ b/addons/gdUnit4/src/core/GdUnitSceneRunnerImpl.gd @@ -502,7 +502,7 @@ func invoke( arg9: Variant = NO_ARG) -> Variant: var args: Array = GdArrayTools.filter_value([arg0,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9], NO_ARG) if scene().has_method(name): - return scene().callv(name, args) + return await scene().callv(name, args) return "The method '%s' not exist checked loaded scene." % name @@ -569,7 +569,7 @@ func _handle_actions(event: InputEventAction) -> bool: return false __print(" process action %s (%s) <- %s" % [scene(), _scene_name(), event.as_text()]) if event.is_pressed(): - Input.action_press(event.action, InputMap.action_get_deadzone(event.action)) + Input.action_press(event.action, event.get_strength()) else: Input.action_release(event.action) return true diff --git a/addons/gdUnit4/src/core/GdUnitSceneRunnerImpl.gd.uid b/addons/gdUnit4/src/core/GdUnitSceneRunnerImpl.gd.uid index 66c5dd62..8ef4396e 100644 --- a/addons/gdUnit4/src/core/GdUnitSceneRunnerImpl.gd.uid +++ b/addons/gdUnit4/src/core/GdUnitSceneRunnerImpl.gd.uid @@ -1 +1 @@ -uid://d28jctgpw3ia4 +uid://ddejpoiwafnsx diff --git a/addons/gdUnit4/src/core/GdUnitSettings.gd.uid b/addons/gdUnit4/src/core/GdUnitSettings.gd.uid index a937b3a4..7b8ab155 100644 --- a/addons/gdUnit4/src/core/GdUnitSettings.gd.uid +++ b/addons/gdUnit4/src/core/GdUnitSettings.gd.uid @@ -1 +1 @@ -uid://b41o5s7w6ruau +uid://kb1fusmpl827 diff --git a/addons/gdUnit4/src/core/GdUnitSignalAwaiter.gd.uid b/addons/gdUnit4/src/core/GdUnitSignalAwaiter.gd.uid index 5411baae..25b42bb5 100644 --- a/addons/gdUnit4/src/core/GdUnitSignalAwaiter.gd.uid +++ b/addons/gdUnit4/src/core/GdUnitSignalAwaiter.gd.uid @@ -1 +1 @@ -uid://vdafterb2ngh +uid://vprbi1v5gyqb diff --git a/addons/gdUnit4/src/core/GdUnitSignalCollector.gd.uid b/addons/gdUnit4/src/core/GdUnitSignalCollector.gd.uid index ca0929b6..181baa96 100644 --- a/addons/gdUnit4/src/core/GdUnitSignalCollector.gd.uid +++ b/addons/gdUnit4/src/core/GdUnitSignalCollector.gd.uid @@ -1 +1 @@ -uid://cpi5b0k7xnw4j +uid://bfxoxj4i1wdmf diff --git a/addons/gdUnit4/src/core/GdUnitSignals.gd.uid b/addons/gdUnit4/src/core/GdUnitSignals.gd.uid index 4a7fd80d..7d8a1529 100644 --- a/addons/gdUnit4/src/core/GdUnitSignals.gd.uid +++ b/addons/gdUnit4/src/core/GdUnitSignals.gd.uid @@ -1 +1 @@ -uid://c3gfd1at2bm81 +uid://bh6i3ln6vlbrk diff --git a/addons/gdUnit4/src/core/GdUnitSingleton.gd.uid b/addons/gdUnit4/src/core/GdUnitSingleton.gd.uid index 07a94f76..5110f1f5 100644 --- a/addons/gdUnit4/src/core/GdUnitSingleton.gd.uid +++ b/addons/gdUnit4/src/core/GdUnitSingleton.gd.uid @@ -1 +1 @@ -uid://bc5fybsywnuya +uid://coll4y58u7q5i diff --git a/addons/gdUnit4/src/core/GdUnitTestResourceLoader.gd b/addons/gdUnit4/src/core/GdUnitTestResourceLoader.gd index 43618525..33b80e28 100644 --- a/addons/gdUnit4/src/core/GdUnitTestResourceLoader.gd +++ b/addons/gdUnit4/src/core/GdUnitTestResourceLoader.gd @@ -40,7 +40,7 @@ static func load_test_suite_gd(resource_path: String) -> GdUnitTestSuite: static func load_test_suite_cs(resource_path: String) -> Node: - if not GdUnit4CSharpApiLoader.is_dotnet_supported(): + if not GdUnit4CSharpApiLoader.is_api_loaded(): return null var script :Script = ClassDB.instantiate("CSharpScript") script.source_code = GdUnitFileAccess.resource_as_string(resource_path) @@ -50,7 +50,7 @@ static func load_test_suite_cs(resource_path: String) -> Node: static func load_cs_script(resource_path: String, debug_write := false) -> Script: - if not GdUnit4CSharpApiLoader.is_dotnet_supported(): + if not GdUnit4CSharpApiLoader.is_api_loaded(): return null var script :Script = ClassDB.instantiate("CSharpScript") script.source_code = GdUnitFileAccess.resource_as_string(resource_path) diff --git a/addons/gdUnit4/src/core/GdUnitTestResourceLoader.gd.uid b/addons/gdUnit4/src/core/GdUnitTestResourceLoader.gd.uid index 31912a1e..169edf2e 100644 --- a/addons/gdUnit4/src/core/GdUnitTestResourceLoader.gd.uid +++ b/addons/gdUnit4/src/core/GdUnitTestResourceLoader.gd.uid @@ -1 +1 @@ -uid://dtinkm1otfo2y +uid://btteb7dviq513 diff --git a/addons/gdUnit4/src/core/GdUnitTestSuiteBuilder.gd.uid b/addons/gdUnit4/src/core/GdUnitTestSuiteBuilder.gd.uid index a2b1341e..325afc1b 100644 --- a/addons/gdUnit4/src/core/GdUnitTestSuiteBuilder.gd.uid +++ b/addons/gdUnit4/src/core/GdUnitTestSuiteBuilder.gd.uid @@ -1 +1 @@ -uid://dm1kreoovutly +uid://sutpkyk072xx diff --git a/addons/gdUnit4/src/core/GdUnitTestSuiteScanner.gd b/addons/gdUnit4/src/core/GdUnitTestSuiteScanner.gd index b5d27349..654bdc88 100644 --- a/addons/gdUnit4/src/core/GdUnitTestSuiteScanner.gd +++ b/addons/gdUnit4/src/core/GdUnitTestSuiteScanner.gd @@ -224,7 +224,7 @@ static func is_test_suite(script: Script) -> bool: return true stack.push_back(base) elif script != null and script.get_class() == "CSharpScript": - return GdUnit4CSharpApiLoader.is_test_suite(script) + return true return false diff --git a/addons/gdUnit4/src/core/GdUnitTestSuiteScanner.gd.uid b/addons/gdUnit4/src/core/GdUnitTestSuiteScanner.gd.uid index f3d0fd6d..5a545073 100644 --- a/addons/gdUnit4/src/core/GdUnitTestSuiteScanner.gd.uid +++ b/addons/gdUnit4/src/core/GdUnitTestSuiteScanner.gd.uid @@ -1 +1 @@ -uid://d05tmi5e02oqi +uid://b7rd1ly2ugi07 diff --git a/addons/gdUnit4/src/core/GdUnitTools.gd.uid b/addons/gdUnit4/src/core/GdUnitTools.gd.uid index 7a94c3ae..6549e888 100644 --- a/addons/gdUnit4/src/core/GdUnitTools.gd.uid +++ b/addons/gdUnit4/src/core/GdUnitTools.gd.uid @@ -1 +1 @@ -uid://bb5gyqgycvniq +uid://coarfyhpqcnc1 diff --git a/addons/gdUnit4/src/core/GodotVersionFixures.gd.uid b/addons/gdUnit4/src/core/GodotVersionFixures.gd.uid index 6c3d5a06..c8605b3d 100644 --- a/addons/gdUnit4/src/core/GodotVersionFixures.gd.uid +++ b/addons/gdUnit4/src/core/GodotVersionFixures.gd.uid @@ -1 +1 @@ -uid://5ihmoi7vjmd +uid://ra53xlpn6c44 diff --git a/addons/gdUnit4/src/core/LocalTime.gd.uid b/addons/gdUnit4/src/core/LocalTime.gd.uid index 9332291f..69637497 100644 --- a/addons/gdUnit4/src/core/LocalTime.gd.uid +++ b/addons/gdUnit4/src/core/LocalTime.gd.uid @@ -1 +1 @@ -uid://bkm1q7yvoxy7j +uid://bjf3dk5qw21wx diff --git a/addons/gdUnit4/src/core/_TestCase.gd.uid b/addons/gdUnit4/src/core/_TestCase.gd.uid index 15288372..b8cfa927 100644 --- a/addons/gdUnit4/src/core/_TestCase.gd.uid +++ b/addons/gdUnit4/src/core/_TestCase.gd.uid @@ -1 +1 @@ -uid://srhv4b4s7cl6 +uid://cbkonrpx4fo1w diff --git a/addons/gdUnit4/src/core/assets/touch-button.png.import b/addons/gdUnit4/src/core/assets/touch-button.png.import index a84ce13b..5c918411 100644 --- a/addons/gdUnit4/src/core/assets/touch-button.png.import +++ b/addons/gdUnit4/src/core/assets/touch-button.png.import @@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/touch-button.png-2fff40c8520d8e97a57db1b2b043 compress/mode=0 compress/high_quality=false compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 compress/hdr_compression=1 compress/normal_map=0 compress/channel_pack=0 @@ -25,6 +27,10 @@ mipmaps/generate=false mipmaps/limit=-1 roughness/mode=0 roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 process/fix_alpha_border=true process/premult_alpha=false process/normal_map_invert_y=false diff --git a/addons/gdUnit4/src/core/attributes/TestCaseAttribute.gd.uid b/addons/gdUnit4/src/core/attributes/TestCaseAttribute.gd.uid index 61fc47c9..7f9c7deb 100644 --- a/addons/gdUnit4/src/core/attributes/TestCaseAttribute.gd.uid +++ b/addons/gdUnit4/src/core/attributes/TestCaseAttribute.gd.uid @@ -1 +1 @@ -uid://dgxgnjr51711k +uid://doey67tyoy6xb diff --git a/addons/gdUnit4/src/core/command/GdUnitCommand.gd.uid b/addons/gdUnit4/src/core/command/GdUnitCommand.gd.uid index 41fca155..7c26cc9f 100644 --- a/addons/gdUnit4/src/core/command/GdUnitCommand.gd.uid +++ b/addons/gdUnit4/src/core/command/GdUnitCommand.gd.uid @@ -1 +1 @@ -uid://b5x0oc5ngf8lj +uid://de56aharilx1p diff --git a/addons/gdUnit4/src/core/command/GdUnitCommandHandler.gd.uid b/addons/gdUnit4/src/core/command/GdUnitCommandHandler.gd.uid index 8c138b6d..43b91fc5 100644 --- a/addons/gdUnit4/src/core/command/GdUnitCommandHandler.gd.uid +++ b/addons/gdUnit4/src/core/command/GdUnitCommandHandler.gd.uid @@ -1 +1 @@ -uid://c0sifu2vquucy +uid://b5tm2bvrkhtbd diff --git a/addons/gdUnit4/src/core/command/GdUnitShortcut.gd.uid b/addons/gdUnit4/src/core/command/GdUnitShortcut.gd.uid index af3594b3..5c9b76eb 100644 --- a/addons/gdUnit4/src/core/command/GdUnitShortcut.gd.uid +++ b/addons/gdUnit4/src/core/command/GdUnitShortcut.gd.uid @@ -1 +1 @@ -uid://do4egyy4scgfs +uid://dch3r18obmu2h diff --git a/addons/gdUnit4/src/core/command/GdUnitShortcutAction.gd.uid b/addons/gdUnit4/src/core/command/GdUnitShortcutAction.gd.uid index b0fbd4ee..24372c27 100644 --- a/addons/gdUnit4/src/core/command/GdUnitShortcutAction.gd.uid +++ b/addons/gdUnit4/src/core/command/GdUnitShortcutAction.gd.uid @@ -1 +1 @@ -uid://bt74gepjg7ekn +uid://buyllgjg2vyux diff --git a/addons/gdUnit4/src/core/discovery/GdUnitGUID.gd.uid b/addons/gdUnit4/src/core/discovery/GdUnitGUID.gd.uid index 713df158..2eba042f 100644 --- a/addons/gdUnit4/src/core/discovery/GdUnitGUID.gd.uid +++ b/addons/gdUnit4/src/core/discovery/GdUnitGUID.gd.uid @@ -1 +1 @@ -uid://d0151xs4n3iyb +uid://dwssr1bh4i1aw diff --git a/addons/gdUnit4/src/core/discovery/GdUnitTestCase.gd b/addons/gdUnit4/src/core/discovery/GdUnitTestCase.gd index d833e3bb..766f9eab 100644 --- a/addons/gdUnit4/src/core/discovery/GdUnitTestCase.gd +++ b/addons/gdUnit4/src/core/discovery/GdUnitTestCase.gd @@ -9,6 +9,9 @@ extends RefCounted ## A unique identifier for the test case. Used to track and reference specific test instances. var guid := GdUnitGUID.new() +## The resource path to the test suite +var suite_resource_path: String + ## The name of the test method/function. Should start with "test_" prefix. var test_name: String @@ -52,6 +55,7 @@ var metadata: Dictionary = {} static func from_dict(dict: Dictionary) -> GdUnitTestCase: var test := GdUnitTestCase.new() test.guid = GdUnitGUID.new(str(dict["guid"])) + test.suite_resource_path = dict["suite_resource_path"] if dict.has("suite_resource_path") else dict["source_file"] test.suite_name = dict["managed_type"] test.test_name = dict["test_name"] test.display_name = dict["simple_name"] @@ -67,6 +71,7 @@ static func from_dict(dict: Dictionary) -> GdUnitTestCase: static func to_dict(test: GdUnitTestCase) -> Dictionary: return { "guid": test.guid._guid, + "suite_resource_path": test.suite_resource_path, "managed_type": test.suite_name, "test_name" : test.test_name, "simple_name" : test.display_name, @@ -79,7 +84,7 @@ static func to_dict(test: GdUnitTestCase) -> Dictionary: } -static func from(_source_file: String, _line_number: int, _test_name: String, _attribute_index := -1, _test_parameters := "") -> GdUnitTestCase: +static func from(_suite_resource_path: String, _source_file: String, _line_number: int, _test_name: String, _attribute_index := -1, _test_parameters := "") -> GdUnitTestCase: if(_source_file == null or _source_file.is_empty()): prints(_test_name) @@ -87,13 +92,14 @@ static func from(_source_file: String, _line_number: int, _test_name: String, _a assert(_source_file != null and not _source_file.is_empty(), "Precondition: The parameter 'source_file' is not set") var test := GdUnitTestCase.new() + test.suite_resource_path = _suite_resource_path test.test_name = _test_name test.source_file = _source_file test.line_number = _line_number test.attribute_index = _attribute_index test._build_suite_name() test._build_display_name(_test_parameters) - test._build_fully_qualified_name() + test._build_fully_qualified_name(_suite_resource_path) return test @@ -109,8 +115,8 @@ func _build_display_name(_test_parameters: String) -> void: display_name = "%s:%d (%s)" % [test_name, attribute_index, _test_parameters.trim_prefix("[").trim_suffix("]").replace('"', "'")] -func _build_fully_qualified_name() -> void: - var name_space := source_file.trim_prefix("res://").trim_suffix(".gd").trim_suffix(".cs").replace("/", ".") +func _build_fully_qualified_name(_resource_path: String) -> void: + var name_space := _resource_path.trim_prefix("res://").trim_suffix(".gd").trim_suffix(".cs").replace("/", ".") if attribute_index == -1: fully_qualified_name = "%s.%s" % [name_space, test_name] diff --git a/addons/gdUnit4/src/core/discovery/GdUnitTestCase.gd.uid b/addons/gdUnit4/src/core/discovery/GdUnitTestCase.gd.uid index cee0b72d..da1e037b 100644 --- a/addons/gdUnit4/src/core/discovery/GdUnitTestCase.gd.uid +++ b/addons/gdUnit4/src/core/discovery/GdUnitTestCase.gd.uid @@ -1 +1 @@ -uid://xluthcvn10cq +uid://di77insyh6j75 diff --git a/addons/gdUnit4/src/core/discovery/GdUnitTestDiscoverGuard.gd b/addons/gdUnit4/src/core/discovery/GdUnitTestDiscoverGuard.gd index f4103787..4f9111d0 100644 --- a/addons/gdUnit4/src/core/discovery/GdUnitTestDiscoverGuard.gd +++ b/addons/gdUnit4/src/core/discovery/GdUnitTestDiscoverGuard.gd @@ -151,6 +151,10 @@ func find_test_by_id(id: GdUnitGUID) -> GdUnitTestCase: ## [param script] The test script to analyze[br] ## [param discover_sink] Optional callback for test discovery events func discover(script: Script, discover_sink: Callable = default_discover_sink) -> void: + # Verify the script has no errors before run test discovery + var result := script.reload(true) + if result != OK: + return if _is_debug: _discovered_changes["changed_tests"] = Array([], TYPE_OBJECT, "RefCounted", GdUnitTestCase) diff --git a/addons/gdUnit4/src/core/discovery/GdUnitTestDiscoverGuard.gd.uid b/addons/gdUnit4/src/core/discovery/GdUnitTestDiscoverGuard.gd.uid index 43ec72d5..46e1b8dd 100644 --- a/addons/gdUnit4/src/core/discovery/GdUnitTestDiscoverGuard.gd.uid +++ b/addons/gdUnit4/src/core/discovery/GdUnitTestDiscoverGuard.gd.uid @@ -1 +1 @@ -uid://bjxpngc0i437j +uid://c4o1eyxqtr85k diff --git a/addons/gdUnit4/src/core/discovery/GdUnitTestDiscoverSink.gd.uid b/addons/gdUnit4/src/core/discovery/GdUnitTestDiscoverSink.gd.uid index 06658467..475228ea 100644 --- a/addons/gdUnit4/src/core/discovery/GdUnitTestDiscoverSink.gd.uid +++ b/addons/gdUnit4/src/core/discovery/GdUnitTestDiscoverSink.gd.uid @@ -1 +1 @@ -uid://di3w8b6us6l0p +uid://6lq18dxktabs diff --git a/addons/gdUnit4/src/core/discovery/GdUnitTestDiscoverer.gd b/addons/gdUnit4/src/core/discovery/GdUnitTestDiscoverer.gd index f7a672b6..996dd95c 100644 --- a/addons/gdUnit4/src/core/discovery/GdUnitTestDiscoverer.gd +++ b/addons/gdUnit4/src/core/discovery/GdUnitTestDiscoverer.gd @@ -11,6 +11,10 @@ static func run() -> Array[GdUnitTestCase]: var t:= Thread.new() @warning_ignore("return_value_discarded") t.start(func () -> Array[GdUnitTestCase]: + # Loading previous test session + var runner_config := GdUnitRunnerConfig.new() + runner_config.load_config() + var recovered_tests := runner_config.test_cases() var test_suite_directories :PackedStringArray = GdUnitCommandHandler.scan_all_test_directories(GdUnitSettings.test_root_folder()) var scanner := GdUnitTestSuiteScanner.new() @@ -24,11 +28,15 @@ static func run() -> Array[GdUnitTestCase]: await (Engine.get_main_loop() as SceneTree).process_frame for test_suites_script in collected_test_suites: discover_tests(test_suites_script, func(test_case: GdUnitTestCase) -> void: + # Sync test uid from last test session + recover_test_guid(test_case, recovered_tests) collected_tests.append(test_case) GdUnitTestDiscoverSink.discover(test_case) ) console_log_discover_results(collected_tests) + if !recovered_tests.is_empty(): + console_log("Recovery last test session successfully, %d tests restored." % recovered_tests.size(), true) return collected_tests ) # wait unblocked to the tread is finished @@ -40,6 +48,46 @@ static func run() -> Array[GdUnitTestCase]: return test_to_execute +## Restores the last test run session by loading the test run config file and rediscover the tests +static func restore_last_session() -> void: + if GdUnitSettings.is_test_discover_enabled(): + return + + var runner_config := GdUnitRunnerConfig.new() + var result := runner_config.load_config() + # Report possible config loading errors + if result.is_error(): + console_log("Recovery of the last test session failed: %s" % result.error_message(), true) + # If no config file found, skip test recovery + if result.is_warn(): + return + + # If no tests recorded, skip test recovery + var test_cases := runner_config.test_cases() + if test_cases.size() == 0: + return + + # We run the test session restoring in an extra thread so that the main thread is not blocked + var t:= Thread.new() + t.start(func () -> void: + # Do sync the main thread before emit the discovered test suites to the inspector + await (Engine.get_main_loop() as SceneTree).process_frame + console_log("Recovery last test session ..", true) + GdUnitSignals.instance().gdunit_event.emit(GdUnitEventTestDiscoverStart.new()) + for test_case in test_cases: + GdUnitTestDiscoverSink.discover(test_case) + GdUnitSignals.instance().gdunit_event.emit(GdUnitEventTestDiscoverEnd.new(0, 0)) + console_log("Recovery last test session successfully, %d tests restored." % test_cases.size(), true) + ) + t.wait_to_finish() + + +static func recover_test_guid(current: GdUnitTestCase, recovered_tests: Array[GdUnitTestCase]) -> void: + for recovered_test in recovered_tests: + if recovered_test.fully_qualified_name == current.fully_qualified_name: + current.guid = recovered_test.guid + + static func console_log_discover_results(tests: Array[GdUnitTestCase]) -> void: var grouped_by_suites := GdArrayTools.group_by(tests, func(test: GdUnitTestCase) -> String: return test.source_file @@ -51,9 +99,10 @@ static func console_log_discover_results(tests: Array[GdUnitTestCase]) -> void: console_log("") -static func console_log(message: String) -> void: +static func console_log(message: String, on_console := false) -> void: prints(message) - #GdUnitSignals.instance().gdunit_message.emit(message) + if on_console: + GdUnitSignals.instance().gdunit_message.emit(message) static func filter_tests(method: Dictionary) -> bool: @@ -81,7 +130,7 @@ static func discover_tests(source_script: Script, discover_sink := default_disco for test_case in resolver.resolve_test_cases(source_script as GDScript): discover_sink.call(test_case) elif source_script.get_class() == "CSharpScript": - if not GdUnit4CSharpApiLoader.is_dotnet_supported(): + if not GdUnit4CSharpApiLoader.is_api_loaded(): return for test_case in GdUnit4CSharpApiLoader.discover_tests(source_script): discover_sink.call(test_case) diff --git a/addons/gdUnit4/src/core/discovery/GdUnitTestDiscoverer.gd.uid b/addons/gdUnit4/src/core/discovery/GdUnitTestDiscoverer.gd.uid index 981c3f9b..60028632 100644 --- a/addons/gdUnit4/src/core/discovery/GdUnitTestDiscoverer.gd.uid +++ b/addons/gdUnit4/src/core/discovery/GdUnitTestDiscoverer.gd.uid @@ -1 +1 @@ -uid://dkh40yvtnqoxw +uid://qubknuaxgms1 diff --git a/addons/gdUnit4/src/core/event/GdUnitEvent.gd.uid b/addons/gdUnit4/src/core/event/GdUnitEvent.gd.uid index 549a202f..e0f4f841 100644 --- a/addons/gdUnit4/src/core/event/GdUnitEvent.gd.uid +++ b/addons/gdUnit4/src/core/event/GdUnitEvent.gd.uid @@ -1 +1 @@ -uid://0bl5sfv34mjl +uid://mi4dinjy4nb8 diff --git a/addons/gdUnit4/src/core/event/GdUnitEventInit.gd.uid b/addons/gdUnit4/src/core/event/GdUnitEventInit.gd.uid index 919c791c..e0fb0946 100644 --- a/addons/gdUnit4/src/core/event/GdUnitEventInit.gd.uid +++ b/addons/gdUnit4/src/core/event/GdUnitEventInit.gd.uid @@ -1 +1 @@ -uid://bc6lj1xsoonhx +uid://durnex2gkjsea diff --git a/addons/gdUnit4/src/core/event/GdUnitEventStop.gd.uid b/addons/gdUnit4/src/core/event/GdUnitEventStop.gd.uid index db9b4a23..d31c5831 100644 --- a/addons/gdUnit4/src/core/event/GdUnitEventStop.gd.uid +++ b/addons/gdUnit4/src/core/event/GdUnitEventStop.gd.uid @@ -1 +1 @@ -uid://bsj6l1y8mebur +uid://bontcauq3i2y3 diff --git a/addons/gdUnit4/src/core/event/GdUnitEventTestDiscoverEnd.gd.uid b/addons/gdUnit4/src/core/event/GdUnitEventTestDiscoverEnd.gd.uid index 141a50b2..79bb2b1b 100644 --- a/addons/gdUnit4/src/core/event/GdUnitEventTestDiscoverEnd.gd.uid +++ b/addons/gdUnit4/src/core/event/GdUnitEventTestDiscoverEnd.gd.uid @@ -1 +1 @@ -uid://bpepiow1roltr +uid://i7i8rjh3m30m diff --git a/addons/gdUnit4/src/core/event/GdUnitEventTestDiscoverStart.gd.uid b/addons/gdUnit4/src/core/event/GdUnitEventTestDiscoverStart.gd.uid index 0f87c131..da5e9a03 100644 --- a/addons/gdUnit4/src/core/event/GdUnitEventTestDiscoverStart.gd.uid +++ b/addons/gdUnit4/src/core/event/GdUnitEventTestDiscoverStart.gd.uid @@ -1 +1 @@ -uid://cvawxva8c1imy +uid://coy02lpj7lgra diff --git a/addons/gdUnit4/src/core/execution/GdUnitExecutionContext.gd.uid b/addons/gdUnit4/src/core/execution/GdUnitExecutionContext.gd.uid index 20171dfc..eb4e8cef 100644 --- a/addons/gdUnit4/src/core/execution/GdUnitExecutionContext.gd.uid +++ b/addons/gdUnit4/src/core/execution/GdUnitExecutionContext.gd.uid @@ -1 +1 @@ -uid://d3efv548pfjn3 +uid://cybn5vv8g6ij4 diff --git a/addons/gdUnit4/src/core/execution/GdUnitMemoryObserver.gd.uid b/addons/gdUnit4/src/core/execution/GdUnitMemoryObserver.gd.uid index 272d4ebb..4f6c1f83 100644 --- a/addons/gdUnit4/src/core/execution/GdUnitMemoryObserver.gd.uid +++ b/addons/gdUnit4/src/core/execution/GdUnitMemoryObserver.gd.uid @@ -1 +1 @@ -uid://befegid5bg08s +uid://bbiwtyyvfpv74 diff --git a/addons/gdUnit4/src/core/execution/GdUnitTestReportCollector.gd.uid b/addons/gdUnit4/src/core/execution/GdUnitTestReportCollector.gd.uid index 009974b7..e8942d0f 100644 --- a/addons/gdUnit4/src/core/execution/GdUnitTestReportCollector.gd.uid +++ b/addons/gdUnit4/src/core/execution/GdUnitTestReportCollector.gd.uid @@ -1 +1 @@ -uid://r6m4c3af0jvf +uid://546waj3gx7jv diff --git a/addons/gdUnit4/src/core/execution/GdUnitTestSuiteExecutor.gd b/addons/gdUnit4/src/core/execution/GdUnitTestSuiteExecutor.gd index 1e1c08f9..b97f6fcd 100644 --- a/addons/gdUnit4/src/core/execution/GdUnitTestSuiteExecutor.gd +++ b/addons/gdUnit4/src/core/execution/GdUnitTestSuiteExecutor.gd @@ -23,9 +23,9 @@ func execute(test_suite :GdUnitTestSuite) -> void: func run_and_wait(tests: Array[GdUnitTestCase]) -> void: - # first we group all tests by his parent suite + # first we group all tests by resource path var grouped_by_suites := GdArrayTools.group_by(tests, func(test: GdUnitTestCase) -> String: - return test.source_file + return test.suite_resource_path ) var scanner := GdUnitTestSuiteScanner.new() for suite_path: String in grouped_by_suites.keys(): diff --git a/addons/gdUnit4/src/core/execution/GdUnitTestSuiteExecutor.gd.uid b/addons/gdUnit4/src/core/execution/GdUnitTestSuiteExecutor.gd.uid index a893e9b8..dc1bfb07 100644 --- a/addons/gdUnit4/src/core/execution/GdUnitTestSuiteExecutor.gd.uid +++ b/addons/gdUnit4/src/core/execution/GdUnitTestSuiteExecutor.gd.uid @@ -1 +1 @@ -uid://byu4stkw4742q +uid://cpopn8eaay2cn diff --git a/addons/gdUnit4/src/core/execution/stages/GdUnitTestCaseAfterStage.gd.uid b/addons/gdUnit4/src/core/execution/stages/GdUnitTestCaseAfterStage.gd.uid index 11b9385b..9ba20046 100644 --- a/addons/gdUnit4/src/core/execution/stages/GdUnitTestCaseAfterStage.gd.uid +++ b/addons/gdUnit4/src/core/execution/stages/GdUnitTestCaseAfterStage.gd.uid @@ -1 +1 @@ -uid://s5oftq7357lm +uid://cvta7ko1501fd diff --git a/addons/gdUnit4/src/core/execution/stages/GdUnitTestCaseBeforeStage.gd.uid b/addons/gdUnit4/src/core/execution/stages/GdUnitTestCaseBeforeStage.gd.uid index 9e433536..0783bdc4 100644 --- a/addons/gdUnit4/src/core/execution/stages/GdUnitTestCaseBeforeStage.gd.uid +++ b/addons/gdUnit4/src/core/execution/stages/GdUnitTestCaseBeforeStage.gd.uid @@ -1 +1 @@ -uid://xpwskm1g6xa7 +uid://ddgonfohcnc71 diff --git a/addons/gdUnit4/src/core/execution/stages/GdUnitTestCaseExecutionStage.gd.uid b/addons/gdUnit4/src/core/execution/stages/GdUnitTestCaseExecutionStage.gd.uid index d6cbf4bb..ee180cf6 100644 --- a/addons/gdUnit4/src/core/execution/stages/GdUnitTestCaseExecutionStage.gd.uid +++ b/addons/gdUnit4/src/core/execution/stages/GdUnitTestCaseExecutionStage.gd.uid @@ -1 +1 @@ -uid://d3ih04g8adile +uid://bvc28jl2py5uv diff --git a/addons/gdUnit4/src/core/execution/stages/GdUnitTestSuiteAfterStage.gd.uid b/addons/gdUnit4/src/core/execution/stages/GdUnitTestSuiteAfterStage.gd.uid index 5d7ec4bd..c9a2c8be 100644 --- a/addons/gdUnit4/src/core/execution/stages/GdUnitTestSuiteAfterStage.gd.uid +++ b/addons/gdUnit4/src/core/execution/stages/GdUnitTestSuiteAfterStage.gd.uid @@ -1 +1 @@ -uid://bk7tpgycds4bi +uid://c65ts615srhu4 diff --git a/addons/gdUnit4/src/core/execution/stages/GdUnitTestSuiteBeforeStage.gd.uid b/addons/gdUnit4/src/core/execution/stages/GdUnitTestSuiteBeforeStage.gd.uid index a1153692..5942fb12 100644 --- a/addons/gdUnit4/src/core/execution/stages/GdUnitTestSuiteBeforeStage.gd.uid +++ b/addons/gdUnit4/src/core/execution/stages/GdUnitTestSuiteBeforeStage.gd.uid @@ -1 +1 @@ -uid://dqowxiqnu8fdt +uid://3o45uqg6xq32 diff --git a/addons/gdUnit4/src/core/execution/stages/GdUnitTestSuiteExecutionStage.gd.uid b/addons/gdUnit4/src/core/execution/stages/GdUnitTestSuiteExecutionStage.gd.uid index a65d54cb..35d6581d 100644 --- a/addons/gdUnit4/src/core/execution/stages/GdUnitTestSuiteExecutionStage.gd.uid +++ b/addons/gdUnit4/src/core/execution/stages/GdUnitTestSuiteExecutionStage.gd.uid @@ -1 +1 @@ -uid://c4bbcbwcgesbb +uid://d1uxwd33mjg3t diff --git a/addons/gdUnit4/src/core/execution/stages/IGdUnitExecutionStage.gd.uid b/addons/gdUnit4/src/core/execution/stages/IGdUnitExecutionStage.gd.uid index 5b7733a3..b46b611a 100644 --- a/addons/gdUnit4/src/core/execution/stages/IGdUnitExecutionStage.gd.uid +++ b/addons/gdUnit4/src/core/execution/stages/IGdUnitExecutionStage.gd.uid @@ -1 +1 @@ -uid://c8homl26jnl3 +uid://dddrb70m1i27q diff --git a/addons/gdUnit4/src/core/execution/stages/fuzzed/GdUnitTestCaseFuzzedExecutionStage.gd.uid b/addons/gdUnit4/src/core/execution/stages/fuzzed/GdUnitTestCaseFuzzedExecutionStage.gd.uid index 35baec26..847a4336 100644 --- a/addons/gdUnit4/src/core/execution/stages/fuzzed/GdUnitTestCaseFuzzedExecutionStage.gd.uid +++ b/addons/gdUnit4/src/core/execution/stages/fuzzed/GdUnitTestCaseFuzzedExecutionStage.gd.uid @@ -1 +1 @@ -uid://dwnhibi8y605u +uid://bw02toxonv7i5 diff --git a/addons/gdUnit4/src/core/execution/stages/fuzzed/GdUnitTestCaseFuzzedTestStage.gd.uid b/addons/gdUnit4/src/core/execution/stages/fuzzed/GdUnitTestCaseFuzzedTestStage.gd.uid index 1f5ec810..996e12ac 100644 --- a/addons/gdUnit4/src/core/execution/stages/fuzzed/GdUnitTestCaseFuzzedTestStage.gd.uid +++ b/addons/gdUnit4/src/core/execution/stages/fuzzed/GdUnitTestCaseFuzzedTestStage.gd.uid @@ -1 +1 @@ -uid://bwl53ncmxcqnf +uid://cw0d366wx8i3n diff --git a/addons/gdUnit4/src/core/execution/stages/single/GdUnitTestCaseSingleExecutionStage.gd.uid b/addons/gdUnit4/src/core/execution/stages/single/GdUnitTestCaseSingleExecutionStage.gd.uid index 8aab3be1..dbe711b0 100644 --- a/addons/gdUnit4/src/core/execution/stages/single/GdUnitTestCaseSingleExecutionStage.gd.uid +++ b/addons/gdUnit4/src/core/execution/stages/single/GdUnitTestCaseSingleExecutionStage.gd.uid @@ -1 +1 @@ -uid://dudj2wcynwlla +uid://ijkm5vlud50 diff --git a/addons/gdUnit4/src/core/execution/stages/single/GdUnitTestCaseSingleTestStage.gd.uid b/addons/gdUnit4/src/core/execution/stages/single/GdUnitTestCaseSingleTestStage.gd.uid index c826c879..4cd87db7 100644 --- a/addons/gdUnit4/src/core/execution/stages/single/GdUnitTestCaseSingleTestStage.gd.uid +++ b/addons/gdUnit4/src/core/execution/stages/single/GdUnitTestCaseSingleTestStage.gd.uid @@ -1 +1 @@ -uid://5mf7vxiq00dn +uid://h1vt5ehmfpc4 diff --git a/addons/gdUnit4/src/core/parse/GdClassDescriptor.gd.uid b/addons/gdUnit4/src/core/parse/GdClassDescriptor.gd.uid index 54e24d96..def2ea99 100644 --- a/addons/gdUnit4/src/core/parse/GdClassDescriptor.gd.uid +++ b/addons/gdUnit4/src/core/parse/GdClassDescriptor.gd.uid @@ -1 +1 @@ -uid://cd7lic1hrb5vf +uid://tfw5f2av7ke7 diff --git a/addons/gdUnit4/src/core/parse/GdDefaultValueDecoder.gd b/addons/gdUnit4/src/core/parse/GdDefaultValueDecoder.gd index 202926ea..de8c29a6 100644 --- a/addons/gdUnit4/src/core/parse/GdDefaultValueDecoder.gd +++ b/addons/gdUnit4/src/core/parse/GdDefaultValueDecoder.gd @@ -255,6 +255,9 @@ static func decode(value: Variant) -> String: @warning_ignore("unsafe_cast") if GdArrayTools.is_type_array(type) and (value as Array).is_empty(): return "" + # For Variant types we need to determine the original type + if type == GdObjects.TYPE_VARIANT: + type = typeof(value) var decoder := _get_value_decoder(type) if decoder == null: push_error("No value decoder registered for type '%d'! Please open a Bug issue at 'https://github.com/MikeSchulze/gdUnit4/issues/new/choose'." % type) @@ -267,6 +270,9 @@ static func decode(value: Variant) -> String: static func decode_typed(type: int, value: Variant) -> String: if value == null: return "null" + # For Variant types we need to determine the original type + if type == GdObjects.TYPE_VARIANT: + type = typeof(value) var decoder := _get_value_decoder(type) if decoder == null: push_error("No value decoder registered for type '%d'! Please open a Bug issue at 'https://github.com/MikeSchulze/gdUnit4/issues/new/choose'." % type) diff --git a/addons/gdUnit4/src/core/parse/GdDefaultValueDecoder.gd.uid b/addons/gdUnit4/src/core/parse/GdDefaultValueDecoder.gd.uid index 7a16a92d..ed3167f3 100644 --- a/addons/gdUnit4/src/core/parse/GdDefaultValueDecoder.gd.uid +++ b/addons/gdUnit4/src/core/parse/GdDefaultValueDecoder.gd.uid @@ -1 +1 @@ -uid://bvcgb8ww4rpy1 +uid://ovt8lkvlngkq diff --git a/addons/gdUnit4/src/core/parse/GdFunctionArgument.gd b/addons/gdUnit4/src/core/parse/GdFunctionArgument.gd index 087cf408..1cc27dbf 100644 --- a/addons/gdUnit4/src/core/parse/GdFunctionArgument.gd +++ b/addons/gdUnit4/src/core/parse/GdFunctionArgument.gd @@ -57,7 +57,7 @@ func set_value(value: String) -> void: if _type == TYPE_NIL or _type == GdObjects.TYPE_VARIANT: _type = _extract_value_type(value) - if _type == GdObjects.TYPE_VARIANT: + if _type == GdObjects.TYPE_VARIANT and _default_value == null: _default_value = value if _default_value == null: match _type: @@ -131,7 +131,7 @@ func _to_string() -> String: s += ": " + GdObjects.type_as_string(_type) if _type_hint != TYPE_NIL: s += "[%s]" % GdObjects.type_as_string(_type_hint) - if typeof(_default_value) != TYPE_STRING: + if has_default(): s += "=" + value_as_string() return s diff --git a/addons/gdUnit4/src/core/parse/GdFunctionArgument.gd.uid b/addons/gdUnit4/src/core/parse/GdFunctionArgument.gd.uid index e8efb74a..30d9ff2c 100644 --- a/addons/gdUnit4/src/core/parse/GdFunctionArgument.gd.uid +++ b/addons/gdUnit4/src/core/parse/GdFunctionArgument.gd.uid @@ -1 +1 @@ -uid://c5iskcxtyerbi +uid://dnmyxq3ftdweh diff --git a/addons/gdUnit4/src/core/parse/GdFunctionDescriptor.gd.uid b/addons/gdUnit4/src/core/parse/GdFunctionDescriptor.gd.uid index 7edf93d8..ef68bd89 100644 --- a/addons/gdUnit4/src/core/parse/GdFunctionDescriptor.gd.uid +++ b/addons/gdUnit4/src/core/parse/GdFunctionDescriptor.gd.uid @@ -1 +1 @@ -uid://bbbvxjnaas2n8 +uid://cwmh0qkwy4lsv diff --git a/addons/gdUnit4/src/core/parse/GdFunctionParameterSetResolver.gd b/addons/gdUnit4/src/core/parse/GdFunctionParameterSetResolver.gd index bb3a11ac..9c45e625 100644 --- a/addons/gdUnit4/src/core/parse/GdFunctionParameterSetResolver.gd +++ b/addons/gdUnit4/src/core/parse/GdFunctionParameterSetResolver.gd @@ -26,7 +26,7 @@ func _init(fd: GdFunctionDescriptor) -> void: func resolve_test_cases(script: GDScript) -> Array[GdUnitTestCase]: if not is_parameterized(): - return [GdUnitTestCase.from(_fd.source_path(), _fd.line_number(), _fd.name())] + return [GdUnitTestCase.from(script.resource_path, _fd.source_path(), _fd.line_number(), _fd.name())] return extract_test_cases_by_reflection(script) @@ -94,7 +94,7 @@ func extract_test_cases_by_reflection(script: GDScript) -> Array[GdUnitTestCase] # if no parameter set detected we need to resolve it by using reflection if parameter_sets.size() == 0: _is_static = false - return _extract_test_cases_by_reflection(source) + return _extract_test_cases_by_reflection(source, script) else: var test_cases: Array[GdUnitTestCase] = [] var property_names := _extract_property_names(source) @@ -102,7 +102,7 @@ func extract_test_cases_by_reflection(script: GDScript) -> Array[GdUnitTestCase] var parameter_set := parameter_sets[parameter_set_index] _static_sets_by_index[parameter_set_index] = _is_static_parameter_set(parameter_set, property_names) @warning_ignore("return_value_discarded") - test_cases.append(GdUnitTestCase.from(_fd.source_path(), _fd.line_number(), _fd.name(), parameter_set_index, parameter_set)) + test_cases.append(GdUnitTestCase.from(script.resource_path, _fd.source_path(), _fd.line_number(), _fd.name(), parameter_set_index, parameter_set)) parameter_set_index += 1 return test_cases @@ -122,13 +122,13 @@ func _is_static_parameter_set(parameters :String, property_names :PackedStringAr return true -func _extract_test_cases_by_reflection(source: Node) -> Array[GdUnitTestCase]: +func _extract_test_cases_by_reflection(source: Node, script: GDScript) -> Array[GdUnitTestCase]: var parameter_sets := load_parameter_sets(source) var test_cases: Array[GdUnitTestCase] = [] for index in parameter_sets.size(): var parameter_set := str(parameter_sets[index]) @warning_ignore("return_value_discarded") - test_cases.append(GdUnitTestCase.from(_fd.source_path(), _fd.line_number(), _fd.name(), index, parameter_set)) + test_cases.append(GdUnitTestCase.from(script.resource_path, _fd.source_path(), _fd.line_number(), _fd.name(), index, parameter_set)) return test_cases diff --git a/addons/gdUnit4/src/core/parse/GdFunctionParameterSetResolver.gd.uid b/addons/gdUnit4/src/core/parse/GdFunctionParameterSetResolver.gd.uid index 183d61bd..ae174881 100644 --- a/addons/gdUnit4/src/core/parse/GdFunctionParameterSetResolver.gd.uid +++ b/addons/gdUnit4/src/core/parse/GdFunctionParameterSetResolver.gd.uid @@ -1 +1 @@ -uid://bk704y2xw4nyd +uid://cr7giifccl6bx diff --git a/addons/gdUnit4/src/core/parse/GdScriptParser.gd b/addons/gdUnit4/src/core/parse/GdScriptParser.gd index 83789361..7f8c7031 100644 --- a/addons/gdUnit4/src/core/parse/GdScriptParser.gd +++ b/addons/gdUnit4/src/core/parse/GdScriptParser.gd @@ -74,6 +74,7 @@ var _regex_clazz_name := GdUnitTools.to_regex("(class) ([a-zA-Z0-9_]+) (extends[ var _regex_strip_comments := GdUnitTools.to_regex("^([^#\"']|'[^']*'|\"[^\"]*\")*\\K#.*") var _scanned_inner_classes := PackedStringArray() var _script_constants := {} +var _is_awaiting := GdUnitTools.to_regex("\\bawait\\s+(?![^\"]*\"[^\"]*$)(?!.*#.*await)") static func to_unix_format(input :String) -> String: @@ -650,14 +651,17 @@ func _enrich_function_descriptor(script: GDScript, fds: Array[GdFunctionDescript func is_func_coroutine(rows :PackedStringArray, index :int) -> bool: var is_coroutine := false for rowIndex in range(index+1, rows.size()): - var input := rows[rowIndex] - is_coroutine = input.contains("await") - if is_coroutine: - return true + var input := rows[rowIndex].strip_edges() + # skip empty lines + if input.is_empty(): + continue var token := next_token(input, 0) # scan until next function if token == TOKEN_FUNCTION_STATIC_DECLARATION or token == TOKEN_FUNCTION_DECLARATION: break + + if _is_awaiting.search(input): + return true return is_coroutine diff --git a/addons/gdUnit4/src/core/parse/GdScriptParser.gd.uid b/addons/gdUnit4/src/core/parse/GdScriptParser.gd.uid index 4961e914..5580f706 100644 --- a/addons/gdUnit4/src/core/parse/GdScriptParser.gd.uid +++ b/addons/gdUnit4/src/core/parse/GdScriptParser.gd.uid @@ -1 +1 @@ -uid://b78j43ljfuk77 +uid://dkoi16up7my6t diff --git a/addons/gdUnit4/src/core/parse/GdUnitExpressionRunner.gd.uid b/addons/gdUnit4/src/core/parse/GdUnitExpressionRunner.gd.uid index a45cbb43..a9351687 100644 --- a/addons/gdUnit4/src/core/parse/GdUnitExpressionRunner.gd.uid +++ b/addons/gdUnit4/src/core/parse/GdUnitExpressionRunner.gd.uid @@ -1 +1 @@ -uid://b1yoqtvbi13bp +uid://db0x6bk6p662j diff --git a/addons/gdUnit4/src/core/parse/GdUnitTestParameterSetResolver.gd.uid b/addons/gdUnit4/src/core/parse/GdUnitTestParameterSetResolver.gd.uid index aad421fd..a338cc7d 100644 --- a/addons/gdUnit4/src/core/parse/GdUnitTestParameterSetResolver.gd.uid +++ b/addons/gdUnit4/src/core/parse/GdUnitTestParameterSetResolver.gd.uid @@ -1 +1 @@ -uid://cxrcrn0fwe7u6 +uid://dqtbrkqywyioi diff --git a/addons/gdUnit4/src/core/report/GdUnitReport.gd.uid b/addons/gdUnit4/src/core/report/GdUnitReport.gd.uid index 97b6e99d..3440b552 100644 --- a/addons/gdUnit4/src/core/report/GdUnitReport.gd.uid +++ b/addons/gdUnit4/src/core/report/GdUnitReport.gd.uid @@ -1 +1 @@ -uid://bvq0loao62flo +uid://2uqm256ou7l4 diff --git a/addons/gdUnit4/src/core/runners/GdUnitBaseTestRunner.gd.uid b/addons/gdUnit4/src/core/runners/GdUnitBaseTestRunner.gd.uid index 43b27cef..cc91c2a9 100644 --- a/addons/gdUnit4/src/core/runners/GdUnitBaseTestRunner.gd.uid +++ b/addons/gdUnit4/src/core/runners/GdUnitBaseTestRunner.gd.uid @@ -1 +1 @@ -uid://d067xlq7k011y +uid://diaekfrhgif7n diff --git a/addons/gdUnit4/src/core/runners/GdUnitTestCIRunner.gd.uid b/addons/gdUnit4/src/core/runners/GdUnitTestCIRunner.gd.uid index 6bd3a81e..5859a2d3 100644 --- a/addons/gdUnit4/src/core/runners/GdUnitTestCIRunner.gd.uid +++ b/addons/gdUnit4/src/core/runners/GdUnitTestCIRunner.gd.uid @@ -1 +1 @@ -uid://bj5xoyqhuebbg +uid://bbmp0coocwb6p diff --git a/addons/gdUnit4/src/core/runners/GdUnitTestRunner.gd.uid b/addons/gdUnit4/src/core/runners/GdUnitTestRunner.gd.uid index aff91a66..22b2fcb0 100644 --- a/addons/gdUnit4/src/core/runners/GdUnitTestRunner.gd.uid +++ b/addons/gdUnit4/src/core/runners/GdUnitTestRunner.gd.uid @@ -1 +1 @@ -uid://ck1aurdyu3fdc +uid://dfybw0apor6w6 diff --git a/addons/gdUnit4/src/core/runners/GdUnitTestRunner.tscn b/addons/gdUnit4/src/core/runners/GdUnitTestRunner.tscn index 1da430e4..afffc171 100644 --- a/addons/gdUnit4/src/core/runners/GdUnitTestRunner.tscn +++ b/addons/gdUnit4/src/core/runners/GdUnitTestRunner.tscn @@ -1,7 +1,7 @@ [gd_scene load_steps=3 format=3 uid="uid://belidlfknh74r"] -[ext_resource type="Script" uid="uid://cewyamo5wr2xw" path="res://addons/gdUnit4/src/core/runners/GdUnitTestRunner.gd" id="1"] -[ext_resource type="Script" uid="uid://cp5knenan84na" path="res://addons/gdUnit4/src/network/GdUnitTcpClient.gd" id="2"] +[ext_resource type="Script" path="res://addons/gdUnit4/src/core/runners/GdUnitTestRunner.gd" id="1"] +[ext_resource type="Script" path="res://addons/gdUnit4/src/network/GdUnitTcpClient.gd" id="2"] [node name="Control" type="Node"] script = ExtResource("1") diff --git a/addons/gdUnit4/src/core/templates/test_suite/GdUnitTestSuiteDefaultTemplate.gd.uid b/addons/gdUnit4/src/core/templates/test_suite/GdUnitTestSuiteDefaultTemplate.gd.uid index 8a49357c..8bdf1f42 100644 --- a/addons/gdUnit4/src/core/templates/test_suite/GdUnitTestSuiteDefaultTemplate.gd.uid +++ b/addons/gdUnit4/src/core/templates/test_suite/GdUnitTestSuiteDefaultTemplate.gd.uid @@ -1 +1 @@ -uid://byso8v2terhtt +uid://0mughm34cuxb diff --git a/addons/gdUnit4/src/core/templates/test_suite/GdUnitTestSuiteTemplate.gd.uid b/addons/gdUnit4/src/core/templates/test_suite/GdUnitTestSuiteTemplate.gd.uid index 30c8f638..04df5344 100644 --- a/addons/gdUnit4/src/core/templates/test_suite/GdUnitTestSuiteTemplate.gd.uid +++ b/addons/gdUnit4/src/core/templates/test_suite/GdUnitTestSuiteTemplate.gd.uid @@ -1 +1 @@ -uid://c14u8ppcco1at +uid://u7tl5obo6ss7 diff --git a/addons/gdUnit4/src/core/thread/GdUnitThreadContext.gd.uid b/addons/gdUnit4/src/core/thread/GdUnitThreadContext.gd.uid index 28f25fcc..66e8f059 100644 --- a/addons/gdUnit4/src/core/thread/GdUnitThreadContext.gd.uid +++ b/addons/gdUnit4/src/core/thread/GdUnitThreadContext.gd.uid @@ -1 +1 @@ -uid://12h8llwtn2r5 +uid://bllwdumm80bl1 diff --git a/addons/gdUnit4/src/core/thread/GdUnitThreadManager.gd.uid b/addons/gdUnit4/src/core/thread/GdUnitThreadManager.gd.uid index 58f9b6cf..e5586a7c 100644 --- a/addons/gdUnit4/src/core/thread/GdUnitThreadManager.gd.uid +++ b/addons/gdUnit4/src/core/thread/GdUnitThreadManager.gd.uid @@ -1 +1 @@ -uid://cwxjlrkeyjqso +uid://b8nbf5wokdtiy diff --git a/addons/gdUnit4/src/core/writers/GdUnitCSIMessageWriter.gd.uid b/addons/gdUnit4/src/core/writers/GdUnitCSIMessageWriter.gd.uid index d3fbc18d..3ecb2f58 100644 --- a/addons/gdUnit4/src/core/writers/GdUnitCSIMessageWriter.gd.uid +++ b/addons/gdUnit4/src/core/writers/GdUnitCSIMessageWriter.gd.uid @@ -1 +1 @@ -uid://dd0l0xtkj75j +uid://ofhpc2ovxde4 diff --git a/addons/gdUnit4/src/core/writers/GdUnitMessageWriter.gd.uid b/addons/gdUnit4/src/core/writers/GdUnitMessageWriter.gd.uid index e5af79ed..880d1ed8 100644 --- a/addons/gdUnit4/src/core/writers/GdUnitMessageWriter.gd.uid +++ b/addons/gdUnit4/src/core/writers/GdUnitMessageWriter.gd.uid @@ -1 +1 @@ -uid://b68mtydadk8xp +uid://ccsi7syb3wtgy diff --git a/addons/gdUnit4/src/core/writers/GdUnitRichTextMessageWriter.gd.uid b/addons/gdUnit4/src/core/writers/GdUnitRichTextMessageWriter.gd.uid index 02a36e64..dc9ce006 100644 --- a/addons/gdUnit4/src/core/writers/GdUnitRichTextMessageWriter.gd.uid +++ b/addons/gdUnit4/src/core/writers/GdUnitRichTextMessageWriter.gd.uid @@ -1 +1 @@ -uid://53rfaenrwp4p +uid://bfxdwhov4a0iv diff --git a/addons/gdUnit4/src/dotnet/GdUnit4CSharpApi.cs b/addons/gdUnit4/src/dotnet/GdUnit4CSharpApi.cs index af8320f4..d62d3da3 100644 --- a/addons/gdUnit4/src/dotnet/GdUnit4CSharpApi.cs +++ b/addons/gdUnit4/src/dotnet/GdUnit4CSharpApi.cs @@ -1,204 +1,176 @@ namespace gdUnit4.addons.gdUnit4.src.dotnet; +#if GDUNIT4NET_API_V5 using System; using System.Collections.Generic; -using System.Collections.Immutable; using System.Linq; -using System.Reflection; using System.Threading; using System.Threading.Tasks; +using GdUnit4; using GdUnit4.Api; -using GdUnit4.Core.Discovery; using Godot; using Godot.Collections; // GdUnit4 GDScript - C# API wrapper // ReSharper disable once CheckNamespace +public partial class GdUnit4CSharpApi : GdUnit4NetApiGodotBridge +{ + [Signal] + public delegate void ExecutionCompletedEventHandler(); + + private CancellationTokenSource? executionCts; + + public override void _Notification(int what) + { + if (what != NotificationPredelete) + return; + executionCts?.Dispose(); + executionCts = null; + } + + public static bool IsApiLoaded() + => true; + + public static Array DiscoverTests(CSharpScript sourceScript) + { + try + { + // Get the list of test case descriptors from the API + var testCaseDescriptors = DiscoverTestsFromScript(sourceScript); + // Convert each TestCaseDescriptor to a Dictionary + return testCaseDescriptors + .Select(descriptor => new Dictionary + { + ["guid"] = descriptor.Id.ToString(), + ["managed_type"] = descriptor.ManagedType, + ["test_name"] = descriptor.ManagedMethod, + ["source_file"] = sourceScript.ResourcePath, + ["line_number"] = descriptor.LineNumber, + ["attribute_index"] = descriptor.AttributeIndex, + ["require_godot_runtime"] = descriptor.RequireRunningGodotEngine, + ["code_file_path"] = descriptor.CodeFilePath ?? "", + ["simple_name"] = descriptor.SimpleName, + ["fully_qualified_name"] = descriptor.FullyQualifiedName, + ["assembly_location"] = descriptor.AssemblyPath + }) + .Aggregate(new Array(), (array, dict) => + { + array.Add(dict); + return array; + }); + } + catch (Exception e) + { + GD.PrintErr($"Error discovering tests: {e.Message}\n{e.StackTrace}"); + return new Array(); + } + } + + public void ExecuteAsync(Array tests, Callable listener) + { + try + { + // Cancel any ongoing execution + executionCts?.Cancel(); + executionCts?.Dispose(); + + // Create new cancellation token source + executionCts = new CancellationTokenSource(); + + var testSuiteNodes = new List { BuildTestSuiteNodeFrom(tests) }; + ExecuteAsync(testSuiteNodes, listener, executionCts.Token) + .GetAwaiter() + .OnCompleted(() => EmitSignal(SignalName.ExecutionCompleted)); + } + catch (Exception e) + { + GD.PrintErr($"Error executing tests: {e.Message}\n{e.StackTrace}"); + Task.Run(() => { }).GetAwaiter().OnCompleted(() => EmitSignal(SignalName.ExecutionCompleted)); + } + } + + public void CancelExecution() + { + try + { + executionCts?.Cancel(); + } + catch (Exception e) + { + GD.PrintErr($"Error cancelling execution: {e.Message}"); + } + } + + // Convert a set of Tests stored as Dictionaries to TestSuiteNode + // all tests are assigned to a single test suit + internal static TestSuiteNode BuildTestSuiteNodeFrom(Array tests) + { + if (tests.Count == 0) + throw new InvalidOperationException("Cant build 'TestSuiteNode' from an empty test set."); + + // Create a suite ID + var suiteId = Guid.NewGuid(); + var firstTest = tests[0]; + var managedType = firstTest["managed_type"].AsString(); + var assemblyLocation = firstTest["assembly_location"].AsString(); + var sourceFile = firstTest["source_file"].AsString(); + + // Create TestCaseNodes for each test in the suite + var testCaseNodes = tests + .Select(test => new TestCaseNode + { + Id = Guid.Parse(test["guid"].AsString()), + ParentId = suiteId, + ManagedMethod = test["test_name"].AsString(), + LineNumber = test["line_number"].AsInt32(), + AttributeIndex = test["attribute_index"].AsInt32(), + RequireRunningGodotEngine = test["require_godot_runtime"].AsBool() + } + ) + .ToList(); + + return new TestSuiteNode + { + Id = suiteId, + ParentId = Guid.Empty, + ManagedType = managedType, + AssemblyPath = assemblyLocation, + SourceFile = sourceFile, + Tests = testCaseNodes + }; + } +} +#else +using Godot; +using Godot.Collections; + public partial class GdUnit4CSharpApi : RefCounted { - [Signal] - public delegate void ExecutionCompletedEventHandler(); - - private static readonly object LockObject = new(); - - private static Type? apiType; - private static Assembly? gdUnit4Api; - private CancellationTokenSource? executionCts; - - public override void _Notification(int what) - { - if (what != NotificationPredelete) - return; - executionCts?.Dispose(); - executionCts = null; - } - - private static Assembly GetApi() - { - if (gdUnit4Api != null) - return gdUnit4Api; - lock (LockObject) - return gdUnit4Api ??= Assembly.Load("gdUnit4Api"); - } - - private static Type? GetApiType() - { - if (apiType != null) - return apiType; - apiType = GetApi().GetType("GdUnit4.GdUnit4NetApiGodotBridge"); - return apiType; - } - - private static Version? GdUnit4NetVersion() - { - try - { - return GetApi().GetName().Version; - } - catch (Exception) - { - return null; - } - } - - private static T? InvokeApiMethod(string methodName, params object[] args) - { - var method = GetApiType()?.GetMethod(methodName) ?? - throw new MethodAccessException($"Can't invoke method {methodName}"); - return (T?)method.Invoke(null, args); - } - - public static bool FindGdUnit4NetAssembly() - { - try - { - return GetApi().GetType("GdUnit4.GdUnit4NetApiGodotBridge") != null; - } - catch (Exception) - { - return false; - } - } - - public static string Version() - => GdUnit4NetVersion()?.ToString() - ?? "Unknown"; - - public static bool IsTestSuite(CSharpScript script) - => InvokeApiMethod("IsTestSuite", script); - - public static Array DiscoverTests(CSharpScript sourceScript) - { - try - { - // Get the list of test case descriptors from the API - var testCaseDescriptors = InvokeApiMethod>("DiscoverTestsFromScript", sourceScript)!; - // Convert each TestCaseDescriptor to a Dictionary - return testCaseDescriptors - .Select(descriptor => new Dictionary - { - ["guid"] = descriptor.Id.ToString(), - ["managed_type"] = descriptor.ManagedType, - ["test_name"] = descriptor.ManagedMethod, - ["source_file"] = sourceScript.ResourcePath, - ["line_number"] = descriptor.LineNumber, - ["attribute_index"] = descriptor.AttributeIndex, - ["require_godot_runtime"] = descriptor.RequireRunningGodotEngine, - ["code_file_path"] = descriptor.CodeFilePath ?? "", - ["simple_name"] = descriptor.SimpleName, - ["fully_qualified_name"] = descriptor.FullyQualifiedName, - ["assembly_location"] = descriptor.AssemblyPath - }) - .Aggregate(new Array(), (array, dict) => - { - array.Add(dict); - return array; - }); - } - catch (Exception e) - { - GD.PrintErr($"Error discovering tests: {e.Message}\n{e.StackTrace}"); - return new Array(); - } - } - - public void ExecuteAsync(Array tests, Callable listener) - { - try - { - // Cancel any ongoing execution - executionCts?.Cancel(); - executionCts?.Dispose(); - - // Create new cancellation token source - executionCts = new CancellationTokenSource(); - - var testSuiteNodes = new List { BuildTestSuiteNodeFrom(tests) }; - InvokeApiMethod("ExecuteAsync", testSuiteNodes, listener, executionCts.Token)? - .GetAwaiter() - .OnCompleted(() => EmitSignal(SignalName.ExecutionCompleted)); - } - catch (Exception e) - { - GD.PrintErr($"Error executing tests: {e.Message}\n{e.StackTrace}"); - Task.Run(() => { }).GetAwaiter().OnCompleted(() => EmitSignal(SignalName.ExecutionCompleted)); - } - } - - public void CancelExecution() - { - try - { - executionCts?.Cancel(); - } - catch (Exception e) - { - GD.PrintErr($"Error cancelling execution: {e.Message}"); - } - } - - public static Dictionary CreateTestSuite(string sourcePath, int lineNumber, string testSuitePath) - => InvokeApiMethod("CreateTestSuite", sourcePath, lineNumber, testSuitePath)!; - - - // Convert a set of Tests stored as Dictionaries to TestSuiteNode - // all tests are assigned to a single test suit - internal static TestSuiteNode BuildTestSuiteNodeFrom(Array tests) - { - if (tests.Count == 0) - throw new InvalidOperationException("Cant build 'TestSuiteNode' from an empty test set."); - - // Create a suite ID - var suiteId = Guid.NewGuid(); - var firstTest = tests[0]; - var managedType = firstTest["managed_type"].AsString(); - var assemblyLocation = firstTest["assembly_location"].AsString(); - var sourceFile = firstTest["source_file"].AsString(); - - // Create TestCaseNodes for each test in the suite - var testCaseNodes = tests - .Select(test => new TestCaseNode - { - Id = Guid.Parse(test["guid"].AsString()), - ParentId = suiteId, - ManagedMethod = test["test_name"].AsString(), - LineNumber = test["line_number"].AsInt32(), - AttributeIndex = test["attribute_index"].AsInt32(), - RequireRunningGodotEngine = test["require_godot_runtime"].AsBool() - } - ) - .ToList(); - - return new TestSuiteNode - { - Id = suiteId, - ParentId = Guid.Empty, - ManagedType = managedType, - AssemblyPath = assemblyLocation, - SourceFile = sourceFile, - Tests = testCaseNodes - }; - } + [Signal] + public delegate void ExecutionCompletedEventHandler(); + + public static bool IsApiLoaded() + { + GD.PushWarning("No `gdunit4.api` dependency found, check your project dependencies."); + return false; + } + + + public static string Version() + => "Unknown"; + + public static Array DiscoverTests(CSharpScript sourceScript) => new(); + + public void ExecuteAsync(Array tests, Callable listener) + { + } + + public static bool IsTestSuite(CSharpScript script) + => false; + + public static Dictionary CreateTestSuite(string sourcePath, int lineNumber, string testSuitePath) + => new(); } +#endif diff --git a/addons/gdUnit4/src/dotnet/GdUnit4CSharpApiLoader.gd b/addons/gdUnit4/src/dotnet/GdUnit4CSharpApiLoader.gd index 398afbe9..199570c6 100644 --- a/addons/gdUnit4/src/dotnet/GdUnit4CSharpApiLoader.gd +++ b/addons/gdUnit4/src/dotnet/GdUnit4CSharpApiLoader.gd @@ -32,7 +32,7 @@ static var _test_event_listener := TestEventListener.new() ## Returns an instance of the GdUnit4CSharpApi wrapper.[br] ## @return Script: The loaded C# wrapper or null if .NET is not supported static func instance() -> Script: - if not GdUnit4CSharpApiLoader.is_dotnet_supported(): + if not GdUnit4CSharpApiLoader.is_api_loaded(): return null return _gdUnit4NetWrapper @@ -41,7 +41,7 @@ static func instance() -> Script: ## Returns or creates a single instance of the API [br] ## This improves performance by reusing the same object static func api_instance() -> RefCounted: - if _api_instance == null and is_dotnet_supported(): + if _api_instance == null and is_api_loaded(): @warning_ignore("unsafe_method_access") _api_instance = instance().new() return _api_instance @@ -52,14 +52,8 @@ static func is_engine_version_supported(engine_version: int = Engine.get_version ## Checks if the .NET environment is properly configured and available.[br] -## This performs multiple checks:[br] -## 1. Verifies if the wrapper is already loaded[br] -## 2. Confirms Godot has C# support[br] -## 3. Validates the project's C# configuration[br] -## 4. Attempts to load the wrapper and find the GdUnit4 assembly[br] -## ## @return bool: True if .NET is fully supported and the assembly is found -static func is_dotnet_supported() -> bool: +static func is_api_loaded() -> bool: # If the wrapper is already loaded we don't need to check again if _gdUnit4NetWrapper != null: return true @@ -74,13 +68,14 @@ static func is_dotnet_supported() -> bool: # Finally load the wrapper and check if the GdUnit4 assembly can be found _gdUnit4NetWrapper = load("res://addons/gdUnit4/src/dotnet/GdUnit4CSharpApi.cs") - return _gdUnit4NetWrapper != null and _gdUnit4NetWrapper.call("FindGdUnit4NetAssembly") + @warning_ignore("unsafe_method_access") + return _gdUnit4NetWrapper.IsApiLoaded() ## Returns the version of the GdUnit4 .NET assembly.[br] ## @return String: The version string or "unknown" if .NET is not supported static func version() -> String: - if not GdUnit4CSharpApiLoader.is_dotnet_supported(): + if not GdUnit4CSharpApiLoader.is_api_loaded(): return "unknown" @warning_ignore("unsafe_method_access") return instance().Version() @@ -105,7 +100,7 @@ static func execute(tests: Array[GdUnitTestCase]) -> void: static func create_test_suite(source_path: String, line_number: int, test_suite_path: String) -> GdUnitResult: - if not GdUnit4CSharpApiLoader.is_dotnet_supported(): + if not GdUnit4CSharpApiLoader.is_api_loaded(): return GdUnitResult.error("Can't create test suite. No .NET support found.") @warning_ignore("unsafe_method_access") var result: Dictionary = instance().CreateTestSuite(source_path, line_number, test_suite_path) @@ -114,11 +109,6 @@ static func create_test_suite(source_path: String, line_number: int, test_suite_ return GdUnitResult.success(result) -static func is_test_suite(script: Script) -> bool: - @warning_ignore("unsafe_method_access") - return instance().IsTestSuite(script) - - static func is_csharp_file(resource_path: String) -> bool: var ext := resource_path.get_extension() - return ext == "cs" and GdUnit4CSharpApiLoader.is_dotnet_supported() + return ext == "cs" and GdUnit4CSharpApiLoader.is_api_loaded() diff --git a/addons/gdUnit4/src/dotnet/GdUnit4CSharpApiLoader.gd.uid b/addons/gdUnit4/src/dotnet/GdUnit4CSharpApiLoader.gd.uid index 0d1c56ab..d46ee2c1 100644 --- a/addons/gdUnit4/src/dotnet/GdUnit4CSharpApiLoader.gd.uid +++ b/addons/gdUnit4/src/dotnet/GdUnit4CSharpApiLoader.gd.uid @@ -1 +1 @@ -uid://em6wu2kmyv05 +uid://clbrjt518h411 diff --git a/addons/gdUnit4/src/doubler/CallableDoubler.gd.uid b/addons/gdUnit4/src/doubler/CallableDoubler.gd.uid index 9c937dca..44ccbcc6 100644 --- a/addons/gdUnit4/src/doubler/CallableDoubler.gd.uid +++ b/addons/gdUnit4/src/doubler/CallableDoubler.gd.uid @@ -1 +1 @@ -uid://c44li8m22q2g +uid://bekuscrnacsu8 diff --git a/addons/gdUnit4/src/doubler/GdFunctionDoubler.gd b/addons/gdUnit4/src/doubler/GdFunctionDoubler.gd index 892e65c8..090b71df 100644 --- a/addons/gdUnit4/src/doubler/GdFunctionDoubler.gd +++ b/addons/gdUnit4/src/doubler/GdFunctionDoubler.gd @@ -200,8 +200,12 @@ static func typeless_args(descriptor: GdFunctionDescriptor) -> String: var collect := PackedStringArray() for arg in descriptor.args(): if arg.has_default(): - @warning_ignore("return_value_discarded") - collect.push_back(arg.name() + "_" + "=" + arg.value_as_string()) + # For Variant types we need to enforce the type in the signature + if arg.type() == GdObjects.TYPE_VARIANT: + collect.push_back("%s_:%s=%s" % [arg.name(), GdObjects.type_as_string(arg.type()), arg.value_as_string()]) + else: + @warning_ignore("return_value_discarded") + collect.push_back("%s_=%s" % [arg.name(), arg.value_as_string()]) else: @warning_ignore("return_value_discarded") collect.push_back(arg.name() + "_") diff --git a/addons/gdUnit4/src/doubler/GdFunctionDoubler.gd.uid b/addons/gdUnit4/src/doubler/GdFunctionDoubler.gd.uid index e0c3e24e..158d6f6a 100644 --- a/addons/gdUnit4/src/doubler/GdFunctionDoubler.gd.uid +++ b/addons/gdUnit4/src/doubler/GdFunctionDoubler.gd.uid @@ -1 +1 @@ -uid://c7snbahh8hwm3 +uid://hdyhj2fbcegc diff --git a/addons/gdUnit4/src/doubler/GdUnitClassDoubler.gd.uid b/addons/gdUnit4/src/doubler/GdUnitClassDoubler.gd.uid index c85f07a2..7b2ae3e0 100644 --- a/addons/gdUnit4/src/doubler/GdUnitClassDoubler.gd.uid +++ b/addons/gdUnit4/src/doubler/GdUnitClassDoubler.gd.uid @@ -1 +1 @@ -uid://by7gx6owx6r0u +uid://dliu4g7unhwj5 diff --git a/addons/gdUnit4/src/doubler/GdUnitObjectInteractions.gd.uid b/addons/gdUnit4/src/doubler/GdUnitObjectInteractions.gd.uid index 742a23df..8b646db9 100644 --- a/addons/gdUnit4/src/doubler/GdUnitObjectInteractions.gd.uid +++ b/addons/gdUnit4/src/doubler/GdUnitObjectInteractions.gd.uid @@ -1 +1 @@ -uid://bx7ng06gj6xt2 +uid://ct4khumjijdfm diff --git a/addons/gdUnit4/src/doubler/GdUnitObjectInteractionsVerifier.gd.uid b/addons/gdUnit4/src/doubler/GdUnitObjectInteractionsVerifier.gd.uid index 3db11b0b..80928c20 100644 --- a/addons/gdUnit4/src/doubler/GdUnitObjectInteractionsVerifier.gd.uid +++ b/addons/gdUnit4/src/doubler/GdUnitObjectInteractionsVerifier.gd.uid @@ -1 +1 @@ -uid://7ni6p5fmj303 +uid://peakocc268o5 diff --git a/addons/gdUnit4/src/extractors/GdUnitFuncValueExtractor.gd.uid b/addons/gdUnit4/src/extractors/GdUnitFuncValueExtractor.gd.uid index 2503e518..66656317 100644 --- a/addons/gdUnit4/src/extractors/GdUnitFuncValueExtractor.gd.uid +++ b/addons/gdUnit4/src/extractors/GdUnitFuncValueExtractor.gd.uid @@ -1 +1 @@ -uid://bnykspgpnndrk +uid://drpfbnkhhiue diff --git a/addons/gdUnit4/src/fuzzers/FloatFuzzer.gd.uid b/addons/gdUnit4/src/fuzzers/FloatFuzzer.gd.uid index 9b5ac982..ba66d779 100644 --- a/addons/gdUnit4/src/fuzzers/FloatFuzzer.gd.uid +++ b/addons/gdUnit4/src/fuzzers/FloatFuzzer.gd.uid @@ -1 +1 @@ -uid://d05keunlyb13g +uid://b7y4t0ub35p13 diff --git a/addons/gdUnit4/src/fuzzers/Fuzzer.gd.uid b/addons/gdUnit4/src/fuzzers/Fuzzer.gd.uid index 1d1bc1b1..e72dd2c9 100644 --- a/addons/gdUnit4/src/fuzzers/Fuzzer.gd.uid +++ b/addons/gdUnit4/src/fuzzers/Fuzzer.gd.uid @@ -1 +1 @@ -uid://dn4s1yxhf58rv +uid://e337t4bar8cp diff --git a/addons/gdUnit4/src/fuzzers/IntFuzzer.gd.uid b/addons/gdUnit4/src/fuzzers/IntFuzzer.gd.uid index 73bd8501..cf79c329 100644 --- a/addons/gdUnit4/src/fuzzers/IntFuzzer.gd.uid +++ b/addons/gdUnit4/src/fuzzers/IntFuzzer.gd.uid @@ -1 +1 @@ -uid://bvyh3bnhntg8f +uid://vtek3ibtchre diff --git a/addons/gdUnit4/src/fuzzers/StringFuzzer.gd.uid b/addons/gdUnit4/src/fuzzers/StringFuzzer.gd.uid index d45396a5..398c6405 100644 --- a/addons/gdUnit4/src/fuzzers/StringFuzzer.gd.uid +++ b/addons/gdUnit4/src/fuzzers/StringFuzzer.gd.uid @@ -1 +1 @@ -uid://cmghw5dtcdrxl +uid://dq400wh5q0ilk diff --git a/addons/gdUnit4/src/fuzzers/Vector2Fuzzer.gd.uid b/addons/gdUnit4/src/fuzzers/Vector2Fuzzer.gd.uid index 36643e8c..42a623da 100644 --- a/addons/gdUnit4/src/fuzzers/Vector2Fuzzer.gd.uid +++ b/addons/gdUnit4/src/fuzzers/Vector2Fuzzer.gd.uid @@ -1 +1 @@ -uid://c0nafcj411138 +uid://bg3nrrvm61ptw diff --git a/addons/gdUnit4/src/fuzzers/Vector3Fuzzer.gd.uid b/addons/gdUnit4/src/fuzzers/Vector3Fuzzer.gd.uid index cb55b26b..1975a70e 100644 --- a/addons/gdUnit4/src/fuzzers/Vector3Fuzzer.gd.uid +++ b/addons/gdUnit4/src/fuzzers/Vector3Fuzzer.gd.uid @@ -1 +1 @@ -uid://bdw37s7i5ddgy +uid://b8dicnlqjqvv1 diff --git a/addons/gdUnit4/src/matchers/AnyArgumentMatcher.gd.uid b/addons/gdUnit4/src/matchers/AnyArgumentMatcher.gd.uid index 418aba02..6bd02e24 100644 --- a/addons/gdUnit4/src/matchers/AnyArgumentMatcher.gd.uid +++ b/addons/gdUnit4/src/matchers/AnyArgumentMatcher.gd.uid @@ -1 +1 @@ -uid://8wtpiv1qvpg6 +uid://clgomxdt2lcgv diff --git a/addons/gdUnit4/src/matchers/AnyBuildInTypeArgumentMatcher.gd.uid b/addons/gdUnit4/src/matchers/AnyBuildInTypeArgumentMatcher.gd.uid index 54dcb2d0..c2eee052 100644 --- a/addons/gdUnit4/src/matchers/AnyBuildInTypeArgumentMatcher.gd.uid +++ b/addons/gdUnit4/src/matchers/AnyBuildInTypeArgumentMatcher.gd.uid @@ -1 +1 @@ -uid://bpvbfh6rscg6b +uid://bg18q33ici5x3 diff --git a/addons/gdUnit4/src/matchers/AnyClazzArgumentMatcher.gd.uid b/addons/gdUnit4/src/matchers/AnyClazzArgumentMatcher.gd.uid index c75956c7..98124612 100644 --- a/addons/gdUnit4/src/matchers/AnyClazzArgumentMatcher.gd.uid +++ b/addons/gdUnit4/src/matchers/AnyClazzArgumentMatcher.gd.uid @@ -1 +1 @@ -uid://berqup1jifqvo +uid://dvmgtradtmap1 diff --git a/addons/gdUnit4/src/matchers/ChainedArgumentMatcher.gd.uid b/addons/gdUnit4/src/matchers/ChainedArgumentMatcher.gd.uid index 12a810d8..0918179f 100644 --- a/addons/gdUnit4/src/matchers/ChainedArgumentMatcher.gd.uid +++ b/addons/gdUnit4/src/matchers/ChainedArgumentMatcher.gd.uid @@ -1 +1 @@ -uid://bxfddo1mxd7yk +uid://bf7cly10vkif1 diff --git a/addons/gdUnit4/src/matchers/EqualsArgumentMatcher.gd.uid b/addons/gdUnit4/src/matchers/EqualsArgumentMatcher.gd.uid index 4066bdc8..3c9dbb33 100644 --- a/addons/gdUnit4/src/matchers/EqualsArgumentMatcher.gd.uid +++ b/addons/gdUnit4/src/matchers/EqualsArgumentMatcher.gd.uid @@ -1 +1 @@ -uid://dptx538y0iv5 +uid://b5g3fu6ia18v3 diff --git a/addons/gdUnit4/src/matchers/GdUnitArgumentMatcher.gd.uid b/addons/gdUnit4/src/matchers/GdUnitArgumentMatcher.gd.uid index da99d3a3..f12b045b 100644 --- a/addons/gdUnit4/src/matchers/GdUnitArgumentMatcher.gd.uid +++ b/addons/gdUnit4/src/matchers/GdUnitArgumentMatcher.gd.uid @@ -1 +1 @@ -uid://lcfje3tsypup +uid://ca01bqnc2dfi5 diff --git a/addons/gdUnit4/src/matchers/GdUnitArgumentMatchers.gd.uid b/addons/gdUnit4/src/matchers/GdUnitArgumentMatchers.gd.uid index f0d7dc53..db251d07 100644 --- a/addons/gdUnit4/src/matchers/GdUnitArgumentMatchers.gd.uid +++ b/addons/gdUnit4/src/matchers/GdUnitArgumentMatchers.gd.uid @@ -1 +1 @@ -uid://c8voejjm5titg +uid://k5if1ve7sf4f diff --git a/addons/gdUnit4/src/mocking/GdUnitMock.gd.uid b/addons/gdUnit4/src/mocking/GdUnitMock.gd.uid index 9c3e5478..1676f1ee 100644 --- a/addons/gdUnit4/src/mocking/GdUnitMock.gd.uid +++ b/addons/gdUnit4/src/mocking/GdUnitMock.gd.uid @@ -1 +1 @@ -uid://dgc1qam4o7i0i +uid://snhg1g74hjp4 diff --git a/addons/gdUnit4/src/mocking/GdUnitMockBuilder.gd.uid b/addons/gdUnit4/src/mocking/GdUnitMockBuilder.gd.uid index f40ca653..2ba58f24 100644 --- a/addons/gdUnit4/src/mocking/GdUnitMockBuilder.gd.uid +++ b/addons/gdUnit4/src/mocking/GdUnitMockBuilder.gd.uid @@ -1 +1 @@ -uid://dq56630tdb00j +uid://c0shsnsrusbyd diff --git a/addons/gdUnit4/src/mocking/GdUnitMockFunctionDoubler.gd.uid b/addons/gdUnit4/src/mocking/GdUnitMockFunctionDoubler.gd.uid index 7e82b1c1..7e3da141 100644 --- a/addons/gdUnit4/src/mocking/GdUnitMockFunctionDoubler.gd.uid +++ b/addons/gdUnit4/src/mocking/GdUnitMockFunctionDoubler.gd.uid @@ -1 +1 @@ -uid://jm8onp8m4k25 +uid://dbftl6vpbaswy diff --git a/addons/gdUnit4/src/mocking/GdUnitMockImpl.gd.uid b/addons/gdUnit4/src/mocking/GdUnitMockImpl.gd.uid index 75e24f16..7d27ffc4 100644 --- a/addons/gdUnit4/src/mocking/GdUnitMockImpl.gd.uid +++ b/addons/gdUnit4/src/mocking/GdUnitMockImpl.gd.uid @@ -1 +1 @@ -uid://derlwqu7gm3qj +uid://bqq7tk4hvva8f diff --git a/addons/gdUnit4/src/monitor/ErrorLogEntry.gd.uid b/addons/gdUnit4/src/monitor/ErrorLogEntry.gd.uid index 1a235d0d..ca7a1423 100644 --- a/addons/gdUnit4/src/monitor/ErrorLogEntry.gd.uid +++ b/addons/gdUnit4/src/monitor/ErrorLogEntry.gd.uid @@ -1 +1 @@ -uid://dkiel0qlk1gk2 +uid://daopfdh4fej8n diff --git a/addons/gdUnit4/src/monitor/GdUnitMonitor.gd.uid b/addons/gdUnit4/src/monitor/GdUnitMonitor.gd.uid index a5a4a1fa..44588a08 100644 --- a/addons/gdUnit4/src/monitor/GdUnitMonitor.gd.uid +++ b/addons/gdUnit4/src/monitor/GdUnitMonitor.gd.uid @@ -1 +1 @@ -uid://cgjdtqp2vmlvn +uid://dw7kiptih6weg diff --git a/addons/gdUnit4/src/monitor/GdUnitOrphanNodesMonitor.gd.uid b/addons/gdUnit4/src/monitor/GdUnitOrphanNodesMonitor.gd.uid index 18e6fab6..79a1439e 100644 --- a/addons/gdUnit4/src/monitor/GdUnitOrphanNodesMonitor.gd.uid +++ b/addons/gdUnit4/src/monitor/GdUnitOrphanNodesMonitor.gd.uid @@ -1 +1 @@ -uid://c05r34gpp50to +uid://dhlaa1gqwg0rm diff --git a/addons/gdUnit4/src/monitor/GodotGdErrorMonitor.gd b/addons/gdUnit4/src/monitor/GodotGdErrorMonitor.gd index 2ea2234e..b0737051 100644 --- a/addons/gdUnit4/src/monitor/GodotGdErrorMonitor.gd +++ b/addons/gdUnit4/src/monitor/GodotGdErrorMonitor.gd @@ -52,6 +52,20 @@ func erase_log_entry(entry: ErrorLogEntry) -> void: _entries.erase(entry) +func collect_full_logs() -> PackedStringArray: + await (Engine.get_main_loop() as SceneTree).process_frame + await (Engine.get_main_loop() as SceneTree).physics_frame + + var file := FileAccess.open(_godot_log_file, FileAccess.READ) + file.seek(_eof) + var records := PackedStringArray() + while not file.eof_reached(): + @warning_ignore("return_value_discarded") + records.append(file.get_line()) + + return records + + func _collect_log_entries(force_collect_reports: bool) -> Array[ErrorLogEntry]: var file := FileAccess.open(_godot_log_file, FileAccess.READ) file.seek(_eof) diff --git a/addons/gdUnit4/src/monitor/GodotGdErrorMonitor.gd.uid b/addons/gdUnit4/src/monitor/GodotGdErrorMonitor.gd.uid index 99621185..b31d376f 100644 --- a/addons/gdUnit4/src/monitor/GodotGdErrorMonitor.gd.uid +++ b/addons/gdUnit4/src/monitor/GodotGdErrorMonitor.gd.uid @@ -1 +1 @@ -uid://1i2srtcp8q5 +uid://dcuvgoaxonxbc diff --git a/addons/gdUnit4/src/network/GdUnitServer.gd.uid b/addons/gdUnit4/src/network/GdUnitServer.gd.uid index 49b1cb8e..fe80d01f 100644 --- a/addons/gdUnit4/src/network/GdUnitServer.gd.uid +++ b/addons/gdUnit4/src/network/GdUnitServer.gd.uid @@ -1 +1 @@ -uid://d2b4atsva3n6r +uid://cdmq5d5672rdx diff --git a/addons/gdUnit4/src/network/GdUnitServer.tscn b/addons/gdUnit4/src/network/GdUnitServer.tscn index 99620f1e..4dbe8c49 100644 --- a/addons/gdUnit4/src/network/GdUnitServer.tscn +++ b/addons/gdUnit4/src/network/GdUnitServer.tscn @@ -1,7 +1,7 @@ [gd_scene load_steps=3 format=3 uid="uid://cn5mp3tmi2gb1"] -[ext_resource type="Script" uid="uid://cw5a5npml5wef" path="res://addons/gdUnit4/src/network/GdUnitServer.gd" id="1"] -[ext_resource type="Script" uid="uid://c7ncb187ucolp" path="res://addons/gdUnit4/src/network/GdUnitTcpServer.gd" id="2"] +[ext_resource type="Script" path="res://addons/gdUnit4/src/network/GdUnitServer.gd" id="1"] +[ext_resource type="Script" path="res://addons/gdUnit4/src/network/GdUnitTcpServer.gd" id="2"] [node name="Control" type="Node"] script = ExtResource("1") diff --git a/addons/gdUnit4/src/network/GdUnitServerConstants.gd.uid b/addons/gdUnit4/src/network/GdUnitServerConstants.gd.uid index a358c1eb..1f7d5624 100644 --- a/addons/gdUnit4/src/network/GdUnitServerConstants.gd.uid +++ b/addons/gdUnit4/src/network/GdUnitServerConstants.gd.uid @@ -1 +1 @@ -uid://jjy8r2hwxssd +uid://cit33bc2qquij diff --git a/addons/gdUnit4/src/network/GdUnitTask.gd.uid b/addons/gdUnit4/src/network/GdUnitTask.gd.uid index b9e21fa8..3ea3fe16 100644 --- a/addons/gdUnit4/src/network/GdUnitTask.gd.uid +++ b/addons/gdUnit4/src/network/GdUnitTask.gd.uid @@ -1 +1 @@ -uid://xe5jb81h1hfm +uid://ccwk7neqtr2sn diff --git a/addons/gdUnit4/src/network/GdUnitTcpClient.gd.uid b/addons/gdUnit4/src/network/GdUnitTcpClient.gd.uid index 6b9a73fe..118d5f3d 100644 --- a/addons/gdUnit4/src/network/GdUnitTcpClient.gd.uid +++ b/addons/gdUnit4/src/network/GdUnitTcpClient.gd.uid @@ -1 +1 @@ -uid://cdqknt40422ej +uid://c38gh6mfpnt83 diff --git a/addons/gdUnit4/src/network/GdUnitTcpNode.gd.uid b/addons/gdUnit4/src/network/GdUnitTcpNode.gd.uid index 272805ba..17912849 100644 --- a/addons/gdUnit4/src/network/GdUnitTcpNode.gd.uid +++ b/addons/gdUnit4/src/network/GdUnitTcpNode.gd.uid @@ -1 +1 @@ -uid://cbkf0u7jrre8m +uid://cjtx84t86jf1g diff --git a/addons/gdUnit4/src/network/GdUnitTcpServer.gd.uid b/addons/gdUnit4/src/network/GdUnitTcpServer.gd.uid index e3d48020..8cee9f96 100644 --- a/addons/gdUnit4/src/network/GdUnitTcpServer.gd.uid +++ b/addons/gdUnit4/src/network/GdUnitTcpServer.gd.uid @@ -1 +1 @@ -uid://b5rg08xa3h6x3 +uid://cauxpc1sb4ptk diff --git a/addons/gdUnit4/src/network/rpc/RPC.gd.uid b/addons/gdUnit4/src/network/rpc/RPC.gd.uid index 7fc771c3..17163402 100644 --- a/addons/gdUnit4/src/network/rpc/RPC.gd.uid +++ b/addons/gdUnit4/src/network/rpc/RPC.gd.uid @@ -1 +1 @@ -uid://b78q0d0k2xhls +uid://cedvqoiapts6d diff --git a/addons/gdUnit4/src/network/rpc/RPCClientConnect.gd.uid b/addons/gdUnit4/src/network/rpc/RPCClientConnect.gd.uid index 74ee5a9c..fb232793 100644 --- a/addons/gdUnit4/src/network/rpc/RPCClientConnect.gd.uid +++ b/addons/gdUnit4/src/network/rpc/RPCClientConnect.gd.uid @@ -1 +1 @@ -uid://dkro11eh12cxm +uid://bwo4g7r6dlqm diff --git a/addons/gdUnit4/src/network/rpc/RPCClientDisconnect.gd.uid b/addons/gdUnit4/src/network/rpc/RPCClientDisconnect.gd.uid index e096f60e..0bbae8a2 100644 --- a/addons/gdUnit4/src/network/rpc/RPCClientDisconnect.gd.uid +++ b/addons/gdUnit4/src/network/rpc/RPCClientDisconnect.gd.uid @@ -1 +1 @@ -uid://chdib4feehlsb +uid://bt5xyiti7u805 diff --git a/addons/gdUnit4/src/network/rpc/RPCGdUnitEvent.gd.uid b/addons/gdUnit4/src/network/rpc/RPCGdUnitEvent.gd.uid index 23b84604..a7efa394 100644 --- a/addons/gdUnit4/src/network/rpc/RPCGdUnitEvent.gd.uid +++ b/addons/gdUnit4/src/network/rpc/RPCGdUnitEvent.gd.uid @@ -1 +1 @@ -uid://bd5vwo3ck8v4c +uid://cijkq1m75qmmv diff --git a/addons/gdUnit4/src/network/rpc/RPCMessage.gd.uid b/addons/gdUnit4/src/network/rpc/RPCMessage.gd.uid index 8f3132ec..61f5bd4f 100644 --- a/addons/gdUnit4/src/network/rpc/RPCMessage.gd.uid +++ b/addons/gdUnit4/src/network/rpc/RPCMessage.gd.uid @@ -1 +1 @@ -uid://dengpjk16on7n +uid://binsc1d6mcj5i diff --git a/addons/gdUnit4/src/reporters/GdUnitConsoleTestReporter.gd.uid b/addons/gdUnit4/src/reporters/GdUnitConsoleTestReporter.gd.uid index 15b89628..de31a85a 100644 --- a/addons/gdUnit4/src/reporters/GdUnitConsoleTestReporter.gd.uid +++ b/addons/gdUnit4/src/reporters/GdUnitConsoleTestReporter.gd.uid @@ -1 +1 @@ -uid://duffxt287c2xv +uid://yf1lwslmsr1p diff --git a/addons/gdUnit4/src/reporters/GdUnitHtmlTestReporter.gd.uid b/addons/gdUnit4/src/reporters/GdUnitHtmlTestReporter.gd.uid index 1e086a98..f27ff085 100644 --- a/addons/gdUnit4/src/reporters/GdUnitHtmlTestReporter.gd.uid +++ b/addons/gdUnit4/src/reporters/GdUnitHtmlTestReporter.gd.uid @@ -1 +1 @@ -uid://ckpa3m7t165g2 +uid://b8r8buvfmxkc1 diff --git a/addons/gdUnit4/src/reporters/GdUnitTestReporter.gd.uid b/addons/gdUnit4/src/reporters/GdUnitTestReporter.gd.uid index df62c4d9..7478658c 100644 --- a/addons/gdUnit4/src/reporters/GdUnitTestReporter.gd.uid +++ b/addons/gdUnit4/src/reporters/GdUnitTestReporter.gd.uid @@ -1 +1 @@ -uid://cqyx7s50kvgit +uid://bgihlovlje028 diff --git a/addons/gdUnit4/src/reporters/JUnitXmlReport.gd.uid b/addons/gdUnit4/src/reporters/JUnitXmlReport.gd.uid index 08b83e47..b6b68cac 100644 --- a/addons/gdUnit4/src/reporters/JUnitXmlReport.gd.uid +++ b/addons/gdUnit4/src/reporters/JUnitXmlReport.gd.uid @@ -1 +1 @@ -uid://ckt5bbakcyu1m +uid://fyna6rb2ko53 diff --git a/addons/gdUnit4/src/reporters/XmlElement.gd.uid b/addons/gdUnit4/src/reporters/XmlElement.gd.uid index 670bd0ad..1a0d1894 100644 --- a/addons/gdUnit4/src/reporters/XmlElement.gd.uid +++ b/addons/gdUnit4/src/reporters/XmlElement.gd.uid @@ -1 +1 @@ -uid://cq27dcqhpeglp +uid://dr0dtmu570ddy diff --git a/addons/gdUnit4/src/reporters/html/GdUnitByPathReport.gd.uid b/addons/gdUnit4/src/reporters/html/GdUnitByPathReport.gd.uid index c80e9b0f..5d41d20e 100644 --- a/addons/gdUnit4/src/reporters/html/GdUnitByPathReport.gd.uid +++ b/addons/gdUnit4/src/reporters/html/GdUnitByPathReport.gd.uid @@ -1 +1 @@ -uid://yo22m618tcs3 +uid://bxtk8ptaee4sy diff --git a/addons/gdUnit4/src/reporters/html/GdUnitHtmlPatterns.gd.uid b/addons/gdUnit4/src/reporters/html/GdUnitHtmlPatterns.gd.uid index e3e8a692..054298b6 100644 --- a/addons/gdUnit4/src/reporters/html/GdUnitHtmlPatterns.gd.uid +++ b/addons/gdUnit4/src/reporters/html/GdUnitHtmlPatterns.gd.uid @@ -1 +1 @@ -uid://bd6iibim1mjbg +uid://c7sqdlct08bsw diff --git a/addons/gdUnit4/src/reporters/html/GdUnitHtmlReport.gd.uid b/addons/gdUnit4/src/reporters/html/GdUnitHtmlReport.gd.uid index f01d91b3..e835ca32 100644 --- a/addons/gdUnit4/src/reporters/html/GdUnitHtmlReport.gd.uid +++ b/addons/gdUnit4/src/reporters/html/GdUnitHtmlReport.gd.uid @@ -1 +1 @@ -uid://dlwag4dpcgbo8 +uid://dc5qieesw2531 diff --git a/addons/gdUnit4/src/reporters/html/GdUnitReportSummary.gd.uid b/addons/gdUnit4/src/reporters/html/GdUnitReportSummary.gd.uid index 1be2ad00..389904a5 100644 --- a/addons/gdUnit4/src/reporters/html/GdUnitReportSummary.gd.uid +++ b/addons/gdUnit4/src/reporters/html/GdUnitReportSummary.gd.uid @@ -1 +1 @@ -uid://bmdjjeedfuqnf +uid://dy757y4ltjjil diff --git a/addons/gdUnit4/src/reporters/html/GdUnitTestCaseReport.gd.uid b/addons/gdUnit4/src/reporters/html/GdUnitTestCaseReport.gd.uid index 8dab443f..1cf32fac 100644 --- a/addons/gdUnit4/src/reporters/html/GdUnitTestCaseReport.gd.uid +++ b/addons/gdUnit4/src/reporters/html/GdUnitTestCaseReport.gd.uid @@ -1 +1 @@ -uid://coymnbc7qpl3o +uid://6amw43v1lk5r diff --git a/addons/gdUnit4/src/reporters/html/GdUnitTestSuiteReport.gd.uid b/addons/gdUnit4/src/reporters/html/GdUnitTestSuiteReport.gd.uid index 0974ce65..6d3c1c09 100644 --- a/addons/gdUnit4/src/reporters/html/GdUnitTestSuiteReport.gd.uid +++ b/addons/gdUnit4/src/reporters/html/GdUnitTestSuiteReport.gd.uid @@ -1 +1 @@ -uid://cvl6b5i5uhnci +uid://dn118sseqeyl2 diff --git a/addons/gdUnit4/src/reporters/html/template/.gdignore b/addons/gdUnit4/src/reporters/html/template/.gdignore new file mode 100644 index 00000000..e69de29b diff --git a/addons/gdUnit4/src/spy/GdUnitSpyBuilder.gd.uid b/addons/gdUnit4/src/spy/GdUnitSpyBuilder.gd.uid index d8975049..200d36b4 100644 --- a/addons/gdUnit4/src/spy/GdUnitSpyBuilder.gd.uid +++ b/addons/gdUnit4/src/spy/GdUnitSpyBuilder.gd.uid @@ -1 +1 @@ -uid://dw53ujxolkr5m +uid://ppqfk5innaal diff --git a/addons/gdUnit4/src/spy/GdUnitSpyFunctionDoubler.gd.uid b/addons/gdUnit4/src/spy/GdUnitSpyFunctionDoubler.gd.uid index d7803326..714bc89d 100644 --- a/addons/gdUnit4/src/spy/GdUnitSpyFunctionDoubler.gd.uid +++ b/addons/gdUnit4/src/spy/GdUnitSpyFunctionDoubler.gd.uid @@ -1 +1 @@ -uid://drnkfb6u0ggpu +uid://w22nuqoq7i4c diff --git a/addons/gdUnit4/src/spy/GdUnitSpyImpl.gd.uid b/addons/gdUnit4/src/spy/GdUnitSpyImpl.gd.uid index 2ac39b47..4b9e7fa0 100644 --- a/addons/gdUnit4/src/spy/GdUnitSpyImpl.gd.uid +++ b/addons/gdUnit4/src/spy/GdUnitSpyImpl.gd.uid @@ -1 +1 @@ -uid://cytpqfrmm0pt3 +uid://dq2ct33cofsyl diff --git a/addons/gdUnit4/src/ui/GdUnitConsole.gd.uid b/addons/gdUnit4/src/ui/GdUnitConsole.gd.uid index 3d53d9db..1aa118ca 100644 --- a/addons/gdUnit4/src/ui/GdUnitConsole.gd.uid +++ b/addons/gdUnit4/src/ui/GdUnitConsole.gd.uid @@ -1 +1 @@ -uid://bc2216ij7fvk1 +uid://2i7agu7i0w68 diff --git a/addons/gdUnit4/src/ui/GdUnitConsole.tscn b/addons/gdUnit4/src/ui/GdUnitConsole.tscn index 924859eb..c3c7e29f 100644 --- a/addons/gdUnit4/src/ui/GdUnitConsole.tscn +++ b/addons/gdUnit4/src/ui/GdUnitConsole.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=2 format=3 uid="uid://dm0wvfyeew7vd"] -[ext_resource type="Script" uid="uid://b0ab52wtehlss" path="res://addons/gdUnit4/src/ui/GdUnitConsole.gd" id="1"] +[ext_resource type="Script" path="res://addons/gdUnit4/src/ui/GdUnitConsole.gd" id="1"] [node name="Control" type="Control"] use_parent_material = true diff --git a/addons/gdUnit4/src/ui/GdUnitFonts.gd.uid b/addons/gdUnit4/src/ui/GdUnitFonts.gd.uid index b5e252dc..939406ef 100644 --- a/addons/gdUnit4/src/ui/GdUnitFonts.gd.uid +++ b/addons/gdUnit4/src/ui/GdUnitFonts.gd.uid @@ -1 +1 @@ -uid://dgf16dlm5ms6k +uid://cao8sc3cwog8q diff --git a/addons/gdUnit4/src/ui/GdUnitInspector.gd.uid b/addons/gdUnit4/src/ui/GdUnitInspector.gd.uid index 9bc99846..c907808b 100644 --- a/addons/gdUnit4/src/ui/GdUnitInspector.gd.uid +++ b/addons/gdUnit4/src/ui/GdUnitInspector.gd.uid @@ -1 +1 @@ -uid://u4ddpnglc1kf +uid://vothtltt41qt diff --git a/addons/gdUnit4/src/ui/GdUnitInspector.tscn b/addons/gdUnit4/src/ui/GdUnitInspector.tscn index 9b5a55fa..54ee9193 100644 --- a/addons/gdUnit4/src/ui/GdUnitInspector.tscn +++ b/addons/gdUnit4/src/ui/GdUnitInspector.tscn @@ -1,12 +1,12 @@ [gd_scene load_steps=8 format=3 uid="uid://mpo5o6d4uybu"] -[ext_resource type="PackedScene" uid="uid://dx7xy4dgi3wwb" path="res://addons/gdUnit4/src/ui/parts/InspectorToolBar.tscn" id="1"] -[ext_resource type="PackedScene" uid="uid://dva3tonxsxrlk" path="res://addons/gdUnit4/src/ui/parts/InspectorProgressBar.tscn" id="2"] -[ext_resource type="PackedScene" uid="uid://c22l4odk7qesc" path="res://addons/gdUnit4/src/ui/parts/InspectorStatusBar.tscn" id="3"] -[ext_resource type="PackedScene" uid="uid://djp8ait0bxpsc" path="res://addons/gdUnit4/src/ui/parts/InspectorMonitor.tscn" id="4"] -[ext_resource type="Script" uid="uid://crbw6kef7nktv" path="res://addons/gdUnit4/src/ui/GdUnitInspector.gd" id="5"] -[ext_resource type="PackedScene" uid="uid://bqfpidewtpeg0" path="res://addons/gdUnit4/src/ui/parts/InspectorTreePanel.tscn" id="7"] -[ext_resource type="PackedScene" uid="uid://cn5mp3tmi2gb1" path="res://addons/gdUnit4/src/network/GdUnitServer.tscn" id="7_721no"] +[ext_resource type="PackedScene" path="res://addons/gdUnit4/src/ui/parts/InspectorToolBar.tscn" id="1"] +[ext_resource type="PackedScene" path="res://addons/gdUnit4/src/ui/parts/InspectorProgressBar.tscn" id="2"] +[ext_resource type="PackedScene" path="res://addons/gdUnit4/src/ui/parts/InspectorStatusBar.tscn" id="3"] +[ext_resource type="PackedScene" path="res://addons/gdUnit4/src/ui/parts/InspectorMonitor.tscn" id="4"] +[ext_resource type="Script" path="res://addons/gdUnit4/src/ui/GdUnitInspector.gd" id="5"] +[ext_resource type="PackedScene" path="res://addons/gdUnit4/src/ui/parts/InspectorTreePanel.tscn" id="7"] +[ext_resource type="PackedScene" path="res://addons/gdUnit4/src/network/GdUnitServer.tscn" id="7_721no"] [node name="GdUnit" type="Panel"] use_parent_material = true diff --git a/addons/gdUnit4/src/ui/GdUnitInspectorTreeConstants.gd.uid b/addons/gdUnit4/src/ui/GdUnitInspectorTreeConstants.gd.uid index 9e51e2d6..105cd856 100644 --- a/addons/gdUnit4/src/ui/GdUnitInspectorTreeConstants.gd.uid +++ b/addons/gdUnit4/src/ui/GdUnitInspectorTreeConstants.gd.uid @@ -1 +1 @@ -uid://s3jesnpl5w4 +uid://djkcwschqiupb diff --git a/addons/gdUnit4/src/ui/GdUnitUiTools.gd.uid b/addons/gdUnit4/src/ui/GdUnitUiTools.gd.uid index 68288f5f..5578a48b 100644 --- a/addons/gdUnit4/src/ui/GdUnitUiTools.gd.uid +++ b/addons/gdUnit4/src/ui/GdUnitUiTools.gd.uid @@ -1 +1 @@ -uid://3w6n0vrjwmo8 +uid://htntluoxnikn diff --git a/addons/gdUnit4/src/ui/ScriptEditorControls.gd b/addons/gdUnit4/src/ui/ScriptEditorControls.gd index 5e07fe15..6f3590b2 100644 --- a/addons/gdUnit4/src/ui/ScriptEditorControls.gd +++ b/addons/gdUnit4/src/ui/ScriptEditorControls.gd @@ -54,9 +54,9 @@ static func save_an_open_script(script_path: String, close:=false) -> bool: # select the script in the editor EditorInterface.edit_script(open_script, 0); # save and close - editor_popup.id_pressed.emit(FILE_SAVE) + editor_popup.id_pressed.emit(Field.FILE_SAVE) if close: - editor_popup.id_pressed.emit(FILE_CLOSE) + editor_popup.id_pressed.emit(Field.FILE_CLOSE) return true return false @@ -64,7 +64,7 @@ static func save_an_open_script(script_path: String, close:=false) -> bool: # Saves all opened script static func save_all_open_script() -> void: if Engine.is_editor_hint(): - _menu_popup().id_pressed.emit(FILE_SAVE_ALL) + _menu_popup().id_pressed.emit(Field.FILE_SAVE_ALL) static func close_open_editor_scripts() -> void: diff --git a/addons/gdUnit4/src/ui/ScriptEditorControls.gd.uid b/addons/gdUnit4/src/ui/ScriptEditorControls.gd.uid index e1923cbc..a249f619 100644 --- a/addons/gdUnit4/src/ui/ScriptEditorControls.gd.uid +++ b/addons/gdUnit4/src/ui/ScriptEditorControls.gd.uid @@ -1 +1 @@ -uid://li3m7sxmxbog +uid://cy3jltba1mub4 diff --git a/addons/gdUnit4/src/ui/menu/EditorFileSystemContextMenuHandler.gd.uid b/addons/gdUnit4/src/ui/menu/EditorFileSystemContextMenuHandler.gd.uid index 67d7dd23..af64f29e 100644 --- a/addons/gdUnit4/src/ui/menu/EditorFileSystemContextMenuHandler.gd.uid +++ b/addons/gdUnit4/src/ui/menu/EditorFileSystemContextMenuHandler.gd.uid @@ -1 +1 @@ -uid://7fd7477usa3w +uid://bh6aoa1oac8pp diff --git a/addons/gdUnit4/src/ui/menu/GdUnitContextMenuItem.gd.uid b/addons/gdUnit4/src/ui/menu/GdUnitContextMenuItem.gd.uid index 832ee47e..5a6c0bc5 100644 --- a/addons/gdUnit4/src/ui/menu/GdUnitContextMenuItem.gd.uid +++ b/addons/gdUnit4/src/ui/menu/GdUnitContextMenuItem.gd.uid @@ -1 +1 @@ -uid://bsdgpryghi78m +uid://3p1xmguf0a4b diff --git a/addons/gdUnit4/src/ui/menu/ScriptEditorContextMenuHandler.gd.uid b/addons/gdUnit4/src/ui/menu/ScriptEditorContextMenuHandler.gd.uid index 7ba54248..d8224efa 100644 --- a/addons/gdUnit4/src/ui/menu/ScriptEditorContextMenuHandler.gd.uid +++ b/addons/gdUnit4/src/ui/menu/ScriptEditorContextMenuHandler.gd.uid @@ -1 +1 @@ -uid://dix5adosojsc +uid://bo1xnst1353h5 diff --git a/addons/gdUnit4/src/ui/parts/InspectorMonitor.gd.uid b/addons/gdUnit4/src/ui/parts/InspectorMonitor.gd.uid index 908d8e01..c26b6d4a 100644 --- a/addons/gdUnit4/src/ui/parts/InspectorMonitor.gd.uid +++ b/addons/gdUnit4/src/ui/parts/InspectorMonitor.gd.uid @@ -1 +1 @@ -uid://crw1egthht6dn +uid://dji3ntx24jxpc diff --git a/addons/gdUnit4/src/ui/parts/InspectorMonitor.tscn b/addons/gdUnit4/src/ui/parts/InspectorMonitor.tscn index d627bf28..0262b8cd 100644 --- a/addons/gdUnit4/src/ui/parts/InspectorMonitor.tscn +++ b/addons/gdUnit4/src/ui/parts/InspectorMonitor.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=6 format=3 uid="uid://djp8ait0bxpsc"] -[ext_resource type="Script" uid="uid://dwc45di05dw2s" path="res://addons/gdUnit4/src/ui/parts/InspectorMonitor.gd" id="3"] +[ext_resource type="Script" path="res://addons/gdUnit4/src/ui/parts/InspectorMonitor.gd" id="3"] [sub_resource type="Image" id="Image_sx31i"] data = { diff --git a/addons/gdUnit4/src/ui/parts/InspectorProgressBar.gd.uid b/addons/gdUnit4/src/ui/parts/InspectorProgressBar.gd.uid index ed4e4d1d..2f120448 100644 --- a/addons/gdUnit4/src/ui/parts/InspectorProgressBar.gd.uid +++ b/addons/gdUnit4/src/ui/parts/InspectorProgressBar.gd.uid @@ -1 +1 @@ -uid://b5sffcmr4tagj +uid://b45snkt7caquf diff --git a/addons/gdUnit4/src/ui/parts/InspectorProgressBar.tscn b/addons/gdUnit4/src/ui/parts/InspectorProgressBar.tscn index c21b3504..1824230a 100644 --- a/addons/gdUnit4/src/ui/parts/InspectorProgressBar.tscn +++ b/addons/gdUnit4/src/ui/parts/InspectorProgressBar.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=3 format=3 uid="uid://dva3tonxsxrlk"] -[ext_resource type="Script" uid="uid://clrglsyemovs2" path="res://addons/gdUnit4/src/ui/parts/InspectorProgressBar.gd" id="1"] +[ext_resource type="Script" path="res://addons/gdUnit4/src/ui/parts/InspectorProgressBar.gd" id="1"] [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_ayfir"] bg_color = Color(0, 0.392157, 0, 1) diff --git a/addons/gdUnit4/src/ui/parts/InspectorStatusBar.gd b/addons/gdUnit4/src/ui/parts/InspectorStatusBar.gd index ee6b3d9b..f2623aeb 100644 --- a/addons/gdUnit4/src/ui/parts/InspectorStatusBar.gd +++ b/addons/gdUnit4/src/ui/parts/InspectorStatusBar.gd @@ -18,8 +18,8 @@ signal tree_view_mode_changed(flat :bool) @onready var _button_failure_up: Button = %btn_failure_up @onready var _button_failure_down: Button = %btn_failure_down @onready var _button_sync: Button = %btn_tree_sync -@onready var _button_view_mode: Button = %btn_tree_mode -@onready var _button_sort_mode: Button = %btn_tree_sort +@onready var _button_view_mode: MenuButton = %btn_tree_mode +@onready var _button_sort_mode: MenuButton = %btn_tree_sort @onready var _icon_errors: TextureRect = %icon_errors @onready var _icon_failures: TextureRect = %icon_failures diff --git a/addons/gdUnit4/src/ui/parts/InspectorStatusBar.gd.uid b/addons/gdUnit4/src/ui/parts/InspectorStatusBar.gd.uid index 5580160e..6bd8c139 100644 --- a/addons/gdUnit4/src/ui/parts/InspectorStatusBar.gd.uid +++ b/addons/gdUnit4/src/ui/parts/InspectorStatusBar.gd.uid @@ -1 +1 @@ -uid://dvrxigojhylsy +uid://o7pbyqyihbvb diff --git a/addons/gdUnit4/src/ui/parts/InspectorStatusBar.tscn b/addons/gdUnit4/src/ui/parts/InspectorStatusBar.tscn index 182338b8..c6848272 100644 --- a/addons/gdUnit4/src/ui/parts/InspectorStatusBar.tscn +++ b/addons/gdUnit4/src/ui/parts/InspectorStatusBar.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=32 format=3 uid="uid://c22l4odk7qesc"] -[ext_resource type="Script" uid="uid://kv33is2tf6np" path="res://addons/gdUnit4/src/ui/parts/InspectorStatusBar.gd" id="3"] +[ext_resource type="Script" path="res://addons/gdUnit4/src/ui/parts/InspectorStatusBar.gd" id="3"] [sub_resource type="Image" id="Image_mb3ih"] data = { diff --git a/addons/gdUnit4/src/ui/parts/InspectorToolBar.gd b/addons/gdUnit4/src/ui/parts/InspectorToolBar.gd index 3407048d..e4d99e44 100644 --- a/addons/gdUnit4/src/ui/parts/InspectorToolBar.gd +++ b/addons/gdUnit4/src/ui/parts/InspectorToolBar.gd @@ -5,6 +5,8 @@ signal run_overall_pressed(debug: bool) signal run_pressed(debug: bool) signal stop_pressed() +const InspectorTreeMainPanel := preload("res://addons/gdUnit4/src/ui/parts/InspectorTreeMainPanel.gd") + @onready var _version_label: Control = %version @onready var _button_wiki: Button = %help @onready var _tool_button: Button = %tool @@ -14,7 +16,6 @@ signal stop_pressed() @onready var _button_stop: Button = %stop - const SETTINGS_SHORTCUT_MAPPING := { GdUnitSettings.SHORTCUT_INSPECTOR_RERUN_TEST: GdUnitShortcut.ShortCut.RERUN_TESTS, GdUnitSettings.SHORTCUT_INSPECTOR_RERUN_TEST_DEBUG: GdUnitShortcut.ShortCut.RERUN_TESTS_DEBUG, @@ -23,11 +24,16 @@ const SETTINGS_SHORTCUT_MAPPING := { } -@warning_ignore("return_value_discarded") func _ready() -> void: + var inspector :InspectorTreeMainPanel = get_parent().get_parent().find_child("MainPanel", false, false) + if inspector == null: + push_error("Internal error, can't connect to the test inspector!") + else: + inspector.tree_item_selected.connect(_on_inspector_selected) + run_pressed.connect(inspector._on_run_pressed) + GdUnit4Version.init_version_label(_version_label) var command_handler := GdUnitCommandHandler.instance() - run_pressed.connect(command_handler._on_run_pressed) run_overall_pressed.connect(command_handler._on_run_overall_pressed) stop_pressed.connect(command_handler._on_stop_pressed) command_handler.gdunit_runner_start.connect(_on_gdunit_runner_start) @@ -37,7 +43,6 @@ func _ready() -> void: init_shortcuts(command_handler) - func init_buttons() -> void: _button_run_overall.icon = GdUnitUiTools.get_run_overall_icon() _button_run_overall.visible = GdUnitSettings.is_inspector_toolbar_button_show() @@ -46,6 +51,9 @@ func init_buttons() -> void: _button_stop.icon = GdUnitUiTools.get_icon("Stop") _tool_button.icon = GdUnitUiTools.get_icon("Tools") _button_wiki.icon = GdUnitUiTools.get_icon("HelpSearch") + # Set run buttons initial disabled + _button_run.disabled = true + _button_run_debug.disabled = true func init_shortcuts(command_handler: GdUnitCommandHandler) -> void: @@ -58,6 +66,12 @@ func init_shortcuts(command_handler: GdUnitCommandHandler) -> void: GdUnitSignals.instance().gdunit_settings_changed.connect(_on_settings_changed.bind(command_handler)) +func _on_inspector_selected(item: TreeItem) -> void: + var button_disabled := item == null + _button_run.disabled = button_disabled + _button_run_debug.disabled = button_disabled + + func _on_runoverall_pressed(debug:=false) -> void: run_overall_pressed.emit(debug) @@ -79,8 +93,6 @@ func _on_gdunit_runner_start() -> void: func _on_gdunit_runner_stop(_client_id: int) -> void: _button_run_overall.disabled = false - _button_run.disabled = false - _button_run_debug.disabled = false _button_stop.disabled = true diff --git a/addons/gdUnit4/src/ui/parts/InspectorToolBar.gd.uid b/addons/gdUnit4/src/ui/parts/InspectorToolBar.gd.uid index 2addee17..951f7463 100644 --- a/addons/gdUnit4/src/ui/parts/InspectorToolBar.gd.uid +++ b/addons/gdUnit4/src/ui/parts/InspectorToolBar.gd.uid @@ -1 +1 @@ -uid://d311g1tcmdbtv +uid://jwd8m4833smh diff --git a/addons/gdUnit4/src/ui/parts/InspectorToolBar.tscn b/addons/gdUnit4/src/ui/parts/InspectorToolBar.tscn index 210fa9e3..5d75da02 100644 --- a/addons/gdUnit4/src/ui/parts/InspectorToolBar.tscn +++ b/addons/gdUnit4/src/ui/parts/InspectorToolBar.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=22 format=3 uid="uid://dx7xy4dgi3wwb"] -[ext_resource type="Script" uid="uid://25styuldjg2p" path="res://addons/gdUnit4/src/ui/parts/InspectorToolBar.gd" id="3"] +[ext_resource type="Script" path="res://addons/gdUnit4/src/ui/parts/InspectorToolBar.gd" id="3"] [sub_resource type="Image" id="Image_c7rhl"] data = { diff --git a/addons/gdUnit4/src/ui/parts/InspectorTreeMainPanel.gd b/addons/gdUnit4/src/ui/parts/InspectorTreeMainPanel.gd index ac383025..fce16f98 100644 --- a/addons/gdUnit4/src/ui/parts/InspectorTreeMainPanel.gd +++ b/addons/gdUnit4/src/ui/parts/InspectorTreeMainPanel.gd @@ -3,6 +3,8 @@ extends VSplitContainer ## Will be emitted when the test index counter is changed signal test_counters_changed(index: int, total: int, state: GdUnitInspectorTreeConstants.STATE) +signal tree_item_selected(item: TreeItem) + const CONTEXT_MENU_RUN_ID = 0 const CONTEXT_MENU_DEBUG_ID = 1 @@ -61,8 +63,10 @@ const STATE = GdUnitInspectorTreeConstants.STATE var _tree_root: TreeItem +var _current_selected_item: TreeItem = null var _item_hash := Dictionary() var _current_tree_view_mode := GdUnitSettings.get_inspector_tree_view_mode() +var _run_test_recovery := true func _build_cache_key(resource_path: String, test_name: String) -> Array: @@ -195,6 +199,11 @@ func is_test_id(item: TreeItem, id: GdUnitGUID) -> bool: var test_case: GdUnitTestCase = item.get_meta(META_TEST_CASE) return test_case.guid.equals(id) + +func disable_test_recovery() -> void: + _run_test_recovery = false + + @warning_ignore("return_value_discarded") func _ready() -> void: _context_menu.set_item_icon(CONTEXT_MENU_RUN_ID, GdUnitUiTools.get_icon("Play")) @@ -215,6 +224,8 @@ func _ready() -> void: var command_handler := GdUnitCommandHandler.instance() command_handler.gdunit_runner_start.connect(_on_gdunit_runner_start) command_handler.gdunit_runner_stop.connect(_on_gdunit_runner_stop) + if _run_test_recovery: + GdUnitTestDiscoverer.restore_last_session() # we need current to manually redraw bacause of the animation bug @@ -226,6 +237,7 @@ func _process(_delta: float) -> void: func init_tree() -> void: cleanup_tree() + _tree.deselect_all() _tree.set_hide_root(true) _tree.ensure_cursor_is_visible() _tree.set_allow_reselect(true) @@ -255,6 +267,7 @@ func cleanup_tree() -> void: return _free_recursive() _tree.clear() + _current_selected_item = null func _free_recursive(items:=_tree_root.get_children()) -> void: @@ -263,12 +276,20 @@ func _free_recursive(items:=_tree_root.get_children()) -> void: item.call_deferred("free") -func sort_tree_items(parent :TreeItem) -> void: +func sort_tree_items(parent: TreeItem) -> void: + _sort_tree_items(parent, GdUnitSettings.get_inspector_tree_sort_mode()) + _tree.queue_redraw() + + +static func _sort_tree_items(parent: TreeItem, sort_mode: GdUnitInspectorTreeConstants.SORT_MODE) -> void: parent.visible = false var items := parent.get_children() + # first remove all childs before sorting + for item in items: + parent.remove_child(item) # do sort by selected sort mode - match GdUnitSettings.get_inspector_tree_sort_mode(): + match sort_mode: GdUnitInspectorTreeConstants.SORT_MODE.UNSORTED: items.sort_custom(sort_items_by_original_index) @@ -281,32 +302,42 @@ func sort_tree_items(parent :TreeItem) -> void: GdUnitInspectorTreeConstants.SORT_MODE.EXECUTION_TIME: items.sort_custom(sort_items_by_execution_time) + # readding sorted childs for item in items: - parent.remove_child(item) parent.add_child(item) if item.get_child_count() > 0: - sort_tree_items(item) + _sort_tree_items(item, sort_mode) parent.visible = true - _tree.queue_redraw() -func sort_items_by_name(a: TreeItem, b: TreeItem, ascending: bool) -> bool: +static func sort_items_by_name(a: TreeItem, b: TreeItem, ascending: bool) -> bool: var type_a: GdUnitType = a.get_meta(META_GDUNIT_TYPE) var type_b: GdUnitType = b.get_meta(META_GDUNIT_TYPE) - # Compare types first - if type_a != type_b: - return type_a == GdUnitType.FOLDER - var name_a :String = a.get_meta(META_GDUNIT_NAME) - var name_b :String = b.get_meta(META_GDUNIT_NAME) - return name_a.naturalnocasecmp_to(name_b) < 0 if ascending else name_a.naturalnocasecmp_to(name_b) > 0 + # Sort folders to the top + if type_a == GdUnitType.FOLDER and type_b != GdUnitType.FOLDER: + return true + if type_b == GdUnitType.FOLDER and type_a != GdUnitType.FOLDER: + return false + + # sort by name + var name_a: String = a.get_meta(META_GDUNIT_NAME) + var name_b: String = b.get_meta(META_GDUNIT_NAME) + var comparison := name_a.naturalnocasecmp_to(name_b) -func sort_items_by_execution_time(a: TreeItem, b: TreeItem) -> bool: + return comparison < 0 if ascending else comparison > 0 + + +static func sort_items_by_execution_time(a: TreeItem, b: TreeItem) -> bool: var type_a: GdUnitType = a.get_meta(META_GDUNIT_TYPE) var type_b: GdUnitType = b.get_meta(META_GDUNIT_TYPE) - # Compare types first - if type_a != type_b: - return type_a == GdUnitType.FOLDER + + # Sort folders to the top + if type_a == GdUnitType.FOLDER and type_b != GdUnitType.FOLDER: + return true + if type_b == GdUnitType.FOLDER and type_a != GdUnitType.FOLDER: + return false + var execution_time_a :int = a.get_meta(META_GDUNIT_EXECUTION_TIME) var execution_time_b :int = b.get_meta(META_GDUNIT_EXECUTION_TIME) # if has same execution time sort by name @@ -317,13 +348,20 @@ func sort_items_by_execution_time(a: TreeItem, b: TreeItem) -> bool: return execution_time_a > execution_time_b -func sort_items_by_original_index(a: TreeItem, b: TreeItem) -> bool: +static func sort_items_by_original_index(a: TreeItem, b: TreeItem) -> bool: var type_a: GdUnitType = a.get_meta(META_GDUNIT_TYPE) var type_b: GdUnitType = b.get_meta(META_GDUNIT_TYPE) - if type_a != type_b: - return type_a == GdUnitType.FOLDER + + # Sort folders to the top + if type_a == GdUnitType.FOLDER and type_b != GdUnitType.FOLDER: + return true + if type_b == GdUnitType.FOLDER and type_a != GdUnitType.FOLDER: + return false + var index_a :int = a.get_meta(META_GDUNIT_ORIGINAL_INDEX) var index_b :int = b.get_meta(META_GDUNIT_ORIGINAL_INDEX) + + # Sorting by index return index_a < index_b @@ -530,11 +568,12 @@ func set_state_running(item: TreeItem) -> void: if parent != _tree_root: set_state_running(parent) # force scrolling to current test case - @warning_ignore("return_value_discarded") - select_item(item) + _tree.scroll_to_item(item, true) func set_state_succeded(item: TreeItem) -> void: + if item == _tree_root: + return item.set_custom_color(0, Color.GREEN) item.set_custom_color(1, Color.GREEN) item.set_meta(META_GDUNIT_STATE, STATE.SUCCESS) @@ -728,7 +767,7 @@ func show_failed_report(selected_item: TreeItem) -> void: func update_test_suite(event: GdUnitEvent) -> void: var item := _find_tree_item_by_path(extract_resource_path(event), event.suite_name()) if not item: - push_error("[GdUnitInspector:731] Internal Error: Can't find tree item for\n %s" % event) + push_error("[InspectorTreeMainPanel.gd:753] Internal Error: Can't find tree item for\n %s" % event) return if event.type() == GdUnitEvent.TESTSUITE_BEFORE: set_state_running(item) @@ -742,7 +781,7 @@ func update_test_suite(event: GdUnitEvent) -> void: func update_test_case(event: GdUnitEvent) -> void: var item := _find_tree_item_by_id(_tree_root, event.guid()) if not item: - push_error("Internal Error: Can't find test id %s" % [event.guid()]) + #push_error("Internal Error: Can't find test id %s" % [event.guid()]) return if event.type() == GdUnitEvent.TESTCASE_BEFORE: set_state_running(item) @@ -766,10 +805,10 @@ func create_item(parent: TreeItem, test: GdUnitTestCase, item_name: String, type item.set_meta(META_TEST_CASE, test) GdUnitType.TEST_GROUP: # We need to create a copy of the test record meta with a new uniqe guid - item.set_meta(META_TEST_CASE, GdUnitTestCase.from(test.source_file, test.line_number, test.test_name)) + item.set_meta(META_TEST_CASE, GdUnitTestCase.from(test.suite_resource_path, test.source_file, test.line_number, test.test_name)) GdUnitType.TEST_SUITE: # We need to create a copy of the test record meta with a new uniqe guid - item.set_meta(META_TEST_CASE, GdUnitTestCase.from(test.source_file, test.line_number, test.suite_name)) + item.set_meta(META_TEST_CASE, GdUnitTestCase.from(test.suite_resource_path, test.source_file, test.line_number, test.suite_name)) # We need to add the suite item to the item cache by path because the guid is not provided add_tree_item_to_cache(test.source_file, item_name, item) @@ -1077,7 +1116,7 @@ func _dump_tree_as_json(dump_name: String) -> void: func _to_json(parent :TreeItem) -> Dictionary: var item_as_dict := GdObjects.obj2dict(parent) - item_as_dict["TreeItem"]["childs"] = parent.get_children().map(func(item: TreeItem) -> Dictionary: + item_as_dict["TreeItem"]["childrens"] = parent.get_children().map(func(item: TreeItem) -> Dictionary: return _to_json(item)) return item_as_dict @@ -1124,6 +1163,8 @@ func _on_Tree_item_selected() -> void: if not _context_menu.is_item_disabled(CONTEXT_MENU_RUN_ID): var selected_item: TreeItem = _tree.get_selected() show_failed_report(selected_item) + _current_selected_item = _tree.get_selected() + tree_item_selected.emit(_current_selected_item) # Opens the test suite @@ -1153,7 +1194,7 @@ func _on_Tree_item_activated() -> void: # external signal receiver ################################################################################ func _on_gdunit_runner_start() -> void: - reset_tree_state(_tree_root) + reset_tree_state(_current_selected_item) _context_menu.set_item_disabled(CONTEXT_MENU_RUN_ID, true) _context_menu.set_item_disabled(CONTEXT_MENU_DEBUG_ID, true) clear_reports() @@ -1179,6 +1220,7 @@ func _on_gdunit_event(event: GdUnitEvent) -> void: GdUnitEvent.DISCOVER_END: sort_tree_items(_tree_root) + select_item(_tree_root.get_first_child()) _discover_hint.visible = false _tree_root.visible = true #_dump_tree_as_json("tree_example_discovered") @@ -1188,6 +1230,7 @@ func _on_gdunit_event(event: GdUnitEvent) -> void: GdUnitEvent.STOP: sort_tree_items(_tree_root) + select_item(_current_selected_item) #_dump_tree_as_json("tree_example") GdUnitEvent.TESTCASE_BEFORE: @@ -1219,7 +1262,7 @@ func _on_settings_changed(property :GdUnitProperty) -> void: match property.name(): GdUnitSettings.INSPECTOR_TREE_SORT_MODE: sort_tree_items(_tree_root) - # _dump_tree_as_json("tree_sorted_by_%s" % GdUnitInspectorTreeConstants.SORT_MODE.keys()[property.value()]) + #_dump_tree_as_json("tree_sorted_by_%s" % GdUnitInspectorTreeConstants.SORT_MODE.keys()[property.value()]) GdUnitSettings.INSPECTOR_TREE_VIEW_MODE: restructure_tree(_tree_root, GdUnitSettings.get_inspector_tree_view_mode()) diff --git a/addons/gdUnit4/src/ui/parts/InspectorTreeMainPanel.gd.uid b/addons/gdUnit4/src/ui/parts/InspectorTreeMainPanel.gd.uid index 2da8e436..356d0f16 100644 --- a/addons/gdUnit4/src/ui/parts/InspectorTreeMainPanel.gd.uid +++ b/addons/gdUnit4/src/ui/parts/InspectorTreeMainPanel.gd.uid @@ -1 +1 @@ -uid://2io2vddkuoqf +uid://b1wycqsf5vf04 diff --git a/addons/gdUnit4/src/ui/parts/InspectorTreePanel.tscn b/addons/gdUnit4/src/ui/parts/InspectorTreePanel.tscn index 7d7af9b4..a4247706 100644 --- a/addons/gdUnit4/src/ui/parts/InspectorTreePanel.tscn +++ b/addons/gdUnit4/src/ui/parts/InspectorTreePanel.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=27 format=3 uid="uid://bqfpidewtpeg0"] -[ext_resource type="Script" uid="uid://dalle60ox3sat" path="res://addons/gdUnit4/src/ui/parts/InspectorTreeMainPanel.gd" id="1"] +[ext_resource type="Script" path="res://addons/gdUnit4/src/ui/parts/InspectorTreeMainPanel.gd" id="1"] [sub_resource type="Image" id="Image_466oo"] data = { diff --git a/addons/gdUnit4/src/ui/settings/GdUnitInputCapture.gd.uid b/addons/gdUnit4/src/ui/settings/GdUnitInputCapture.gd.uid index 8b2dd786..b123c8f2 100644 --- a/addons/gdUnit4/src/ui/settings/GdUnitInputCapture.gd.uid +++ b/addons/gdUnit4/src/ui/settings/GdUnitInputCapture.gd.uid @@ -1 +1 @@ -uid://djjujnonaiy34 +uid://c3unwpwya10b5 diff --git a/addons/gdUnit4/src/ui/settings/GdUnitInputCapture.tscn b/addons/gdUnit4/src/ui/settings/GdUnitInputCapture.tscn index 40bdb502..7e62c438 100644 --- a/addons/gdUnit4/src/ui/settings/GdUnitInputCapture.tscn +++ b/addons/gdUnit4/src/ui/settings/GdUnitInputCapture.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=2 format=3 uid="uid://pmnkxrhglak5"] -[ext_resource type="Script" uid="uid://birwkunpkmqc4" path="res://addons/gdUnit4/src/ui/settings/GdUnitInputCapture.gd" id="1_gki1u"] +[ext_resource type="Script" path="res://addons/gdUnit4/src/ui/settings/GdUnitInputCapture.gd" id="1_gki1u"] [node name="GdUnitInputMapper" type="Control"] modulate = Color(0.929099, 0.929099, 0.929099, 0.936189) diff --git a/addons/gdUnit4/src/ui/settings/GdUnitSettingsDialog.gd b/addons/gdUnit4/src/ui/settings/GdUnitSettingsDialog.gd index 4a9a9465..14a8bd5b 100644 --- a/addons/gdUnit4/src/ui/settings/GdUnitSettingsDialog.gd +++ b/addons/gdUnit4/src/ui/settings/GdUnitSettingsDialog.gd @@ -10,15 +10,15 @@ const GdUnitUpdateClient = preload ("res://addons/gdUnit4/src/update/GdUnitUpdat @onready var _btn_install: Button = %btn_install_examples @onready var _progress_bar: ProgressBar = %ProgressBar @onready var _progress_text: Label = %progress_lbl -@onready var _properties_template: Node = $property_template -@onready var _properties_common: Node = % "common-content" -@onready var _properties_ui: Node = % "ui-content" -@onready var _properties_shortcuts: Node = % "shortcut-content" -@onready var _properties_report: Node = % "report-content" +@onready var _properties_template: Control = $property_template +@onready var _properties_common: Control = % "common-content" +@onready var _properties_ui: Control = % "ui-content" +@onready var _properties_shortcuts: Control = % "shortcut-content" +@onready var _properties_report: Control = % "report-content" @onready var _input_capture: GdUnitInputCapture = %GdUnitInputCapture @onready var _property_error: Window = % "propertyError" @onready var _tab_container: TabContainer = %Properties -@onready var _update_tab: = %Update +@onready var _update_tab: Control = %Update var _font_size: float @@ -41,7 +41,7 @@ func _sort_by_key(left: GdUnitProperty, right: GdUnitProperty) -> bool: return left.name() < right.name() -func setup_properties(properties_parent: Node, property_category: String) -> void: +func setup_properties(properties_parent: Control, property_category: String) -> void: # Do remove first potential previous added properties (could be happened when the dlg is opened at twice) for child in properties_parent.get_children(): properties_parent.remove_child(child) @@ -66,8 +66,9 @@ func setup_properties(properties_parent: Node, property_category: String) -> voi grid.columns = 4 grid.theme = theme_ - var sub_category: Node = _properties_template.get_child(3).duplicate() - sub_category.get_child(0).text = current_category.capitalize() + var sub_category: Control = _properties_template.get_child(3).duplicate() + var category_label: Label = sub_category.get_child(0) + category_label.text = current_category.capitalize() sub_category.custom_minimum_size.y = _font_size + 16 properties_parent.add_child(sub_category) properties_parent.add_child(grid) @@ -91,7 +92,7 @@ func setup_properties(properties_parent: Node, property_category: String) -> voi @warning_ignore("return_value_discarded") reset_btn.pressed.connect(_on_btn_property_reset_pressed.bind(property, input, reset_btn)) # property help text - var info: Node = _properties_template.get_child(2).duplicate() + var info: Label = _properties_template.get_child(2).duplicate() info.text = property.help() info_labels.append(info) grid.add_child(info) @@ -106,7 +107,6 @@ func setup_properties(properties_parent: Node, property_category: String) -> voi properties_parent.custom_minimum_size.x = min_size_overall -@warning_ignore("return_value_discarded") func _create_input_element(property: GdUnitProperty, reset_btn: Button) -> Node: if property.is_selectable_value(): var options := OptionButton.new() @@ -114,7 +114,7 @@ func _create_input_element(property: GdUnitProperty, reset_btn: Button) -> Node: for value in property.value_set(): options.add_item(value) options.item_selected.connect(_on_option_selected.bind(property, reset_btn)) - options.select(property.value()) + options.select(property.int_value()) return options if property.type() == TYPE_BOOL: var check_btn := CheckButton.new() @@ -131,7 +131,8 @@ func _create_input_element(property: GdUnitProperty, reset_btn: Button) -> Node: return input if property.type() == TYPE_PACKED_INT32_ARRAY: var key_input_button := Button.new() - key_input_button.text = to_shortcut(property.value()) + var value:PackedInt32Array = property.value() + key_input_button.text = to_shortcut(value) key_input_button.pressed.connect(_on_shortcut_change.bind(key_input_button, property, reset_btn)) return key_input_button return Control.new() @@ -150,7 +151,6 @@ func to_shortcut(keys: PackedInt32Array) -> String: return input_event.as_text() -@warning_ignore("return_value_discarded") func to_keys(input_event: InputEventKey) -> PackedInt32Array: var keys := PackedInt32Array() if input_event.ctrl_pressed: @@ -184,8 +184,8 @@ func _install_examples() -> void: var tmp_path := GdUnitFileAccess.create_temp_dir("download") var zip_file := tmp_path + "/examples.zip" var response: GdUnitUpdateClient.HttpResponse = await _update_client.request_zip_package(EAXAMPLE_URL, zip_file) - if response.code() != 200: - push_warning("Examples cannot be retrieved from GitHub! \n Error code: %d : %s" % [response.code(), response.response()]) + if response.status() != 200: + push_warning("Examples cannot be retrieved from GitHub! \n Error code: %d : %s" % [response.status(), response.response()]) update_progress("Install examples failed! Try it later again.") await get_tree().create_timer(3).timeout stop_progress() @@ -199,20 +199,28 @@ func _install_examples() -> void: stop_progress() return update_progress("Refresh project") - await rescan(true) + await rescan() + await reimport("res://gdUnit4-examples/") + update_progress("Examples successfully installed") await get_tree().create_timer(3).timeout stop_progress() -func rescan(update_scripts:=false) -> void: - await get_tree().idle_frame +func rescan() -> void: + await get_tree().process_frame var fs := EditorInterface.get_resource_filesystem() fs.scan_sources() while fs.is_scanning(): await get_tree().create_timer(1).timeout - if update_scripts: - EditorInterface.get_resource_filesystem().update_script_classes() + + +func reimport(path: String) -> void: + await get_tree().process_frame + var files := DirAccess.get_files_at(path) + EditorInterface.get_resource_filesystem().reimport_files(files) + for directory in DirAccess.get_directories_at(path): + reimport(directory) func check_for_update() -> void: @@ -252,17 +260,19 @@ func _on_btn_close_pressed() -> void: func _on_btn_property_reset_pressed(property: GdUnitProperty, input: Node, reset_btn: Button) -> void: if input is CheckButton: - input.button_pressed = property.default() + var is_default_pressed: bool = property.default() + (input as CheckButton).button_pressed = is_default_pressed elif input is LineEdit: - input.text = str(property.default()) + (input as LineEdit).text = str(property.default()) # we have to update manually for text input fields because of no change event is emited _on_property_text_changed(property.default(), property, reset_btn) elif input is OptionButton: - input.select(0) + (input as OptionButton).select(0) _on_option_selected(0, property, reset_btn) elif input is Button: - input.text = to_shortcut(property.default()) - _on_property_text_changed(property.default(), property, reset_btn) + var value: PackedInt32Array = property.default() + (input as Button).text = to_shortcut(value) + _on_property_text_changed(value, property, reset_btn) func _on_property_text_changed(new_value: Variant, property: GdUnitProperty, reset_btn: Button) -> void: @@ -271,7 +281,7 @@ func _on_property_text_changed(new_value: Variant, property: GdUnitProperty, res var error: Variant = GdUnitSettings.update_property(property) if error: var label: Label = _property_error.get_child(0) as Label - label.set_text(error) + label.set_text(str(error)) var control := gui_get_focus_owner() _property_error.show() if control != null: diff --git a/addons/gdUnit4/src/ui/settings/GdUnitSettingsDialog.gd.uid b/addons/gdUnit4/src/ui/settings/GdUnitSettingsDialog.gd.uid index 11e3f9e3..49da37f8 100644 --- a/addons/gdUnit4/src/ui/settings/GdUnitSettingsDialog.gd.uid +++ b/addons/gdUnit4/src/ui/settings/GdUnitSettingsDialog.gd.uid @@ -1 +1 @@ -uid://bbmloatmyvou5 +uid://bf71hux0t1te6 diff --git a/addons/gdUnit4/src/ui/settings/GdUnitSettingsDialog.tscn b/addons/gdUnit4/src/ui/settings/GdUnitSettingsDialog.tscn index 96f1c0b0..ba732ad1 100644 --- a/addons/gdUnit4/src/ui/settings/GdUnitSettingsDialog.tscn +++ b/addons/gdUnit4/src/ui/settings/GdUnitSettingsDialog.tscn @@ -1,11 +1,11 @@ [gd_scene load_steps=8 format=3 uid="uid://dwgat6j2u77g4"] -[ext_resource type="Script" uid="uid://dgoxpc1orxs08" path="res://addons/gdUnit4/src/ui/settings/GdUnitSettingsDialog.gd" id="2"] -[ext_resource type="Texture2D" uid="uid://bkh022wwqq7s3" path="res://addons/gdUnit4/src/ui/settings/logo.png" id="3_isfyl"] -[ext_resource type="PackedScene" uid="uid://dte0m2endcgtu" path="res://addons/gdUnit4/src/ui/templates/TestSuiteTemplate.tscn" id="4"] -[ext_resource type="PackedScene" uid="uid://0xyeci1tqebj" path="res://addons/gdUnit4/src/update/GdUnitUpdateNotify.tscn" id="5_n1jtv"] -[ext_resource type="PackedScene" uid="uid://pmnkxrhglak5" path="res://addons/gdUnit4/src/ui/settings/GdUnitInputCapture.tscn" id="5_xu3j8"] -[ext_resource type="Script" uid="uid://ogva4spkrtij" path="res://addons/gdUnit4/src/update/GdUnitUpdateClient.gd" id="8_2ggr0"] +[ext_resource type="Script" path="res://addons/gdUnit4/src/ui/settings/GdUnitSettingsDialog.gd" id="2"] +[ext_resource type="Texture2D" path="res://addons/gdUnit4/src/ui/settings/logo.png" id="3_isfyl"] +[ext_resource type="PackedScene" path="res://addons/gdUnit4/src/ui/templates/TestSuiteTemplate.tscn" id="4"] +[ext_resource type="PackedScene" path="res://addons/gdUnit4/src/update/GdUnitUpdateNotify.tscn" id="5_n1jtv"] +[ext_resource type="PackedScene" path="res://addons/gdUnit4/src/ui/settings/GdUnitInputCapture.tscn" id="5_xu3j8"] +[ext_resource type="Script" path="res://addons/gdUnit4/src/update/GdUnitUpdateClient.gd" id="8_2ggr0"] [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_hbbq5"] content_margin_left = 10.0 diff --git a/addons/gdUnit4/src/ui/settings/logo.png.import b/addons/gdUnit4/src/ui/settings/logo.png.import index c2a071e8..2cb878c0 100644 --- a/addons/gdUnit4/src/ui/settings/logo.png.import +++ b/addons/gdUnit4/src/ui/settings/logo.png.import @@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/logo.png-deda0e4ba02a0b9e4e4a830029a5817f.cte compress/mode=0 compress/high_quality=false compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 compress/hdr_compression=1 compress/normal_map=0 compress/channel_pack=0 @@ -25,6 +27,10 @@ mipmaps/generate=false mipmaps/limit=-1 roughness/mode=0 roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 process/fix_alpha_border=true process/premult_alpha=false process/normal_map_invert_y=false diff --git a/addons/gdUnit4/src/ui/templates/TestSuiteTemplate.gd.uid b/addons/gdUnit4/src/ui/templates/TestSuiteTemplate.gd.uid index 94cc662d..7b1034e6 100644 --- a/addons/gdUnit4/src/ui/templates/TestSuiteTemplate.gd.uid +++ b/addons/gdUnit4/src/ui/templates/TestSuiteTemplate.gd.uid @@ -1 +1 @@ -uid://b8ypatydap4v6 +uid://bcnywkpktlnqy diff --git a/addons/gdUnit4/src/ui/templates/TestSuiteTemplate.tscn b/addons/gdUnit4/src/ui/templates/TestSuiteTemplate.tscn index f0667923..5ccc4430 100644 --- a/addons/gdUnit4/src/ui/templates/TestSuiteTemplate.tscn +++ b/addons/gdUnit4/src/ui/templates/TestSuiteTemplate.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=2 format=3 uid="uid://dte0m2endcgtu"] -[ext_resource type="Script" uid="uid://d6ayx5x8dpnw" path="res://addons/gdUnit4/src/ui/templates/TestSuiteTemplate.gd" id="1"] +[ext_resource type="Script" path="res://addons/gdUnit4/src/ui/templates/TestSuiteTemplate.gd" id="1"] [node name="TestSuiteTemplate" type="MarginContainer"] anchors_preset = 15 diff --git a/addons/gdUnit4/src/update/GdMarkDownReader.gd b/addons/gdUnit4/src/update/GdMarkDownReader.gd index ce6885de..dab19e40 100644 --- a/addons/gdUnit4/src/update/GdMarkDownReader.gd +++ b/addons/gdUnit4/src/update/GdMarkDownReader.gd @@ -215,7 +215,7 @@ func process_tables(input: String) -> String: return "\n".join(bbcode) -class Table: +class GdUnitMDReaderTable: var _columns: int var _rows: Array[Row] = [] @@ -292,7 +292,7 @@ class Table: func parse_table(lines: Array) -> PackedStringArray: var line: String = lines[0] - var table := Table.new(line.count("|") + 1) + var table := GdUnitMDReaderTable.new(line.count("|") + 1) while not lines.is_empty(): line = lines.pop_front() if not table.parse_row(line): diff --git a/addons/gdUnit4/src/update/GdMarkDownReader.gd.uid b/addons/gdUnit4/src/update/GdMarkDownReader.gd.uid index f8964a21..0d04a4ef 100644 --- a/addons/gdUnit4/src/update/GdMarkDownReader.gd.uid +++ b/addons/gdUnit4/src/update/GdMarkDownReader.gd.uid @@ -1 +1 @@ -uid://c0pbiv6wn5iiu +uid://dj3esct7kbp36 diff --git a/addons/gdUnit4/src/update/GdUnitPatch.gd.uid b/addons/gdUnit4/src/update/GdUnitPatch.gd.uid index 76bf4f50..111ab472 100644 --- a/addons/gdUnit4/src/update/GdUnitPatch.gd.uid +++ b/addons/gdUnit4/src/update/GdUnitPatch.gd.uid @@ -1 +1 @@ -uid://yfl8yfxw73e1 +uid://bxiyaaxrv5obm diff --git a/addons/gdUnit4/src/update/GdUnitPatcher.gd b/addons/gdUnit4/src/update/GdUnitPatcher.gd index 1adae828..73d25c92 100644 --- a/addons/gdUnit4/src/update/GdUnitPatcher.gd +++ b/addons/gdUnit4/src/update/GdUnitPatcher.gd @@ -22,6 +22,7 @@ func _scan(scan_path :String, current :GdUnit4Version) -> void: func patch_count() -> int: var count := 0 for key :String in _patches.keys(): + @warning_ignore("unsafe_method_access") count += _patches[key].size() return count @@ -29,7 +30,7 @@ func patch_count() -> int: func execute() -> void: for key :String in _patches.keys(): for path :String in _patches[key]: - var patch :GdUnitPatch = load(key + "/" + path).new() + var patch :GdUnitPatch = (load(key + "/" + path) as GDScript).new() if patch: prints("execute patch", patch.version(), patch.get_script().resource_path) if not patch.execute(): diff --git a/addons/gdUnit4/src/update/GdUnitPatcher.gd.uid b/addons/gdUnit4/src/update/GdUnitPatcher.gd.uid index c3dd5eac..80781f6c 100644 --- a/addons/gdUnit4/src/update/GdUnitPatcher.gd.uid +++ b/addons/gdUnit4/src/update/GdUnitPatcher.gd.uid @@ -1 +1 @@ -uid://cdcl6oy7t8r2a +uid://cy5bcbbj383x1 diff --git a/addons/gdUnit4/src/update/GdUnitUpdate.gd b/addons/gdUnit4/src/update/GdUnitUpdate.gd index 1b492fe8..ef878151 100644 --- a/addons/gdUnit4/src/update/GdUnitUpdate.gd +++ b/addons/gdUnit4/src/update/GdUnitUpdate.gd @@ -18,7 +18,7 @@ var _download_url :String func _ready() -> void: - init_progress(5) + init_progress(6) func _process(_delta :float) -> void: @@ -56,6 +56,8 @@ func message_h4(message: String, color: Color, show_spinner := true) -> void: if show_spinner: _progress_content.add_image(_spinner_img) _progress_content.append_text(" [font_size=16]%s[/font_size]" % _colored(message, color)) + if _debug_mode: + prints(message) @warning_ignore("return_value_discarded") @@ -91,6 +93,9 @@ func run_update() -> void: else: copy_directory(tmp_path, "res://") + await update_progress("Patch invalid UID's") + await patch_uids() + await update_progress("New GdUnit version successfully installed, Restarting Godot please wait.") await get_tree().create_timer(3).timeout enable_gdUnit() @@ -99,6 +104,60 @@ func run_update() -> void: restart_godot() +func patch_uids(path := "res://addons/gdUnit4/src/") -> void: + var to_reimport: PackedStringArray + for file in DirAccess.get_files_at(path): + var file_path := path.path_join(file) + var ext := file.get_extension() + + if ext == "tscn" or ext == "scn" or ext == "tres" or ext == "res": + message_h4("Patch GdUnit4 scene: '%s'" % file, Color.WEB_GREEN) + remove_uids_from_file(file_path) + elif FileAccess.file_exists(file_path + ".import"): + to_reimport.append(file_path) + + if not to_reimport.is_empty(): + message_h4("Reimport resources '%s'" % ", ".join(to_reimport), Color.WEB_GREEN) + if Engine.is_editor_hint(): + EditorInterface.get_resource_filesystem().reimport_files(to_reimport) + + for dir in DirAccess.get_directories_at(path): + if not dir.begins_with("."): + patch_uids(path.path_join(dir)) + await get_tree().process_frame + + +func remove_uids_from_file(file_path: String) -> bool: + var file := FileAccess.open(file_path, FileAccess.READ) + if file == null: + print("Failed to open file: ", file_path) + return false + + var original_content := file.get_as_text() + file.close() + + # Remove UIDs using regex + var regex := RegEx.new() + regex.compile("(\\[ext_resource[^\\]]*?)\\s+uid=\"uid://[^\"]*\"") + + var modified_content := regex.sub(original_content, "$1", true) + + # Check if any changes were made + if original_content != modified_content: + prints("Patched invalid uid's out in '%s'" % file_path) + # Write the modified content back + file = FileAccess.open(file_path, FileAccess.WRITE) + if file == null: + print("Failed to write to file: ", file_path) + return false + + file.store_string(modified_content) + file.close() + return true + + return false + + func restart_godot() -> void: prints("Force restart Godot") EditorInterface.restart_editor(true) diff --git a/addons/gdUnit4/src/update/GdUnitUpdate.gd.uid b/addons/gdUnit4/src/update/GdUnitUpdate.gd.uid index ebd02b68..6167660c 100644 --- a/addons/gdUnit4/src/update/GdUnitUpdate.gd.uid +++ b/addons/gdUnit4/src/update/GdUnitUpdate.gd.uid @@ -1 +1 @@ -uid://yq8po6gm4kqs +uid://b4820gymnwsmc diff --git a/addons/gdUnit4/src/update/GdUnitUpdate.tscn b/addons/gdUnit4/src/update/GdUnitUpdate.tscn index 3654f7d1..20d60b76 100644 --- a/addons/gdUnit4/src/update/GdUnitUpdate.tscn +++ b/addons/gdUnit4/src/update/GdUnitUpdate.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=6 format=3 uid="uid://2eahgaw88y6q"] -[ext_resource type="Script" uid="uid://cyyxey236wyyr" path="res://addons/gdUnit4/src/update/GdUnitUpdate.gd" id="1"] +[ext_resource type="Script" path="res://addons/gdUnit4/src/update/GdUnitUpdate.gd" id="1"] [sub_resource type="Gradient" id="Gradient_wilsr"] colors = PackedColorArray(0.151276, 0.151276, 0.151276, 1, 1, 1, 1, 1) diff --git a/addons/gdUnit4/src/update/GdUnitUpdateClient.gd.uid b/addons/gdUnit4/src/update/GdUnitUpdateClient.gd.uid index 498979e8..5cf7da1e 100644 --- a/addons/gdUnit4/src/update/GdUnitUpdateClient.gd.uid +++ b/addons/gdUnit4/src/update/GdUnitUpdateClient.gd.uid @@ -1 +1 @@ -uid://2lrcgo0tmnlo +uid://dhi05b5jk225i diff --git a/addons/gdUnit4/src/update/GdUnitUpdateNotify.gd.uid b/addons/gdUnit4/src/update/GdUnitUpdateNotify.gd.uid index 4b7e5900..d401f804 100644 --- a/addons/gdUnit4/src/update/GdUnitUpdateNotify.gd.uid +++ b/addons/gdUnit4/src/update/GdUnitUpdateNotify.gd.uid @@ -1 +1 @@ -uid://cje1afd65l33e +uid://w4jy3sjetpin diff --git a/addons/gdUnit4/src/update/GdUnitUpdateNotify.tscn b/addons/gdUnit4/src/update/GdUnitUpdateNotify.tscn index 0878ad47..46119f14 100644 --- a/addons/gdUnit4/src/update/GdUnitUpdateNotify.tscn +++ b/addons/gdUnit4/src/update/GdUnitUpdateNotify.tscn @@ -1,8 +1,8 @@ [gd_scene load_steps=4 format=3 uid="uid://0xyeci1tqebj"] -[ext_resource type="Script" uid="uid://touotnvkoyo" path="res://addons/gdUnit4/src/update/GdUnitUpdateNotify.gd" id="1_112wo"] -[ext_resource type="Script" uid="uid://ogva4spkrtij" path="res://addons/gdUnit4/src/update/GdUnitUpdateClient.gd" id="2_18asx"] -[ext_resource type="PackedScene" uid="uid://2eahgaw88y6q" path="res://addons/gdUnit4/src/update/GdUnitUpdate.tscn" id="3_x87h6"] +[ext_resource type="Script" path="res://addons/gdUnit4/src/update/GdUnitUpdateNotify.gd" id="1_112wo"] +[ext_resource type="Script" path="res://addons/gdUnit4/src/update/GdUnitUpdateClient.gd" id="2_18asx"] +[ext_resource type="PackedScene" path="res://addons/gdUnit4/src/update/GdUnitUpdate.tscn" id="3_x87h6"] [node name="Control" type="MarginContainer"] anchors_preset = 15 diff --git a/addons/gdUnit4/src/update/assets/border_bottom.png.import b/addons/gdUnit4/src/update/assets/border_bottom.png.import index 70e9a028..0054a84f 100644 --- a/addons/gdUnit4/src/update/assets/border_bottom.png.import +++ b/addons/gdUnit4/src/update/assets/border_bottom.png.import @@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/border_bottom.png-30d66a4c67e3a03ad191e37cdf1 compress/mode=0 compress/high_quality=false compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 compress/hdr_compression=1 compress/normal_map=0 compress/channel_pack=0 @@ -25,6 +27,10 @@ mipmaps/generate=false mipmaps/limit=-1 roughness/mode=0 roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 process/fix_alpha_border=true process/premult_alpha=false process/normal_map_invert_y=false diff --git a/addons/gdUnit4/src/update/assets/border_top.png.import b/addons/gdUnit4/src/update/assets/border_top.png.import index 814882aa..0b748c72 100644 --- a/addons/gdUnit4/src/update/assets/border_top.png.import +++ b/addons/gdUnit4/src/update/assets/border_top.png.import @@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/border_top.png-c47cbebdb755144731c6ae309e18bb compress/mode=0 compress/high_quality=false compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 compress/hdr_compression=1 compress/normal_map=0 compress/channel_pack=0 @@ -25,6 +27,10 @@ mipmaps/generate=false mipmaps/limit=-1 roughness/mode=0 roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 process/fix_alpha_border=true process/premult_alpha=false process/normal_map_invert_y=false diff --git a/addons/gdUnit4/src/update/assets/dot1.png.import b/addons/gdUnit4/src/update/assets/dot1.png.import index f01f7098..fa76ec88 100644 --- a/addons/gdUnit4/src/update/assets/dot1.png.import +++ b/addons/gdUnit4/src/update/assets/dot1.png.import @@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/dot1.png-380baf1b5247addda93bce3c799aa4e7.cte compress/mode=0 compress/high_quality=false compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 compress/hdr_compression=1 compress/normal_map=0 compress/channel_pack=0 @@ -25,6 +27,10 @@ mipmaps/generate=false mipmaps/limit=-1 roughness/mode=0 roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 process/fix_alpha_border=true process/premult_alpha=false process/normal_map_invert_y=false diff --git a/addons/gdUnit4/src/update/assets/dot2.png.import b/addons/gdUnit4/src/update/assets/dot2.png.import index f1e10178..de06952e 100644 --- a/addons/gdUnit4/src/update/assets/dot2.png.import +++ b/addons/gdUnit4/src/update/assets/dot2.png.import @@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/dot2.png-86a9db80ef4413e353c4339ad8f68a5f.cte compress/mode=0 compress/high_quality=false compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 compress/hdr_compression=1 compress/normal_map=0 compress/channel_pack=0 @@ -25,6 +27,10 @@ mipmaps/generate=false mipmaps/limit=-1 roughness/mode=0 roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 process/fix_alpha_border=true process/premult_alpha=false process/normal_map_invert_y=false diff --git a/addons/gdUnit4/src/update/assets/embedded.png.import b/addons/gdUnit4/src/update/assets/embedded.png.import index 26f37261..06f69325 100644 --- a/addons/gdUnit4/src/update/assets/embedded.png.import +++ b/addons/gdUnit4/src/update/assets/embedded.png.import @@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/embedded.png-29390948772209a603567d24f8766495 compress/mode=0 compress/high_quality=false compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 compress/hdr_compression=1 compress/normal_map=0 compress/channel_pack=0 @@ -25,6 +27,10 @@ mipmaps/generate=false mipmaps/limit=-1 roughness/mode=0 roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 process/fix_alpha_border=true process/premult_alpha=false process/normal_map_invert_y=false diff --git a/addons/gdUnit4/src/update/assets/horizontal-line2.png.import b/addons/gdUnit4/src/update/assets/horizontal-line2.png.import index 949745cf..8755fd87 100644 --- a/addons/gdUnit4/src/update/assets/horizontal-line2.png.import +++ b/addons/gdUnit4/src/update/assets/horizontal-line2.png.import @@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/horizontal-line2.png-92618e6ee5cc9002847547a8 compress/mode=0 compress/high_quality=false compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 compress/hdr_compression=1 compress/normal_map=0 compress/channel_pack=0 @@ -25,6 +27,10 @@ mipmaps/generate=false mipmaps/limit=-1 roughness/mode=0 roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 process/fix_alpha_border=true process/premult_alpha=false process/normal_map_invert_y=false diff --git a/addons/monologue/assets/Node.svg.import b/addons/monologue/assets/Node.svg.import index b236e3d3..35dac993 100644 --- a/addons/monologue/assets/Node.svg.import +++ b/addons/monologue/assets/Node.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://cgs1pju1mljky" -path="res://.godot/imported/Node.svg-e16dadd791df1928ceaf195a00daa668.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/Node.svg-e16dadd791df1928ceaf195a00daa668.dpitex" [deps] source_file="res://addons/monologue/assets/Node.svg" -dest_files=["res://.godot/imported/Node.svg-e16dadd791df1928ceaf195a00daa668.ctex"] +dest_files=["res://.godot/imported/Node.svg-e16dadd791df1928ceaf195a00daa668.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/addons/monologue/assets/RichTextLabel.svg.import b/addons/monologue/assets/RichTextLabel.svg.import index 41e94928..942e4352 100644 --- a/addons/monologue/assets/RichTextLabel.svg.import +++ b/addons/monologue/assets/RichTextLabel.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://tdn0wg47rwvc" -path="res://.godot/imported/RichTextLabel.svg-5ab481203362918ef68d076c470c15e7.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/RichTextLabel.svg-5ab481203362918ef68d076c470c15e7.dpitex" [deps] source_file="res://addons/monologue/assets/RichTextLabel.svg" -dest_files=["res://.godot/imported/RichTextLabel.svg-5ab481203362918ef68d076c470c15e7.ctex"] +dest_files=["res://.godot/imported/RichTextLabel.svg-5ab481203362918ef68d076c470c15e7.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/autoloads/constants.gd b/autoloads/constants.gd index 3ce56ef1..eb926f14 100644 --- a/autoloads/constants.gd +++ b/autoloads/constants.gd @@ -2,24 +2,24 @@ extends Node ## Dictionary of Monologue node types and their corresponding scenes. const NODE_SCENES = { - "Root": preload("res://nodes/root_node/root_node.tscn"), - "Audio": preload("res://nodes/audio_node/audio_node.tscn"), - "Action": preload("res://nodes/action_node/action_node.tscn"), - "Background": preload("res://nodes/background_node/background_node.tscn"), - "Bridge": preload("res://nodes/bridge_in_node/bridge_in_node.tscn"), - "BridgeIn": preload("res://nodes/bridge_in_node/bridge_in_node.tscn"), - "BridgeOut": preload("res://nodes/bridge_out_node/bridge_out_node.tscn"), - "Choice": preload("res://nodes/choice_node/choice_node.tscn"), - "Character": preload("res://nodes/character_node/character_node.tscn"), - "Comment": preload("res://nodes/comment_node/comment_node.tscn"), - "Condition": preload("res://nodes/condition_node/condition_node.tscn"), - "Random": preload("res://nodes/random_node/random_node.tscn"), - "EndPath": preload("res://nodes/end_path_node/end_path_node.tscn"), - "Event": preload("res://nodes/event_node/event_node.tscn"), - "Sentence": preload("res://nodes/sentence_node/sentence_node.tscn"), - "Setter": preload("res://nodes/setter_node/setter_node.tscn"), - "Wait": preload("res://nodes/wait_node/wait_node.tscn"), - "Reroute": preload("res://nodes/reroute_node/reroute_node.tscn") +#"Root": preload("res://nodes/root_node/root_node.tscn"), +#"Audio": preload("res://nodes/audio_node/audio_node.tscn"), +#"Action": preload("res://nodes/action_node/action_node.tscn"), +#"Background": preload("res://nodes/background_node/background_node.tscn"), +#"Bridge": preload("res://nodes/bridge_in_node/bridge_in_node.tscn"), +#"BridgeIn": preload("res://nodes/bridge_in_node/bridge_in_node.tscn"), +#"BridgeOut": preload("res://nodes/bridge_out_node/bridge_out_node.tscn"), +#"Choice": preload("res://nodes/choice_node/choice_node.tscn"), +#"Character": preload("res://nodes/character_node/character_node.tscn"), +#"Comment": preload("res://nodes/comment_node/comment_node.tscn"), +#"Condition": preload("res://nodes/condition_node/condition_node.tscn"), +#"Random": preload("res://nodes/random_node/random_node.tscn"), +#"EndPath": preload("res://nodes/end_path_node/end_path_node.tscn"), +#"Event": preload("res://nodes/event_node/event_node.tscn"), +#"Sentence": preload("res://nodes/sentence_node/sentence_node.tscn"), +#"Setter": preload("res://nodes/setter_node/setter_node.tscn"), +#"Wait": preload("res://nodes/wait_node/wait_node.tscn"), +#"Reroute": preload("res://nodes/reroute_node/reroute_node.tscn") } const HISTORY_PATH = "user://history.save" const PREFERENCES_PATH = "user://preferences.cfg" diff --git a/autoloads/storyline_manager.gd b/autoloads/storyline_manager.gd new file mode 100644 index 00000000..75642550 --- /dev/null +++ b/autoloads/storyline_manager.gd @@ -0,0 +1,59 @@ +extends Node + +signal storyline_created +signal storyline_closed +signal storyline_changed +signal storyline_switched + +var _documents: Dictionary = {} +var _active_document_id: String + + +func create_storyline(fname: String = "unnamed_storyline") -> StorylineDocument: + var doc: StorylineDocument = StorylineDocument.new(fname) + doc.is_dirty = true + doc.content_changed.connect(_on_document_content_changed) + _documents.set(doc.id, doc) + set_active_storyline(doc.id) + storyline_created.emit() + if _documents.size() <= 1: + storyline_switched.emit() + return doc + + +func close_storyline(id: String) -> void: + var doc = _documents.get(id, null) + if doc == null: + return + if doc.is_dirty: + # Save changes ? + return + _documents.erase(id) + + if _active_document_id == id: + var remaining = _documents.keys() + if remaining.size() > 0: + _active_document_id = remaining[0] + else: + _active_document_id = "" + storyline_closed.emit() + + +func set_active_storyline(id: String) -> void: + _active_document_id = id + + +func get_storyline(id: String) -> StorylineDocument: + return _documents.get(id, null) + + +func get_storyline_ids() -> Array: + return _documents.keys() + + +func get_active_storyline() -> StorylineDocument: + return _documents.get(_active_document_id) + + +func _on_document_content_changed() -> void: + storyline_changed.emit() diff --git a/autoloads/storyline_manager.gd.uid b/autoloads/storyline_manager.gd.uid new file mode 100644 index 00000000..ed977378 --- /dev/null +++ b/autoloads/storyline_manager.gd.uid @@ -0,0 +1 @@ +uid://dabxmafwjrhkv diff --git a/autoloads/theme_manager.gd b/autoloads/theme_manager.gd new file mode 100644 index 00000000..25aa3df6 --- /dev/null +++ b/autoloads/theme_manager.gd @@ -0,0 +1,65 @@ +extends Node +## Manages theme generation, saving, and application for the Monologue application + +var current_theme: Theme +var current_settings: ThemeSettings +var is_light_theme: bool = false + + +func _ready() -> void: + generate_and_apply_theme(false) + + +## Generate a theme from a settings and apply it +func generate_and_apply_theme(light: bool = false) -> void: + is_light_theme = light + + if is_light_theme: + current_settings = ThemeSettingsLight.new() + else: + current_settings = ThemeSettingsDark.new() + + current_theme = ThemeBuilder.build_theme(current_settings) + + if not current_theme: + push_error("Failed to generate theme") + return + + apply_theme_to_tree(current_theme) + print("Theme generated and applied: %s" % ("Light" if light else "Dark")) + + +## Save the current theme to disk +func save_current_theme() -> void: + if not current_theme: + push_error("No theme to save") + return + + var theme_path = current_settings.get_path() + var err = ResourceSaver.save(current_theme, theme_path) + + if err == OK: + print("Theme saved to: %s" % theme_path) + else: + push_error("Failed to save theme to: %s (error %d)" % [theme_path, err]) + + +## Apply theme to all Control nodes in the scene tree +func apply_theme_to_tree(theme: Theme) -> void: + var root: Window = get_tree().root + root.set_theme(theme) + + +## Switch between light and dark themes +func toggle_theme() -> void: + generate_and_apply_theme(not is_light_theme) + + +## Get the current theme +func get_current_theme() -> Theme: + return current_theme + + +## Get the current settings +func get_current_settings() -> RefCounted: + return current_settings diff --git a/autoloads/theme_manager.gd.uid b/autoloads/theme_manager.gd.uid new file mode 100644 index 00000000..5087d8ac --- /dev/null +++ b/autoloads/theme_manager.gd.uid @@ -0,0 +1 @@ +uid://b0c887r1lq57j diff --git a/autoloads/undo_redo_service.gd b/autoloads/undo_redo_service.gd new file mode 100644 index 00000000..1db57981 --- /dev/null +++ b/autoloads/undo_redo_service.gd @@ -0,0 +1,36 @@ +# UndoRedoService +extends Node + +const MAX_STEPS: int = 100 + +var contexts: Dictionary = {} +var active_context_id: String = "" + + +func create_context(context_id: String) -> HistoryHandler: + if contexts.has(context_id): + return contexts[context_id] + + var undo_redo: HistoryHandler = HistoryHandler.new() + undo_redo.max_steps = MAX_STEPS + contexts[context_id] = undo_redo + return undo_redo + + +func get_context(context_id: String) -> HistoryHandler: + return contexts.get(context_id, null) + + +func destroy_context(context_id: String) -> void: + if not contexts.has(context_id): + return + + var undo_redo: HistoryHandler = contexts[context_id] + undo_redo.clear_history() + contexts.erase(undo_redo) + + +func get_active_context() -> HistoryHandler: + if active_context_id.is_empty(): + return null + return get_context(active_context_id) diff --git a/autoloads/undo_redo_service.gd.uid b/autoloads/undo_redo_service.gd.uid new file mode 100644 index 00000000..a7d4ddb5 --- /dev/null +++ b/autoloads/undo_redo_service.gd.uid @@ -0,0 +1 @@ +uid://cl3x7l44eayh3 diff --git a/autoloads/util.gd b/autoloads/util.gd index 3aa06a58..861b75f2 100644 --- a/autoloads/util.gd +++ b/autoloads/util.gd @@ -49,6 +49,10 @@ func to_key_name(snake_case_name: String, delimiter: String = "") -> String: for word in words: capitalized_list.append("ID" if word.to_lower() == "id" else word) return delimiter.join(capitalized_list) + +## Converts a snake_case name to readable string with capitalized "ID". +func to_readable_name(snake_case_name: String) -> String: + return to_key_name(snake_case_name, " ") ## Left-truncate a filename string based on MAX_FILENAME_LENGTH. diff --git a/bilUDX.png.import b/bilUDX.png.import index b45c9584..3cb032c9 100644 --- a/bilUDX.png.import +++ b/bilUDX.png.import @@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/bilUDX.png-4b799bae1c669628ee420ba80d3eba36.c compress/mode=0 compress/high_quality=false compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 compress/hdr_compression=1 compress/normal_map=0 compress/channel_pack=0 @@ -25,6 +27,10 @@ mipmaps/generate=false mipmaps/limit=-1 roughness/mode=0 roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 process/fix_alpha_border=true process/premult_alpha=false process/normal_map_invert_y=false diff --git a/common/assets/logo/logo_256x256.png.import b/common/assets/logo/logo_256x256.png.import index 94ba4b54..12412049 100644 --- a/common/assets/logo/logo_256x256.png.import +++ b/common/assets/logo/logo_256x256.png.import @@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/logo_256x256.png-c64139f54d35de8927bbaa3e9e2c compress/mode=0 compress/high_quality=false compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 compress/hdr_compression=1 compress/normal_map=0 compress/channel_pack=0 @@ -25,6 +27,10 @@ mipmaps/generate=false mipmaps/limit=-1 roughness/mode=0 roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 process/fix_alpha_border=true process/premult_alpha=false process/normal_map_invert_y=false diff --git a/common/assets/logo/logo_256x256.svg.import b/common/assets/logo/logo_256x256.svg.import index 3cd5ed55..4c711d6c 100644 --- a/common/assets/logo/logo_256x256.svg.import +++ b/common/assets/logo/logo_256x256.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://exl7lwdbgxr2" -path="res://.godot/imported/logo_256x256.svg-af415b1c6dd0fa173899415407767412.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/logo_256x256.svg-af415b1c6dd0fa173899415407767412.dpitex" [deps] source_file="res://common/assets/logo/logo_256x256.svg" -dest_files=["res://.godot/imported/logo_256x256.svg-af415b1c6dd0fa173899415407767412.ctex"] +dest_files=["res://.godot/imported/logo_256x256.svg-af415b1c6dd0fa173899415407767412.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/common/assets/logo/logo_32x32.png.import b/common/assets/logo/logo_32x32.png.import index ab1f6931..58d4c850 100644 --- a/common/assets/logo/logo_32x32.png.import +++ b/common/assets/logo/logo_32x32.png.import @@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/logo_32x32.png-a9ec36e08c728751a55ec37b054696 compress/mode=0 compress/high_quality=false compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 compress/hdr_compression=1 compress/normal_map=0 compress/channel_pack=0 @@ -25,6 +27,10 @@ mipmaps/generate=false mipmaps/limit=-1 roughness/mode=0 roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 process/fix_alpha_border=true process/premult_alpha=false process/normal_map_invert_y=false diff --git a/common/assets/logo/logo_32x32.svg.import b/common/assets/logo/logo_32x32.svg.import index 1ed2486e..3c2ce479 100644 --- a/common/assets/logo/logo_32x32.svg.import +++ b/common/assets/logo/logo_32x32.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://b35w6abcbrbvw" -path="res://.godot/imported/logo_32x32.svg-13a21cb5dc383e97ea1060616438d51c.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/logo_32x32.svg-13a21cb5dc383e97ea1060616438d51c.dpitex" [deps] source_file="res://common/assets/logo/logo_32x32.svg" -dest_files=["res://.godot/imported/logo_32x32.svg-13a21cb5dc383e97ea1060616438d51c.ctex"] +dest_files=["res://.godot/imported/logo_32x32.svg-13a21cb5dc383e97ea1060616438d51c.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/common/assets/logo/logo_512x512.png.import b/common/assets/logo/logo_512x512.png.import index 2700cb6e..99c047db 100644 --- a/common/assets/logo/logo_512x512.png.import +++ b/common/assets/logo/logo_512x512.png.import @@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/logo_512x512.png-dac42d53bf3ffaa08235f733c584 compress/mode=0 compress/high_quality=false compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 compress/hdr_compression=1 compress/normal_map=0 compress/channel_pack=0 @@ -25,6 +27,10 @@ mipmaps/generate=false mipmaps/limit=-1 roughness/mode=0 roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 process/fix_alpha_border=true process/premult_alpha=false process/normal_map_invert_y=false diff --git a/common/assets/logo/logo_512x512.svg.import b/common/assets/logo/logo_512x512.svg.import index f3e3fe43..cec06eb2 100644 --- a/common/assets/logo/logo_512x512.svg.import +++ b/common/assets/logo/logo_512x512.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://d3icwpvi8vr6x" -path="res://.godot/imported/logo_512x512.svg-d52f6f4fda3afc8cd27c75d996e2ed6b.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/logo_512x512.svg-d52f6f4fda3afc8cd27c75d996e2ed6b.dpitex" [deps] source_file="res://common/assets/logo/logo_512x512.svg" -dest_files=["res://.godot/imported/logo_512x512.svg-d52f6f4fda3afc8cd27c75d996e2ed6b.ctex"] +dest_files=["res://.godot/imported/logo_512x512.svg-d52f6f4fda3afc8cd27c75d996e2ed6b.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/common/assets/logo/logo_72x72.png.import b/common/assets/logo/logo_72x72.png.import index 6ea0d2b0..ca6d1efd 100644 --- a/common/assets/logo/logo_72x72.png.import +++ b/common/assets/logo/logo_72x72.png.import @@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/logo_72x72.png-053db1a5547f3fbe3dc44285da1ce4 compress/mode=0 compress/high_quality=false compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 compress/hdr_compression=1 compress/normal_map=0 compress/channel_pack=0 @@ -25,6 +27,10 @@ mipmaps/generate=false mipmaps/limit=-1 roughness/mode=0 roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 process/fix_alpha_border=true process/premult_alpha=false process/normal_map_invert_y=false diff --git a/common/assets/logo/logo_72x72.svg.import b/common/assets/logo/logo_72x72.svg.import index b9b55c67..23a3977f 100644 --- a/common/assets/logo/logo_72x72.svg.import +++ b/common/assets/logo/logo_72x72.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://bn75u1jdkiwu3" -path="res://.godot/imported/logo_72x72.svg-73f50997eb81123373b48dd50423d36e.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/logo_72x72.svg-73f50997eb81123373b48dd50423d36e.dpitex" [deps] source_file="res://common/assets/logo/logo_72x72.svg" -dest_files=["res://.godot/imported/logo_72x72.svg-73f50997eb81123373b48dd50423d36e.ctex"] +dest_files=["res://.godot/imported/logo_72x72.svg-73f50997eb81123373b48dd50423d36e.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/common/connection_manager.gd b/common/connection_manager.gd new file mode 100644 index 00000000..f8cb2608 --- /dev/null +++ b/common/connection_manager.gd @@ -0,0 +1,352 @@ +class_name ConnectionManager extends RefCounted + +## Manages connections between node properties for easy access and validation + +var _storyline: StorylineDocument +var _suspended_connections: Dictionary = {} + + +func _init(storyline: StorylineDocument) -> void: + _storyline = storyline + + +## Updates property connection tracking when a connection is made (using property names) +## All parameters are node_ids, not scene node names. +func register_connection_by_property( + from_node_id: String, from_property_name: String, to_node_id: String, to_property_name: String +) -> void: + var from_node: InspectableNode = _get_node_view_by_id(from_node_id) + var to_node: InspectableNode = _get_node_view_by_id(to_node_id) + + if not from_node or not to_node: + push_warning("Cannot register connection: node not found") + return + + var from_prop: Property = from_node.get_property(from_property_name) + var to_prop: Property = to_node.get_property(to_property_name) + + if not from_prop or not to_prop: + push_warning("Cannot register connection: property not found") + return + + # Track the connection in both properties using property names + from_prop.add_connection_to(to_node_id, to_property_name) + to_prop.add_connection_from(from_node_id, from_property_name) + + +## Updates property connection tracking when a connection is made (using port indices - legacy) +## Parameters are node_ids for compatibility with GraphEdit using ids for names. +func register_connection( + from_node_id: String, from_port: int, to_node_id: String, to_port: int +) -> void: + var from_node = _get_node_view_by_id(from_node_id) + var to_node = _get_node_view_by_id(to_node_id) + + if not from_node or not to_node: + push_warning("Cannot register connection: node not found") + return + + var from_prop = _get_property_at_port(from_node, from_port) + var to_prop = _get_property_at_port(to_node, to_port) + + if not from_prop or not to_prop: + push_warning("Cannot register connection: property not found") + return + + # Track the connection using property names + register_connection_by_property(from_node_id, from_prop.name, to_node_id, to_prop.name) + + +## Updates property connection tracking when a connection is removed (using property names) +## All parameters are node_ids, not scene node names. +func unregister_connection_by_property( + from_node_id: String, from_property_name: String, to_node_id: String, to_property_name: String +) -> void: + var from_node = _get_node_view_by_id(from_node_id) + var to_node = _get_node_view_by_id(to_node_id) + + if not from_node or not to_node: + return + + var from_prop = from_node.get_property(from_property_name) + var to_prop = to_node.get_property(to_property_name) + + if not from_prop or not to_prop: + return + + # Remove the connection from both properties using property names + from_prop.connected_to = from_prop.connected_to.filter( + func(c): return not (c["node_id"] == to_node_id and c["property_name"] == to_property_name) + ) + to_prop.connected_from = to_prop.connected_from.filter( + func(c): + return not (c["node_id"] == from_node_id and c["property_name"] == from_property_name) + ) + + +## Updates property connection tracking when a connection is removed (using port indices - legacy) +## Parameters are node_ids for compatibility. +func unregister_connection( + from_node_id: String, from_port: int, to_node_id: String, to_port: int +) -> void: + var from_node = _get_node_view_by_id(from_node_id) + var to_node = _get_node_view_by_id(to_node_id) + + if not from_node or not to_node: + return + + var from_prop = _get_property_at_port(from_node, from_port) + var to_prop = _get_property_at_port(to_node, to_port) + + if not from_prop or not to_prop: + return + + # Remove the connection using property names + unregister_connection_by_property(from_node_id, from_prop.name, to_node_id, to_prop.name) + + +## Gets all connections tracked by properties +## Returns array of {from_node_id, from_property, to_node_id, to_property} +func get_all_connections() -> Array[Dictionary]: + var connections: Array[Dictionary] = [] + var processed_connections = {} # To avoid duplicates + + for node: InspectableNode in _storyline.nodes: + var node_id: String = node.get_property("id").get_value() + for prop: Property in node.get_properties(): + # Only process outgoing connections to avoid duplicates + for conn in prop.connected_to: + var key = ( + "%s.%s->%s.%s" % [node_id, prop.name, conn["node_id"], conn["property_name"]] + ) + if key not in processed_connections: + connections.append( + { + "from_node_id": node_id, + "from_property": prop.name, + "to_node_id": conn["node_id"], + "to_property": conn["property_name"] + } + ) + processed_connections[key] = true + + return connections + + +## Gets all properties that are connected (have at least one connection) +func get_connected_properties() -> Array[Property]: + var connected: Array[Property] = [] + for node: InspectableNode in _storyline.nodes: + for prop: Property in node.get_properties(): + if prop.is_port_connected(): + connected.append(prop) + return connected + + +## Gets the node a property is connected to (for single connection) +func get_connected_node(node: InspectableNode, property_name: String) -> InspectableNode: + var prop = node.get_property(property_name) + if not prop or not prop.is_port_connected(): + return null + + # Get first connection (assuming single connection for simplicity) + var connection = null + if prop.connected_to.size() > 0: + connection = prop.connected_to[0] + elif prop.connected_from.size() > 0: + connection = prop.connected_from[0] + + if connection: + return _get_node_view_by_id(connection["node_id"]) + + return null + + +## Validates all connections are still valid (nodes and properties exist) +func validate_connections() -> bool: + var all_valid = true + for node: InspectableNode in _storyline.nodes: + for prop: Property in node.get_properties(): + # Check outgoing connections + for conn in prop.connected_to: + var target_node = _get_node_view_by_id(conn["node_id"]) + if not target_node or not target_node.get_property(conn["property_name"]): + push_warning( + ( + "Invalid connection found from %s.%s" + % [node.get_property_value("id"), prop.name] + ) + ) + all_valid = false + + # Check incoming connections + for conn in prop.connected_from: + var source_node = _get_node_view_by_id(conn["node_id"]) + if not source_node or not source_node.get_property(conn["property_name"]): + push_warning( + ( + "Invalid connection found to %s.%s" + % [node.get_property_value("id"), prop.name] + ) + ) + all_valid = false + + return all_valid + + +## Rename a node id across all connection references and suspended snapshots +func rename_node_id(old_id: String, new_id: String) -> void: + if old_id == new_id or old_id.is_empty() or new_id.is_empty(): + return + + # Update connections on all properties + for node: InspectableNode in _storyline.nodes: + for prop: Property in node.get_properties(): + for i in range(prop.connected_to.size()): + var conn: Dictionary = prop.connected_to[i] + if conn.get("node_id", "") == old_id: + conn["node_id"] = new_id + prop.connected_to[i] = conn + for i in range(prop.connected_from.size()): + var conn_in: Dictionary = prop.connected_from[i] + if conn_in.get("node_id", "") == old_id: + conn_in["node_id"] = new_id + prop.connected_from[i] = conn_in + + # Update suspended connection snapshots + var keys := _suspended_connections.keys() + for k: String in keys: + var parts: Array = k.split("::") + if parts.size() != 2: + continue + if parts[0] != old_id: + continue + var new_key := "%s::%s" % [new_id, parts[1]] + var snapshot: Dictionary = _suspended_connections[k] + # Update inner arrays + for dir in ["incoming", "outgoing"]: + if snapshot.has(dir): + var arr: Array = snapshot[dir] + for i in range(arr.size()): + var c: Dictionary = arr[i] + if c.get("node_id", "") == old_id: + c["node_id"] = new_id + arr[i] = c + snapshot[dir] = arr + _suspended_connections.erase(k) + _suspended_connections[new_key] = snapshot + + +func suspend_incoming_property_connections(node_id: String, property_name: String) -> void: + _suspend_property_connections(node_id, property_name, "incoming", "connected_from", true) + + +func suspend_outgoing_property_connections(node_id: String, property_name: String) -> void: + _suspend_property_connections(node_id, property_name, "outgoing", "connected_to", false) + + +func restore_incoming_property_connections(node_id: String, property_name: String) -> void: + _restore_property_connections(node_id, property_name, "incoming", true) + + +func restore_outgoing_property_connections(node_id: String, property_name: String) -> void: + _restore_property_connections(node_id, property_name, "outgoing", false) + + +func _suspend_property_connections( + node_id: String, + property_name: String, + direction: String, + connection_array_name: String, + is_incoming: bool +) -> void: + var key: String = _connection_key(node_id, property_name) + if not _suspended_connections.has(key): + _suspended_connections[key] = {} + + var node := _get_node_view_by_id(node_id) + if not node: + return + + var prop := node.get_property(property_name) + if not prop: + return + + var connections: Array[Dictionary] = prop.get(connection_array_name).duplicate(true) + if connections.is_empty(): + return + + _suspended_connections[key][direction] = connections + + # Unregister each connection + for conn_dict in connections: + var other_node: String = conn_dict.get("node_id", "") + var other_property: String = conn_dict.get("property_name", "") + if other_node.is_empty() or other_property.is_empty(): + continue + + if is_incoming: + unregister_connection_by_property(other_node, other_property, node_id, property_name) + else: + unregister_connection_by_property(node_id, property_name, other_node, other_property) + + +func _restore_property_connections( + node_id: String, property_name: String, direction: String, is_incoming: bool +) -> void: + var key: String = _connection_key(node_id, property_name) + if not _suspended_connections.has(key): + return + + var snapshot: Dictionary = _suspended_connections[key] + _suspended_connections.erase(key) + + # Re-register each connection + var connections: Array = snapshot.get(direction, []) + for conn_dict in connections: + var other_node: String = conn_dict.get("node_id", "") + var other_property: String = conn_dict.get("property_name", "") + if other_node.is_empty() or other_property.is_empty(): + continue + + if is_incoming: + register_connection_by_property(other_node, other_property, node_id, property_name) + else: + register_connection_by_property(node_id, property_name, other_node, other_property) + + +func _connection_key(node_id: String, property_name: String) -> String: + return "%s::%s" % [node_id, property_name] + + +func _get_node_view_by_id(node_id: String) -> InspectableNode: + for node: InspectableNode in _storyline.nodes: + if node.get_property("id").get_value() == node_id: + return node + return null + + +## Helper: Get property at a specific port index in the graph view +func _get_property_at_port(node: InspectableNode, port: int) -> Property: + var properties = node.get_properties() + var visible_props: Array[Property] = [] + + # Build list of visible properties in graph (matching graph display logic) + for prop: Property in properties: + if not prop.get_settings_value("visible_in_graph", true): + continue + var has_input = prop.get_settings_value("exposed", false) + var has_output = prop.get_settings_value("export", false) + if not has_input and not has_output: + continue + + # Main property goes first + if prop.get_settings_value("is_main_property"): + visible_props.push_front(prop) + else: + visible_props.append(prop) + + if port >= 0 and port < visible_props.size(): + return visible_props[port] + + return null diff --git a/common/connection_manager.gd.uid b/common/connection_manager.gd.uid new file mode 100644 index 00000000..2bff7438 --- /dev/null +++ b/common/connection_manager.gd.uid @@ -0,0 +1 @@ +uid://cve25hgfr76tx diff --git a/common/graph_node_row.gd b/common/graph_node_row.gd new file mode 100644 index 00000000..5abfad4d --- /dev/null +++ b/common/graph_node_row.gd @@ -0,0 +1,23 @@ +class_name GraphNodeRow + +var _key: String = "" +var _type: String = "" +var _enable_left_port: bool = false +var _enable_right_port: bool = false + + +func _init( + key: String, type: String = "", enable_left_port: bool = false, enable_right_port: bool = true +) -> void: + _key = key + _type = type + _enable_left_port = enable_left_port + _enable_right_port = enable_right_port + + +func get_key() -> String: + return _key + + +func get_type() -> String: + return _type diff --git a/common/graph_node_row.gd.uid b/common/graph_node_row.gd.uid new file mode 100644 index 00000000..32da1f7f --- /dev/null +++ b/common/graph_node_row.gd.uid @@ -0,0 +1 @@ +uid://bu0v85m5t527i diff --git a/common/inspectable_node.gd b/common/inspectable_node.gd new file mode 100644 index 00000000..3b8fdf35 --- /dev/null +++ b/common/inspectable_node.gd @@ -0,0 +1,166 @@ +@abstract +class_name InspectableNode extends InspectableObject + +const ID_LENGTH: int = 6 + +var graph_view: GraphNode +var storyline_id: String = "" +var _main_property_defined: bool = false + + +func _init(command_manager: CommandManager = null) -> void: + define_property( + "color", + "#000000", + "color", + { + "visible_in_graph": false, + "visible_in_inspector": true, + "flat": true, + "expand": false, + }, + "Special:Header" + ) + define_property( + "id", + IDGen.generate(ID_LENGTH), + "text", + { + "visible_in_graph": false, + "visible_in_inspector": true, + "flat": true, + }, + "Special:Header" + ) + # Keep all connection references in sync when the id changes + var _id_prop := get_property("id") + if _id_prop and not _id_prop.value_changed.is_connected(_on_id_value_changed): + _id_prop.value_changed.connect(_on_id_value_changed) + super._init(command_manager) + define_property( + "notes", + "", + "textarea", + { + "visible_in_graph": false, + "visible_in_inspector": true, + "exposable": false, + }, + "Extra" + ) + define_property( + "position", + Vector2.ZERO, + "vector2", + { + "visible_in_graph": false, + "visible_in_inspector": false, + "editable": false, + "exposable": false, + }, + "Extra" + ) + + if not _main_property_defined: + push_error("Main property not defined") + + +func define_main_property( + pname: String, + type: String, + editable: bool = false, + default_value: Variant = null, + psettings: Dictionary = {}, + category: String = "General" +) -> void: + if _main_property_defined: + push_error("Main property already defined") + return + + var default_settings: Dictionary = {} + default_settings["visible_in_graph"] = true + default_settings["visible_in_inspector"] = editable + default_settings["editable"] = editable + default_settings["exposable"] = true + default_settings["exposed"] = true + default_settings["export"] = true + default_settings["is_main_property"] = true + + var merged_settings: Dictionary = default_settings.duplicate() + merged_settings.merge(psettings, true) + + define_property(pname, default_value, type, merged_settings, category) + _main_property_defined = true + + +func define_property( + pname: String, + default_value: Variant, + ptype: String, + psettings: Dictionary = {}, + category: String = "General" +) -> void: + super.define_property(pname, default_value, ptype, psettings, category) + + +func rebuild_preview() -> void: + if not is_instance_valid(graph_view): + return + var graph_edit: MonologueGraphEdit = graph_view.get_parent() + if graph_edit and graph_edit is MonologueGraphEdit: + graph_edit.refresh_node(self) + + +@abstract func get_type() -> String + + +func _on_id_value_changed(old_value: Variant, new_value: Variant) -> void: + var old_id := String(old_value) + var new_id := String(new_value) + if old_id == new_id: + return + + # Update all connection references via connection manager if available + var storyline: StorylineDocument = StorylineManager.get_storyline(storyline_id) + if storyline: + # Try to find a graph_edit and its connection manager + var graph_edit := graph_view.get_parent() if is_instance_valid(graph_view) else null + if graph_edit and graph_edit is MonologueGraphEdit and graph_edit.connection_manager: + graph_edit.connection_manager.rename_node_id(old_id, new_id) + else: + # Fallback: direct update across storyline + for node: InspectableNode in storyline.nodes: + for prop: Property in node.get_properties(): + # Update outgoing connections + for i in range(prop.connected_to.size()): + var conn: Dictionary = prop.connected_to[i] + if conn.get("node_id", "") == old_id: + conn["node_id"] = new_id + prop.connected_to[i] = conn + # Update incoming connections + for i in range(prop.connected_from.size()): + var conn_in: Dictionary = prop.connected_from[i] + if conn_in.get("node_id", "") == old_id: + conn_in["node_id"] = new_id + prop.connected_from[i] = conn_in + + # Ensure the GraphNode uses the new id as its name and reconnect + if is_instance_valid(graph_view): + graph_view.name = new_id + var gv_parent := graph_view.get_parent() + if gv_parent and gv_parent is MonologueGraphEdit: + gv_parent.clear_connections() + gv_parent._reconnect_all_slots() + + +@warning_ignore("native_method_override") +func duplicate(deep: bool = false) -> Resource: + var duplicated: InspectableNode = super.duplicate(deep) + duplicated.get_property("id").value = IDGen.generate(ID_LENGTH) + duplicated.get_property("position").value += Vector2(30, 30) + + return duplicated + + +@abstract func get_color() -> Color +@abstract func get_icon() -> Texture2D diff --git a/common/monologue_graph_node.gd.uid b/common/inspectable_node.gd.uid similarity index 100% rename from common/monologue_graph_node.gd.uid rename to common/inspectable_node.gd.uid diff --git a/common/inspectable_object.gd b/common/inspectable_object.gd new file mode 100644 index 00000000..ac039d0a --- /dev/null +++ b/common/inspectable_object.gd @@ -0,0 +1,148 @@ +@abstract +class_name InspectableObject extends Resource + +var _properties: Dictionary[String, Property] = {} +var _observers: Array[Callable] = [] +var history: CommandManager +var settings: Dictionary = {} + + +func _init(command_manager: CommandManager = null) -> void: + if not command_manager: + push_warning("InspectableObject does not have a command manager.") + history = command_manager + + initialize_properties() + _load_settings() + + +func _load_settings() -> void: + var new_settings: Dictionary = {} + new_settings.merge(get_settings(), true) + settings = new_settings + + +func define_property( + pname: String, + default_value: Variant, + type: String, + psettings: Dictionary = {}, + category: String = "General" +) -> void: + var merged_settings: Dictionary = psettings.duplicate(true) + merged_settings["category"] = category + + var property: Property = Property.new(pname, default_value, type, merged_settings) + _properties.set(pname, property) + + property.value_changed.connect(func(_old, _new): _notify_change(pname)) + + +func add_observer(callable: Callable) -> void: + if callable in _observers: + push_warning("Observer is already registered.") + return + + _observers.append(callable) + + +func remove_observer(callable: Callable) -> void: + _observers.erase(callable) + + +func _notify_change(pname: String) -> void: + for observer: Callable in _observers: + if not observer or not observer.is_valid() or observer.get_object() == null: + _observers.erase(observer) + continue + observer.call(self, pname) + + +func get_properties() -> Array[Property]: + var properties: Array[Property] = [] + for pname in _properties.keys(): + properties.append(_properties[pname]) + + return properties + + +func get_property(pname: String) -> Property: + return _properties.get(pname) + + +func get_property_value(pname: String) -> Variant: + return get_property(pname).get_value() + + +func get_property_settings_value(pname: String, skey: String) -> Variant: + var property: Property = get_property(pname) + return property.settings.get(skey) + + +func set_property_value(pname: String, pvalue: Variant) -> void: + if not _properties.has(pname): + return + + var old_value: Variant = get_property_value(pname) + + if pvalue == old_value: + return + + var command: PropertyChangeCommand = PropertyChangeCommand.new(self, pname, old_value, pvalue) + history.execute(command) + + _notify_change(pname) + + +func set_property_settings_value(pname: String, skey: Variant, svalue: Variant) -> void: + if not _properties.has(pname): + return + + var old_value: Variant = get_property_settings_value(pname, skey) + + var command: PropertySettingsChangeCommand = PropertySettingsChangeCommand.new( + self, pname, skey, old_value, svalue + ) + history.execute(command) + + +func _to_dict() -> Dictionary: + var dict: Dictionary = {"$type": get_type()} + for property: Property in get_properties(): + dict[property.name] = property._to_dict() + + return dict + + +# Do not trigger undo/redo +func _from_dict(dict: Dictionary) -> void: + dict.erase("$type") + for property: Property in get_properties(): + var property_dict: Dictionary = dict.get(property.name, {}) + property._from_dict(property_dict) + + +func get_settings() -> Dictionary: + return {} + + +func rebuild_preview() -> void: + pass + + +@warning_ignore("native_method_override") +func duplicate(deep: bool = false) -> Resource: + var duplicated: InspectableNode = super.duplicate(deep) + duplicated.history = history + duplicated.settings = settings + + for property: Property in get_properties(): + var d_prop: Property = duplicated.get_property(property.name) + d_prop.value = property.get_value() + + return duplicated + + +@abstract func get_type() -> String +@abstract func initialize_properties() -> void +@abstract func _on_property_changed(pname: String, old_value: Variant, new_value: Variant) -> void diff --git a/common/inspectable_object.gd.uid b/common/inspectable_object.gd.uid new file mode 100644 index 00000000..d5c2a3e0 --- /dev/null +++ b/common/inspectable_object.gd.uid @@ -0,0 +1 @@ +uid://c7ehitto0jxu3 diff --git a/common/inspectable_storyline_object.gd b/common/inspectable_storyline_object.gd new file mode 100644 index 00000000..db84e46e --- /dev/null +++ b/common/inspectable_storyline_object.gd @@ -0,0 +1,9 @@ +@abstract +class_name InspectableStorylineObject extends InspectableObject + + +func _init(command_manager: CommandManager = null) -> void: + super._init(command_manager) + + +@abstract func build_graph_preview() -> Array[Control] diff --git a/common/inspectable_storyline_object.gd.uid b/common/inspectable_storyline_object.gd.uid new file mode 100644 index 00000000..6015b309 --- /dev/null +++ b/common/inspectable_storyline_object.gd.uid @@ -0,0 +1 @@ +uid://c4pgnm3s0fk7m diff --git a/common/layout_manager.gd b/common/layout_manager.gd new file mode 100644 index 00000000..85732a3e --- /dev/null +++ b/common/layout_manager.gd @@ -0,0 +1,191 @@ +class_name LayoutManager + + +static func create_layout( + schema: Dictionary, + item: ListItemObject, + list_field: ListField, + layout_name: String = "default", +) -> Control: + var layout_config = _get_layout_config(schema, layout_name) + + var vbox = VBoxContainer.new() + var fields = _get_fields_to_display(schema, layout_config) + var properties = schema.get("properties", {}) + var index = list_field.get_item_index(item) + + for field_name in fields: + if not properties.has(field_name): + continue + + var field_container = _create_field_container( + field_name, properties[field_name], list_field, item + ) + + vbox.add_child(field_container) + + _create_item_header(vbox, index, list_field, item, layout_config) + + return vbox + + +static func _get_layout_config(schema: Dictionary, layout_name: String) -> Dictionary: + var layouts = schema.get("layouts", {}) + return layouts.get(layout_name, layouts.get("default", {})) + + +static func _create_field_container( + field_name: String, field_config: Dictionary, _list_field: ListField, item: ListItemObject +) -> Control: + var container: VBoxContainer = VBoxContainer.new() + + var title_container: HBoxContainer = _create_title_container(field_name, field_config) + container.add_child(title_container) + + var field: Field = _create_and_configure_field(field_name, field_config, item) + container.add_child(field) + + var property: Property = item.get_property(field_name) + if property: + var merged_settings: Dictionary = field_config.duplicate() + merged_settings.merge(property.get_settings(), true) + field.settings = merged_settings + + _bind_field_to_property.call_deferred(field, field_name, item) + + var is_editable: bool = not (field_config.get("protect", false) and item.is_protected()) + field.set_editable.call_deferred(is_editable) + + return container + + +static func _create_title_container(field_name: String, field_config: Dictionary) -> HBoxContainer: + var title_container = HBoxContainer.new() + title_container.size_flags_horizontal = Control.SIZE_EXPAND_FILL + + var label = Label.new() + label.text = Util.to_readable_name(field_name) + label.size_flags_horizontal = Control.SIZE_EXPAND_FILL + + if field_config.has("tooltip"): + label.tooltip_text = field_config["tooltip"] + + title_container.add_child(label) + return title_container + + +static func _create_and_configure_field( + _field_name: String, field_config: Dictionary, _item: ListItemObject +) -> Field: + var field_type: String = field_config.get("type") + var field: Field = FieldBucket.safe_create_field(field_type) + + if field is Field: + field.settings = field_config.duplicate() + field.size_flags_horizontal = Control.SIZE_EXPAND_FILL + + return field + + +static func _bind_field_to_property(field: Field, field_name: String, item: ListItemObject) -> void: + var property = item.get_property(field_name) + if not property: + push_warning("Property '%s' not found in item" % field_name) + return + + if field.is_node_ready(): + property.bind_field(field, item) + return + field.ready.connect(func(): property.bind_field(field, item), CONNECT_ONE_SHOT) + + +static func _get_fields_to_display(schema: Dictionary, layout_config: Dictionary) -> Array: + var properties = schema.get("properties", {}) + return layout_config.get("fields", properties.keys()) + + +static func _create_item_header( + content: Control, + index: int, + list_field: ListField, + item: ListItemObject, + layout_config: Dictionary +) -> Control: + var header = _get_or_create_header_container(content) + var actions = layout_config.get("actions", ["delete"]) + + _add_action_buttons(header, actions, index, list_field, item) + + return header + + +static func _get_or_create_header_container(content: Control) -> HBoxContainer: + if content.get_child_count() == 0: + return HBoxContainer.new() + + var first_child = content.get_child(0) + if not first_child is BoxContainer or first_child.get_child_count() == 0: + return HBoxContainer.new() + + var header_candidate = first_child.get_child(0) + if header_candidate is HBoxContainer: + return header_candidate + + return HBoxContainer.new() + + +static func _add_action_buttons( + header: HBoxContainer, actions: Array, index: int, list_field: ListField, item: ListItemObject +) -> void: + if "edit" in actions: + _add_button( + header, + index, + list_field, + "edit", + "Edit item", + preload("res://ui/assets/icons/pen.svg"), + ) + + if "duplicate" in actions and not item.is_protected(): + _add_button( + header, + index, + list_field, + "duplicate", + "Duplicate item", + preload("res://ui/assets/icons/copy.png"), + ) + + if "delete" in actions and not item.is_protected(): + _add_button( + header, + index, + list_field, + "delete", + "Delete item", + preload("res://ui/assets/icons/trash.svg"), + ) + + +static func _add_button( + header: HBoxContainer, + index: int, + list_field: ListField, + action_name: String, + tooltip: String, + icon: Texture2D +) -> void: + if not list_field.has_method("_on_%s_item" % action_name): + return + + var button = Button.new() + button.icon = icon + button.tooltip_text = tooltip + button.pressed.connect(list_field.call.bind("_on_%s_item" % action_name, index)) + header.add_child(button) + + +static func _resolve_dynamic_enum(_path: String, _data: Dictionary) -> Array: + # TODO: Implement full resolution for dynamic enums + return [] diff --git a/common/layout_manager.gd.uid b/common/layout_manager.gd.uid new file mode 100644 index 00000000..5ccc685f --- /dev/null +++ b/common/layout_manager.gd.uid @@ -0,0 +1 @@ +uid://mm6khj33mtil diff --git a/common/layouts/character_edit/assets/triangle_pointer.svg.import b/common/layouts/character_edit/assets/triangle_pointer.svg.import index 5d5ecb14..573aa9dc 100644 --- a/common/layouts/character_edit/assets/triangle_pointer.svg.import +++ b/common/layouts/character_edit/assets/triangle_pointer.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://mjb34j4suabp" -path="res://.godot/imported/triangle_pointer.svg-1a5e452f0eac195ecf23f23e96dbf3b7.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/triangle_pointer.svg-1a5e452f0eac195ecf23f23e96dbf3b7.dpitex" [deps] source_file="res://common/layouts/character_edit/assets/triangle_pointer.svg" -dest_files=["res://.godot/imported/triangle_pointer.svg-1a5e452f0eac195ecf23f23e96dbf3b7.ctex"] +dest_files=["res://.godot/imported/triangle_pointer.svg-1a5e452f0eac195ecf23f23e96dbf3b7.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=4.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/common/layouts/character_edit/character_edit.gd b/common/layouts/character_edit/character_edit.gd index 87f59a03..e1e52152 100644 --- a/common/layouts/character_edit/character_edit.gd +++ b/common/layouts/character_edit/character_edit.gd @@ -1,70 +1,70 @@ class_name CharacterEdit extends CharacterEditSection - -var nicknames := Property.new(MonologueGraphNode.LINE) -var display_name := Property.new(MonologueGraphNode.LINE) -var description := Property.new(MonologueGraphNode.TEXT) - - -func _ready() -> void: - close() - GlobalSignal.add_listener("open_character_edit", open) - GlobalSignal.add_listener("close_character_edit", close) - GlobalSignal.add_listener("reload_character_edit", reload) - super._ready() - - -func open(graph: MonologueGraphEdit, index: int) -> void: - if index >= 0: - graph_edit = graph - character_index = index - %PortraitSettingsSection.base_path = graph.file_path - %PortraitListSection.selected = -1 - _from_dict(graph.characters[index]) - show() - else: - close() - - -func close() -> void: - # also triggered when 'Done' button is pressed - if graph_edit: - graph_edit.characters[character_index]["Character"].merge(_to_dict(), true) - hide() - graph_edit = null - character_index = -1 - - -func reload(index: int) -> void: - # triggered if character edit is opened but character index is different - if character_index != index: - open(graph_edit, index) - - -func _from_dict(dict: Dictionary = {}) -> void: - var character_dict: Dictionary = dict.get("Character", {}) - super._from_dict(character_dict) - _from_recursive(character_dict, linked_sections) - - -func _from_recursive(dict: Dictionary, subsections: Array[CharacterEditSection]) -> void: - for subsection in subsections: - subsection._from_dict(dict) - _from_recursive(dict, subsection.linked_sections) - - -func _to_dict() -> Dictionary: - var flat_map = super._to_dict() - for section in linked_sections: - flat_map.merge(section._to_dict(), true) - return flat_map - - -func _on_visibility_changed() -> void: - if visible: - GlobalSignal.emit("show_dimmer", [self]) - return - GlobalSignal.emit("hide_dimmer", [self]) - - -func _on_timeline_section_visibility_changed() -> void: - pass # Replace with function body. +# +#var nicknames := OldProperty.new(Field.LINE) +#var display_name := OldProperty.new(Field.LINE) +#var description := OldProperty.new(Field.TEXT) +# +# +#func _ready() -> void: +#close() +#GlobalSignal.add_listener("open_character_edit", open) +#GlobalSignal.add_listener("close_character_edit", close) +#GlobalSignal.add_listener("reload_character_edit", reload) +#super._ready() +# +# +#func open(graph: MonologueGraphEdit, index: int) -> void: +#if index >= 0: +#graph_edit = graph +#character_index = index +#%PortraitSettingsSection.base_path = graph.file_path +#%PortraitListSection.selected = -1 +#_from_dict(graph.characters.value[index]) +#show() +#else: +#close() +# +# +#func close() -> void: +## also triggered when 'Done' button is pressed +#if graph_edit: +#graph_edit.characters.value[character_index]["Character"].merge(_to_dict(), true) +#hide() +#graph_edit = null +#character_index = -1 +# +# +#func reload(index: int) -> void: +## triggered if character edit is opened but character index is different +#if character_index != index: +#open(graph_edit, index) +# +# +#func _from_dict(dict: Dictionary = {}) -> void: +#var character_dict: Dictionary = dict.get("Character", {}) +#super._from_dict(character_dict) +#_from_recursive(character_dict, linked_sections) +# +# +#func _from_recursive(dict: Dictionary, subsections: Array[CharacterEditSection]) -> void: +#for subsection in subsections: +#subsection._from_dict(dict) +#_from_recursive(dict, subsection.linked_sections) +# +# +#func _to_dict() -> Dictionary: +#var flat_map = super._to_dict() +#for section in linked_sections: +#flat_map.merge(section._to_dict(), true) +#return flat_map +# +# +#func _on_visibility_changed() -> void: +#if visible: +#GlobalSignal.emit("show_dimmer", [self]) +#return +#GlobalSignal.emit("hide_dimmer", [self]) +# +# +#func _on_timeline_section_visibility_changed() -> void: +#pass # Replace with function body. diff --git a/common/layouts/character_edit/character_edit.tscn b/common/layouts/character_edit/character_edit.tscn index 1894c18a..0f70202b 100644 --- a/common/layouts/character_edit/character_edit.tscn +++ b/common/layouts/character_edit/character_edit.tscn @@ -194,7 +194,7 @@ stretch = true disable_3d = true transparent_bg = true handle_input_locally = false -size = Vector2i(2, 2) +size = Vector2i(366, 251) size_2d_override_stretch = true render_target_update_mode = 4 diff --git a/common/layouts/character_edit/character_edit_section.gd b/common/layouts/character_edit/character_edit_section.gd index 9d06c5c2..e169f2b8 100644 --- a/common/layouts/character_edit/character_edit_section.gd +++ b/common/layouts/character_edit/character_edit_section.gd @@ -49,30 +49,30 @@ func set_index(index: int) -> void: section.character_index = index -func _from_dict(dict: Dictionary) -> void: +func _from_dict(_dict: Dictionary) -> void: flush() - for entry in get_property_list(): - if Constants.PROPERTY_CLASSES.has(entry.class_name): - var key = Util.to_key_name(entry.name) - var property = get(entry.name) - var is_value = property is Property - var is_raw = property is Localizable - if property and (is_value or is_raw): - if is_value: - property.value = dict.get(key, property.default_value) - elif is_raw: - property.raw_data = dict.get(key, {}) - var label = key.capitalize() - property.callers["set_label_text"] = [label] - property.show(field_vbox) + #for entry in get_property_list(): + #if Constants.PROPERTY_CLASSES.has(entry.class_name): + #var key = Util.to_key_name(entry.name) + #var property = get(entry.name) + #var is_value = property is Property + #var is_raw = property is Localizable + #if property and (is_value or is_raw): + #if is_value: + #property.value = dict.get(key, property.default_value) + #elif is_raw: + #property.raw_data = dict.get(key, {}) + #var label = key.capitalize() + #property.callers["set_label_text"] = [label] + #property.show(field_vbox) func _to_dict() -> Dictionary: var dict: Dictionary = {} - for property in get_property_list(): - if Constants.PROPERTY_CLASSES.has(property.class_name): - var reference = get(property.name) - var is_raw = reference is Localizable - var value = reference.to_raw_value() if is_raw else reference.value - dict[Util.to_key_name(property.name)] = value + #for property in get_property_list(): + #if Constants.PROPERTY_CLASSES.has(property.class_name): + #var reference = get(property.name) + #var is_raw = reference is Localizable + #var value = reference.to_raw_value() if is_raw else reference.value + #dict[Util.to_key_name(property.name)] = value return dict diff --git a/common/layouts/character_edit/portrait_list_section.gd b/common/layouts/character_edit/portrait_list_section.gd index 4974edb3..437a4038 100644 --- a/common/layouts/character_edit/portrait_list_section.gd +++ b/common/layouts/character_edit/portrait_list_section.gd @@ -1,171 +1,171 @@ class_name PortraitListSection extends CharacterEditSection - -signal portrait_selected - -const DEFAULT_PORTRAIT_NAME = "new portrait %s" - -var portraits := Property.new(MonologueGraphNode.LIST, {}, []) -var default_portrait := Property.new(MonologueGraphNode.LINE, {}, "") - -var selected: int = -1 -var references: Array[AbstractPortraitOption] = [] - -@onready var portrait_settings_section := %PortraitSettingsSection -@onready var timeline_section := %TimelineSection -@onready var preview_section := %PreviewSection -@onready var scroll_container := $ScrollContainer - - -func _ready() -> void: - GlobalSignal.add_listener("select_portrait_option", select_option) - portraits.setters["add_callback"] = add_portrait - portraits.setters["get_callback"] = get_portraits - portraits.setters["flat"] = true - portraits.setters["expand"] = true - portraits.connect("preview", load_portraits) - portraits.connect("change", _on_portraits_change) - default_portrait.visible = false - super._ready() - - -func add_portrait(option_dict: Dictionary = {}) -> AbstractPortraitOption: - _sync_references() - var new_portrait := AbstractPortraitOption.new(self) - new_portrait.graph = graph_edit - if option_dict: - new_portrait._from_dict(option_dict) - else: - new_portrait.portrait_name.value = DEFAULT_PORTRAIT_NAME % (references.size() + 1) - new_portrait.portrait.callers["set_option_name"] = [new_portrait.portrait_name.value] - new_portrait.idx.value = references.size() - new_portrait.portrait.connecters[_on_portrait_option_pressed] = "pressed" - new_portrait.portrait.connecters[_on_portrait_option_set_to_default] = "set_to_default" - new_portrait.portrait.connecters[_on_portrait_option_name_submitted] = "name_submitted" - references.append(new_portrait) - - if new_portrait.idx.value == selected: - new_portrait.portrait.callers["set_active"] = [] - else: - new_portrait.portrait.callers["release_active"] = [] - return new_portrait - - -func get_portraits() -> Array: - return references - - -func _on_portraits_change(old_value: Variant, new_value: Variant) -> void: - if new_value.size() <= 0: - select_option(-1) - elif new_value.size() < old_value.size(): - select_option(0) - elif new_value.size() > old_value.size() and false: - select_option(references.size()) - _update_portrait() - - -func get_portrait_options() -> Array: - return get_portraits().map(func(i: AbstractPortraitOption): return i.portrait.field) - - -## Perform loading of speakers and set indexes correctly. -func load_portraits(new_portrait_list: Array) -> void: - references.clear() - var ascending = func(a, b): return a.get("EditorIndex") < b.get("EditorIndex") - new_portrait_list.sort_custom(ascending) - - for portrait_data in new_portrait_list: - var abstract_option = add_portrait(portrait_data) - if new_portrait_list.size() <= 1: - default_portrait.value = abstract_option.id.value - if default_portrait.value == abstract_option.id.value: - abstract_option.portrait.callers["set_default"] = [] - - portraits.value = new_portrait_list - _update_portrait() - - -## Selects portrait option by index. -func select_option(index: int) -> void: - if selected == index: - return - - selected = index - if index < 0: - return - - var all_options := get_portrait_options() - if index < all_options.size(): - _update_option(all_options[index]) - - -func _from_dict(dict: Dictionary) -> void: - super._from_dict(dict) - # custom handling because the default_portrait property is a little special - default_portrait.value = dict.get("DefaultPortrait", "") - load_portraits(dict.get("Portraits", [])) - portraits.propagate(portraits.value) - _update_portrait() - - -func _on_portrait_option_pressed(portrait_option: PortraitOption) -> void: - var all_options := get_portrait_options() - selected = all_options.find(portrait_option) - _update_option(portrait_option) - - -func _on_portrait_option_set_to_default(portrait_option: PortraitOption) -> void: - var all_options := get_portrait_options() - for option: PortraitOption in all_options: - if option == portrait_option: - var index = all_options.find(option) - default_portrait.save_value(references[index].id.value) - else: - option.release_default() - - -func _on_portrait_option_name_submitted(portrait_option: PortraitOption) -> void: - var all_options := get_portrait_options() - for option: PortraitOption in all_options: - if option == portrait_option: - var index = all_options.find(option) - references[index].portrait_name.save_value(portrait_option.line_edit.text) - _sync_references() - - -func _update_option(selected_option: PortraitOption) -> void: - for option: PortraitOption in get_portrait_options(): - if option == selected_option: - option.set_active() - for section in linked_sections: - section.portrait_index = selected - else: - option.release_active() - portrait_selected.emit() - _update_portrait() - - await get_tree().process_frame - scroll_container.ensure_control_visible(selected_option) - - -func _sync_references() -> void: - var data_list: Array = portraits.value - for ref: AbstractPortraitOption in references: - var ref_candidates: Array = data_list.filter( - func(p: Dictionary): return p.get("EditorIndex", -1) == ref.idx.value - ) - if ref_candidates.size() <= 0: - continue - - var data: Dictionary = ref_candidates[0] - ref._from_dict(data) - - -func _update_portrait() -> void: - var show_portrait_sections: bool = selected >= 0 - portrait_settings_section.visible = show_portrait_sections - preview_section.visible = show_portrait_sections - timeline_section.visible = show_portrait_sections - if show_portrait_sections: - var character_dict = graph_edit.characters[character_index]["Character"] - portrait_settings_section._from_dict(character_dict) +# +#signal portrait_selected +# +#const DEFAULT_PORTRAIT_NAME = "new portrait %s" +# +#var portraits := OldProperty.new(Field.LIST, {}, []) +#var default_portrait := OldProperty.new(Field.LINE, {}, "") +# +#var selected: int = -1 +#var references: Array[AbstractPortraitOption] = [] +# +#@onready var portrait_settings_section := %PortraitSettingsSection +#@onready var timeline_section := %TimelineSection +#@onready var preview_section := %PreviewSection +#@onready var scroll_container := $ScrollContainer +# +# +#func _ready() -> void: + #GlobalSignal.add_listener("select_portrait_option", select_option) + #portraits.setters["add_callback"] = add_portrait + #portraits.setters["get_callback"] = get_portraits + #portraits.setters["flat"] = true + #portraits.setters["expand"] = true + #portraits.connect("preview", load_portraits) + #portraits.connect("change", _on_portraits_change) + #default_portrait.visible = false + #super._ready() +# +# +#func add_portrait(option_dict: Dictionary = {}) -> AbstractPortraitOption: + #_sync_references() + #var new_portrait := AbstractPortraitOption.new(self) + #new_portrait.graph = graph_edit + #if option_dict: + #new_portrait._from_dict(option_dict) + #else: + #new_portrait.portrait_name.value = DEFAULT_PORTRAIT_NAME % (references.size() + 1) + #new_portrait.portrait.callers["set_option_name"] = [new_portrait.portrait_name.value] + #new_portrait.idx.value = references.size() + #new_portrait.portrait.connecters[_on_portrait_option_pressed] = "pressed" + #new_portrait.portrait.connecters[_on_portrait_option_set_to_default] = "set_to_default" + #new_portrait.portrait.connecters[_on_portrait_option_name_submitted] = "name_submitted" + #references.append(new_portrait) +# + #if new_portrait.idx.value == selected: + #new_portrait.portrait.callers["set_active"] = [] + #else: + #new_portrait.portrait.callers["release_active"] = [] + #return new_portrait +# +# +#func get_portraits() -> Array: + #return references +# +# +#func _on_portraits_change(old_value: Variant, new_value: Variant) -> void: + #if new_value.size() <= 0: + #select_option(-1) + #elif new_value.size() < old_value.size(): + #select_option(0) + #elif new_value.size() > old_value.size() and false: + #select_option(references.size()) + #_update_portrait() +# +# +#func get_portrait_options() -> Array: + #return get_portraits().map(func(i: AbstractPortraitOption): return i.portrait.field) +# +# +### Perform loading of speakers and set indexes correctly. +#func load_portraits(new_portrait_list: Array) -> void: + #references.clear() + #var ascending = func(a, b): return a.get("EditorIndex") < b.get("EditorIndex") + #new_portrait_list.sort_custom(ascending) +# + #for portrait_data in new_portrait_list: + #var abstract_option = add_portrait(portrait_data) + #if new_portrait_list.size() <= 1: + #default_portrait.value = abstract_option.id.value + #if default_portrait.value == abstract_option.id.value: + #abstract_option.portrait.callers["set_default"] = [] +# + #portraits.value = new_portrait_list + #_update_portrait() +# +# +### Selects portrait option by index. +#func select_option(index: int) -> void: + #if selected == index: + #return +# + #selected = index + #if index < 0: + #return +# + #var all_options := get_portrait_options() + #if index < all_options.size(): + #_update_option(all_options[index]) +# +# +#func _from_dict(dict: Dictionary) -> void: + #super._from_dict(dict) + ## custom handling because the default_portrait property is a little special + #default_portrait.value = dict.get("DefaultPortrait", "") + #load_portraits(dict.get("Portraits", [])) + #portraits.propagate(portraits.value) + #_update_portrait() +# +# +#func _on_portrait_option_pressed(portrait_option: PortraitOption) -> void: + #var all_options := get_portrait_options() + #selected = all_options.find(portrait_option) + #_update_option(portrait_option) +# +# +#func _on_portrait_option_set_to_default(portrait_option: PortraitOption) -> void: + #var all_options := get_portrait_options() + #for option: PortraitOption in all_options: + #if option == portrait_option: + #var index = all_options.find(option) + #default_portrait.save_value(references[index].id.value) + #else: + #option.release_default() +# +# +#func _on_portrait_option_name_submitted(portrait_option: PortraitOption) -> void: + #var all_options := get_portrait_options() + #for option: PortraitOption in all_options: + #if option == portrait_option: + #var index = all_options.find(option) + #references[index].portrait_name.save_value(portrait_option.line_edit.text) + #_sync_references() +# +# +#func _update_option(selected_option: PortraitOption) -> void: + #for option: PortraitOption in get_portrait_options(): + #if option == selected_option: + #option.set_active() + #for section in linked_sections: + #section.portrait_index = selected + #else: + #option.release_active() + #portrait_selected.emit() + #_update_portrait() +# + #await get_tree().process_frame + #scroll_container.ensure_control_visible(selected_option) +# +# +#func _sync_references() -> void: + #var data_list: Array = portraits.value + #for ref: AbstractPortraitOption in references: + #var ref_candidates: Array = data_list.filter( + #func(p: Dictionary): return p.get("EditorIndex", -1) == ref.idx.value + #) + #if ref_candidates.size() <= 0: + #continue +# + #var data: Dictionary = ref_candidates[0] + #ref._from_dict(data) +# +# +#func _update_portrait() -> void: + #var show_portrait_sections: bool = selected >= 0 + #portrait_settings_section.visible = show_portrait_sections + #preview_section.visible = show_portrait_sections + #timeline_section.visible = show_portrait_sections + #if show_portrait_sections: + #var character_dict = graph_edit.characters.value[character_index]["Character"] + #portrait_settings_section._from_dict(character_dict) diff --git a/common/layouts/character_edit/portrait_settings_section.gd b/common/layouts/character_edit/portrait_settings_section.gd index 075278cb..c7d752df 100644 --- a/common/layouts/character_edit/portrait_settings_section.gd +++ b/common/layouts/character_edit/portrait_settings_section.gd @@ -1,116 +1,114 @@ class_name PortraitSettingsSection extends PortraitEditSection - -@warning_ignore("unused_signal") -signal changed - -var portrait_type := Property.new(MonologueGraphNode.DROPDOWN, {}, "Image", "PortraitType") -var image_path := Property.new( - MonologueGraphNode.FILE, {"filters": FilePicker.IMAGE}, "", "ImagePath" -) -var offset := Property.new(MonologueGraphNode.VECTOR, {}, [0, 0], "Offset") -var mirror := Property.new(MonologueGraphNode.TOGGLE, {}, false, "Mirror") -var one_shot := Property.new(MonologueGraphNode.TOGGLE, {}, false, "OneShot") - -@onready var preview_section := %PreviewSection -@onready var timeline_section: TimelineSection = %TimelineSection - -var id: String -var base_path: String: - set = _set_base_path - -var _control_groups = { - "Image": [portrait_type, image_path, offset, mirror], - "Animation": [portrait_type, offset, mirror, one_shot], -} - - -func _ready() -> void: - portrait_type.callers["set_items"] = [ - [ - {"id": 0, "text": "Image"}, - {"id": 1, "text": "Animation"}, - ] - ] - portrait_type.change.connect(_on_portrait_type_change) - portrait_type.connect("preview", _show_group) - image_path.change.connect(_on_image_path_change) - offset.change.connect(_on_offset_change) - mirror.change.connect(_on_mirror_change) - super._ready() - - -func _set_base_path(val: String) -> void: - base_path = val - if not image_path.field: - image_path.setters["base_path"] = val - else: - image_path.field.base_path = val - - -func _from_dict(dict: Dictionary = {}) -> void: - var portrait_list: Array = dict.get("Portraits", []) - if ( - portrait_index >= 0 - and portrait_index < portrait_list.size() - and portrait_index == %PortraitListSection.selected - ): - var portrait_dict: Dictionary = portrait_list[portrait_index]["Portrait"] - super._from_dict(portrait_dict) - timeline_section._from_dict.bind(portrait_dict).call_deferred() - timeline_section.portrait_index = portrait_index - timeline_section.character_index = character_index - timeline_section.base_path = base_path - _on_portrait_type_change.call_deferred() - - -func _to_dict() -> Dictionary: - return super._to_dict() - - -func _on_check_button_toggled(toggled_on: bool) -> void: - preview_section.update_mirror(toggled_on) - - -func _on_portrait_type_change(_old_value: Variant = null, _new_value: Variant = null) -> void: - var _process_type_change = func(): - if visible: - timeline_section.visible = portrait_type.value == "Animation" - if portrait_type.value == "Animation": - preview_section.update_animation([]) - else: - _on_image_path_change(null, image_path.value) - _show_group() - - _process_type_change.call_deferred() - - -func _on_image_path_change(_old_value: Variant = null, new_value: Variant = null) -> void: - if not new_value or not image_path.field: - return - - var is_valid: bool = image_path.field.validate(image_path.value) - if is_valid: - var abs_image_path: String = Path.relative_to_absolute(new_value, base_path) - var texture: ImageTexture = ImageLoader.load_image(abs_image_path) - preview_section.update_preview(texture) - return - preview_section.update_preview(ImageTexture.new()) - - -func _on_offset_change(_old_value: Variant = null, new_value: Variant = null) -> void: - preview_section.update_offset(new_value) - - -func _on_mirror_change(_old_value: Variant = null, new_value: Variant = null) -> void: - preview_section.update_mirror(new_value) - - -func _show_group(prt_type: Variant = portrait_type.value) -> void: - var group = _control_groups.get(prt_type) - for key in _control_groups.keys(): - for property: Property in _control_groups.get(key): - property.set_visible(group.has(property)) - - -func _on_delete_button_pressed() -> void: - %PortraitListSection.references[portrait_index].custom_delete_button.pressed.emit() +# +#@warning_ignore("unused_signal") +#signal changed +# +#var portrait_type := OldProperty.new(Field.DROPDOWN, {}, "Image", "PortraitType") +#var image_path := OldProperty.new(Field.FILE, {"filters": FilePicker.IMAGE}, "", "ImagePath") +#var offset := OldProperty.new(Field.VECTOR, {}, [0, 0], "Offset") +#var mirror := OldProperty.new(Field.TOGGLE, {}, false, "Mirror") +#var one_shot := OldProperty.new(Field.TOGGLE, {}, false, "OneShot") +# +#@onready var preview_section := %PreviewSection +#@onready var timeline_section: TimelineSection = %TimelineSection +# +#var id: String +#var base_path: String: + #set = _set_base_path +# +#var _control_groups = { + #"Image": [portrait_type, image_path, offset, mirror], + #"Animation": [portrait_type, offset, mirror, one_shot], +#} +# +# +#func _ready() -> void: + #portrait_type.callers["set_items"] = [ + #[ + #{"id": 0, "text": "Image"}, + #{"id": 1, "text": "Animation"}, + #] + #] + #portrait_type.change.connect(_on_portrait_type_change) + #portrait_type.connect("preview", _show_group) + #image_path.change.connect(_on_image_path_change) + #offset.change.connect(_on_offset_change) + #mirror.change.connect(_on_mirror_change) + #super._ready() +# +# +#func _set_base_path(val: String) -> void: + #base_path = val + #if not image_path.field: + #image_path.setters["base_path"] = val + #else: + #image_path.field.base_path = val +# +# +#func _from_dict(dict: Dictionary = {}) -> void: + #var portrait_list: Array = dict.get("Portraits", []) + #if ( + #portrait_index >= 0 + #and portrait_index < portrait_list.size() + #and portrait_index == %PortraitListSection.selected + #): + #var portrait_dict: Dictionary = portrait_list[portrait_index]["Portrait"] + #super._from_dict(portrait_dict) + #timeline_section._from_dict.bind(portrait_dict).call_deferred() + #timeline_section.portrait_index = portrait_index + #timeline_section.character_index = character_index + #timeline_section.base_path = base_path + #_on_portrait_type_change.call_deferred() +# +# +#func _to_dict() -> Dictionary: + #return super._to_dict() +# +# +#func _on_check_button_toggled(toggled_on: bool) -> void: + #preview_section.update_mirror(toggled_on) +# +# +#func _on_portrait_type_change(_old_value: Variant = null, _new_value: Variant = null) -> void: + #var _process_type_change = func(): + #if visible: + #timeline_section.visible = portrait_type.value == "Animation" + #if portrait_type.value == "Animation": + #preview_section.update_animation([]) + #else: + #_on_image_path_change(null, image_path.value) + #_show_group() +# + #_process_type_change.call_deferred() +# +# +#func _on_image_path_change(_old_value: Variant = null, new_value: Variant = null) -> void: + #if not new_value or not image_path.field: + #return +# + #var is_valid: bool = image_path.field.validate(image_path.value) + #if is_valid: + #var abs_image_path: String = Path.relative_to_absolute(new_value, base_path) + #var texture: ImageTexture = ImageLoader.load_image(abs_image_path) + #preview_section.update_preview(texture) + #return + #preview_section.update_preview(ImageTexture.new()) +# +# +#func _on_offset_change(_old_value: Variant = null, new_value: Variant = null) -> void: + #preview_section.update_offset(new_value) +# +# +#func _on_mirror_change(_old_value: Variant = null, new_value: Variant = null) -> void: + #preview_section.update_mirror(new_value) +# +# +#func _show_group(prt_type: Variant = portrait_type.value) -> void: + #var group = _control_groups.get(prt_type) + #for key in _control_groups.keys(): + #for property: Property in _control_groups.get(key): + #property.set_visible(group.has(property)) +# +# +#func _on_delete_button_pressed() -> void: + #%PortraitListSection.references[portrait_index].custom_delete_button.pressed.emit() diff --git a/common/layouts/character_edit/timeline_section.gd b/common/layouts/character_edit/timeline_section.gd index bde6dede..9adf2ee6 100644 --- a/common/layouts/character_edit/timeline_section.gd +++ b/common/layouts/character_edit/timeline_section.gd @@ -3,7 +3,7 @@ class_name TimelineSection extends PortraitEditSection @warning_ignore("unused_signal") signal changed -var animation := Property.new(MonologueGraphNode.TIMELINE, {}, {}) +#var animation := OldProperty.new(Field.TIMELINE, {}, {}) var id: String var base_path: String: @@ -12,12 +12,12 @@ var base_path: String: func _ready() -> void: super._ready() - animation.setters["preview_section"] = %PreviewSection + #animation.setters["preview_section"] = %PreviewSection func _set_base_path(val: String) -> void: base_path = val - animation.setters["base_path"] = val + #animation.setters["base_path"] = val func _from_dict(dict: Dictionary = {}) -> void: diff --git a/common/layouts/dimmer/dimmer.gd b/common/layouts/dimmer/dimmer.gd deleted file mode 100644 index 017f196c..00000000 --- a/common/layouts/dimmer/dimmer.gd +++ /dev/null @@ -1,20 +0,0 @@ -extends ColorRect - -var request_count: int = 0 - - -func _ready() -> void: - hide() - GlobalSignal.add_listener("show_dimmer", _on_show_dimmer) - GlobalSignal.add_listener("hide_dimmer", _on_hide_dimmer) - - -func _on_show_dimmer(_focus_node: Node = null) -> void: - request_count = max(1, request_count + 1) - show() - - -func _on_hide_dimmer(_focus_node: Node = null) -> void: - request_count = max(0, request_count - 1) - if request_count == 0: - hide() diff --git a/common/layouts/editor/editor_dimmer.gd b/common/layouts/editor/editor_dimmer.gd new file mode 100644 index 00000000..988aa902 --- /dev/null +++ b/common/layouts/editor/editor_dimmer.gd @@ -0,0 +1,36 @@ +extends ColorRect + +var _focus_nodes: Array = [] +var request_count: int = 0 + + +func _ready() -> void: + hide() + GlobalSignal.add_listener("show_dimmer", _on_show_dimmer) + GlobalSignal.add_listener("hide_dimmer", _on_hide_dimmer) + + +func _on_show_dimmer(focus_node: Node = null) -> void: + if focus_node and not focus_node in _focus_nodes: + _focus_nodes.append(focus_node) + + request_count = max(1, request_count + 1) + show() + + +func _on_hide_dimmer(focus_node: Node = null) -> void: + if focus_node and focus_node in _focus_nodes: + focus_node.hide() + _focus_nodes.erase(focus_node) + + request_count = max(0, request_count - 1) + if request_count == 0: + hide() + + +func _on_gui_input(event: InputEvent) -> void: + if event is InputEventMouseButton and event.is_pressed(): + for node in _focus_nodes: + node.hide() + request_count = 0 + hide() diff --git a/common/layouts/dimmer/dimmer.gd.uid b/common/layouts/editor/editor_dimmer.gd.uid similarity index 100% rename from common/layouts/dimmer/dimmer.gd.uid rename to common/layouts/editor/editor_dimmer.gd.uid diff --git a/common/layouts/editor/editor_list_section.gd b/common/layouts/editor/editor_list_section.gd new file mode 100644 index 00000000..79777556 --- /dev/null +++ b/common/layouts/editor/editor_list_section.gd @@ -0,0 +1,89 @@ +extends PanelContainer + +@export var section_icon: Texture2D + +var _property: Property +var _list_field: ListField +var _property_owner: InspectableObject + +@onready var vbox := %VBox +@onready var search_bar: LineEdit = %SearchLine +@onready var add_button: Button = $VBox/ToolBar/AddButton + + +func _ready() -> void: + search_bar.placeholder_text = "Filter %s" % name.to_lower() + if add_button: + add_button.pressed.connect(_on_add_button_pressed) + + +func clear() -> void: + for child in vbox.get_children(): + child.queue_free() + + +func load_items(property: Property, property_owner: InspectableObject = null) -> void: + clear() + _property = property + _property_owner = property_owner + + if not _property: + return + + _list_field = FieldBucket.safe_create_field(_property.type) + if _list_field is ListField: + _property.bind_field(_list_field, _property_owner) + vbox.add_child(_list_field) + + +func _on_add_button_pressed() -> void: + if not (_property and _property_owner): + return + + var data_schema = _property.get_settings_value("data_schema", {}) + var schema_properties: Dictionary = data_schema.get("properties", {}) + var item_initial_data: Dictionary = {} + for prop_name in schema_properties.keys(): + var prop_config = schema_properties[prop_name] + + if prop_config.get("editor_only", false): + continue + + item_initial_data[prop_name] = prop_config.get("default", "") + if prop_config.get("default") is Callable: + item_initial_data[prop_name] = item_initial_data[prop_name].call() + + var item_object = ListItemObject.new( + data_schema, item_initial_data, _list_field._command_manager, schema_properties + ) + item_object.list_field = _list_field + item_object.make_all_values_unique() + + var new_item_list: Array = _property.get_value().duplicate(true) + new_item_list.append(item_object._to_dict()) + _property_owner.set_property_value(_property.name, new_item_list) + + +func _on_search_line_text_changed(new_text: String) -> void: + _list_field.show_all_items() + if new_text.is_empty(): + return + + var search_keys: Array[String] = ["name", "display_name", "nicknames", "description"] + var item_list: Array = _list_field._list_items + + for item: ListItemObject in item_list: + var hide_item: bool = true + var item_idx: int = item_list.find(item) + for prop: Property in item.get_properties(): + if not prop.name in search_keys: + continue + + var value: Variant = prop.get_value() + if value is not String: + continue + + if new_text.to_lower() in value.to_lower(): + hide_item = false + if hide_item: + _list_field.hide_item(item_idx) diff --git a/common/layouts/editor/editor_list_section.gd.uid b/common/layouts/editor/editor_list_section.gd.uid new file mode 100644 index 00000000..40a85d71 --- /dev/null +++ b/common/layouts/editor/editor_list_section.gd.uid @@ -0,0 +1 @@ +uid://yglbu25x1rsy diff --git a/common/layouts/editor/editor_list_section.tscn b/common/layouts/editor/editor_list_section.tscn new file mode 100644 index 00000000..a221d269 --- /dev/null +++ b/common/layouts/editor/editor_list_section.tscn @@ -0,0 +1,38 @@ +[gd_scene load_steps=3 format=3 uid="uid://mfdu320oy6ex"] + +[ext_resource type="Script" uid="uid://yglbu25x1rsy" path="res://common/layouts/editor/editor_list_section.gd" id="1_coa1v"] +[ext_resource type="Texture2D" uid="uid://hlck6y4i3l5q" path="res://ui/assets/icons/plus.svg" id="3_j4mj2"] + +[node name="ListSection" type="PanelContainer"] +custom_minimum_size = Vector2(250, 0) +offset_right = 250.0 +offset_bottom = 47.0 +script = ExtResource("1_coa1v") + +[node name="VBox" type="VBoxContainer" parent="."] +layout_mode = 2 + +[node name="ToolBar" type="HBoxContainer" parent="VBox"] +layout_mode = 2 + +[node name="SearchLine" type="LineEdit" parent="VBox/ToolBar"] +unique_name_in_owner = true +layout_mode = 2 +size_flags_horizontal = 3 +placeholder_text = "Filter" + +[node name="AddButton" type="Button" parent="VBox/ToolBar"] +layout_mode = 2 +icon = ExtResource("3_j4mj2") + +[node name="ScrollContainer" type="ScrollContainer" parent="VBox"] +layout_mode = 2 +size_flags_vertical = 3 + +[node name="VBox" type="VBoxContainer" parent="VBox/ScrollContainer"] +unique_name_in_owner = true +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 3 + +[connection signal="text_changed" from="VBox/ToolBar/SearchLine" to="." method="_on_search_line_text_changed"] diff --git a/common/layouts/editor/graph.tscn b/common/layouts/editor/graph.tscn new file mode 100644 index 00000000..bf89e6d5 --- /dev/null +++ b/common/layouts/editor/graph.tscn @@ -0,0 +1,84 @@ +[gd_scene load_steps=11 format=3 uid="uid://c8525nhvwt1y0"] + +[ext_resource type="Script" uid="uid://nxistnt1yhxc" path="res://scenes/main/graph_container.gd" id="1_nykfi"] +[ext_resource type="Script" uid="uid://bmku341x5gaoe" path="res://scenes/main/add_node_button.gd" id="2_4vw8t"] +[ext_resource type="Texture2D" uid="uid://bfmsxfn26cvfn" path="res://ui/assets/icons/character.svg" id="3_fbi2i"] +[ext_resource type="Texture2D" uid="uid://b46sqb5g0spae" path="res://ui/assets/icons/variables.svg" id="4_4hcgi"] +[ext_resource type="PackedScene" uid="uid://cb3se7h7akt47" path="res://common/layouts/language_switcher/language_switcher.tscn" id="5_l617j"] +[ext_resource type="Texture2D" uid="uid://d4fesqfd2v8fd" path="res://ui/assets/icons/settings.svg" id="6_p1o4h"] +[ext_resource type="Texture2D" uid="uid://dd6wdpndndufl" path="res://ui/assets/icons/sparkles.svg" id="7_lhc65"] +[ext_resource type="Texture2D" uid="uid://b272tbdmvxj20" path="res://ui/assets/icons/play.svg" id="8_7526h"] +[ext_resource type="PackedScene" uid="uid://qdgl8co6qy6" path="res://common/layouts/graph_edit/monologue_graph_edit.tscn" id="9_4vw8t"] + +[sub_resource type="GDScript" id="GDScript_lenro"] +script/source = "extends Button + + +func _on_pressed() -> void: + GlobalSignal.emit(\"test_trigger\") +" + +[node name="Graph" type="PanelContainer"] + +[node name="GraphContainer" type="VBoxContainer" parent="."] +unique_name_in_owner = true +layout_mode = 2 +size_flags_vertical = 3 +mouse_filter = 2 +script = ExtResource("1_nykfi") + +[node name="ToolBar" type="HBoxContainer" parent="GraphContainer"] +layout_mode = 2 + +[node name="AddNodeBtn" type="Button" parent="GraphContainer/ToolBar"] +layout_mode = 2 +theme_type_variation = &"Button_Flat" +text = "Add a node..." +script = ExtResource("2_4vw8t") + +[node name="ButtonCharacters" type="Button" parent="GraphContainer/ToolBar"] +visible = false +layout_mode = 2 +theme_type_variation = &"Button_Flat" +icon = ExtResource("3_fbi2i") +icon_alignment = 1 + +[node name="ButtonVariables" type="Button" parent="GraphContainer/ToolBar"] +visible = false +layout_mode = 2 +theme_type_variation = &"Button_Flat" +icon = ExtResource("4_4hcgi") +icon_alignment = 1 + +[node name="LanguageSwitcher" parent="GraphContainer/ToolBar" instance=ExtResource("5_l617j")] +unique_name_in_owner = true +layout_mode = 2 +theme_type_variation = &"Button_Flat" +disabled = true + +[node name="ButtonSettings" type="Button" parent="GraphContainer/ToolBar"] +visible = false +layout_mode = 2 +theme_type_variation = &"Button_Flat" +icon = ExtResource("6_p1o4h") +icon_alignment = 1 + +[node name="ButtonSparkle" type="Button" parent="GraphContainer/ToolBar"] +visible = false +layout_mode = 2 +theme_type_variation = &"Button_Flat" +icon = ExtResource("7_lhc65") + +[node name="RunButton" type="Button" parent="GraphContainer/ToolBar"] +layout_mode = 2 +theme_type_variation = &"Button_Flat" +icon = ExtResource("8_7526h") +script = SubResource("GDScript_lenro") + +[node name="GraphEdit" parent="GraphContainer" instance=ExtResource("9_4vw8t")] +unique_name_in_owner = true +layout_mode = 2 + +[connection signal="pressed" from="GraphContainer/ToolBar/AddNodeBtn" to="GraphContainer/ToolBar/AddNodeBtn" method="_on_pressed"] +[connection signal="pressed" from="GraphContainer/ToolBar/RunButton" to="GraphContainer/ToolBar/RunButton" method="_on_pressed"] +[connection signal="node_view_selected" from="GraphContainer/GraphEdit" to="GraphContainer" method="_on_graph_edit_node_view_selected"] diff --git a/common/layouts/editor/inspector/expose_button.tscn b/common/layouts/editor/inspector/expose_button.tscn new file mode 100644 index 00000000..e3eba3f0 --- /dev/null +++ b/common/layouts/editor/inspector/expose_button.tscn @@ -0,0 +1,17 @@ +[gd_scene load_steps=4 format=3 uid="uid://2ehh7rdn6yg6"] + +[ext_resource type="Texture2D" uid="uid://x3csrllomotc" path="res://ui/assets/icons/unexposed.svg" id="1_g3anq"] +[ext_resource type="Texture2D" uid="uid://d4fp2shj4o5sk" path="res://ui/assets/icons/exposed.svg" id="2_uxtll"] +[ext_resource type="Texture2D" uid="uid://qs0nswphmi80" path="res://ui/assets/icons/unexposable.svg" id="3_6c77f"] + +[node name="ExposeButton" type="TextureButton"] +custom_minimum_size = Vector2(16, 16) +offset_right = 16.0 +offset_bottom = 16.0 +size_flags_vertical = 3 +toggle_mode = true +texture_normal = ExtResource("1_g3anq") +texture_pressed = ExtResource("2_uxtll") +texture_disabled = ExtResource("3_6c77f") +ignore_texture_size = true +stretch_mode = 5 diff --git a/common/layouts/editor/inspector/inspector_category_container.gd b/common/layouts/editor/inspector/inspector_category_container.gd new file mode 100644 index 00000000..b00c0f54 --- /dev/null +++ b/common/layouts/editor/inspector/inspector_category_container.gd @@ -0,0 +1,23 @@ +extends FoldableContainer + +@onready var _vbox: VBoxContainer = %VBox + + +func add_control( + node: Node, + force_readable_name: bool = false, + internal: InternalMode = InternalMode.INTERNAL_MODE_DISABLED +) -> void: + if not is_node_ready(): + # FIXME: Do weird stuff + return + + if not is_instance_valid(node): + push_warning("Attempted to add a null control to inspector category container.") + return + + _vbox.add_child(node, force_readable_name, internal) + + +func is_empty() -> bool: + return _vbox.get_child_count() <= 0 diff --git a/common/layouts/editor/inspector/inspector_category_container.gd.uid b/common/layouts/editor/inspector/inspector_category_container.gd.uid new file mode 100644 index 00000000..df6a747c --- /dev/null +++ b/common/layouts/editor/inspector/inspector_category_container.gd.uid @@ -0,0 +1 @@ +uid://djpi62hkqu8r6 diff --git a/common/layouts/editor/inspector/inspector_category_container.tscn b/common/layouts/editor/inspector/inspector_category_container.tscn new file mode 100644 index 00000000..8ced7dcc --- /dev/null +++ b/common/layouts/editor/inspector/inspector_category_container.tscn @@ -0,0 +1,13 @@ +[gd_scene load_steps=2 format=3 uid="uid://bvf68w7xrfrom"] + +[ext_resource type="Script" uid="uid://djpi62hkqu8r6" path="res://common/layouts/editor/inspector/inspector_category_container.gd" id="1_d6x5l"] + +[node name="FoldableContainer" type="FoldableContainer"] +offset_right = 24.0 +offset_bottom = 32.0 +title_alignment = 1 +script = ExtResource("1_d6x5l") + +[node name="VBox" type="VBoxContainer" parent="."] +unique_name_in_owner = true +layout_mode = 2 diff --git a/common/layouts/editor/inspector/inspector_panel.gd b/common/layouts/editor/inspector/inspector_panel.gd new file mode 100644 index 00000000..ee133afd --- /dev/null +++ b/common/layouts/editor/inspector/inspector_panel.gd @@ -0,0 +1,325 @@ +class_name InspectorPanel extends PanelContainer + +var current_object: InspectableObject +var _special_fields: Array[Control] = [] +var _category_states: Dictionary = {} +var _pending_expand_category: String = "" + +@onready var header_container: VBoxContainer = %Header +@onready var property_container: VBoxContainer = %Fields +@onready var inspector_category_container: PackedScene = preload("uid://bvf68w7xrfrom") +@onready var expose_button: PackedScene = preload("uid://2ehh7rdn6yg6") + + +func _ready() -> void: + GlobalSignal.add_listener("inspector_property_changed", _on_external_property_changed) + + +func _exit_tree() -> void: + GlobalSignal.remove_listener("inspector_property_changed", _on_external_property_changed) + + +func inspect(object: InspectableObject) -> void: + var is_new_object := current_object != object + if current_object and current_object != object: + if current_object is InspectableNode and is_instance_valid(current_object.graph_view): + current_object.graph_view.selected = false + current_object.remove_observer(on_property_changed) + elif current_object: + current_object.remove_observer(on_property_changed) + + current_object = object + if is_new_object: + _category_states.clear() + rebuild() + + if current_object: + current_object.add_observer(on_property_changed) + + +func rebuild() -> void: + # Store the current focus owner before rebuilding + var focus_owner = get_viewport().gui_get_focus_owner() + var focused_property_name: String = "" + + # Try to identify which property had focus + if focus_owner and focus_owner.is_inside_tree(): + var node = focus_owner + while node: + if node.get_parent() == property_container: + # Found the property container, try to extract property name + for child in property_container.get_children(): + if child == node or child.is_ancestor_of(focus_owner): + # Try to find the property name from the label + var labels = [] + _find_labels(child, labels) + if labels.size() > 0: + focused_property_name = labels[0].text + break + break + node = node.get_parent() + + _cache_category_states() + for prop: Control in property_container.get_children(): + prop.queue_free() + + for field: Control in _special_fields: + field.queue_free() + _special_fields.clear() + + if !current_object: + var label: Label = Label.new() + label.text = "No node selected" + property_container.add_child(label) + _pending_expand_category = "" + return + + var properties: Array[Property] = current_object.get_properties() + var categories: Dictionary = _group_by_category(properties) + for category_name: String in categories.keys(): + var props = categories[category_name] + + if category_name.begins_with("Special"): + var special_category: String = category_name.trim_prefix("Special:") + _handle_special_category_section(special_category, props) + continue + _create_category_section(category_name, props) + + post_build() + + # Restore focus if we had a focused property + if not focused_property_name.is_empty(): + await get_tree().process_frame + _restore_focus_to_property(focused_property_name) + + _pending_expand_category = "" + + +func _find_labels(node: Node, labels: Array) -> void: + if node is Label: + labels.append(node) + for child in node.get_children(): + _find_labels(child, labels) + + +func _restore_focus_to_property(property_display_name: String) -> void: + # Find the property with matching display name and restore focus to its field + for container in property_container.get_children(): + var labels = [] + _find_labels(container, labels) + for label in labels: + if label.text == property_display_name: + # Found the property, now find its field and focus it + var fields = [] + _find_focusable_fields(container, fields) + if fields.size() > 0: + fields[0].grab_focus() + return + + +func _find_focusable_fields(node: Node, fields: Array) -> void: + if node is LineEdit or node is TextEdit or node is OptionButton: + fields.append(node) + for child in node.get_children(): + _find_focusable_fields(child, fields) + + +func _group_by_category(properties: Array) -> Dictionary: + var groups: Dictionary = {} + for prop in properties: + # Skip properties not visible in inspector + if not prop.get_settings_value("visible_in_inspector", true): + continue + + var category: String = "General" + if prop.has_settings("category"): + category = prop.get_settings_value("category") + + if not groups.has(category): + groups[category] = [] + groups[category].append(prop) + return groups + + +func _create_category_section(category_name: String, properties: Array) -> void: + if not property_container.is_node_ready(): + await property_container.ready + + var container: FoldableContainer = inspector_category_container.instantiate() + container.title = category_name + property_container.add_child(container) + _apply_category_state(container, category_name) + + for property: Property in properties: + var property_editor: Control = _create_property_editor(property) + if property_editor: + container.add_control(property_editor) + + +func _handle_special_category_section(category_name: String, properties: Array) -> void: + var container: Control + + match category_name: + "Header": + container = header_container + + for property: Property in properties: + var index: int = properties.find(property) + var property_editor: Control = _create_property_editor(property) + if not property_editor: + continue + + _special_fields.append(property_editor) + + if container.get_child_count() >= index: + var sub_container: Control = container.get_child(index - 1) + sub_container.add_child(property_editor) + sub_container.move_child(property_editor, 0) + continue + container.add_child(property_editor) + + +func _create_property_editor(property: Property) -> Control: + if ( + not property.get_settings_value("editable", true) + and not property.get_settings_value("exposed", false) + and not property.get_settings_value("export", false) + ): + return + + var p_container: PanelContainer = PanelContainer.new() + var p_hbox: HBoxContainer = HBoxContainer.new() + var p_vbox: VBoxContainer = VBoxContainer.new() + var p_expose_button: TextureButton = expose_button.instantiate() + var p_label: Label = Label.new() + + p_container.theme_type_variation = "FieldContainer" + + p_label.text = property.get_display_name() + p_hbox.add_child(p_expose_button) + p_hbox.add_child(p_label) + + p_vbox.add_child(p_hbox) + + if property.get_settings_value("flat"): + p_container.add_theme_stylebox_override("panel", StyleBoxEmpty.new()) + p_hbox.hide() + + var p_field: Control + if property.is_intput_connected(): # Add inspect connected node button if property is connected + var inspect_button: Button = Button.new() + inspect_button.text = "Go to connected node" + inspect_button.tooltip_text = "Inspect connected node" + inspect_button.size_flags_horizontal = Control.SIZE_EXPAND_FILL + inspect_button.pressed.connect(_on_inspect_connected_node.bind(property)) + p_field = inspect_button + else: + p_field = FieldBucket.safe_create_field(property.type) + if p_field is Field: + property.call_deferred("bind_field", p_field, current_object) + + p_vbox.add_child(p_field) + p_container.add_child(p_vbox) + if property.get_settings_value("expand", true): + p_container.size_flags_horizontal = Control.SIZE_EXPAND_FILL + + p_expose_button.disabled = not property.get_settings_value("exposable", false) + p_expose_button.button_pressed = property.get_settings_value("exposed", false) + p_expose_button.toggled.connect( + _on_property_expose_state_changed.bind(current_object, property.name) + ) + + # TODO: Make field read-only if property is not editable or is connected + #if p_field and p_field.has_method("set_editable"): + #var is_editable = ( + #property.get_settings_value("editable", true) and not property.is_intput_connected() + #) + #p_field.set_editable(is_editable) + + return p_container + + +func _cache_category_states() -> void: + for child: Control in property_container.get_children(): + if child is FoldableContainer: + _category_states[child.title] = child.folded + + +func _apply_category_state(container: FoldableContainer, category_name: String) -> void: + var stored_state = _category_states.get(category_name) + if stored_state is bool: + container.folded = stored_state + else: + container.folded = false + + if _pending_expand_category == category_name: + container.folded = false + + _category_states[category_name] = container.folded + + +func post_build() -> void: + for child: Control in property_container.get_children(): + if child is FoldableContainer and child.is_empty(): + child.queue_free() + + _cache_category_states() + + +func _on_property_expose_state_changed( + toggled_on: bool, node: InspectableNode, property_name: String +) -> void: + node.set_property_settings_value(property_name, "exposed", toggled_on) + + +func _on_inspect_connected_node(property: Property) -> void: + if not current_object or not current_object is InspectableNode: + return + + var node: InspectableNode = current_object as InspectableNode + + # Get the graph edit from the node's graph view + if not node.graph_view or not node.graph_view.get_parent(): + return + + var graph_edit := node.graph_view.get_parent() + if not (graph_edit is GraphEdit): + return + + if not graph_edit.connection_manager: + return + + # Get the connected node from the connection manager + var connected_node = graph_edit.connection_manager.get_connected_node(node, property.name) + + if connected_node and connected_node.graph_view: + GlobalSignal.emit("request_node_inspection", [connected_node, connected_node.storyline_id]) + + +func on_property_changed(obj: InspectableObject, _property_name: String) -> void: + if not obj: + return + + rebuild() + + +func _on_external_property_changed( + obj: InspectableObject, property_name: String, _is_undo: bool +) -> void: + if not obj: + return + + var property: Property = obj.get_property(property_name) + if not property: + return + + if not property.get_settings_value("visible_in_inspector", true): + return + + _pending_expand_category = property.get_category() + + if obj == current_object: + rebuild() + return + + inspect(obj) diff --git a/common/layouts/side_panel/side_panel.gd.uid b/common/layouts/editor/inspector/inspector_panel.gd.uid similarity index 100% rename from common/layouts/side_panel/side_panel.gd.uid rename to common/layouts/editor/inspector/inspector_panel.gd.uid diff --git a/common/layouts/side_panel/side_panel.tscn b/common/layouts/editor/inspector/inspector_panel.tscn similarity index 51% rename from common/layouts/side_panel/side_panel.tscn rename to common/layouts/editor/inspector/inspector_panel.tscn index b39ff815..ef17fca8 100644 --- a/common/layouts/side_panel/side_panel.tscn +++ b/common/layouts/editor/inspector/inspector_panel.tscn @@ -1,12 +1,12 @@ [gd_scene load_steps=3 format=3 uid="uid://dgvhvxdrd58qp"] -[ext_resource type="Script" uid="uid://dtf4ge38njewp" path="res://common/layouts/side_panel/side_panel.gd" id="1_haagr"] +[ext_resource type="Script" uid="uid://dtf4ge38njewp" path="res://common/layouts/editor/inspector/inspector_panel.gd" id="1_haagr"] [ext_resource type="Texture2D" uid="uid://b272tbdmvxj20" path="res://ui/assets/icons/play.svg" id="2_34x8o"] -[node name="SidePanel" type="PanelContainer"] +[node name="InspectorPanel" type="PanelContainer"] offset_right = 158.0 offset_bottom = 121.0 -theme_type_variation = &"EditorSidePanel" +theme_type_variation = &"InspectorPanel" script = ExtResource("1_haagr") [node name="VBox" type="VBoxContainer" parent="."] @@ -14,34 +14,25 @@ layout_mode = 2 size_flags_horizontal = 3 size_flags_vertical = 3 -[node name="PanelContainer" type="PanelContainer" parent="VBox"] -z_index = 1 -layout_mode = 2 -theme_type_variation = &"EditorSidePanelTopBox" - -[node name="VBox" type="VBoxContainer" parent="VBox/PanelContainer"] +[node name="Header" type="VBoxContainer" parent="VBox"] +unique_name_in_owner = true layout_mode = 2 -[node name="TopBox" type="HBoxContainer" parent="VBox/PanelContainer/VBox"] -unique_name_in_owner = true +[node name="FirstField" type="HBoxContainer" parent="VBox/Header"] layout_mode = 2 theme_type_variation = &"HBoxContainer_Small" +alignment = 2 -[node name="RFHButton" type="Button" parent="VBox/PanelContainer/VBox/TopBox"] -custom_minimum_size = Vector2(34, 29) +[node name="RFHButton" type="Button" parent="VBox/Header/FirstField"] layout_mode = 2 icon = ExtResource("2_34x8o") icon_alignment = 1 -expand_icon = true - -[node name="HSeparator" type="HSeparator" parent="VBox/PanelContainer/VBox"] -layout_mode = 2 -theme_type_variation = &"HSeparatorGrow" [node name="Scroller" type="ScrollContainer" parent="VBox"] clip_contents = false layout_mode = 2 size_flags_vertical = 3 +follow_focus = true [node name="Fields" type="VBoxContainer" parent="VBox/Scroller"] unique_name_in_owner = true @@ -49,4 +40,4 @@ layout_mode = 2 size_flags_horizontal = 3 size_flags_vertical = 3 -[connection signal="pressed" from="VBox/PanelContainer/VBox/TopBox/RFHButton" to="." method="_on_rfh_button_pressed"] +[connection signal="pressed" from="VBox/Header/FirstField/RFHButton" to="." method="_on_rfh_button_pressed"] diff --git a/common/layouts/expanded_text_edit/expanded_text_edit_container.gd b/common/layouts/expanded_text_edit/expanded_text_edit_container.gd index 3bdfe18e..12a6e91a 100644 --- a/common/layouts/expanded_text_edit/expanded_text_edit_container.gd +++ b/common/layouts/expanded_text_edit/expanded_text_edit_container.gd @@ -23,7 +23,7 @@ func _on_button_pressed() -> void: func _on_text_edit_text_changed() -> void: little_text_edit.text = text_edit.text - little_text_edit.text_changed.emit() + little_text_edit.text_changed.emit(text_edit.text) func _on_visibility_changed() -> void: diff --git a/common/layouts/graph_edit/custom_graph_edit.gd b/common/layouts/graph_edit/custom_graph_edit.gd new file mode 100644 index 00000000..02ae2ae8 --- /dev/null +++ b/common/layouts/graph_edit/custom_graph_edit.gd @@ -0,0 +1,57 @@ +## Represents the graph area which creates and connects MonologueGraphNodes. +class_name CustomGraphEdit extends GraphEdit + +const SCROLLBAR_OVERRIDE_KEYS := ["grabber", "scroll"] + +var connecting_mode: bool +var mouse_hovering: bool = false + + +func _ready() -> void: + _hide_default_scrollbars() + + +func _hide_default_scrollbars() -> void: + for child in get_children(true): + if child is GraphNode: + continue + for subchild in child.get_children(true): + if subchild is ScrollBar: + for key in SCROLLBAR_OVERRIDE_KEYS: + subchild.add_theme_stylebox_override(key, StyleBoxEmpty.new()) + + +func _on_connection_to_empty(node: String, port: int, release: Vector2) -> void: + var center = (get_local_mouse_position() + scroll_offset) / zoom + var graph_release = (release + scroll_offset) / zoom + GlobalSignal.emit("enable_picker_mode", [node, port, release, graph_release, center]) + + +func _on_gui_input(event: InputEvent) -> void: + if mouse_hovering: + var cursor_drag := Input.is_action_pressed("Spacebar") + var cursor_hand_closed := cursor_drag and Input.is_mouse_button_pressed(MOUSE_BUTTON_LEFT) + if Input.is_mouse_button_pressed(MOUSE_BUTTON_MIDDLE): + cursor_hand_closed = true + if cursor_hand_closed: + DisplayServer.cursor_set_custom_image(Cursor.closed_hand) + elif cursor_drag: + DisplayServer.cursor_set_custom_image(Cursor.hand) + else: + DisplayServer.cursor_set_custom_image(Cursor.arrow) + + if ( + event is InputEventMouseButton + and event.is_pressed() + and event.button_index == MOUSE_BUTTON_LEFT + ): + GlobalSignal.emit("show_languages", [false]) + + +func _on_mouse_entered() -> void: + mouse_hovering = true + + +func _on_mouse_exited() -> void: + DisplayServer.cursor_set_custom_image(null) + mouse_hovering = false diff --git a/common/layouts/graph_edit/custom_graph_edit.gd.uid b/common/layouts/graph_edit/custom_graph_edit.gd.uid new file mode 100644 index 00000000..4401c67f --- /dev/null +++ b/common/layouts/graph_edit/custom_graph_edit.gd.uid @@ -0,0 +1 @@ +uid://dfy1ptnvfis7m diff --git a/common/layouts/graph_edit/graph_node_view_factory.gd b/common/layouts/graph_edit/graph_node_view_factory.gd new file mode 100644 index 00000000..d5ce534b --- /dev/null +++ b/common/layouts/graph_edit/graph_node_view_factory.gd @@ -0,0 +1,155 @@ +class_name GraphNodeViewFactory extends RefCounted + +const SLOT_IN_TEXTURE := preload("res://ui/assets/icons/slot_in.svg") +const SLOT_OUT_TEXTURE := preload("res://ui/assets/icons/slot_out.svg") + + +static func build(node: InspectableNode) -> GraphNode: + var graph_node := GraphNode.new() + graph_node.custom_minimum_size.x = 192 + graph_node.draggable = true + graph_node.selectable = true + graph_node.resizable = false + modulate_stylebox(graph_node, node) + apply_metadata(graph_node, node) + populate(graph_node, node) + return graph_node + + +static func modulate_stylebox(graph_node: GraphNode, node: InspectableNode) -> void: + var color_prop: Property = node.get_property("color") + if not color_prop: + return + + var node_color: Color = Color(color_prop.get_value()) + var sb_names: Array = ["panel", "panel_selected"] + + for sb_name: String in sb_names: + graph_node.remove_theme_stylebox_override(sb_name) + + if node_color == Color.BLACK: + return + + for sb_name: String in sb_names: + var base_sb: StyleBox = graph_node.get_theme_stylebox(sb_name) + + if base_sb is StyleBoxFlat: + var new_sb: StyleBoxFlat = base_sb.duplicate() + var new_bg_color = Color(node_color, 0.35) + var new_border_color = Color(node_color, 0.35) + new_bg_color = base_sb.bg_color.blend(new_bg_color) + new_border_color = base_sb.border_color.blend(new_border_color) + new_sb.bg_color = new_bg_color + new_sb.border_color = new_border_color + graph_node.add_theme_stylebox_override(sb_name, new_sb) + + +static func populate(graph_node: GraphNode, node: InspectableNode) -> void: + if not is_instance_valid(graph_node): + return + + apply_metadata(graph_node, node) + + for child: Control in graph_node.get_children(): + graph_node.remove_child(child) + child.queue_free() + + if graph_node.has_method("clear_all_slots"): + graph_node.clear_all_slots() + + var title_bar: HBoxContainer = graph_node.get_titlebar_hbox() + if title_bar: + title_bar.hide() + + var rows := _build_rows(node) + for idx in rows.size(): + var row: GraphNodeRow = rows[idx] + var container := HBoxContainer.new() + container.mouse_filter = Control.MOUSE_FILTER_PASS + container.theme_type_variation = "GraphNodeViewRownHBox" + + var key_label := Label.new() + key_label.mouse_filter = Control.MOUSE_FILTER_PASS + key_label.size_flags_horizontal = Control.SIZE_EXPAND_FILL + key_label.text = row.get_key() + + var value_label := Label.new() + value_label.mouse_filter = Control.MOUSE_FILTER_PASS + if row.get_type(): + value_label.text = "[%s]" % row.get_type() + + var field_metadata := FieldBucket.get_metadata(row.get_type()) + var slot_color: Color = field_metadata.get("color", Color.WHITE) + + value_label.label_settings = LabelSettings.new() + value_label.label_settings.font_color = slot_color + + if idx == 0: + key_label.theme_type_variation = "GraphNodeViewTitleLabel" + value_label.theme_type_variation = "GraphNodeViewValueLabel" + + container.add_child(key_label) + container.add_child(value_label) + graph_node.add_child(container) + + var type_id: int = FieldBucket.get_type_id(row.get_type()) + graph_node.set_slot( + idx, + row._enable_left_port, + type_id, + slot_color, + row._enable_right_port, + type_id, + slot_color, + SLOT_IN_TEXTURE, + SLOT_OUT_TEXTURE, + true + ) + + graph_node.set_slot_custom_icon_left(idx, SLOT_IN_TEXTURE) + graph_node.set_slot_custom_icon_right(idx, SLOT_OUT_TEXTURE) + + graph_node.set_size(Vector2.ZERO) + + +static func apply_metadata(graph_node: GraphNode, node: InspectableNode) -> void: + if not is_instance_valid(graph_node): + return + graph_node.title = Util.to_readable_name(node.get_type()) + # Use node id as the graph node name to make connections rely on ids only + var id_prop := node.get_property("id") + graph_node.name = String(id_prop.get_value()) if id_prop else _derive_node_name(node) + + +static func _build_rows(node: InspectableNode) -> Array[GraphNodeRow]: + var rows: Array[GraphNodeRow] = [] + for prop: Property in node.get_properties(): + var enable_left: bool = bool(prop.get_settings_value("exposed", false)) + var enable_right: bool = bool(prop.get_settings_value("export", false)) + if ( + not prop.get_settings_value("visible_in_graph", true) + and not (enable_left or enable_right) + ): + continue + + var label := ( + prop.get_display_name() if prop.get_settings_value("is_main_property") else prop.name + ) + var row := GraphNodeRow.new(label, prop.type, enable_left, enable_right) + if prop.get_settings_value("is_main_property"): + rows.push_front(row) + continue + rows.append(row) + + return rows + + +static func _derive_node_name(node: InspectableNode) -> String: + # Fallback to id (no type prefix) if needed + var id_value := "" + var id_property := node.get_property("id") + if id_property: + id_value = String(id_property.get_value()) + if id_value.is_empty(): + id_value = IDGen.generate(5) + return id_value diff --git a/common/layouts/graph_edit/graph_node_view_factory.gd.uid b/common/layouts/graph_edit/graph_node_view_factory.gd.uid new file mode 100644 index 00000000..e9449977 --- /dev/null +++ b/common/layouts/graph_edit/graph_node_view_factory.gd.uid @@ -0,0 +1 @@ +uid://d3r62bie5le05 diff --git a/common/layouts/graph_edit/monologue_graph_edit.gd b/common/layouts/graph_edit/monologue_graph_edit.gd index 2a24a655..9f8cf126 100644 --- a/common/layouts/graph_edit/monologue_graph_edit.gd +++ b/common/layouts/graph_edit/monologue_graph_edit.gd @@ -1,422 +1,405 @@ -## Represents the graph area which creates and connects MonologueGraphNodes. -class_name MonologueGraphEdit extends GraphEdit +class_name MonologueGraphEdit extends CustomGraphEdit +signal node_view_selected(node: InspectableNode) -var close_button_scene = preload("res://common/ui/buttons/close_button.tscn") -var base_options = {} -var data: Dictionary -var file_path: String -var undo_redo := HistoryHandler.new() -var version = undo_redo.get_version() - -var languages = [] -var characters = [] -var variables = [] - -var active_graphnode: MonologueGraphNode # for tab-switching purpose -var connecting_mode: bool -var current_language_index: int -var moving_mode: bool -var recorded_positions: Dictionary = {} # for undo/redo positoning purpose -var selected_nodes: Array[MonologueGraphNode] = [] # for group delete -var mouse_hovering: bool = false +var storyline_id: String +var connection_manager: ConnectionManager +var _node_map: Dictionary = {} # Maps GraphNode -> InspectableNode +var _selected_nodes: Dictionary = {} +var _copied_nodes: Array = [] +var _pending_positions: Dictionary = {} # GraphNode -> Vector2 captured during drag +var _is_applying_position: bool = false func _ready() -> void: - var auto_arrange_button = get_menu_hbox().get_children().back() - auto_arrange_button.connect("pressed", _on_auto_arrange_nodes) + super._ready() + StorylineManager.storyline_switched.connect(_on_storyline_switched) - center_offset.call_deferred() - # Hide scroll bar - for child in get_children(true): - if child is GraphNode: - continue +func refresh() -> void: + var storyline: StorylineDocument = StorylineManager.get_storyline(storyline_id) + if not storyline: + return - for subchild in child.get_children(true): - if subchild is not ScrollBar: - continue + # Initialize connection manager if not already done + if not connection_manager: + connection_manager = ConnectionManager.new(storyline) - for sb_name in ["grabber", "scroll"]: - subchild.add_theme_stylebox_override(sb_name, StyleBoxEmpty.new()) + # Clear node map and connections + _node_map.clear() + _pending_positions.clear() + clear_connections() + for child: GraphElement in get_all_graph_nodes(): + child.queue_free() -func _on_add_btn() -> void: - GlobalSignal.emit("select_new_node") + for node: InspectableNode in storyline.nodes: + add_graph_node_view(node) + # Reconnect all tracked connections after rebuilding nodes + _reconnect_all_slots() -func center_offset(): - var base_offset = Vector2.ZERO - var root_node: RootNode = get_root_node() - if root_node: - base_offset = root_node.position_offset + (root_node.size / 2) * zoom - scroll_offset = -size / 2 + base_offset +func refresh_node(node: InspectableNode) -> void: + if not node or not is_instance_valid(node.graph_view): + return + clear_connections() + GraphNodeViewFactory.modulate_stylebox(node.graph_view, node) + GraphNodeViewFactory.apply_metadata(node.graph_view, node) + GraphNodeViewFactory.populate(node.graph_view, node) + _sync_position_from_property(node) + _reconnect_all_slots() -func _input(event: InputEvent) -> void: - moving_mode = ( - Input.is_action_pressed("Select") - and event is InputEventMouseMotion - and not selected_nodes.is_empty() - ) +func add_graph_node_view(node: InspectableNode) -> void: + var graph_node: GraphNode = GraphNodeViewFactory.build(node) -func _gui_input(_event: InputEvent) -> void: - if not mouse_hovering: - return + # Store bidirectional mapping + _node_map[graph_node] = node + node.graph_view = graph_node + + # Connect signals + if not graph_node.position_offset_changed.is_connected( + _on_graph_node_position_changed.bind(graph_node) + ): + graph_node.position_offset_changed.connect(_on_graph_node_position_changed.bind(graph_node)) - var cursor_drag: bool = false - var cursor_hand_closed: bool = false + # Add to scene and set initial position + add_child(graph_node) + if not _on_inspectable_node_property_changed in node._observers: + node.add_observer(_on_inspectable_node_property_changed) - if Input.is_action_pressed("Spacebar"): - cursor_drag = true - if Input.is_mouse_button_pressed(MOUSE_BUTTON_LEFT): - cursor_hand_closed = true + # Apply initial position from property + _sync_position_from_property(node) - if Input.is_mouse_button_pressed(MOUSE_BUTTON_MIDDLE): - cursor_hand_closed = true - if cursor_hand_closed: - DisplayServer.cursor_set_custom_image(Cursor.closed_hand) - elif cursor_drag: - DisplayServer.cursor_set_custom_image(Cursor.hand) +## Called when InspectableNode property changes (undo/redo, programmatic) +func _on_inspectable_node_property_changed(node: InspectableNode, property_name: String) -> void: + if property_name == "position": + if not _is_applying_position: + _sync_position_from_property(node) else: - DisplayServer.cursor_set_custom_image(Cursor.arrow) + refresh_node(node) -## Adds a node of the given type to this graph. -func add_node( - node_type, record: bool = true, picker: GraphNodePicker = null -) -> Array[MonologueGraphNode]: - # if adding from picker, track existing to_nodes of the picker_from_node - var picker_to_names = [] - if picker: - for picker_to_node in get_all_connections_from_slot(picker.from_node, picker.from_port): - picker_to_names.append(picker_to_node.name) +## Sync GraphNode position from InspectableNode property +func _sync_position_from_property(node: InspectableNode) -> void: + if not node or not is_instance_valid(node.graph_view): + return - var node_scene = Constants.NODE_SCENES.get(node_type) - var new_node = node_scene.instantiate() + var position_property := node.get_property("position") + var desired_position: Vector2 = ( + position_property.get_value() if position_property else Vector2.ZERO + ) - # created_nodes include auxilliary nodes from new_node, such as BridgeOut - var created_nodes = new_node.add_to(self) + if node.graph_view.position_offset == desired_position: + return - # if enabled, track the addition of created_nodes into the graph history - if record: - var addition = AddNodeHistory.new(self, created_nodes) - if not picker_to_names.is_empty(): - addition.picker_from_node = picker.from_node - addition.picker_from_port = picker.from_port - addition.picker_to_names = picker_to_names + _is_applying_position = true + node.graph_view.position_offset = desired_position + _is_applying_position = false + _pending_positions.erase(node.graph_view) + _pending_positions.erase(node.graph_view) - undo_redo.create_action("Add new %s" % [new_node.node_type]) - undo_redo.add_prepared_history(addition) - undo_redo.commit_action(false) - return created_nodes +## Called when GraphNode position changes (user drag) +func _on_graph_node_position_changed(graph_node: GraphNode) -> void: + if _is_applying_position: + return + _pending_positions[graph_node] = graph_node.position_offset -func clear(): - for node in get_nodes(): - node.queue_free() - clear_connections() +func _on_node_selected(graph_node: Node) -> void: + _selected_nodes[graph_node] = true + var node: InspectableNode = _node_map.get(graph_node) + if node: + node_view_selected.emit(node) -## Disconnect all outbound connections of the given graphnode and port. -func disconnect_outbound_from_node(from_node: StringName, from_port: int) -> void: - for connection in get_connection_list(): - if connection.get("from_node") == from_node: - var to_node = connection.get("to_node") - var to_port = connection.get("to_port") - disconnect_node(from_node, from_port, to_node, to_port) - - -## Deletes the given graphnode and return its dictionary data. -func free_graphnode(node: MonologueGraphNode) -> Dictionary: - var inbound_connections = get_all_inbound_connections(node.name) - var outbound_connections = get_all_outbound_connections(node.name) - for c in inbound_connections + outbound_connections: - disconnect_node(c.get("from_node"), c.get("from_port"), c.get("to_node"), c.get("to_port")) - - var node_data = node._to_dict() - if "options" in node: - # tag options into the node_data - node_data.merge({"Options": node.options.value}) - if active_graphnode == node: - active_graphnode = null - - selected_nodes.erase(node) - recorded_positions.erase(node) - node.queue_free() - # if side panel is showing this node, close it since it's gone - GlobalSignal.emit("close_panel", [node]) - return node_data - - -## Find all other connections that connect to the given graphnode. -func get_all_inbound_connections(from_node: StringName) -> Array: - var node_connections = [] - for connection in get_connection_list(): - if connection.get("to_node") == from_node: - node_connections.append(connection) - return node_connections - - -## Find all connections that originate from the given graphnode. -func get_all_outbound_connections(from_node: StringName) -> Array: - var node_connections = [] - for connection in get_connection_list(): - if connection.get("from_node") == from_node: - node_connections.append(connection) - return node_connections - - -## Find connections of the given [param from_node] at its [param from_port]. -func get_all_connections_from_slot(from_node: StringName, from_port: int) -> Array: - var node_connections = [] - for connection in get_connection_list(): - if connection.get("from_node") == from_node and connection.get("from_port") == from_port: - var to = get_node_or_null(NodePath(connection.get("to_node"))) - node_connections.append(to) - return node_connections - - -func get_free_bridge_number(_n = 1, lp_max = 50) -> int: - for node in get_nodes(): - if ( - (node.node_type == "NodeBridgeOut" or node.node_type == "NodeBridgeIn") - and node.number_selector.value == _n - ): - if lp_max <= 0: - return _n - - return get_free_bridge_number(_n + 1, lp_max - 1) - return _n - - -func get_linked_bridge_node(target_number) -> MonologueGraphNode: - for node in get_nodes(): - if node.node_type == "NodeBridgeOut" and node.number_selector.value == target_number: - return node - return null +func _on_node_deselected(graph_node: Node) -> void: + _selected_nodes[graph_node] = false -func get_root_node() -> RootNode: - for node in get_nodes(): - if node is RootNode: - return node - return null +func _on_connection_request( + from_view_name: StringName, from_port: int, to_view_name: StringName, to_port: int +) -> void: + var from_node: InspectableNode = get_node_from_view_name(from_view_name) + var to_node: InspectableNode = get_node_from_view_name(to_view_name) + var from_graph_node: GraphNode = get_node(from_view_name as String) + var to_graph_node: GraphNode = get_node(to_view_name as String) + var from_port_type: int = from_graph_node.get_output_port_type(from_port) + var to_port_type: int = to_graph_node.get_input_port_type(to_port) -## Find a graph node by ID. Includes OptionNodes. -func get_node_by_id(id: String) -> MonologueGraphNode: - if not id.is_empty(): - for node in get_nodes(): - if node.id.value == id: - return node - elif node is ChoiceNode: - var option = node.get_option_by_id(id) - if option: - return option - return null + if from_port_type != to_port_type: + return + # Get property names at the port indices + var from_property_name = get_property_name_at_port(String(from_view_name), from_port, true) + var to_property_name = get_property_name_at_port(String(to_view_name), to_port, false) -func is_unsaved() -> bool: - return version != undo_redo.get_version() + if from_property_name.is_empty() or to_property_name.is_empty(): + push_warning("Cannot create connection: property not found at port") + return + + var storyline: StorylineDocument = StorylineManager.get_storyline(storyline_id) + var command: NodeConnectionCommand = NodeConnectionCommand.new( + self, + from_node.get_property_value("id"), + to_node.get_property_value("id"), + from_property_name, + to_property_name + ) + storyline.history.execute(command) -## Connect picker_from_node to [param node] if needed, reposition nodes. -func pick_and_center( - nodes: Array[MonologueGraphNode], picker: GraphNodePicker -) -> PackedStringArray: - var to_names = [] - var offset = (scroll_offset + size/2) / zoom # center of graph +func _has_connection_at_slot(node_name: StringName, port_index: int, is_output: bool) -> bool: + var node_key := "from_node" if is_output else "to_node" + var port_key := "from_port" if is_output else "to_port" + var target_name := String(node_name) - if picker.from_node and picker.from_port != -1: - if nodes[0].get_input_port_count() > 0: - var from_node = picker.from_node - var from_port = picker.from_port - disconnect_outbound_from_node(from_node, from_port) - propagate_connection(from_node, from_port, nodes[0].name, 0) - if picker.graph_release: - offset = (picker.release + scroll_offset) / zoom + for connection: Dictionary in get_connection_list(): + if String(connection.get(node_key, "")) != target_name: + continue + if int(connection.get(port_key, -1)) == port_index: + return true - picker.flush() - - for node in nodes: - node.position_offset = offset + return false - post_node_offset.call_deferred(nodes) - return to_names +func get_all_graph_nodes() -> Array: + return get_children().filter(func(child) -> bool: return child is GraphNode) -func post_node_offset(nodes: Array[MonologueGraphNode]) -> void: - for node in nodes: - node.position_offset -= node.size/2 - - if not nodes[0].is_slot_enabled_left(0): + +## Reconnect all slots based on tracked connections in connection_manager +func _reconnect_all_slots() -> void: + if not connection_manager: return - var first_port_pos = nodes[0].get_input_port_position(0) - for node in nodes: - node.position_offset -= first_port_pos - node.position_offset = round(node.position_offset / snapping_distance) * snapping_distance + var storyline: StorylineDocument = StorylineManager.get_storyline(storyline_id) + var all_connections = connection_manager.get_all_connections() + for conn in all_connections: + var from_node_id = conn["from_node_id"] + var from_property = conn["from_property"] + var to_node_id = conn["to_node_id"] + var to_property = conn["to_property"] -## Connects/disconnects and updates a given connection's NextID if possible. -## If [param next] is true, establish connection and propagate NextIDs. -## If it is false, destroy connection and clear all linked NextIDs. -func propagate_connection(from_node, from_port, to_node, to_port, next = true) -> void: - if next: - connect_node(from_node, from_port, to_node, to_port) + var from_node: InspectableNode = storyline.get_node(from_node_id) + var to_node: InspectableNode = storyline.get_node(to_node_id) + var from_view_name: String = from_node.graph_view.name + var to_view_name: String = to_node.graph_view.name - else: - disconnect_node(from_node, from_port, to_node, to_port) + # Get port indices for the properties + var from_port = get_port_index_for_property(from_view_name, from_property) + var to_port = get_port_index_for_property(to_view_name, to_property) + + # Only connect if both ports are valid + if from_port >= 0 and to_port >= 0: + connect_node(from_view_name, from_port, to_view_name, to_port) - var graph_node = get_node_or_null(NodePath(from_node)) - if graph_node and graph_node.has_method("update_next_id"): - if next: - var next_node = get_node_or_null(NodePath(to_node)) - graph_node.update_next_id(from_port, next_node) + +## Get visible properties in the same order as displayed in graph +func _get_visible_properties(node: InspectableNode) -> Array[Property]: + var visible_props: Array[Property] = [] + var properties = node.get_properties() + + for prop: Property in properties: + if not prop.get_settings_value("visible_in_graph", true): + continue + var exposed = prop.get_settings_value("exposed", false) or false + var export = prop.get_settings_value("export", false) or false + + # Skip if no ports + if not exposed and not export: + continue + + # Main property goes first + if prop.get_settings_value("is_main_property"): + visible_props.push_front(prop) else: - graph_node.update_next_id(from_port, null) + visible_props.append(prop) + + return visible_props -func trigger_delete(): - if not active_graphnode and selected_nodes: - var root_filter = func(n): return n is not RootNode - var selected_copy = selected_nodes.duplicate().filter(root_filter) - var delete_history = DeleteNodeHistory.new(self, selected_copy) - undo_redo.create_action("Delete %s" % str(selected_copy)) - undo_redo.add_prepared_history(delete_history) - undo_redo.commit_action() +## Get the port index for a specific property by name +func get_port_index_for_property(node_name: String, property_name: String) -> int: + var storyline: StorylineDocument = StorylineManager.get_storyline(storyline_id) + for node: InspectableNode in storyline.nodes: + if node.graph_view.name == node_name: + var visible_props = _get_visible_properties(node) -## Checks and ensure graph is ready before triggering undo. -func trigger_undo() -> void: - if not connecting_mode: - undo_redo.undo() + # Find the property by name and return its index + for i in range(visible_props.size()): + if visible_props[i].name == property_name: + return i + break + return -1 -## Checks and ensure graph is ready before triggering redo. -func trigger_redo() -> void: - if not connecting_mode: - undo_redo.redo() +func get_node_from_view_name(graph_view_name: String) -> InspectableNode: + var storyline: StorylineDocument = StorylineManager.get_storyline(storyline_id) -func update_node_positions() -> void: - var affected_nodes = selected_nodes if selected_nodes else get_nodes() - for node in affected_nodes: - recorded_positions[node] = node.position_offset + for node: InspectableNode in storyline.nodes: + if node.graph_view.name == graph_view_name: + return node + return null -func update_version() -> void: - version = undo_redo.get_version() +## Get property name at a specific port index +func get_property_name_at_port(node_name: String, port_index: int, is_output: bool) -> String: + var node: InspectableNode = get_node_from_view_name(node_name) + if not node: + return "" + + var count := 0 + for prop: Property in node.get_properties(): + var has_port: bool = ( + prop.get_settings_value("export", false) + if is_output + else prop.get_settings_value("exposed", false) + ) + if not has_port: + continue + if count == port_index: + return prop.name + count += 1 + return "" + + +func _on_end_node_move() -> void: + if _pending_positions.is_empty(): + return + + _is_applying_position = true + var storyline: StorylineDocument = StorylineManager.get_storyline(storyline_id) + var history: CommandManager = storyline.history if storyline else null + if not history: + _is_applying_position = false + _pending_positions.clear() + return -func _on_auto_arrange_nodes() -> void: - var affected = selected_nodes if selected_nodes else get_nodes() - var changed = affected.filter(func(n): return n.position_offset != recorded_positions[n]) - if changed and affected.size() > 1: - undo_redo.create_action("Auto arrange nodes") - for node in changed: - undo_redo.add_do_property(node, "position_offset", node.position_offset) - undo_redo.add_undo_property(node, "position_offset", recorded_positions[node]) - undo_redo.commit_action(false) - update_node_positions() + for graph_node in _pending_positions.keys(): + if not is_instance_valid(graph_node): + continue + var node: InspectableNode = _node_map.get(graph_node) + if not node: + continue -func _on_child_entered_tree(node: Node) -> void: - if node is MonologueGraphNode: - if node is RootNode: - return + var target_position: Vector2 = _pending_positions[graph_node] + var position_property := node.get_property("position") + if not position_property: + continue - if not node.show_close_button: - return + var current_position: Vector2 = position_property.get_value() + if current_position == target_position: + continue - var node_header = node.get_children(true)[0] - var close_button: TextureButton = close_button_scene.instantiate() + var command := PropertyChangeCommand.new( + node, "position", current_position, target_position + ) + history.execute(command, UndoRedo.MERGE_DISABLE) - var close_callback = func(): - var delete_history = DeleteNodeHistory.new(self, [node]) - var message = "Delete %s (id: %s)" - undo_redo.create_action(message % [node.node_type, node.id.value]) - undo_redo.add_prepared_history(delete_history) - undo_redo.commit_action(false) - selected_nodes.erase(node) - recorded_positions.erase(node) - free_graphnode(node) + _is_applying_position = false + _pending_positions.clear() - close_button.connect("pressed", close_callback) - node_header.add_child(close_button) +func _on_disconnection_request( + from_view_name: StringName, from_port: int, to_view_name: StringName, to_port: int +) -> void: + if not connection_manager: + return -func _on_connection_drag_started(_from_node, _from_port, _is_output) -> void: - connecting_mode = true + connection_manager.unregister_connection(from_view_name, from_port, to_view_name, to_port) + var from_node: InspectableNode = get_node_from_view_name(from_view_name) + var to_node: InspectableNode = get_node_from_view_name(to_view_name) + var from_graph_node: GraphNode = get_node(from_view_name as String) + var to_graph_node: GraphNode = get_node(to_view_name as String) + var from_port_type: int = from_graph_node.get_output_port_type(from_port) + var to_port_type: int = to_graph_node.get_input_port_type(to_port) + if from_port_type != to_port_type: + return -func _on_connection_drag_ended() -> void: - connecting_mode = false + # Get property names at the port indices + var from_property_name = get_property_name_at_port(String(from_view_name), from_port, true) + var to_property_name = get_property_name_at_port(String(to_view_name), to_port, false) + if from_property_name.is_empty() or to_property_name.is_empty(): + push_warning("Cannot create connection: property not found at port") + return -func _on_connection_request(from_node, from_port, to_node, to_port) -> void: - # so check to make sure there are no other connections before connecting - if get_all_connections_from_slot(from_node, from_port).size() <= 0: - var arguments = [from_node, from_port, to_node, to_port] - var message = "Connect %s port %d to %s port %d" - undo_redo.create_action(message % arguments) - undo_redo.add_do_method(propagate_connection.bindv(arguments)) - undo_redo.add_undo_method(propagate_connection.bindv(arguments + [false])) - undo_redo.commit_action() + var storyline: StorylineDocument = StorylineManager.get_storyline(storyline_id) + var command: NodeConnectionCommand = NodeConnectionCommand.new( + self, + from_node.get_property_value("id"), + to_node.get_property_value("id"), + from_property_name, + to_property_name + ) + storyline.history.execute(command) -func _on_disconnection_request(from_node, from_port, to_node, to_port) -> void: - var arguments = [from_node, from_port, to_node, to_port] - var message = "Disconnect %s from %s port %d" - undo_redo.create_action(message % [to_node, from_node, from_port]) - undo_redo.add_do_method(propagate_connection.bindv(arguments + [false])) - undo_redo.add_undo_method(propagate_connection.bindv(arguments)) - undo_redo.commit_action() +func _on_storyline_switched() -> void: + var storyline: StorylineDocument = StorylineManager.get_active_storyline() + if not storyline.node_added.is_connected(refresh): + storyline.node_added.connect(refresh) + if not storyline.node_removed.is_connected(refresh): + storyline.node_removed.connect(refresh) + refresh() -func _on_connection_to_empty(node: String, port: int, release: Vector2) -> void: - var center = (get_local_mouse_position() + scroll_offset) / zoom - var graph_release = (release + scroll_offset) / zoom - GlobalSignal.emit("enable_picker_mode", [node, port, release, graph_release, center]) +func _on_copy_nodes_request() -> void: + if _selected_nodes.size() <= 0: + return + _copied_nodes.clear() -func _on_gui_input(event: InputEvent) -> void: - # when the user clicks on the graph edit, close unnecessary stuff - if ( - event is InputEventMouseButton - and event.is_pressed() - and event.button_index == MOUSE_BUTTON_LEFT - ): - GlobalSignal.emit("show_languages", [false]) + for node in get_children(): + if node is GraphNode and _selected_nodes.get(node, false): + var duplicated: InspectableNode = _node_map.get(node).duplicate(true) + _copied_nodes.append(duplicated) -func _on_node_selected(node) -> void: - if node is MonologueGraphNode: - selected_nodes.append(node) +func _on_paste_nodes_request() -> void: + # TODO: Move nodes based on the cursor position + var storyline: StorylineDocument = StorylineManager.get_storyline(storyline_id) + var command: AddNodesCommand = AddNodesCommand.new(storyline_id, _copied_nodes) + storyline.history.execute(command) -func _on_node_deselected(node) -> void: - recorded_positions[node] = node.position_offset - selected_nodes.erase(node) - active_graphnode = null # when a deselection happens, clear active node +func _on_cut_nodes_request() -> void: + if _selected_nodes.size() <= 0: + return + _copied_nodes.clear() + var nodes_to_delete: Array[InspectableNode] = [] -func get_nodes() -> Array[MonologueGraphNode]: - var list: Array[MonologueGraphNode] = [] for node in get_children(): - if node is MonologueGraphNode: - list.append(node) - return list + if node is GraphNode and _selected_nodes.get(node, false): + var duplicated: InspectableNode = _node_map.get(node).duplicate(true) + _copied_nodes.append(duplicated) + nodes_to_delete.append(_node_map.get(node)) + + var storyline: StorylineDocument = StorylineManager.get_storyline(storyline_id) + var command: DeleteNodesCommand = DeleteNodesCommand.new(storyline_id, nodes_to_delete) + storyline.history.execute(command) -func _on_mouse_entered() -> void: - mouse_hovering = true +func _on_delete_nodes_request(graph_nodes: Array[StringName]) -> void: + var storyline: StorylineDocument = StorylineManager.get_storyline(storyline_id) + var nodes: Array[InspectableNode] = [] + for node_name: StringName in graph_nodes: + var graph_node: GraphNode = get_node("%s" % node_name) + var node: InspectableNode = _node_map.get(graph_node) + nodes.append(node) + var command: DeleteNodesCommand = DeleteNodesCommand.new(storyline_id, nodes) + storyline.history.execute(command) -func _on_mouse_exited() -> void: - DisplayServer.cursor_set_custom_image(null) - mouse_hovering = false + refresh() diff --git a/common/layouts/graph_edit/monologue_graph_edit.tscn b/common/layouts/graph_edit/monologue_graph_edit.tscn index 6cb08519..4d7633ca 100644 --- a/common/layouts/graph_edit/monologue_graph_edit.tscn +++ b/common/layouts/graph_edit/monologue_graph_edit.tscn @@ -10,13 +10,13 @@ grow_horizontal = 2 grow_vertical = 2 size_flags_horizontal = 3 size_flags_vertical = 3 +show_grid = false grid_pattern = 1 snapping_enabled = false snapping_distance = 30 right_disconnects = true -zoom = 0.6 zoom_min = 0.1 -zoom_max = 1.2 +zoom_max = 2.0 minimap_enabled = false show_menu = false show_zoom_buttons = false @@ -25,14 +25,17 @@ show_minimap_button = false show_arrange_button = false script = ExtResource("1_ivjsb") -[connection signal="child_entered_tree" from="." to="." method="_on_child_entered_tree"] -[connection signal="connection_drag_ended" from="." to="." method="_on_connection_drag_ended"] -[connection signal="connection_drag_started" from="." to="." method="_on_connection_drag_started"] [connection signal="connection_request" from="." to="." method="_on_connection_request"] [connection signal="connection_to_empty" from="." to="." method="_on_connection_to_empty"] +[connection signal="copy_nodes_request" from="." to="." method="_on_copy_nodes_request"] +[connection signal="cut_nodes_request" from="." to="." method="_on_cut_nodes_request"] +[connection signal="delete_nodes_request" from="." to="." method="_on_delete_nodes_request"] [connection signal="disconnection_request" from="." to="." method="_on_disconnection_request"] +[connection signal="duplicate_nodes_request" from="." to="." method="_on_duplicate_nodes_request"] +[connection signal="end_node_move" from="." to="." method="_on_end_node_move"] [connection signal="gui_input" from="." to="." method="_on_gui_input"] [connection signal="mouse_entered" from="." to="." method="_on_mouse_entered"] [connection signal="mouse_exited" from="." to="." method="_on_mouse_exited"] [connection signal="node_deselected" from="." to="." method="_on_node_deselected"] [connection signal="node_selected" from="." to="." method="_on_node_selected"] +[connection signal="paste_nodes_request" from="." to="." method="_on_paste_nodes_request"] diff --git a/common/layouts/language_switcher/language_switcher.tscn b/common/layouts/language_switcher/language_switcher.tscn index cc85123d..e878e6bc 100644 --- a/common/layouts/language_switcher/language_switcher.tscn +++ b/common/layouts/language_switcher/language_switcher.tscn @@ -25,14 +25,15 @@ grow_vertical = 2 mouse_filter = 2 [node name="PanelContainer" type="PanelContainer" parent="Dropdown"] +z_index = 2 layout_mode = 1 anchors_preset = 15 anchor_right = 1.0 anchor_bottom = 1.0 -offset_left = -10.0 -offset_top = -220.0 -offset_right = 10.0 -offset_bottom = -60.0 +offset_left = -3.0 +offset_top = 42.0 +offset_right = 3.0 +offset_bottom = 202.0 grow_horizontal = 2 grow_vertical = 2 theme_type_variation = &"OuterPanel" diff --git a/common/layouts/search_bar/search_bar.gd b/common/layouts/search_bar/search_bar.gd index 62ff5b2e..9e49172f 100644 --- a/common/layouts/search_bar/search_bar.gd +++ b/common/layouts/search_bar/search_bar.gd @@ -2,25 +2,24 @@ extends PanelContainer const SCROLL_CONTAINER_MAX_SIZE: int = 200 -@export var graph_edit_switcher: GraphEditSwitcher - @onready var line_edit: LineEdit = %LineEdit func focus() -> void: line_edit.grab_focus() line_edit.select_all() - + _on_h_box_resized() -func _on_line_edit_text_changed(new_text: String) -> void: - var graph_edit: MonologueGraphEdit = graph_edit_switcher.current - var all_nodes: Array = graph_edit.get_nodes() - - for node: MonologueGraphNode in all_nodes: - if node.node_type.containsn(new_text): - continue +func _on_line_edit_text_changed(_new_text: String) -> void: + pass + #var graph_edit: MonologueGraphEdit = graph_edit_switcher.current + #var all_nodes: Array = graph_edit.get_nodes() + # + #for node: MonologueGraphNode in all_nodes: + #if node.node_type.containsn(new_text): + #continue func _on_h_box_resized() -> void: diff --git a/common/layouts/side_panel/side_panel.gd b/common/layouts/side_panel/side_panel.gd deleted file mode 100644 index 7e07ab0c..00000000 --- a/common/layouts/side_panel/side_panel.gd +++ /dev/null @@ -1,200 +0,0 @@ -## Side panel which displays graph node details. This panel should not contain -## references to MonologueControl or GraphEditSwitcher. -class_name SidePanel extends PanelContainer - -@onready var fields_container = %Fields -@onready var topbox = %TopBox -@onready var ribbon_scene = preload("res://common/ui/ribbon/ribbon.tscn") -@onready -var collapsible_field = preload("res://common/ui/fields/collapsible_field/collapsible_field.tscn") - -var collapsibles: Dictionary[String, CollapsibleField] -var id_field_container: Control -var selected_node: MonologueGraphNode - - -func _ready(): - GlobalSignal.add_listener("close_panel", _on_close_button_pressed) - hide() - - -func clear(): - for field in fields_container.get_children(): - field.free() - if is_instance_valid(id_field_container): - id_field_container.queue_free() - collapsibles.clear() - - -func on_graph_node_deselected(_node): - hide.call_deferred() - - -func on_graph_node_selected(node: MonologueGraphNode, bypass: bool = false): - if not bypass: - var graph_edit = node.get_parent() - await get_tree().create_timer(0.1).timeout - if ( - is_instance_valid(node) - and not graph_edit.moving_mode - and graph_edit.selected_nodes.size() == 1 - ): - graph_edit.active_graphnode = node - else: - graph_edit.active_graphnode = null - return - - # hack to preserve focus if the side panel contains the same node paths - var focus_owner = get_viewport().gui_get_focus_owner() - var refocus_path: NodePath = "" - var refocus_line: int = -1 - var refocus_column: int = -1 - if focus_owner: - refocus_path = get_path_to(focus_owner) - if focus_owner is TextEdit: - refocus_line = focus_owner.get_caret_line() - refocus_column = focus_owner.get_caret_column() - elif focus_owner is LineEdit: - refocus_column = focus_owner.get_caret_column() - var uncollapse_paths: Array[NodePath] = [] - if node == selected_node: - for collapsible: CollapsibleField in collapsibles.values(): - if collapsible.is_open(): - uncollapse_paths.append(get_path_to(collapsible)) - - clear() - selected_node = node - node._update() - - if not node.is_editable(): - return - - var items = node._get_field_groups() - var already_invoke := [] - var property_names = node.get_property_names() - - for item in items: - _load_groups(item, node, already_invoke) - - for property_name in property_names: - if property_name in already_invoke: - continue - - if property_name == "id": - var field = node.get(property_name) - field.show(topbox, 0, false) - id_field_container = field.field_container - else: - var field = node.get(property_name).show(fields_container) - field.set_label_text(property_name.capitalize()) - - show() - restore_collapsible_state(uncollapse_paths) - # if focus was preserved, restore it - restore_focus(refocus_path, refocus_line, refocus_column) - - -func _load_groups(item, graph_node: MonologueGraphNode, already_invoke) -> void: - if item is String: - var property = graph_node.get(item) - var field = property.show(fields_container) - - if property.custom_label != null: - field.set_label_text(property.custom_label) - else: - field.set_label_text(item.capitalize()) - - already_invoke.append(item) - else: - for group in item: - _recursive_build_collapsible_field( - fields_container, item, group, graph_node, already_invoke - ) - - -func _recursive_build_collapsible_field( - parent: Control, - item: Dictionary, - group: String, - graph_node: MonologueGraphNode, - already_invoke: Array -) -> CollapsibleField: - var fields = item[group] - var field_obj: CollapsibleField = collapsible_field.instantiate() - var field_margin = MarginContainer.new() - field_margin.size_flags_horizontal = Control.SIZE_EXPAND_FILL - field_margin.add_theme_constant_override("margin_right", 0) - field_margin.add_theme_constant_override("margin_bottom", 0) - field_margin.add_child(field_obj) - if parent is CollapsibleField: - parent.add_item(field_margin) - else: - parent.add_child(field_margin) - field_obj.set_title(group) - - for field_name in fields: - if field_name is Dictionary: - for sub_group in field_name: - _recursive_build_collapsible_field( - field_obj, field_name, sub_group, graph_node, already_invoke - ) - continue - - var property: Property = graph_node.get(field_name) - var field = property.show(fields_container) - var field_container = property.field_container - - if property.custom_label != null: - field.set_label_text(property.custom_label) - else: - field.set_label_text(field_name.capitalize()) - - fields_container.remove_child(field_container) - field_obj.add_item(field_container) - already_invoke.append(field_name) - - field.collapsible_field = field_obj - if property.uncollapse: - field_obj.open() - property.uncollapse = false - return field_obj - - -## If the side panel for the node is visible, release the focus so that -## text controls trigger the focus_exited() signal to update. -func refocus(node: MonologueGraphNode) -> void: - if visible and selected_node == node: - var focus_owner = get_viewport().gui_get_focus_owner() - if focus_owner: - focus_owner.release_focus() - focus_owner.grab_focus() - - -## If any collapsible fields were opened before the side panel was refreshed, -## this method will reopen them via their node paths. -func restore_collapsible_state(uncollapse_paths: Array[NodePath]) -> void: - for path in uncollapse_paths: - var field = get_node_or_null(path) - if is_instance_valid(field) and field is CollapsibleField: - field.open() - - -## Hacky improvement for #52 to maintain focus on side panel refresh. -func restore_focus(node_path: NodePath, line: int, column: int) -> void: - if node_path: - var node = get_node_or_null(node_path) - if is_instance_valid(node) and node is Control: - node.grab_focus() - if line >= 0: - node.set_caret_line(line) - if column >= 0: - node.set_caret_column(column) - - -func _on_rfh_button_pressed() -> void: - GlobalSignal.emit("test_trigger", [selected_node.id.value]) - - -func _on_close_button_pressed(node: MonologueGraphNode = null) -> void: - if not node or selected_node == node: - selected_node.get_parent().set_selected(null) diff --git a/common/monologue_graph_node.gd b/common/monologue_graph_node.gd deleted file mode 100644 index 57381a2c..00000000 --- a/common/monologue_graph_node.gd +++ /dev/null @@ -1,227 +0,0 @@ -## Abstract graph node class for Monologue dialogue nodes. This should not -## be used on its own, it should be overridden to replace [member node_type]. -class_name MonologueGraphNode extends GraphNode - -static var subclasses = [] - -@export_group("Appearance") -@export var titlebar_color: Color = Color("ff0000") -@export var show_close_button: bool = true -@export var show_titlebar: bool = true - -# field UI scene definitions that a graph node can have -const CHECKBOX = preload("res://common/ui/fields/check_box/monologue_check_box.tscn") -const DROPDOWN = preload("res://common/ui/fields/dropdown/monologue_dropdown.tscn") -const FILE = preload("res://common/ui/fields/file_picker/monologue_file_picker.tscn") -const LINE = preload("res://common/ui/fields/line_edit/monologue_line_edit.tscn") -const LIST = preload("res://common/ui/fields/list/monologue_list.tscn") -const SLIDER = preload("res://common/ui/fields/slider/monologue_slider.tscn") -const SPINBOX = preload("res://common/ui/fields/spin_box/monologue_spin_box.tscn") -const TIMELINE = preload("res://common/ui/fields/timeline/monologue_timeline.tscn") -const TEXT = preload("res://common/ui/fields/text/monologue_text.tscn") -const TOGGLE = preload("res://common/ui/fields/toggle/monologue_toggle.tscn") -const VECTOR = preload("res://common/ui/fields/vector/monologue_vector.tscn") - -const LEFT_SLOT = preload("res://ui/assets/icons/slot.svg") -const RIGHT_SLOT = preload("res://ui/assets/icons/slot.svg") - -var id := Property.new(LINE, {}, IDGen.generate()) -var editor_position := Property.new(VECTOR, {}, [0.0, 0.0]) -var node_type: String = "NodeUnknown" - - -func _ready() -> void: - set_anchors_preset(Control.PRESET_TOP_LEFT) - if show_titlebar: - _set_titlebar_color(titlebar_color) - - title = node_type - id.setters["copyable"] = true - id.setters["validator"] = _validate_id - id.callers["set_label_visible"] = [false] - editor_position.display.connect(_on_editor_position_change) - editor_position.visible = false - for property_name in get_property_names(): - get(property_name).connect("change", change.bind(property_name)) - get(property_name).connect("display", display) - - _update_slot_icons() - _harmonize_size.call_deferred() - - dragged.connect(_on_dragged) - - -func _on_dragged(_from: Vector2 = Vector2.ZERO, _to: Vector2 = Vector2.ZERO) -> void: - var new_editor_position: Array = [position_offset.x, position_offset.y] - editor_position.save_value(new_editor_position) - - -func _on_editor_position_change() -> void: - await get_tree().process_frame - position_offset.x = editor_position.value[0] - position_offset.y = editor_position.value[1] - - -func _update_slot_icons() -> void: - for slot_idx in get_child_count(): - if is_slot_enabled_left(slot_idx): - set_slot_custom_icon_left(slot_idx, LEFT_SLOT) - if is_slot_enabled_right(slot_idx): - set_slot_custom_icon_right(slot_idx, RIGHT_SLOT) - - -func _harmonize_size() -> void: - var min_size: Vector2 = get_combined_minimum_size() - size.x = ceil(min_size.x / 30) * 30 - size.y = min_size.y - - -func _set_titlebar_color(val: Color): - var is_dark = val.get_luminance() < 0.5 - var stylebox: StyleBoxFlat = get_theme_stylebox("titlebar", "GraphNode").duplicate() - stylebox.bg_color = val - stylebox.corner_radius_top_left = 5 - stylebox.corner_radius_top_right = 5 - - stylebox.border_color = Color("4d4d4d") - stylebox.set_border_width_all(1) - stylebox.border_width_bottom = 0 - - var stylebox_selected = get_theme_stylebox("titlebar_selected", "GraphNode").duplicate() - stylebox_selected.bg_color = val - - remove_theme_stylebox_override("titlebar") - remove_theme_stylebox_override("titlebar_selected") - add_theme_stylebox_override("titlebar", stylebox) - add_theme_stylebox_override("titlebar_selected", stylebox_selected) - - var titlebar: HBoxContainer = get_titlebar_hbox() - var title_label: Label = titlebar.get_children().filter(func(c) -> bool: return c is Label)[0] - title_label.add_theme_color_override("font_color", Color.WHITE if is_dark else Color.BLACK) - - -func add_to(graph: MonologueGraphEdit) -> Array[MonologueGraphNode]: - graph.add_child(self, true) - var all_ids := graph.get_nodes().map(func(n) -> String: return n.id.value) - id.setters["value"] = IDGen.generate(10, all_ids) - return [self] - - -## Commits a given property's value into undo/redo history. -## Order of parameters is important due to how bind() works. -func change(old_value: Variant, new_value: Variant, property: String) -> void: - var changes: Array[PropertyChange] = [] - changes.append(PropertyChange.new(property, old_value, new_value)) - - var graph = get_graph_edit() - var undo_redo = graph.undo_redo - undo_redo.create_action("%s: %s => %s" % [property, old_value, new_value]) - var history = PropertyHistory.new(graph, graph.get_path_to(self), changes) - undo_redo.add_prepared_history(history) - undo_redo.commit_action() - - -func display() -> void: - get_graph_edit().set_selected(self) - - -func get_graph_edit() -> MonologueGraphEdit: - return get_parent() - - -func get_property_names() -> PackedStringArray: - var names = PackedStringArray() - for property in get_property_list(): - if Constants.PROPERTY_CLASSES.has(property.class_name): - names.append(property.name) - return names - - -func is_editable() -> bool: - var ignorable := ["id"] - - for property in get_property_names(): - if property in ignorable: - continue - return true - return false - - -## Reload the preview text of the graph node, if any. -func reload_preview() -> void: - pass - - -func _from_dict(dict: Dictionary) -> void: - var editor_pos = dict.get("EditorPosition") - if editor_pos is Dictionary: - editor_pos = [editor_pos.get("x", 0), editor_pos.get("y", 0)] - dict["EditorPosition"] = editor_pos - - for key in dict.keys(): - var property = get(key.to_snake_case()) - if property is Property: - property.value = dict.get(key) - var private_property = get("_" + key.to_snake_case()) - if private_property is Property: - private_property.value = dict.get(key) - - _load_position(dict) - _update() # refresh node UI after loading properties - - -func _load_connections(data: Dictionary, key: String = "NextID") -> void: - var next_id = data.get(key) - if next_id is String: - var next_node = get_graph_edit().get_node_by_id(next_id) - if next_node: - get_graph_edit().connect_node(name, 0, next_node.name, 0) - - -func _load_position(data: Dictionary) -> void: - var editor_pos = data.get("EditorPosition") - if editor_pos and editor_pos is Dictionary: # Backward compatibility - position_offset.x = editor_pos.get("x", randi_range(-400, 400)) - position_offset.y = editor_pos.get("y", randi_range(-200, 200)) - elif editor_position and editor_pos is Array: - position_offset.x = editor_pos[0] - position_offset.y = editor_pos[1] - - -func _to_dict() -> Dictionary: - var base_dict = {"$type": node_type, "ID": id.value, "EditorPosition": editor_position.value} - _to_next(base_dict) - _to_fields(base_dict) - - #base_dict["EditorPosition"] = { - #"x": int(position_offset.x), - #"y": int(position_offset.y) - #} - return base_dict - - -func _to_fields(dict: Dictionary) -> void: - for property_name in get_property_names(): - var property = get(property_name) - var is_raw = property is Localizable - if property.visible: - var value = property.to_raw_value() if is_raw else property.value - dict[Util.to_key_name(property_name)] = value - - -func _to_next(dict: Dictionary, key: String = "NextID") -> void: - var next_id_node = get_graph_edit().get_all_connections_from_slot(name, 0) - dict[key] = next_id_node[0].id.value if next_id_node else -1 - - -func _update() -> void: - size.y = 0 - _harmonize_size() - - -func _validate_id(text: String) -> bool: - return get_graph_edit().get_node_by_id(text) == null - - -func _get_field_groups() -> Array: - return [] diff --git a/common/monologue_indexer.gd b/common/monologue_indexer.gd new file mode 100644 index 00000000..0d715198 --- /dev/null +++ b/common/monologue_indexer.gd @@ -0,0 +1,8 @@ +@abstract class_name MonologueIndexer + +enum ObjectType { NODE, FIELD } + +@abstract func get_scene() -> PackedScene + +# {"name": "", "type": ""} +@abstract func get_metadata() -> Dictionary diff --git a/common/monologue_indexer.gd.uid b/common/monologue_indexer.gd.uid new file mode 100644 index 00000000..40702262 --- /dev/null +++ b/common/monologue_indexer.gd.uid @@ -0,0 +1 @@ +uid://dc5qyu0n5oaqb diff --git a/common/name_generator.gd b/common/name_generator.gd new file mode 100644 index 00000000..b4e1f110 --- /dev/null +++ b/common/name_generator.gd @@ -0,0 +1,29492 @@ +class_name NameGenerator + + +static func generate() -> String: + var first_name: String = [_female_first_names, _female_first_names].pick_random().pick_random() + var last_name: String = _last_names.pick_random() + + return "%s %s" % [first_name, last_name] + + +# Taken from https://cerol.itch.io/godot-name-generator-class +const _female_first_names = [ + "Aaliyah", + "Aarti", + "Abbe", + "Abbey", + "Abbie", + "Abby", + "Abena", + "Abigail", + "Abiola", + "Ada", + "Adalgisa", + "Adanna", + "Addie", + "Addy", + "Adela", + "Adelaida", + "Adelaide", + "Adele", + "Adelina", + "Adeline", + "Adena", + "Adeola", + "Adina", + "Aditi", + "Adjoa", + "Adria", + "Adriana", + "Adriane", + "Adrianna", + "Adrianne", + "Adrienne", + "Adwoa", + "Ady", + "Afiya", + "Afton", + "Aga", + "Agata", + "Agatha", + "Agathe", + "Aggie", + "Agi", + "Agnese", + "Agnieszka", + "Ahuva", + "Ai", + "Aicha", + "Aida", + "Aiesha", + "Aiko", + "Aileen", + "Aimee", + "Aisha", + "Aisling", + "Aislinn", + "Aixa", + "Aiysha", + "Aja", + "Akane", + "Akemi", + "Aki", + "Akia", + "Akiko", + "Akilah", + "Akosua", + "Akua", + "Alaina", + "Alana", + "Alane", + "Alanna", + "Alba", + "Albana", + "Albania", + "Albee", + "Alberta", + "Albina", + "Alea", + "Alecia", + "Aleida", + "Alejandra", + "Aleksandra", + "Alena", + "Alesha", + "Alesia", + "Alessandra", + "Alessia", + "Aleta", + "Alethea", + "Alexa", + "Alexandra", + "Alexandrea", + "Alexandria", + "Alexia", + "Alexis", + "Alexus", + "Alia", + "Alice", + "Alicia", + "Alicja", + "Alida", + "Alina", + "Aline", + "Alisa", + "Alise", + "Alisha", + "Alisia", + "Alison", + "Alissa", + "Alisson", + "Aliya", + "Aliyah", + "Aliza", + "Alka", + "Alla", + "Allana", + "Allegra", + "Alley", + "Alli", + "Allie", + "Allison", + "Ally", + "Allyson", + "Alma", + "Almira", + "Alona", + "Alondra", + "Altagracia", + "Althea", + "Alva", + "Alvina", + "Alyce", + "Alycia", + "Alyona", + "Alysa", + "Alyse", + "Alysha", + "Alysia", + "Alyson", + "Alyssa", + "Ama", + "Amada", + "Amal", + "Amalia", + "Amanda", + "Amandine", + "Amani", + "Amara", + "Amarilis", + "Amaris", + "Ambar", + "Amber", + "Ambika", + "Amelia", + "Amelie", + "Amena", + "Ami", + "Amie", + "Amina", + "Aminata", + "Amira", + "Amirah", + "Amisha", + "Amita", + "Amma", + "Amna", + "Amoy", + "Amparo", + "Amrita", + "Amy", + "Ana", + "Anabel", + "Anabella", + "Anabelle", + "Anais", + "Analia", + "Anam", + "Anamaria", + "Anamika", + "Ananda", + "Anastasia", + "Anastasiya", + "Anastassia", + "Anat", + "Anaya", + "Anca", + "Anda", + "Andi", + "Andie", + "Andra", + "Andrea", + "Andree", + "Andreea", + "Andreina", + "Andrene", + "Andria", + "Andriana", + "Anel", + "Anesha", + "Aneta", + "Anette", + "Angela", + "Angelia", + "Angelic", + "Angelica", + "Angelika", + "Angeliki", + "Angelina", + "Angeline", + "Angelique", + "Angelita", + "Angella", + "Angie", + "Ani", + "Ania", + "Anika", + "Anila", + "Anisa", + "Anisah", + "Anisha", + "Anissa", + "Anita", + "Anitha", + "Anitra", + "Anja", + "Anjali", + "Anjana", + "Anjelica", + "Anju", + "Anjuli", + "Ankita", + "Ann", + "Ann-Marie", + "Anna", + "Annabel", + "Annabelle", + "Annalisa", + "Annamaria", + "Annamarie", + "Anne", + "Anne-Marie", + "Annemarie", + "Annet", + "Annette", + "Anni", + "Annia", + "Annick", + "Annie", + "Annika", + "Annmarie", + "Anny", + "Anthea", + "Antionette", + "Antoinette", + "Antonella", + "Antonette", + "Antonia", + "Antonietta", + "Antonina", + "Anu", + "Anupama", + "Anusha", + "Anushka", + "Any", + "Anya", + "Aoife", + "Aparna", + "Apple", + "April", + "Aquila", + "Arabella", + "Araceli", + "Aracelis", + "Aracely", + "Archana", + "Arelis", + "Arely", + "Aretha", + "Aria", + "Ariadna", + "Ariana", + "Ariane", + "Arianna", + "Arianne", + "Ariela", + "Ariella", + "Arielle", + "Arisa", + "Arleen", + "Arlene", + "Arlette", + "Arline", + "Arlyn", + "Arlyne", + "Artemis", + "Arti", + "Aruna", + "Arzu", + "Asako", + "Asha", + "Ashante", + "Ashanti", + "Ashima", + "Ashlee", + "Ashleigh", + "Ashley", + "Ashli", + "Ashlie", + "Ashly", + "Ashwini", + "Asia", + "Asli", + "Asma", + "Asta", + "Astrid", + "Asuka", + "Asya", + "Atheña", + "Atiya", + "Atsuko", + "Aude", + "Audra", + "Audrey", + "Audrina", + "Audry", + "Augusta", + "Augustina", + "Aundrea", + "Aura", + "Aurea", + "Aurelia", + "Aurelie", + "Aurora", + "Autumn", + "Ava", + "Avalon", + "Avani", + "Ave", + "Avigail", + "Avion", + "Avis", + "Avital", + "Aviva", + "Avril", + "Awa", + "Awilda", + "Aya", + "Ayako", + "Ayana", + "Ayanna", + "Aye", + "Ayelet", + "Ayesha", + "Ayisha", + "Ayla", + "Aylin", + "Aysha", + "Ayumi", + "Ayça", + "Ayşe", + "Aziza", + "Azra", + "Azucena", + "Babette", + "Babs", + "Bahar", + "Bambi", + "Banu", + "Bara", + "Barb", + "Barbara", + "Barbie", + "Barbra", + "Bari", + "Barri", + "Barrie", + "Basia", + "Batsheva", + "Batya", + "Bea", + "Beata", + "Beatrice", + "Beatriz", + "Beba", + "Bebe", + "Becca", + "Becka", + "Beckie", + "Becky", + "Bee", + "Beena", + "Bei", + "Beka", + "Belen", + "Belinda", + "Belkis", + "Belkys", + "Bell", + "Bella", + "Belle", + "Benedetta", + "Benita", + "Berenice", + "Bernadette", + "Bernadine", + "Bernice", + "Berry", + "Berta", + "Bertha", + "Beryl", + "Bess", + "Bessie", + "Beth", + "Bethania", + "Bethann", + "Bethanne", + "Bethany", + "Betina", + "Betsey", + "Betsy", + "Bette", + "Betti", + "Bettie", + "Bettina", + "Betty", + "Bettyann", + "Betzaida", + "Bev", + "Beverley", + "Beverly", + "Biana", + "Bianca", + "Bianka", + "Bibi", + "Bibiana", + "Billie", + "Bina", + "Bindu", + "Birgit", + "Blair", + "Blaire", + "Blanca", + "Blanche", + "Blerta", + "Blossom", + "Blythe", + "Bobbi", + "Bobbie", + "Bonita", + "Bonnie", + "Bozena", + "Bracha", + "Brandee", + "Brandi", + "Brandie", + "Brandy", + "Bre", + "Breanna", + "Breanne", + "Bree", + "Brenda", + "Brenna", + "Bri", + "Bria", + "Briana", + "Brianna", + "Brianne", + "Bridget", + "Bridgett", + "Bridgette", + "Bridie", + "Brie", + "Brigette", + "Brigid", + "Brigida", + "Brigitta", + "Brigitte", + "Brina", + "Brit", + "Britney", + "Britt", + "Britta", + "Brittani", + "Brittany", + "Brittney", + "Brittni", + "Brittny", + "Britton", + "Bronwen", + "Bronwyn", + "Brooke", + "Bruna", + "Brunilda", + "Brynn", + "Bukola", + "Bunny", + "Burcu", + "Bushra", + "Cait", + "Caitlin", + "Caitlyn", + "Calandra", + "Cali", + "Callie", + "Camara", + "Camelia", + "Cami", + "Camila", + "Camilla", + "Camille", + "Cammy", + "Candace", + "Candi", + "Candice", + "Candida", + "Candie", + "Candis", + "Candy", + "Caprice", + "Cara", + "Caren", + "Carey", + "Cari", + "Caridad", + "Carin", + "Carina", + "Carine", + "Carissa", + "Carla", + "Carleen", + "Carlene", + "Carley", + "Carli", + "Carlie", + "Carlina", + "Carline", + "Carlotta", + "Carly", + "Carlyn", + "Carmel", + "Carmela", + "Carmelina", + "Carmelita", + "Carmella", + "Carmen", + "Carmencita", + "Caro", + "Carol", + "Carola", + "Carolann", + "Carole", + "Carolee", + "Carolin", + "Carolina", + "Caroline", + "Carolyn", + "Carolyne", + "Caron", + "Carrie", + "Carrol", + "Carroll", + "Caryl", + "Caryn", + "Casandra", + "Casie", + "Cass", + "Cassandra", + "Cassandre", + "Cassidy", + "Cassie", + "Cassy", + "Cat", + "Cata", + "Catalina", + "Catarina", + "Cate", + "Caterina", + "Catharine", + "Catherine", + "Cathi", + "Cathie", + "Cathleen", + "Cathrine", + "Cathryn", + "Cathy", + "Catia", + "Catie", + "Catrice", + "Catrina", + "Catriona", + "Caty", + "Cece", + "Cecelia", + "Ceci", + "Cecilia", + "Cecily", + "Celena", + "Celeste", + "Celestina", + "Celestine", + "Celia", + "Celina", + "Celine", + "Cerissa", + "Cha", + "Chana", + "Chanda", + "Chandra", + "Chanel", + "Chanell", + "Chanelle", + "Chani", + "Chanice", + "Chanie", + "Channel", + "Channing", + "Chantal", + "Chantay", + "Chante", + "Chantee", + "Chantel", + "Chantell", + "Chantelle", + "Char", + "Charis", + "Charise", + "Charisma", + "Charissa", + "Charisse", + "Charity", + "Charleen", + "Charlene", + "Charline", + "Charlotte", + "Charlyn", + "Charmaine", + "Charo", + "Charu", + "Chasity", + "Chastity", + "Chava", + "Chavi", + "Chaya", + "Chelle", + "Chelsea", + "Chelsey", + "Chelsie", + "Cher", + "Cherelle", + "Cheri", + "Cherie", + "Cherise", + "Cherish", + "Cherisse", + "Cherrie", + "Cherry", + "Cherryann", + "Cherryl", + "Cheryl", + "Cherylann", + "Chevonne", + "Cheyenne", + "Chi-Chi", + "Chiaki", + "Chiara", + "Chichi", + "Chickie", + "Chika", + "China", + "Chinyere", + "Chioma", + "Chitra", + "Chloe", + "Chrissie", + "Chrissy", + "Christa", + "Christabel", + "Christal", + "Christel", + "Christelle", + "Christen", + "Christi", + "Christiana", + "Christiane", + "Christianna", + "Christie", + "Christin", + "Christina", + "Christine", + "Christy", + "Chrystal", + "Chrystie", + "Chyna", + "Ciara", + "Cicely", + "Cici", + "Cielo", + "Ciera", + "Cierra", + "Cindi", + "Cindy", + "Cinnamon", + "Cinthia", + "Cinthya", + "Cintia", + "Cinzia", + "Clair", + "Claire", + "Clara", + "Clare", + "Claribel", + "Clarice", + "Clarisa", + "Clarissa", + "Clarisse", + "Claudette", + "Claudia", + "Claudina", + "Claudine", + "Cleo", + "Cleopatra", + "Clover", + "Coco", + "Cocoa", + "Coleen", + "Colette", + "Colleen", + "Collette", + "Concetta", + "Connie", + "Constance", + "Consuelo", + "Cora", + "Coral", + "Cordelia", + "Coreen", + "Coretta", + "Cori", + "Corie", + "Corina", + "Corine", + "Corinna", + "Corinne", + "Corinthia", + "Cornelia", + "Corrie", + "Corrine", + "Cortney", + "Courtenay", + "Courteney", + "Courtney", + "Cricket", + "Crissy", + "Crista", + "Cristal", + "Cristen", + "Cristiana", + "Cristin", + "Cristina", + "Cristine", + "Cristy", + "Crystal", + "Cui", + "Cyn", + "Cyndi", + "Cynthia", + "Cécile", + "Dacia", + "Dagmar", + "Dagmara", + "Dahiana", + "Dahlia", + "Daiana", + "Daina", + "Daisy", + "Dali", + "Dalia", + "Dalila", + "Damali", + "Damaris", + "Damla", + "Dana", + "Danae", + "Danelle", + "Danessa", + "Danette", + "Dani", + "Dania", + "Danica", + "Daniela", + "Daniella", + "Danielle", + "Danika", + "Danisha", + "Danit", + "Danita", + "Danna", + "Danni", + "Dannie", + "Dannielle", + "Danuta", + "Danya", + "Danyelle", + "Daphne", + "Daphnee", + "Daphney", + "Dara", + "Darcel", + "Darci", + "Darcy", + "Daria", + "Darla", + "Darleen", + "Darlene", + "Darline", + "Darling", + "Darya", + "Dasha", + "Davida", + "Davina", + "Dawn", + "Dawne", + "Dawnmarie", + "Dayana", + "Dayna", + "Daysi", + "Dea", + "Deana", + "Deandra", + "Deanna", + "Deanne", + "Deb", + "Debbi", + "Debbie", + "Debby", + "Debi", + "Debora", + "Deborah", + "Debra", + "Dede", + "Dedra", + "Deedee", + "Deena", + "Deepa", + "Deepali", + "Deepika", + "Deepthi", + "Deepti", + "Deidra", + "Deidre", + "Deirdra", + "Deirdre", + "Deisy", + "Deja", + "Delia", + "Delilah", + "Della", + "Delma", + "Delores", + "Deloris", + "Delphine", + "Demetra", + "Demetria", + "Demi", + "Dena", + "Deneen", + "Denice", + "Denise", + "Denisha", + "Denisse", + "Dennise", + "Denyse", + "Derin", + "Derya", + "Des", + "Deserie", + "Desirae", + "Desire", + "Desiree", + "Despina", + "Destiny", + "Deva", + "Devan", + "Devi", + "Devika", + "Devina", + "Devona", + "Devora", + "Devorah", + "Devra", + "Devyn", + "Deyanira", + "Dhara", + "Dia", + "Diamond", + "Dian", + "Diandra", + "Diane", + "Diann", + "Dianna", + "Dianne", + "Didi", + "Diedre", + "Digna", + "Dikla", + "Dilcia", + "Dimitra", + "Dimple", + "Dina", + "Dinah", + "Dinara", + "Dini", + "Dinorah", + "Diona", + "Dione", + "Dionne", + "Dior", + "Divina", + "Divya", + "Dixie", + "Dolly", + "Dolores", + "Domenica", + "Dominika", + "Dominique", + "Domonique", + "Dona", + "Donatella", + "Donette", + "Donielle", + "Donna", + "Donnamarie", + "Donnette", + "Dora", + "Dorcas", + "Doreen", + "Dorene", + "Dori", + "Dorie", + "Dorina", + "Doris", + "Dorit", + "Dorota", + "Dorothea", + "Dorothee", + "Dorothy", + "Dory", + "Dot", + "Dottie", + "Dotty", + "Dragana", + "Drea", + "Drita", + "Dulce", + "Dyan", + "Dyana", + "Eartha", + "Eboni", + "Ebonie", + "Ebony", + "Ebru", + "Ece", + "Eda", + "Eden", + "Edie", + "Edina", + "Edita", + "Edith", + "Edna", + "Edwina", + "Edyta", + "Effie", + "Efrat", + "Eileen", + "Ekaterina", + "Ekta", + "Ela", + "Elaina", + "Elaine", + "Elana", + "Elayne", + "Elba", + "Elda", + "Eleana", + "Eleanor", + "Elektra", + "Elen", + "Elena", + "Eleni", + "Eleonor", + "Eleonora", + "Eliana", + "Elicia", + "Elida", + "Elif", + "Elin", + "Elina", + "Elinor", + "Elisa", + "Elisabeth", + "Elisabetta", + "Elise", + "Elisha", + "Elisheva", + "Elissa", + "Eliza", + "Elizabeth", + "Elka", + "Elke", + "Ella", + "Elle", + "Ellen", + "Elli", + "Ellie", + "Elly", + "Ellyn", + "Elma", + "Elodie", + "Eloisa", + "Eloise", + "Elona", + "Elsa", + "Elsie", + "Elsy", + "Elva", + "Elvia", + "Elvira", + "Elyse", + "Elyssa", + "Elzbieta", + "Em", + "Ema", + "Eman", + "Emanuela", + "Emel", + "Emelia", + "Emely", + "Emerald", + "Emi", + "Emiko", + "Emilee", + "Emilia", + "Emilie", + "Emily", + "Emma", + "Emmanuella", + "Emmanuelle", + "Emmie", + "Emmy", + "Emy", + "Ena", + "Eneida", + "Enid", + "Enjoli", + "Enny", + "Enza", + "Era", + "Eri", + "Erica", + "Ericka", + "Erika", + "Eriko", + "Erin", + "Erina", + "Erinn", + "Erlinda", + "Erna", + "Ernestina", + "Ernestine", + "Eryka", + "Eryn", + "Esha", + "Esin", + "Esmeralda", + "Esperanza", + "Esra", + "Essence", + "Essie", + "Esta", + "Estee", + "Estefania", + "Estefany", + "Estela", + "Estella", + "Estelle", + "Ester", + "Esther", + "Esti", + "Estrella", + "Esty", + "Ethel", + "Eti", + "Etta", + "Eugenia", + "Eugenie", + "Eun", + "Eunhye", + "Eunice", + "Eunsun", + "Eva", + "Evana", + "Evangelia", + "Evangeline", + "Eve", + "Evelin", + "Evelina", + "Eveline", + "Evelyn", + "Evette", + "Evgenia", + "Evgeniya", + "Evi", + "Evie", + "Evita", + "Evon", + "Evonne", + "Evy", + "Ewa", + "Ewelina", + "Fabiana", + "Fabienne", + "Fabiola", + "Faigy", + "Faina", + "Faith", + "Fallon", + "Fancy", + "Fang", + "Fannie", + "Fanny", + "Fanta", + "Fara", + "Farah", + "Farhana", + "Farida", + "Farrah", + "Farzana", + "Fatema", + "Fatima", + "Fatimah", + "Fatou", + "Fatoumata", + "Fawn", + "Fay", + "Faye", + "Faïza", + "Fe", + "Federica", + "Felecia", + "Felice", + "Felicia", + "Felicita", + "Felicity", + "Felisa", + "Felise", + "Felisha", + "Fern", + "Fernanda", + "Fia", + "Fidelia", + "Fifi", + "Filiz", + "Filomena", + "Fiona", + "Fior", + "Fiordaliza", + "Fiorella", + "Flavia", + "Flawless", + "Fleur", + "Flo", + "Flor", + "Flora", + "Florence", + "Florencia", + "Florina", + "Fluffy", + "Fran", + "Franca", + "France", + "Frances", + "Francesca", + "Franchesca", + "Francheska", + "Francia", + "Francine", + "Francisca", + "Francoise", + "Francy", + "Frannie", + "Franny", + "Franziska", + "Freda", + "Fredda", + "Frederica", + "Freya", + "Frida", + "Frieda", + "Fumiko", + "Funmi", + "Gabby", + "Gabi", + "Gabriela", + "Gabriella", + "Gabrielle", + "Gaby", + "Gaelle", + "Gaia", + "Gail", + "Gale", + "Galia", + "Galina", + "Galit", + "Gamze", + "Gay", + "Gaye", + "Gayle", + "Geeta", + "Geisha", + "Gemma", + "Gena", + "Genesis", + "Geneva", + "Genevieve", + "Genia", + "Genie", + "Genine", + "Genise", + "Genna", + "Genny", + "Georgette", + "Georgia", + "Georgiana", + "Georgianna", + "Georgina", + "Geraldine", + "Geralyn", + "Geri", + "Germaine", + "Gerri", + "Gertrude", + "Ghislaine", + "Gi", + "Gia", + "Giana", + "Gianna", + "Gidget", + "Gigi", + "Gila", + "Gilda", + "Gillian", + "Gina", + "Ginamarie", + "Ginette", + "Ginger", + "Gini", + "Ginna", + "Ginny", + "Giorgia", + "Giovana", + "Giovanna", + "Gisela", + "Gisele", + "Gisella", + "Giselle", + "Gissel", + "Gissell", + "Gisselle", + "Gita", + "Gitty", + "Giulia", + "Giuliana", + "Giuseppina", + "Gizem", + "Gladys", + "Glenda", + "Glenna", + "Glenny", + "Gleny", + "Glenys", + "Gloria", + "Glory", + "Glynis", + "Golda", + "Goldie", + "Gordana", + "Gosia", + "Gozde", + "Grace", + "Graceanne", + "Gracie", + "Graciela", + "Graziella", + "Greer", + "Greta", + "Gretchen", + "Gricel", + "Grisel", + "Griselda", + "Guadalupe", + "Guerda", + "Gwen", + "Gwendolyn", + "Gwenn", + "Gwyneth", + "Ha", + "Habiba", + "Hadas", + "Hadassah", + "Hadley", + "Hailey", + "Hala", + "Haley", + "Halima", + "Halina", + "Halley", + "Hallie", + "Hana", + "Hanan", + "Hanna", + "Hannah", + "Hanny", + "Harmony", + "Harriet", + "Haruka", + "Hatice", + "Hattie", + "Haydee", + "Hayley", + "Hazel", + "Heather", + "Heba", + "Hedy", + "Heejin", + "Heide", + "Heidi", + "Heidy", + "Heike", + "Helaine", + "Helen", + "Helena", + "Helga", + "Hellen", + "Heloise", + "Hema", + "Henna", + "Henny", + "Henrietta", + "Hester", + "Hila", + "Hilary", + "Hilda", + "Hildy", + "Hillary", + "Hina", + "Hindy", + "Hira", + "Hiroko", + "Hiromi", + "Hitomi", + "Hollie", + "Holly", + "Honey", + "Honor", + "Hope", + "Hortensia", + "Hui", + "Hulya", + "Huma", + "Hyacinth", + "Hye", + "Hyunjoo", + "Hélène", + "Ida", + "Idalia", + "Iesha", + "Ife", + "Ifeoma", + "Ijeoma", + "Ilana", + "Ilaria", + "Ildiko", + "Ileana", + "Ilene", + "Iliana", + "Ilka", + "Ilona", + "Ilse", + "Ilyssa", + "Ima", + "Iman", + "Imani", + "Imelda", + "Imogen", + "Ina", + "Inbal", + "Indi", + "India", + "Indiana", + "Indira", + "Indra", + "Inessa", + "Inez", + "Inga", + "Inge", + "Inger", + "Ingrid", + "Inna", + "Inés", + "Ioana", + "Ioanna", + "Iona", + "Iraida", + "Irena", + "Irene", + "Irina", + "Iris", + "Irma", + "Iryna", + "Isabel", + "Isabela", + "Isabella", + "Isabelle", + "Isadora", + "Isamar", + "Isaura", + "Isela", + "Isha", + "Isis", + "Israt", + "Ita", + "Iva", + "Ivana", + "Ivanna", + "Ive", + "Ivelisse", + "Iveta", + "Ivette", + "Ivie", + "Ivon", + "Ivona", + "Ivonne", + "Ivory", + "Ivy", + "Iwona", + "Izabela", + "Izabella", + "Izumi", + "Jaci", + "Jacinda", + "Jacinta", + "Jacinth", + "Jackee", + "Jackeline", + "Jacki", + "Jackie", + "Jacklyn", + "Jaclyn", + "Jacque", + "Jacquelin", + "Jacqueline", + "Jacquelyn", + "Jacqui", + "Jacquie", + "Jacy", + "Jada", + "Jade", + "Jael", + "Jahaira", + "Jaimee", + "Jaimie", + "Jaleesa", + "Jalisa", + "Jalissa", + "Jameela", + "Jamela", + "Jamelia", + "Jamella", + "Jami", + "Jamie", + "Jamila", + "Jamilah", + "Jamillah", + "Jana", + "Janae", + "Janay", + "Jane", + "Janee", + "Janeen", + "Janel", + "Janell", + "Janelle", + "Janessa", + "Janet", + "Janeth", + "Janett", + "Janette", + "Janey", + "Janice", + "Janie", + "Janiece", + "Janina", + "Janine", + "Janis", + "Janise", + "Janna", + "Jannelle", + "Jannet", + "Jannette", + "Jannie", + "Jannine", + "Janny", + "January", + "Jany", + "Jaqueline", + "Jasleen", + "Jasmin", + "Jasmina", + "Jasmine", + "Jasmyn", + "Jaya", + "Jaye", + "Jayme", + "Jaymee", + "Jaymie", + "Jayne", + "Jazmin", + "Jazmine", + "Jeana", + "Jeanelle", + "Jeanette", + "Jeanie", + "Jeanine", + "Jeanmarie", + "Jeanna", + "Jeanne", + "Jeannette", + "Jeannie", + "Jeannine", + "Jee", + "Jeimy", + "Jelena", + "Jemima", + "Jemma", + "Jen", + "Jena", + "Jenee", + "Jenel", + "Jenelle", + "Jeni", + "Jenice", + "Jenifer", + "Jeniffer", + "Jenine", + "Jenise", + "Jenn", + "Jenna", + "Jennefer", + "Jennette", + "Jenni", + "Jennie", + "Jennifer", + "Jenniffer", + "Jennine", + "Jenny", + "Jennyfer", + "Jenya", + "Jeri", + "Jerilyn", + "Jerri", + "Jes", + "Jesenia", + "Jesica", + "Jess", + "Jessa", + "Jessenia", + "Jessi", + "Jessica", + "Jessie", + "Jessika", + "Jessy", + "Jessyca", + "Jewel", + "Jewell", + "Jewels", + "Jieun", + "Jihae", + "Jihan", + "Jihee", + "Jihye", + "Jihyun", + "Jill", + "Jillian", + "Jilly", + "Jina", + "Jinelle", + "Jing", + "Jingjing", + "Jinna", + "Jinnie", + "Jinny", + "Jiwon", + "Jiyeon", + "Jiyoung", + "Jo", + "Jo-Ann", + "Joan", + "Joana", + "Joane", + "Joanie", + "Joann", + "Joanna", + "Joanne", + "Joannie", + "Joanny", + "Jocelyn", + "Jocelyne", + "Jodee", + "Jodi", + "Jodi-Ann", + "Jodian", + "Jodie", + "Jody", + "Joelle", + "Joellen", + "Johana", + "Johanne", + "Johanny", + "Johnna", + "Joi", + "Joie", + "Jola", + "Jolanda", + "Jolanta", + "Joleen", + "Jolene", + "Jolie", + "Joline", + "Jonelle", + "Joni", + "Jonna", + "Joo", + "Jordana", + "Jordyn", + "Josefa", + "Josefina", + "Josefine", + "Joselin", + "Joselyn", + "Josephine", + "Josette", + "Josie", + "Joslyn", + "Josy", + "Jovanna", + "Jovita", + "Joy", + "Joyce", + "Joycelyn", + "Juana", + "Juanita", + "Judi", + "Judie", + "Judit", + "Judith", + "Judy", + "Juju", + "Julene", + "Juli", + "Juliana", + "Juliane", + "Juliann", + "Julianna", + "Julianne", + "Julie", + "Julieann", + "Juliet", + "Julieta", + "Juliette", + "Julisa", + "Julissa", + "Juliya", + "July", + "June", + "Junko", + "Justina", + "Justine", + "Justyna", + "Jyoti", + "Jóhanna", + "Júlia", + "Kacey", + "Kaci", + "Kacie", + "Kadian", + "Kady", + "Kae", + "Kafi", + "Kaila", + "Kaisha", + "Kait", + "Kaitlin", + "Kaitlyn", + "Kaitlynn", + "Kaity", + "Kali", + "Kalimah", + "Kalina", + "Kalisha", + "Kally", + "Kalpana", + "Kamala", + "Kamaria", + "Kami", + "Kamika", + "Kamila", + "Kamilah", + "Kamilla", + "Kamille", + "Kamini", + "Kamisha", + "Kana", + "Kanako", + "Kandi", + "Kandice", + "Kandis", + "Kanika", + "Kaori", + "Kara", + "Kareen", + "Karem", + "Karen", + "Karena", + "Karima", + "Karimah", + "Karin", + "Karina", + "Karine", + "Karisa", + "Karishma", + "Karissa", + "Karla", + "Karlene", + "Karli", + "Karmen", + "Karolina", + "Karoline", + "Karolyn", + "Karren", + "Karrie", + "Kary", + "Karyn", + "Kasandra", + "Kasey", + "Kasia", + "Kassandra", + "Kassie", + "Kat", + "Katalin", + "Katalina", + "Katarina", + "Katarzyna", + "Kate", + "Katelyn", + "Katerina", + "Katey", + "Katharina", + "Katharine", + "Katherin", + "Katherina", + "Katherine", + "Katheryn", + "Kathi", + "Kathia", + "Kathie", + "Kathleen", + "Kathrin", + "Kathrine", + "Kathryn", + "Kathy", + "Kathyann", + "Kati", + "Katia", + "Katiana", + "Katie", + "Katina", + "Katiria", + "Katja", + "Katlyn", + "Katrice", + "Katrin", + "Katrina", + "Katty", + "Katy", + "Katya", + "Kavita", + "Kay", + "Kaya", + "Kayan", + "Kaydian", + "Kaye", + "Kayla", + "Kaylee", + "Kayleigh", + "Kaylie", + "Kaylin", + "Kayo", + "Kayon", + "Keara", + "Kecia", + "Keely", + "Keesha", + "Keiko", + "Keila", + "Keira", + "Keisha", + "Keke", + "Keli", + "Kellee", + "Kelley", + "Kelli", + "Kellie", + "Kelly", + "Kelly-Ann", + "Kellyann", + "Kelsey", + "Kemba", + "Kemi", + "Kendra", + "Kenia", + "Kenisha", + "Kenya", + "Kenyetta", + "Kera", + "Keren", + "Keri", + "Keriann", + "Kerin", + "Kerisha", + "Kerri", + "Kerri-Ann", + "Kerrie", + "Kerrin", + "Kerry", + "Kerry-Ann", + "Kerryann", + "Kerstin", + "Kesha", + "Keshia", + "Ketsia", + "Ketty", + "Keturah", + "Keya", + "Keyanna", + "Keyla", + "Keyonna", + "Keysha", + "Kezia", + "Khadija", + "Khadijah", + "Khadine", + "Khalia", + "Khalilah", + "Kia", + "Kiana", + "Kiara", + "Kiera", + "Kierra", + "Kiesha", + "Kika", + "Kiki", + "Kiley", + "Kim", + "Kima", + "Kimara", + "Kimberlee", + "Kimberley", + "Kimberly", + "Kimesha", + "Kimmie", + "Kimmy", + "Kinga", + "Kira", + "Kiri", + "Kirsten", + "Kirstin", + "Kirsty", + "Kisha", + "Kitty", + "Kiya", + "Kizzy", + "Klara", + "Klaudia", + "Koko", + "Komal", + "Kori", + "Korin", + "Kortney", + "Kourtney", + "Krissie", + "Krissy", + "Krista", + "Kristal", + "Kristan", + "Kristel", + "Kristen", + "Kristi", + "Kristie", + "Kristin", + "Kristina", + "Kristine", + "Kristy", + "Kristyn", + "Krisztina", + "Krupa", + "Krysta", + "Krystal", + "Krystel", + "Krysten", + "Krystin", + "Krystina", + "Krystle", + "Krystyna", + "Ksenia", + "Kseniya", + "Kumiko", + "Kyla", + "Kylie", + "Kym", + "Kyoko", + "Kyra", + "Kári", + "La", + "Lacey", + "Lacy", + "Ladii", + "Ladonna", + "Lady", + "Laetitia", + "Laila", + "Laine", + "Lainie", + "Lakeisha", + "Lakesha", + "Lakeya", + "Lakia", + "Lakiesha", + "Lakisha", + "Lakshmi", + "Lala", + "Lale", + "Lali", + "Lalita", + "Lama", + "Lamia", + "Lan", + "Lana", + "Lani", + "Laquana", + "Laquanda", + "Lara", + "Laraine", + "Larisa", + "Larissa", + "Lariza", + "Larysa", + "Lashana", + "Lashanda", + "Lashanna", + "Lashaun", + "Lashawn", + "Lashawna", + "Lashon", + "Lashonda", + "Latanya", + "Latasha", + "Lateefah", + "Lateisha", + "Latesha", + "Latia", + "Laticia", + "Latifa", + "Latifah", + "Latisha", + "Latonia", + "Latonya", + "Latosha", + "Latoya", + "Latrice", + "Latricia", + "Laura", + "Lauralee", + "Laure", + "Laureen", + "Laurel", + "Lauren", + "Lauretta", + "Laurette", + "Lauri", + "Laurice", + "Laurie", + "Laury", + "Lauryn", + "Lavern", + "Laverne", + "Lavinia", + "Lavonne", + "Lawanda", + "Layla", + "Lea", + "Leah", + "Leandra", + "Leann", + "Leanna", + "Leanne", + "Leda", + "Leeann", + "Leeanne", + "Leela", + "Leena", + "Leesa", + "Leia", + "Leidy", + "Leigh", + "Leigha", + "Leighann", + "Leighanne", + "Leila", + "Leilani", + "Leisa", + "Lela", + "Lelia", + "Lena", + "Lenette", + "Leni", + "Lenka", + "Lenora", + "Lenore", + "Leona", + "Leonela", + "Leonie", + "Leonor", + "Leonora", + "Leora", + "Lesa", + "Lesia", + "Lesley", + "Leslie", + "Leslye", + "Leslyn", + "Leta", + "Leticia", + "Letisha", + "Letitia", + "Letizia", + "Letty", + "Lexi", + "Lexie", + "Lexy", + "Leydi", + "Leydy", + "Leyla", + "Leyna", + "Lia", + "Liana", + "Liane", + "Lianna", + "Lianne", + "Liat", + "Libby", + "Liberty", + "Libia", + "Lida", + "Lidia", + "Ligia", + "Lila", + "Lilach", + "Lili", + "Lilia", + "Lilian", + "Liliana", + "Liliane", + "Lilibeth", + "Lilith", + "Liliya", + "Lilla", + "Lilli", + "Lilliam", + "Lillian", + "Lilliana", + "Lillie", + "Lilly", + "Lily", + "Limor", + "Lina", + "Linda", + "Lindsay", + "Lindsey", + "Lindy", + "Linette", + "Ling", + "Linh", + "Linn", + "Linnea", + "Linnette", + "Lis", + "Lisa", + "Lisa-Marie", + "Lisamarie", + "Lisandra", + "Lisbeth", + "Lise", + "Lisette", + "Lisha", + "Lisi", + "Lissa", + "Lissett", + "Lissette", + "Lissy", + "Lita", + "Lital", + "Liv", + "Livia", + "Liya", + "Liz", + "Liza", + "Lizabeth", + "Lizbeth", + "Lizeth", + "Lizette", + "Lizz", + "Lizzette", + "Lizzie", + "Lizzy", + "Loida", + "Lois", + "Lola", + "Lolita", + "Loni", + "Lopez", + "Lora", + "Loraine", + "Lore", + "Loredana", + "Loreen", + "Lorelei", + "Loren", + "Lorena", + "Loreta", + "Loretta", + "Lori", + "Loriann", + "Lorie", + "Lorine", + "Lorna", + "Lorraine", + "Lorri", + "Lorrie", + "Lory", + "Lotus", + "Louann", + "Louella", + "Louisa", + "Louise", + "Lourdes", + "Lovely", + "Loyda", + "Luana", + "Luann", + "Luanne", + "Luba", + "Lucero", + "Luci", + "Lucia", + "Luciana", + "Lucie", + "Lucienne", + "Lucila", + "Lucille", + "Lucinda", + "Lucrecia", + "Lucretia", + "Lucy", + "Luda", + "Ludmila", + "Luisa", + "Luiza", + "Lula", + "Lulu", + "Luna", + "Lupita", + "Luz", + "Lydia", + "Lyn", + "Lynda", + "Lyndsay", + "Lyndsey", + "Lynette", + "Lynn", + "Lynne", + "Lynnette", + "Lynsey", + "Lysa", + "Lysette", + "Lyssa", + "Lystra", + "Lyubov", + "Lyudmila", + "Maame", + "Maayan", + "Mabel", + "Macarena", + "Mackenzie", + "Macy", + "Maddalena", + "Maddie", + "Maddy", + "Madelaine", + "Madeleine", + "Madelin", + "Madeline", + "Madelyn", + "Madhavi", + "Madi", + "Madina", + "Madison", + "Madonna", + "Mae", + "Maegan", + "Maeve", + "Magali", + "Magalie", + "Magaly", + "Magda", + "Magdalena", + "Magen", + "Maggi", + "Maggie", + "Maggy", + "Magnolia", + "Maha", + "Mahalia", + "Mahogany", + "Mai", + "Maia", + "Maida", + "Maiko", + "Maira", + "Mairead", + "Maisha", + "Maite", + "Maja", + "Makeba", + "Makeda", + "Maki", + "Makiko", + "Mala", + "Malaika", + "Malene", + "Malgorzata", + "Mali", + "Malia", + "Malika", + "Malin", + "Malina", + "Malinda", + "Malini", + "Malissa", + "Malka", + "Malkie", + "Malky", + "Mallory", + "Malorie", + "Malou", + "Malu", + "Malvina", + "Mami", + "Mamie", + "Mamta", + "Manal", + "Manda", + "Mandi", + "Mandie", + "Mandisa", + "Mandy", + "Manisha", + "Manju", + "Manon", + "Mansi", + "Manuela", + "Mara", + "Maralyn", + "Marcela", + "Marcelina", + "Marcella", + "Marcelle", + "Marci", + "Marcia", + "Marcie", + "Marcy", + "Maren", + "Margaret", + "Margarita", + "Margaux", + "Marge", + "Margery", + "Margherita", + "Margi", + "Margie", + "Margit", + "Margo", + "Margot", + "Margrét", + "Marguerite", + "Mari", + "Maria", + "Mariaelena", + "Mariah", + "Mariam", + "Mariama", + "Marian", + "Mariana", + "Marianela", + "Marianella", + "Mariangela", + "Mariann", + "Marianna", + "Marianne", + "Maribel", + "Maribeth", + "Maricel", + "Maricela", + "Marie", + "Mariel", + "Mariela", + "Mariella", + "Marielle", + "Mariely", + "Marietta", + "Marija", + "Marika", + "Mariko", + "Marilee", + "Marilena", + "Marilou", + "Marilu", + "Mariluz", + "Marilyn", + "Marilynn", + "Marina", + "Marinela", + "Mariné", + "Mariola", + "Marion", + "Maris", + "Marisa", + "Marisel", + "Marisela", + "Marisol", + "Marissa", + "Marita", + "Maritza", + "Mariuxi", + "Marivel", + "Marivic", + "Mariya", + "Marjan", + "Marjorie", + "Marjory", + "Marketa", + "Marla", + "Marleen", + "Marlena", + "Marlene", + "Marleny", + "Marlin", + "Marline", + "Marlo", + "Marly", + "Marlyn", + "Marni", + "Marnie", + "Marquita", + "Marsha", + "Marta", + "Martha", + "Marti", + "Martina", + "Martine", + "Martyna", + "Maru", + "Marva", + "Marwa", + "Mary", + "Mary-Jane", + "Marya", + "Maryam", + "Maryana", + "Maryann", + "Maryanne", + "Marybeth", + "Maryellen", + "Maryjane", + "Marylin", + "Marylou", + "Marylu", + "Maryrose", + "Maryse", + "Marzena", + "Masako", + "Masha", + "Massiel", + "Mathilde", + "Matilda", + "Matilde", + "Mattie", + "Maud", + "Maude", + "Maura", + "Maureen", + "Mavis", + "Maxie", + "Maxine", + "May", + "Maya", + "Maylin", + "Mayra", + "Maytal", + "Mayu", + "Mayuko", + "Mayumi", + "Mazal", + "Mckenzie", + "Meagan", + "Meaghan", + "Mecca", + "Medina", + "Meeka", + "Meena", + "Meera", + "Meg", + "Megan", + "Megha", + "Meghan", + "Meghann", + "Meghna", + "Megumi", + "Mehreen", + "Mei", + "Meiling", + "Meira", + "Meisha", + "Meital", + "Meka", + "Mela", + "Melaine", + "Melani", + "Melania", + "Melanie", + "Melany", + "Melba", + "Meli", + "Melida", + "Melina", + "Melinda", + "Melis", + "Melisa", + "Melissa", + "Mellisa", + "Mellissa", + "Melly", + "Melodie", + "Melody", + "Melonie", + "Melony", + "Meltem", + "Melva", + "Mely", + "Melyssa", + "Meme", + "Merav", + "Mercedes", + "Mercy", + "Meredith", + "Meri", + "Merideth", + "Meridith", + "Merle", + "Merlene", + "Merlyn", + "Merri", + "Merrie", + "Merry", + "Merryl", + "Merve", + "Mery", + "Meryl", + "Mesha", + "Mi", + "Mia", + "Miao", + "Mica", + "Micaela", + "Mich", + "Michaela", + "Michaelle", + "Michela", + "Michele", + "Michelina", + "Micheline", + "Michell", + "Michelle", + "Michi", + "Michiko", + "Micki", + "Mickie", + "Midge", + "Midori", + "Migdalia", + "Miguelina", + "Mihaela", + "Miho", + "Miisz", + "Mika", + "Mikaela", + "Mikki", + "Mila", + "Milagros", + "Milana", + "Mildred", + "Milena", + "Miley", + "Mili", + "Milica", + "Milli", + "Millicent", + "Millie", + "Milly", + "Mima", + "Mimi", + "Mimoza", + "Mina", + "Minal", + "Mindi", + "Mindy", + "Minerva", + "Mini", + "Minji", + "Minjung", + "Minna", + "Minnie", + "Minyoung", + "Mio", + "Miosotis", + "Mira", + "Miracle", + "Miranda", + "Mireille", + "Mirela", + "Mirella", + "Mireya", + "Miri", + "Miriam", + "Mirian", + "Mirjana", + "Mirna", + "Mirta", + "Mirtha", + "Miryam", + "Misa", + "Mischa", + "Miss", + "Missy", + "Misty", + "Mita", + "Mitra", + "Mitzi", + "Mitzie", + "Miya", + "Miyuki", + "Miz", + "Mocha", + "Moira", + "Mollie", + "Molly", + "Mona", + "Monae", + "Monalisa", + "Monet", + "Moni", + "Monie", + "Monifa", + "Monika", + "Monique", + "Monisha", + "Moon", + "Moran", + "Morgen", + "Moriah", + "Moya", + "Muna", + "Muriel", + "Murielle", + "Mya", + "Myisha", + "Myla", + "Mylene", + "Myra", + "Myriam", + "Myrlene", + "Myrna", + "Myrtle", + "Má", + "Mónica", + "Na", + "Naa", + "Naama", + "Nabila", + "Nada", + "Nadeen", + "Nadege", + "Nadia", + "Nadine", + "Nadira", + "Nadiyah", + "Nadja", + "Nadya", + "Naeemah", + "Nahid", + "Naida", + "Naila", + "Nailah", + "Naima", + "Naimah", + "Naisha", + "Naja", + "Najah", + "Najla", + "Nakia", + "Nakisha", + "Nala", + "Nalini", + "Nami", + "Namrata", + "Nan", + "Nanci", + "Nancie", + "Nancy", + "Nandi", + "Nandini", + "Nandita", + "Nanette", + "Nani", + "Nannette", + "Nao", + "Naoko", + "Naomi", + "Naomy", + "Narcisa", + "Narda", + "Narissa", + "Naseem", + "Nasha", + "Nasrin", + "Nastassia", + "Natacha", + "Natalee", + "Natali", + "Natalia", + "Natalie", + "Nataliya", + "Nataly", + "Natalya", + "Natasa", + "Natascha", + "Natasha", + "Natasia", + "Nathalia", + "Nathalie", + "Nathaly", + "Natia", + "Natisha", + "Natividad", + "Natoya", + "Naudia", + "Nava", + "Navi", + "Nay", + "Nayda", + "Naz", + "Nazia", + "Ndeye", + "Nechama", + "Neda", + "Neelam", + "Neena", + "Neeta", + "Neetu", + "Nef", + "Nefertiti", + "Neha", + "Neisha", + "Nekeisha", + "Nekia", + "Nelida", + "Nell", + "Nella", + "Nelle", + "Nellie", + "Nelly", + "Nelsi", + "Nelsy", + "Nena", + "Nereida", + "Nerissa", + "Nery", + "Nesha", + "Nessa", + "Neta", + "Netta", + "Nettie", + "Neva", + "Ngoc", + "Ngozi", + "Nia", + "Niamh", + "Niasia", + "Nicci", + "Niccole", + "Nichelle", + "Nichol", + "Nichola", + "Nichole", + "Nickesha", + "Nickey", + "Nicki", + "Nickie", + "Nicol", + "Nicole", + "Nicoletta", + "Nicolette", + "Nicolina", + "Nicolle", + "Nida", + "Nidhi", + "Nidia", + "Niecy", + "Niesha", + "Nieves", + "Nijah", + "Nika", + "Nikesha", + "Niki", + "Nikia", + "Nikisha", + "Nikki", + "Nikkia", + "Nikol", + "Nikole", + "Nila", + "Nilda", + "Nili", + "Nilka", + "Nilsa", + "Nina", + "Ninfa", + "Nini", + "Ninoska", + "Nira", + "Nirmala", + "Nisa", + "Nisha", + "Nita", + "Nitza", + "Niurka", + "Niya", + "Nneka", + "Noa", + "Noelia", + "Noelle", + "Noemi", + "Nola", + "Nomi", + "Nona", + "Noni", + "Nonna", + "Nora", + "Norah", + "Nordia", + "Noreen", + "Nori", + "Noriko", + "Norka", + "Norma", + "Noura", + "Novella", + "Nuala", + "Nubia", + "Nur", + "Nuria", + "Nurit", + "Nury", + "Nusrat", + "Nya", + "Nyasha", + "Nyasia", + "Nydia", + "Nyesha", + "Nyisha", + "Nykia", + "Nyla", + "Nyoka", + "Nyree", + "Oana", + "Octavia", + "Odalis", + "Odalys", + "Odessa", + "Odetta", + "Odette", + "Ofelia", + "Oksana", + "Ola", + "Olena", + "Olesya", + "Olga", + "Olimpia", + "Olive", + "Olya", + "Olympia", + "Oma", + "Omaira", + "Omayra", + "Omi", + "Omolara", + "Oneida", + "Onica", + "Onika", + "Opal", + "Ophelia", + "Ora", + "Oriana", + "Orit", + "Orla", + "Orlee", + "Orli", + "Orly", + "Orna", + "Ornella", + "Osnat", + "Oxana", + "Padma", + "Paige", + "Pallavi", + "Palma", + "Paloma", + "Pam", + "Pamela", + "Pamella", + "Pammy", + "Paola", + "Pari", + "Parul", + "Pascale", + "Patience", + "Patrice", + "Patrina", + "Patrizia", + "Patrycja", + "Patrícia", + "Patsy", + "Patt", + "Patti", + "Pattie", + "Patty", + "Pau", + "Paula", + "Paulette", + "Paulina", + "Pauline", + "Payal", + "Pearl", + "Pebbles", + "Peg", + "Peggy", + "Pei", + "Pelin", + "Pema", + "Penina", + "Penny", + "Penèlope", + "Pepi", + "Pepper", + "Peri", + "Perla", + "Perri", + "Petal", + "Petra", + "Petrina", + "Petula", + "Petunia", + "Phaedra", + "Philippa", + "Philomena", + "Phoebe", + "Phuong", + "Phylicia", + "Phyllis", + "Pia", + "Piedad", + "Piera", + "Pilar", + "Pina", + "Pinar", + "Ping", + "Pink", + "Pinky", + "Piper", + "Pixie", + "Polina", + "Polly", + "Pooja", + "Poonam", + "Popi", + "Poppy", + "Porsche", + "Porsha", + "Portia", + "Prachi", + "Pratima", + "Precious", + "Preeti", + "Pretty", + "Preya", + "Princess", + "Prisca", + "Priscila", + "Priscilla", + "Priti", + "Priya", + "Priyanka", + "Prudence", + "Pui", + "Puja", + "Pura", + "Purvi", + "Qian", + "Qiana", + "Qing", + "Quana", + "Queenie", + "Quiana", + "Quianna", + "Quynh", + "Rabia", + "Rachael", + "Racheal", + "Rachel", + "Rachele", + "Racheli", + "Rachelle", + "Rachna", + "Racquel", + "Rada", + "Radha", + "Radhika", + "Rae", + "Rafaela", + "Rafaelina", + "Raffaela", + "Raffaella", + "Rahel", + "Rai", + "Raina", + "Raine", + "Raisa", + "Raizy", + "Rakhee", + "Ramona", + "Ramya", + "Randee", + "Randi", + "Randie", + "Rani", + "Rania", + "Raquel", + "Rasa", + "Rasha", + "Rasheda", + "Rasheeda", + "Rasheedah", + "Rashel", + "Rashi", + "Rashida", + "Rashidah", + "Rashmi", + "Raven", + "Ravit", + "Raya", + "Rayna", + "Raysa", + "Rea", + "Reagan", + "Reba", + "Rebeca", + "Rebecca", + "Rebekah", + "Rebekka", + "Reem", + "Reema", + "Reena", + "Regina", + "Regine", + "Rehana", + "Reiko", + "Reina", + "Rekha", + "Rena", + "Renae", + "Renate", + "Renee", + "Renita", + "Renu", + "Renáta", + "Reshma", + "Reva", + "Revital", + "Reyna", + "Rhea", + "Rhiannon", + "Rhina", + "Rhoda", + "Rhona", + "Rhonda", + "Ria", + "Rica", + "Richa", + "Richelle", + "Ricki", + "Rie", + "Rika", + "Riki", + "Rikki", + "Rima", + "Rimma", + "Rina", + "Rinat", + "Risa", + "Rita", + "Ritu", + "Ritz", + "Riva", + "Rivka", + "Rivki", + "Rivky", + "Roberta", + "Robin", + "Robyn", + "Rochel", + "Rochelle", + "Rocío", + "Roe", + "Rohini", + "Rolanda", + "Roma", + "Romana", + "Romi", + "Romina", + "Romona", + "Romy", + "Rona", + "Ronda", + "Roni", + "Ronica", + "Ronit", + "Ronni", + "Rori", + "Rosa", + "Rosalba", + "Rosalee", + "Rosalia", + "Rosalie", + "Rosalina", + "Rosalind", + "Rosalinda", + "Rosaline", + "Rosalyn", + "Rosamaria", + "Rosana", + "Rosangela", + "Rosann", + "Rosanna", + "Rosanne", + "Rosaria", + "Rosary", + "Rosaura", + "Rose", + "Roseann", + "Roseanna", + "Roseanne", + "Roseline", + "Roselle", + "Rosely", + "Roselyn", + "Rosemarie", + "Rosemary", + "Rosetta", + "Rosette", + "Rosey", + "Roshni", + "Rosi", + "Rosie", + "Rosina", + "Rosita", + "Roslyn", + "Rossana", + "Rossi", + "Rossy", + "Rosy", + "Roula", + "Rowena", + "Roxana", + "Roxann", + "Roxanna", + "Roxanne", + "Roxie", + "Roxy", + "Roya", + "Roz", + "Roza", + "Rubi", + "Rubina", + "Ruby", + "Ruchi", + "Rupa", + "Rupi", + "Ruth", + "Ruthie", + "Ruthy", + "Ryann", + "Ryoko", + "Räñå", + "Saadia", + "Saba", + "Sabah", + "Sabina", + "Sabine", + "Sabrena", + "Sabrina", + "Sachi", + "Sadaf", + "Sade", + "Sadia", + "Sadie", + "Safia", + "Safiya", + "Sagrario", + "Sahar", + "Saida", + "Saima", + "Saira", + "Sakina", + "Sakinah", + "Sakura", + "Salima", + "Salina", + "Sallie", + "Sally", + "Sallyann", + "Salma", + "Salome", + "Samanta", + "Samantha", + "Samar", + "Samara", + "Sameera", + "Samia", + "Samina", + "Samira", + "Sammi", + "Sana", + "Sanam", + "Sandee", + "Sandhya", + "Sandi", + "Sandra", + "Sandrine", + "Sandy", + "Sanela", + "Sangeeta", + "Sania", + "Saniya", + "Sanja", + "Sanjana", + "Sanna", + "Santa", + "Sanya", + "Saori", + "Sapna", + "Sapphire", + "Sara", + "Sarah", + "Sarai", + "Saran", + "Saray", + "Sari", + "Sarika", + "Sarina", + "Sarit", + "Sarita", + "Sasha", + "Saskia", + "Satoko", + "Saundra", + "Savannah", + "Savita", + "Savitri", + "Sayaka", + "Scarlet", + "Scarlett", + "Scarlette", + "Seda", + "Seema", + "Seeta", + "Seiko", + "Sejal", + "Selena", + "Selene", + "Selin", + "Selina", + "Selma", + "Sena", + "Senada", + "Sera", + "Serena", + "Serene", + "Serenity", + "Serina", + "Serita", + "Serra", + "Shabana", + "Shabnam", + "Shade", + "Shadia", + "Shae", + "Shahida", + "Shaila", + "Shaina", + "Shakeema", + "Shakema", + "Shakia", + "Shakila", + "Shakima", + "Shakina", + "Shakira", + "Shala", + "Shaleen", + "Shalini", + "Shalonda", + "Shama", + "Shamara", + "Shamecca", + "Shameeka", + "Shameika", + "Shameka", + "Shamika", + "Shana", + "Shanae", + "Shanay", + "Shanaya", + "Shanaz", + "Shanda", + "Shanea", + "Shanee", + "Shaneka", + "Shanel", + "Shanell", + "Shanelle", + "Shanequa", + "Shanette", + "Shani", + "Shania", + "Shanice", + "Shaniece", + "Shanika", + "Shanikqua", + "Shaniqua", + "Shanique", + "Shanise", + "Shanita", + "Shanna", + "Shannan", + "Shannel", + "Shannon", + "Shanta", + "Shantae", + "Shantal", + "Shantay", + "Shante", + "Shantel", + "Shantell", + "Shantelle", + "Shanti", + "Shaquana", + "Shaquanna", + "Shar", + "Shara", + "Sharae", + "Sharay", + "Sharda", + "Sharday", + "Sharee", + "Shareen", + "Shareena", + "Shareese", + "Sharell", + "Sharene", + "Sharese", + "Shari", + "Sharice", + "Sharifa", + "Sharine", + "Sharise", + "Sharisse", + "Sharita", + "Sharla", + "Sharleen", + "Sharlene", + "Sharmaine", + "Sharmila", + "Sharmin", + "Sharon", + "Sharona", + "Sharonda", + "Sharron", + "Sharyn", + "Shasha", + "Shatima", + "Shatisha", + "Shauna", + "Shaunda", + "Shaunna", + "Shauntay", + "Shaunte", + "Shavon", + "Shavonne", + "Shawana", + "Shawanda", + "Shawanna", + "Shawna", + "Shawnee", + "Shawnette", + "Shawntay", + "Shayla", + "Shayna", + "Shazia", + "She", + "Sheba", + "Sheena", + "Sheetal", + "Shefali", + "Sheila", + "Sheilah", + "Shelby", + "Shelia", + "Shell", + "Shelley", + "Shelli", + "Shellie", + "Shelly", + "Shelly-Ann", + "Shellyann", + "Shenelle", + "Shenequa", + "Shenika", + "Sheniqua", + "Shera", + "Sheree", + "Shereen", + "Sherelle", + "Sherene", + "Sherese", + "Sheri", + "Sherica", + "Sherice", + "Sherika", + "Sherine", + "Sherise", + "Sherley", + "Sherly", + "Sherma", + "Sheron", + "Sherrell", + "Sherri", + "Sherrie", + "Sherry", + "Sherryann", + "Sheryl", + "Shifra", + "Shiho", + "Shikha", + "Shilpa", + "Shilpi", + "Shiny", + "Shira", + "Shiran", + "Shireen", + "Shiri", + "Shirin", + "Shirlene", + "Shirley", + "Shivani", + "Shivon", + "Shlomit", + "Shoko", + "Shona", + "Shonda", + "Shonette", + "Shonna", + "Shoshana", + "Shoshanna", + "Shoshi", + "Shpresa", + "Shreya", + "Shruti", + "Shuang", + "Shuchi", + "Shuli", + "Shweta", + "Shy", + "Sia", + "Sian", + "Sibel", + "Sibyl", + "Sidra", + "Sienna", + "Sierra", + "Sigal", + "Sigi", + "Sigrid", + "Silke", + "Silvana", + "Silvia", + "Silvina", + "Sima", + "Simi", + "Simmone", + "Simona", + "Simone", + "Simran", + "Sindy", + "Sinead", + "Siobhan", + "Sirena", + "Siri", + "Sisi", + "Sissy", + "Sita", + "Sivan", + "Skye", + "Smadar", + "Smiley", + "Smita", + "Smitha", + "Sneha", + "Socorro", + "Sofia", + "Sofie", + "Sofiya", + "Sofya", + "Solange", + "Sole", + "Soledad", + "Sona", + "Sonal", + "Sonali", + "Sondra", + "Soni", + "Sonia", + "Soniya", + "Sonja", + "Sonya", + "Soo", + "Soojin", + "Sophia", + "Sophie", + "Sora", + "Soraya", + "Sparkle", + "Spring", + "Stacey", + "Stacey-Ann", + "Staceyann", + "Staci", + "Stacia", + "Stacie", + "Stacy", + "Stacy-Ann", + "Stacyann", + "Star", + "Starr", + "Stasia", + "Stef", + "Stefani", + "Stefania", + "Stefanie", + "Stefany", + "Steffi", + "Stela", + "Stella", + "Steph", + "Stephani", + "Stephania", + "Stephanie", + "Stephany", + "Stephenie", + "Stephy", + "Stina", + "Stormy", + "Su", + "Subrina", + "Sudha", + "Sue", + "Sugar", + "Sui", + "Sujata", + "Sujin", + "Suki", + "Sultana", + "Suly", + "Summer", + "Sunita", + "Sunshine", + "Supriya", + "Suri", + "Susan", + "Susana", + "Susanna", + "Susannah", + "Susanne", + "Susi", + "Susie", + "Susy", + "Suzan", + "Suzana", + "Suzanna", + "Suzanne", + "Suzette", + "Suzi", + "Suzie", + "Suzy", + "Suzzette", + "Sveta", + "Svetlana", + "Swati", + "Sweet", + "Sweta", + "Swetha", + "Sybil", + "Sydelle", + "Sydney", + "Syeda", + "Sylvia", + "Sylvie", + "Sylwia", + "Symone", + "Synthia", + "Syreeta", + "Szilvia", + "Tabatha", + "Tabitha", + "Tahira", + "Tahirah", + "Tahisha", + "Taina", + "Taisha", + "Takako", + "Takia", + "Tali", + "Talia", + "Talisa", + "Talisha", + "Talya", + "Tamar", + "Tamara", + "Tameeka", + "Tameika", + "Tameka", + "Tamesha", + "Tami", + "Tamia", + "Tamica", + "Tamieka", + "Tamika", + "Tamiko", + "Tamisha", + "Tammi", + "Tammie", + "Tammy", + "Tamra", + "Tana", + "Tanaya", + "Taneisha", + "Tanesha", + "Tania", + "Taniesha", + "Tanika", + "Taniqua", + "Tanisha", + "Tanishia", + "Tanja", + "Tanvi", + "Tanya", + "Tara", + "Tarah", + "Tarika", + "Tarra", + "Tarsha", + "Taryn", + "Tash", + "Tasha", + "Tashana", + "Tashauna", + "Tashawna", + "Tashia", + "Tashika", + "Tasia", + "Tata", + "Tati", + "Tatiana", + "Tatjana", + "Tatyana", + "Tavia", + "Tawana", + "Tawanda", + "Tawanna", + "Tea", + "Teal", + "Teena", + "Tegan", + "Teisha", + "Temitope", + "Tene", + "Tenesha", + "Tenika", + "Tenisha", + "Tennille", + "Tera", + "Teresa", + "Terese", + "Teresita", + "Tereza", + "Teri", + "Terra", + "Terri", + "Terri-Ann", + "Terrie", + "Terryann", + "Tesha", + "Tess", + "Tessa", + "Tessie", + "Tetyana", + "Thais", + "Thalia", + "Thao", + "Thea", + "Theda", + "Thelma", + "Theodora", + "Theresa", + "Therese", + "Thomasina", + "Tia", + "Tiana", + "Tianna", + "Tiara", + "Tierney", + "Tierra", + "Tiesha", + "Tiff", + "Tiffani", + "Tiffanie", + "Tiffany", + "Tijuana", + "Tina", + "Tinamarie", + "Ting", + "Tingting", + "Tish", + "Tisha", + "Tita", + "Titi", + "Tiziana", + "Tobey", + "Toi", + "Tola", + "Tomoko", + "Toni", + "Toni-Ann", + "Tonia", + "Toniann", + "Tonisha", + "Tonya", + "Topaz", + "Tori", + "Toria", + "Tosha", + "Toula", + "Tova", + "Tovah", + "Towana", + "Toya", + "Toyin", + "Tracee", + "Tracey", + "Traci", + "Tracie", + "Tracy", + "Tran", + "Treasure", + "Tressa", + "Tricia", + "Trina", + "Trinidad", + "Trinity", + "Trish", + "Trisha", + "Trixie", + "Trudi", + "Trudy", + "Twana", + "Twanna", + "Tyeisha", + "Tyesha", + "Tyisha", + "Tynisha", + "Tyra", + "Tzippy", + "Tzivia", + "Ulrike", + "Uma", + "Una", + "Unique", + "Ursula", + "Urszula", + "Urvashi", + "Usha", + "Uzma", + "Valarie", + "Valbona", + "Valencia", + "Valentina", + "Valeria", + "Valerie", + "Valeriya", + "Valrie", + "Vanda", + "Vandana", + "Vanesa", + "Vanessa", + "Vania", + "Vanita", + "Vanity", + "Vanna", + "Vannessa", + "Varsha", + "Vashti", + "Vasiliki", + "Veda", + "Vee", + "Veena", + "Velma", + "Velvet", + "Venecia", + "Venera", + "Venessa", + "Venetia", + "Venice", + "Venus", + "Vera", + "Vered", + "Verena", + "Verna", + "Vernell", + "Vero", + "Verona", + "Veronika", + "Veronique", + "Verónica", + "Vesna", + "Vickey", + "Vicki", + "Vickie", + "Vicky", + "Victoria", + "Vida", + "Vidya", + "Vielka", + "Vienna", + "Viki", + "Vikki", + "Viktoria", + "Viktoriya", + "Vilma", + "Vina", + "Vincenza", + "Vinette", + "Vinita", + "Viola", + "Violet", + "Violeta", + "Violetta", + "Violette", + "Virginia", + "Virginie", + "Vita", + "Viv", + "Viva", + "Vivi", + "Vivian", + "Viviana", + "Viviane", + "Vivien", + "Vivienne", + "Vlada", + "Vonetta", + "Voula", + "Vy", + "Waleska", + "Wanda", + "Wendi", + "Wendie", + "Wendy", + "Whitney", + "Wilda", + "Wilhelmina", + "Willa", + "Willow", + "Wilma", + "Windy", + "Winifred", + "Winnie", + "Winsome", + "Wioletta", + "Xena", + "Xenia", + "Xia", + "Ximena", + "Xiomara", + "Xue", + "Yadira", + "Yael", + "Yaffa", + "Yafit", + "Yahaira", + "Yajaira", + "Yali", + "Yalitza", + "Yamileth", + "Yana", + "Yanet", + "Yani", + "Yanick", + "Yanina", + "Yanique", + "Yanira", + "Yaniris", + "Yanna", + "Yara", + "Yaritza", + "Yary", + "Yarí", + "Yasemin", + "Yashira", + "Yasmeen", + "Yasmin", + "Yasmina", + "Yasmine", + "Yaya", + "Yazmin", + "Yecenia", + "Yehudis", + "Yejin", + "Yekaterina", + "Yelena", + "Yelitza", + "Yen", + "Yeni", + "Yenifer", + "Yenny", + "Yesenia", + "Yessenia", + "Yessica", + "Yetunde", + "Yevgeniya", + "Yin", + "Ying", + "Yira", + "Yocasta", + "Yogita", + "Yohanna", + "Yohanny", + "Yokasta", + "Yoko", + "Yola", + "Yolanda", + "Yolande", + "Yoly", + "Yomaira", + "Yomayra", + "Yona", + "Yonit", + "Yoo", + "Yoojin", + "Yoon", + "Yoselin", + "Youjin", + "Yudelka", + "Yuen", + "Yuka", + "Yukari", + "Yuki", + "Yukiko", + "Yuko", + "Yulia", + "Yuliana", + "Yuliya", + "Yumi", + "Yumiko", + "Yun", + "Yuna", + "Yuni", + "Yvelisse", + "Yvette", + "Yvonne", + "Zahra", + "Zaida", + "Zainab", + "Zaira", + "Zakia", + "Zakiya", + "Zakiyyah", + "Zamira", + "Zana", + "Zandra", + "Zara", + "Zarina", + "Zehra", + "Zeina", + "Zelda", + "Zena", + "Zenaida", + "Zenia", + "Zenobia", + "Zeta", + "Zeynep", + "Zhanna", + "Zhenya", + "Zina", + "Zita", + "Zoe", + "Zoey", + "Zofia", + "Zoila", + "Zoraida", + "Zoraya", + "Zoya", + "Zsuzsanna", + "Zulay", + "Zuleika", + "Zulema", + "Zuleyka", + "Zulma", + "Zuzana", +] + +const _male_first_names = [ + "Aakash", + "Aamir", + "Aaron", + "Ab", + "Abba", + "Abbas", + "Abdel", + "Abdiel", + "Abdou", + "Abdoul", + "Abdoulaye", + "Abdul", + "Abdulla", + "Abdullah", + "Abe", + "Abel", + "Abey", + "Abhay", + "Abhi", + "Abhilash", + "Abhinav", + "Abhishek", + "Abid", + "Abie", + "Abir", + "Abner", + "Abraham", + "Abu", + "Aby", + "Ace", + "Achilles", + "Adalberto", + "Adam", + "Adams", + "Addis", + "Addison", + "Ade", + "Adebayo", + "Adeel", + "Adekunle", + "Adel", + "Adem", + "Ademola", + "Adewale", + "Adeyemi", + "Adham", + "Adiel", + "Adil", + "Adis", + "Aditya", + "Admir", + "Adnan", + "Adolfo", + "Adonis", + "Adriano", + "Adriel", + "Adrien", + "Ag", + "Agim", + "Agostino", + "Agron", + "Aharon", + "Ahmad", + "Ahmed", + "Ahmet", + "Ahsan", + "Aidan", + "Aiden", + "Ainsworth", + "Aj", + "Ajamu", + "Ajani", + "Ajay", + "Ajit", + "Ajith", + "Ak", + "Akash", + "Akbar", + "Akeem", + "Akhil", + "Akihiro", + "Akil", + "Akim", + "Akin", + "Akira", + "Akis", + "Akiva", + "Akram", + "Akshay", + "Akwasi", + "Al", + "Alain", + "Alan", + "Alaric", + "Alban", + "Albert", + "Alberto", + "Albi", + "Albin", + "Albion", + "Alcides", + "Alden", + "Aldo", + "Aldrin", + "Alec", + "Alejandro", + "Alek", + "Aleks", + "Aleksandar", + "Aleksander", + "Aleksandr", + "Aleksey", + "Alen", + "Alessandro", + "Alessio", + "Alex", + "Alexander", + "Alexandr", + "Alexandre", + "Alexandros", + "Alexandru", + "Alexei", + "Alexey", + "Alexi", + "Alexie", + "Alfie", + "Alfonso", + "Alfred", + "Alfredo", + "Algernon", + "Ali", + "Alioune", + "Alistair", + "Allan", + "Allen", + "Allister", + "Allon", + "Alok", + "Alon", + "Alonso", + "Alonzo", + "Alp", + "Alper", + "Alpesh", + "Alphonse", + "Alphonso", + "Alston", + "Altaf", + "Altin", + "Alton", + "Alvaro", + "Alvin", + "Alwyn", + "Amado", + "Amadou", + "Aman", + "Amandeep", + "Amar", + "Amauri", + "Amaury", + "Ambrose", + "Amedeo", + "Ameer", + "Ameet", + "Amer", + "Americo", + "Amilcar", + "Amin", + "Amine", + "Amir", + "Amish", + "Amit", + "Amjad", + "Ammar", + "Amnon", + "Amol", + "Amos", + "Amr", + "Amrit", + "Anand", + "Anant", + "Anas", + "Anastasios", + "Anatoliy", + "Anatoly", + "Ande", + "Anders", + "Anderson", + "Andrae", + "Andre", + "Andreas", + "Andrei", + "Andrew", + "Andrews", + "Andrey", + "Andri", + "Andriy", + "Andry", + "Andrzej", + "Andrés", + "Andy", + "Angel", + "Angelo", + "Angus", + "Anibal", + "Anil", + "Aniruddha", + "Anis", + "Anish", + "Anjum", + "Ankit", + "Ankur", + "Ankush", + "Anoop", + "Ansel", + "Anselm", + "Anselmo", + "Anshul", + "Anson", + "Ant", + "Ante", + "Anthony", + "Antoine", + "Anton", + "Antonino", + "Antonio", + "Antonis", + "Antony", + "Antwan", + "Antwon", + "Anuj", + "Anup", + "Anurag", + "Anwar", + "Apurva", + "Aqeel", + "Ar", + "Aram", + "Aramis", + "Arash", + "Aravind", + "Arben", + "Archie", + "Arda", + "Ardian", + "Ardit", + "Argenis", + "Ari", + "Arian", + "Aric", + "Arie", + "Ariel", + "Arif", + "Arik", + "Aris", + "Aristides", + "Aristotle", + "Arjun", + "Arkadiy", + "Arkady", + "Arlen", + "Arman", + "Armand", + "Armando", + "Armani", + "Armel", + "Armen", + "Armin", + "Arnaldo", + "Arnaud", + "Arnel", + "Arnie", + "Arno", + "Arnold", + "Arnulfo", + "Aron", + "Arron", + "Arsalan", + "Arsen", + "Arsenio", + "Arshad", + "Arslan", + "Art", + "Artan", + "Artem", + "Arthur", + "Artie", + "Arto", + "Artur", + "Arturo", + "Arty", + "Arun", + "Arvin", + "Arvind", + "Aryan", + "Aryeh", + "Asad", + "Asaf", + "Asher", + "Ashish", + "Ashok", + "Ashraf", + "Ashton", + "Ashutosh", + "Ashwin", + "Asi", + "Asif", + "Asim", + "Aslam", + "Assaf", + "Aston", + "Atakan", + "Atef", + "Athanasios", + "Atiba", + "Atif", + "Atsushi", + "Attila", + "Attilio", + "Atul", + "Aubyn", + "Augie", + "August", + "Augustine", + "Augusto", + "Augustus", + "Aung", + "Aurelio", + "Austen", + "Austin", + "Avery", + "Avi", + "Aviad", + "Avinash", + "Avishai", + "Aviv", + "Avner", + "Avraham", + "Avrohom", + "Axel", + "Aydin", + "Ayhan", + "Ayinde", + "Ayman", + "Ayo", + "Ayodele", + "Azad", + "Azeem", + "Azhar", + "Azim", + "Aziz", + "Baba", + "Babak", + "Babatunde", + "Babu", + "Bah", + "Bakari", + "Bala", + "Baldwin", + "Bam", + "Bang", + "Banks", + "Bao", + "Bar", + "Barak", + "Baran", + "Baris", + "Barnett", + "Barney", + "Baron", + "Barrett", + "Barrington", + "Barron", + "Barry", + "Bart", + "Barton", + "Baruch", + "Basem", + "Bashir", + "Basil", + "Bass", + "Bassam", + "Bassem", + "Bastien", + "Batuhan", + "Baxter", + "Bayo", + "Bear", + "Beat", + "Beau", + "Bekim", + "Ben", + "Bender", + "Benedict", + "Beni", + "Benito", + "Benj", + "Benjamin", + "Benji", + "Benjie", + "Benjy", + "Bennett", + "Bennie", + "Benny", + "Benoit", + "Benson", + "Bentley", + "Berk", + "Bernard", + "Bernardo", + "Bernd", + "Bernhard", + "Bernie", + "Bert", + "Berto", + "Bertram", + "Bertrand", + "Besim", + "Besnik", + "Beto", + "Bharat", + "Bhavin", + "Biagio", + "Bienvenido", + "Bigg", + "Biggie", + "Biju", + "Bikram", + "Bilal", + "Bill", + "Bin", + "Bing", + "Binod", + "Binu", + "Binyomin", + "Bishop", + "Björn", + "Black", + "Blaine", + "Blaise", + "Blake", + "Blanco", + "Blas", + "Blaze", + "Bledar", + "Blerim", + "Blu", + "Bo", + "Boaz", + "Bob", + "Bobby", + "Bobo", + "Bogdan", + "Bojan", + "Bolivar", + "Bong", + "Boo", + "Boogie", + "Bora", + "Boris", + "Boruch", + "Bosco", + "Boss", + "Boyce", + "Brad", + "Braden", + "Bradford", + "Bradley", + "Brady", + "Brahim", + "Bram", + "Brandan", + "Branden", + "Brando", + "Brandon", + "Branko", + "Braulio", + "Brayan", + "Brayden", + "Brenden", + "Brendon", + "Brennan", + "Brent", + "Brenton", + "Bret", + "Brett", + "Brian", + "Brice", + "Brien", + "Bright", + "Brion", + "Broadway", + "Brock", + "Brody", + "Bronx", + "Brooks", + "Bruce", + "Bruno", + "Bryan", + "Bryant", + "Bryce", + "Bryon", + "Brëndan", + "Bubba", + "Buck", + "Bud", + "Buddha", + "Buddy", + "Budi", + "Buffalo", + "Burak", + "Burhan", + "Burke", + "Burt", + "Burton", + "Buster", + "Butch", + "Buzz", + "Byron", + "Bïlly", + "Bülent", + "Caesar", + "Cal", + "Cale", + "Caleb", + "Callum", + "Calogero", + "Calvin", + "Cam", + "Camden", + "Cameron", + "Camilo", + "Campbell", + "Can", + "Candido", + "Carl", + "Carlin", + "Carlito", + "Carlitos", + "Carlo", + "Carlos", + "Carlton", + "Carlyle", + "Carmelo", + "Carmine", + "Carrington", + "Carson", + "Carter", + "Cary", + "Cas", + "Cash", + "Casimir", + "Casper", + "Cassius", + "Cecil", + "Cecilio", + "Cedric", + "Cedrick", + "Celso", + "Cem", + "Cengiz", + "Cenk", + "Ceo", + "Cesare", + "Cezar", + "Chad", + "Chadwick", + "Chaim", + "Chaitanya", + "Chaka", + "Champ", + "Chan", + "Chance", + "Chandler", + "Chang", + "Chao", + "Charles", + "Charley", + "Charlie", + "Charlton", + "Charly", + "Chas", + "Chase", + "Chauncey", + "Chavez", + "Chaz", + "Che", + "Cheng", + "Chester", + "Chet", + "Chetan", + "Chi", + "Chico", + "Chike", + "Chin", + "Chinedu", + "Chino", + "Chintan", + "Chip", + "Chirag", + "Chris", + "Christian", + "Christo", + "Christoph", + "Christophe", + "Christopher", + "Christos", + "Chuck", + "Chuckie", + "Chucky", + "Chun", + "Chung", + "Ciaran", + "Cid", + "Cihan", + "Ciprian", + "Ciro", + "Cisco", + "Clarence", + "Clark", + "Clarke", + "Classic", + "Claude", + "Claudio", + "Clay", + "Clayton", + "Clem", + "Clement", + "Clemente", + "Cleon", + "Cletus", + "Cleve", + "Cleveland", + "Clif", + "Cliff", + "Clifford", + "Clifton", + "Clint", + "Clinton", + "Clive", + "Clyde", + "Coby", + "Cody", + "Colby", + "Cole", + "Coleman", + "Colin", + "Collin", + "Collins", + "Colm", + "Colton", + "Connor", + "Cono", + "Conor", + "Conrad", + "Conroy", + "Constantin", + "Constantine", + "Constantinos", + "Cool", + "Cooper", + "Corbin", + "Cordell", + "Corey", + "Cornel", + "Cornelius", + "Cornell", + "Corrado", + "Cortez", + "Corwin", + "Cory", + "Cosimo", + "Cosmo", + "Costa", + "Costas", + "Court", + "Craig", + "Crispin", + "Cristhian", + "Cristian", + "Cristiano", + "Cristobal", + "Cullen", + "Culture", + "Curt", + "Curtis", + "Cy", + "Cyril", + "Cyrus", + "César", + "Da", + "Dada", + "Dae", + "Daily", + "Daisuke", + "Dale", + "Dalibor", + "Dallas", + "Dalton", + "Daman", + "Damani", + "Damian", + "Damiano", + "Damien", + "Damion", + "Damir", + "Damon", + "Damone", + "Dan", + "Dane", + "Daniel", + "Danijel", + "Danilo", + "Danish", + "Danny", + "Dante", + "Dany", + "Daquan", + "Darell", + "Daren", + "Darian", + "Dariel", + "Darien", + "Darin", + "Dario", + "Darion", + "Darius", + "Dariusz", + "Dark", + "Darnel", + "Darnell", + "Daron", + "Darrel", + "Darrell", + "Darren", + "Darrin", + "Darron", + "Darryl", + "Darshan", + "Darwin", + "Daryl", + "Daryll", + "Dash", + "Dashaun", + "Dashawn", + "Dave", + "Davey", + "David", + "Davide", + "Davidson", + "Davie", + "Davin", + "Davis", + "Davon", + "Davy", + "Dawid", + "Dawud", + "Dax", + "Day", + "Dayne", + "Dayo", + "De", + "Dean", + "Deandre", + "Declan", + "Deejay", + "Deep", + "Deepak", + "Deion", + "Dejan", + "Delano", + "Dele", + "Dell", + "Delon", + "Delroy", + "Demetri", + "Demetrios", + "Demetrius", + "Demian", + "Demir", + "Demitri", + "Den", + "Denis", + "Dennis", + "Denny", + "Denton", + "Denver", + "Denys", + "Denzel", + "Denzil", + "Deon", + "Dequan", + "Dereck", + "Derek", + "Derick", + "Derik", + "Dermot", + "Deron", + "Derrick", + "Derron", + "Derwin", + "Deryck", + "Deshaun", + "Deshawn", + "Deshon", + "Desmond", + "Deuce", + "Dev", + "Devaughn", + "Deven", + "Devendra", + "Devin", + "Devon", + "Devonte", + "Dewayne", + "Dewey", + "Dexter", + "Dez", + "Dhaval", + "Dheeraj", + "Dhiren", + "Dhruv", + "Diallo", + "Dice", + "Dick", + "Didier", + "Diego", + "Dieter", + "Dijon", + "Dil", + "Dilip", + "Dillon", + "Dima", + "Dimas", + "Dimitar", + "Dimitri", + "Dimitrios", + "Dimitris", + "Dimitry", + "Din", + "Dinesh", + "Ding", + "Dino", + "Dio", + "Diogenes", + "Dion", + "Dionis", + "Dionisio", + "Dipak", + "Dirk", + "Divine", + "Dixon", + "Django", + "Dmitri", + "Dmitriy", + "Dmitry", + "Dmytro", + "Do", + "Doc", + "Dollar", + "Dom", + "Domenic", + "Domenick", + "Domenico", + "Domingo", + "Dominic", + "Dominick", + "Dominik", + "Domo", + "Don", + "Donal", + "Donald", + "Donatello", + "Donato", + "Donavan", + "Donavin", + "Donell", + "Dong", + "Doni", + "Donn", + "Donnell", + "Donnie", + "Donny", + "Donovan", + "Donte", + "Doran", + "Doron", + "Dorsey", + "Doug", + "Dougie", + "Douglas", + "Dov", + "Dovid", + "Doğan", + "Dragan", + "Dragos", + "Drake", + "Drama", + "Dre", + "Drew", + "Dritan", + "Dru", + "Duane", + "Dudley", + "Dudu", + "Dujon", + "Duke", + "Duncan", + "Duran", + "Durell", + "Durrell", + "Dusan", + "Dustin", + "Dusty", + "Dutch", + "Duwayne", + "Dwain", + "Dwaine", + "Dwayne", + "Dwight", + "Dylan", + "Eamon", + "Eamonn", + "Ean", + "Earl", + "Earle", + "Eazy", + "Eben", + "Ebenezer", + "Ed", + "Edan", + "Edd", + "Eddie", + "Eddy", + "Eder", + "Edgar", + "Edgard", + "Edgardo", + "Edge", + "Edi", + "Edin", + "Edison", + "Edmond", + "Edmund", + "Edmundo", + "Edo", + "Edouard", + "Edson", + "Eduard", + "Eduardo", + "Edward", + "Edwards", + "Edwin", + "Efe", + "Efraim", + "Efrain", + "Efren", + "Ehab", + "Eitan", + "Ej", + "El", + "Elad", + "Eladio", + "Elan", + "Elbert", + "Eldad", + "Eldar", + "Elder", + "Eldon", + "Eli", + "Elias", + "Elie", + "Eliezer", + "Elijah", + "Elio", + "Eliot", + "Eliran", + "Elis", + "Eliseo", + "Elkin", + "Ellery", + "Elliot", + "Elliott", + "Ellis", + "Ellison", + "Elmer", + "Elmo", + "Elon", + "Eloy", + "Elton", + "Elvin", + "Elvis", + "Emad", + "Emanuel", + "Emanuele", + "Emeka", + "Emerson", + "Emil", + "Emile", + "Emiliano", + "Emilio", + "Emin", + "Emir", + "Emmanuel", + "Emmet", + "Emmett", + "Emory", + "Emrah", + "Emre", + "Ender", + "Enes", + "Engels", + "Engin", + "Enis", + "Enmanuel", + "Enoch", + "Enrico", + "Enrique", + "Enzo", + "Eon", + "Ephraim", + "Eran", + "Ercan", + "Erdal", + "Erdem", + "Eren", + "Erez", + "Erhan", + "Eric", + "Erich", + "Erick", + "Erik", + "Erkan", + "Ermal", + "Ernest", + "Ernesto", + "Ernie", + "Ernst", + "Erol", + "Errol", + "Ervin", + "Erwin", + "Espezy", + "Esteban", + "Etan", + "Ethan", + "Etienne", + "Eugene", + "Eugenio", + "Eusebio", + "Evan", + "Evangelos", + "Evans", + "Evens", + "Ever", + "Everett", + "Everton", + "Evgeny", + "Ewan", + "Extra", + "Eyal", + "Eytan", + "Ez", + "Ezekiel", + "Ezequiel", + "Ezra", + "Fabien", + "Fabio", + "Fabián", + "Fabrice", + "Fabricio", + "Fabrizio", + "Fadi", + "Fady", + "Fahad", + "Faheem", + "Fahim", + "Faisal", + "Faiz", + "Faraz", + "Fareed", + "Farhad", + "Farhan", + "Farid", + "Faris", + "Farrukh", + "Faruk", + "Farzad", + "Fatih", + "Fatmir", + "Fatos", + "Faustino", + "Fausto", + "Fazal", + "Federico", + "Felipe", + "Felix", + "Femi", + "Feng", + "Ferdinand", + "Ferdinando", + "Ferhat", + "Fermin", + "Fernando", + "Fidel", + "Filip", + "Filipe", + "Filippo", + "Finest", + "Finn", + "Fish", + "Fitz", + "Fitzgerald", + "Fitzroy", + "Flash", + "Flat", + "Flavio", + "Fletcher", + "Flip", + "Florian", + "Florin", + "Floyd", + "Fly", + "Flynn", + "Forbes", + "Ford", + "Forest", + "Forrest", + "Foster", + "Fouad", + "Fox", + "Francesco", + "Francis", + "Francisco", + "Franck", + "Franco", + "Francois", + "Frank", + "Frankie", + "Franklin", + "Franklyn", + "Franky", + "Frantz", + "Franz", + "Fraser", + "Fred", + "Freddie", + "Freddy", + "Frederic", + "Frederick", + "Frederik", + "Fredric", + "Fredrick", + "Fredrik", + "Fredy", + "Free", + "French", + "Fritz", + "Fu", + "Fuad", + "Fuat", + "Furkan", + "Gab", + "Gabe", + "Gabino", + "Gabor", + "Gabriel", + "Gaetano", + "Gagan", + "Gagandeep", + "Gal", + "Galen", + "Galo", + "Gamal", + "Games", + "Ganesh", + "Gar", + "Gardy", + "Gareth", + "Garfield", + "Garland", + "Garnet", + "Garnett", + "Garret", + "Garrett", + "Garrick", + "Garry", + "Garth", + "Garvey", + "Garvin", + "Gary", + "Gaspar", + "Gasper", + "Gaston", + "Gaurav", + "Gautam", + "Gavin", + "Gavriel", + "Gbenga", + "Gee", + "Gen", + "Genaro", + "Gene", + "Gennadiy", + "Gennady", + "Gennaro", + "Geno", + "Geo", + "Geoff", + "Geoffrey", + "Georg", + "George", + "Georges", + "Georgi", + "Georgio", + "Geovanni", + "Geovanny", + "Ger", + "Gerald", + "Geraldo", + "Gerard", + "Gerardo", + "Germain", + "German", + "Gerome", + "Geronimo", + "Gerry", + "Gershon", + "Gerson", + "Get", + "Gezim", + "Ghulam", + "Giacomo", + "Gian", + "Giancarlo", + "Giancarlos", + "Gianfranco", + "Gianluca", + "Gianni", + "Gibran", + "Gideon", + "Gil", + "Gilad", + "Gilbert", + "Gilberto", + "Giles", + "Gill", + "Gilles", + "Gino", + "Gio", + "Giorgio", + "Giovanni", + "Giovanny", + "Girish", + "Giuliano", + "Giulio", + "Giuseppe", + "Gleb", + "Glen", + "Glenn", + "Glenroy", + "Glyn", + "Go", + "Godfrey", + "Godwin", + "Gonzalo", + "Good", + "Gopal", + "Gopi", + "Goran", + "Gordon", + "Grady", + "Graeme", + "Graham", + "Graig", + "Grant", + "Granville", + "Gray", + "Grayson", + "Greg", + "Gregg", + "Gregor", + "Gregorio", + "Gregory", + "Griffin", + "Grzegorz", + "Gucci", + "Gui", + "Guido", + "Guilherme", + "Guillaume", + "Guillermo", + "Gunnar", + "Guo", + "Gurpreet", + "Gus", + "Gustav", + "Gustave", + "Gustavo", + "Guy", + "Gyasi", + "Gökhan", + "Habeeb", + "Habib", + "Hadi", + "Hai", + "Haider", + "Haim", + "Hakan", + "Hakeem", + "Hakim", + "Hal", + "Halil", + "Hamad", + "Hamid", + "Hamilton", + "Hamish", + "Hamlet", + "Hammad", + "Hamza", + "Han", + "Hanif", + "Hank", + "Hannibal", + "Hans", + "Hansel", + "Hanson", + "Hany", + "Hao", + "Hardik", + "Hardy", + "Hari", + "Haris", + "Harish", + "Harlan", + "Harlem", + "Harold", + "Haroon", + "Harpreet", + "Harri", + "Harris", + "Harrison", + "Harry", + "Harsh", + "Harun", + "Harvey", + "Hasan", + "Hasani", + "Hashim", + "Hassan", + "Hatem", + "Haywood", + "Hazem", + "He", + "Heath", + "Helio", + "Hemal", + "Hemant", + "Hendrik", + "Heng", + "Henning", + "Henri", + "Henrik", + "Henrique", + "Henry", + "Herb", + "Herbert", + "Herbie", + "Herby", + "Hercules", + "Heriberto", + "Herman", + "Hermes", + "Herminio", + "Hernando", + "Hernán", + "Hersh", + "Hershey", + "Herve", + "Hesham", + "Heshy", + "Hezekiah", + "Hicham", + "Hideki", + "Hillel", + "Hilton", + "Himanshu", + "Hin", + "Hing", + "Hiram", + "Hiren", + "Hiro", + "Hiroki", + "Hiroshi", + "Hiroyuki", + "Hitesh", + "Ho", + "Hoi", + "Holden", + "Holger", + "Homer", + "Hon", + "Hood", + "Hoon", + "Hopeton", + "Horace", + "Horacio", + "Howard", + "Howie", + "Hoàng", + "Hua", + "Hubert", + "Hudson", + "Hue", + "Huey", + "Hugh", + "Hugo", + "Humayun", + "Humberto", + "Humza", + "Hung", + "Hunter", + "Huseyin", + "Hussain", + "Hussein", + "Hy", + "Hymie", + "Hyung", + "Héctor", + "Iain", + "Iam", + "Ian", + "Ibrahima", + "Idan", + "Ido", + "Idris", + "Igal", + "Iggy", + "Ignacio", + "Ignatius", + "Ignazio", + "Igor", + "Ihab", + "Ike", + "Ikenna", + "Ikey", + "Il", + "Ilan", + "Ilhan", + "Ilir", + "Ill", + "Ilya", + "Ilyas", + "Imad", + "Imran", + "Imtiaz", + "Ioannis", + "Iqbal", + "Ira", + "Irfan", + "Irv", + "Irvin", + "Irving", + "Irwin", + "Isaac", + "Isaiah", + "Isaias", + "Ishmael", + "Isiah", + "Islam", + "Ismael", + "Ismet", + "Israel", + "Issac", + "Itai", + "Italo", + "Itamar", + "Itay", + "Itzik", + "Ivo", + "Ivor", + "Iván", + "Iwan", + "Izzy", + "Ja", + "Jabari", + "Jace", + "Jacek", + "Jack", + "Jackson", + "Jacky", + "Jacob", + "Jacopo", + "Jacques", + "Jad", + "Jaden", + "Jae", + "Jaewon", + "Jah", + "Jahid", + "Jahmal", + "Jahmel", + "Jai", + "Jair", + "Jairo", + "Jaison", + "Jaja", + "Jake", + "Jakob", + "Jakub", + "Jalen", + "Jalil", + "Jam", + "Jamaal", + "Jamal", + "Jamar", + "Jame", + "Jameel", + "Jamel", + "Jamell", + "James", + "Jameson", + "Jamey", + "Jamil", + "Jamin", + "Jamison", + "Janusz", + "Jaquan", + "Jarad", + "Jared", + "Jarek", + "Jarel", + "Jarell", + "Jarett", + "Jarod", + "Jaron", + "Jarred", + "Jarret", + "Jarrett", + "Jarrod", + "Jarvis", + "Jasen", + "Jason", + "Jasper", + "Jaspreet", + "Jatin", + "Javan", + "Javed", + "Javi", + "Javid", + "Javier", + "Javon", + "Jawad", + "Jay", + "Jayden", + "Jayquan", + "Jaysen", + "Jayson", + "Jean-Claude", + "Jean-Louis", + "Jean-Luc", + "Jean-Michel", + "Jean-Paul", + "Jean-Pierre", + "Jeb", + "Jed", + "Jeet", + "Jef", + "Jeff", + "Jefferson", + "Jeffery", + "Jeffrey", + "Jeffry", + "Jeffy", + "Jelani", + "Jemal", + "Jemel", + "Jens", + "Jensen", + "Jerald", + "Jerard", + "Jerel", + "Jerell", + "Jeremiah", + "Jeremias", + "Jeremy", + "Jermain", + "Jermaine", + "Jermel", + "Jerome", + "Jerrell", + "Jerson", + "Jesper", + "Jesse", + "Jesús", + "Jet", + "Jevon", + "Jey", + "Jhon", + "Jhonatan", + "Jhonathan", + "Jhonny", + "Jhony", + "Jian", + "Jiang", + "Jide", + "Jigar", + "Jignesh", + "Jim", + "Jimbo", + "Jimi", + "Jimmie", + "Jimmy", + "Jinal", + "Jitendra", + "Joaquim", + "Joaquín", + "Job", + "Joe", + "Joel", + "Joeseph", + "Joey", + "Joffre", + "Johan", + "Johann", + "Johannes", + "John", + "John-Paul", + "Johnathan", + "Johnathon", + "Johnnie", + "Johnny", + "Johnpaul", + "Johnson", + "Johny", + "Jomo", + "Jon", + "Jon-Paul", + "Jonah", + "Jonas", + "Jonatan", + "Jonathan", + "Jonathon", + "Jonel", + "Jong", + "Jonny", + "Jony", + "Joon", + "Jordan", + "Jordi", + "Jordon", + "Jorel", + "Jorge", + "Jos", + "Josef", + "Joselito", + "Joseph", + "Josh", + "Joshua", + "Josiah", + "Josias", + "Josip", + "Josuë", + "José", + "Jourdan", + "Jovan", + "Jovani", + "Jovanny", + "Jovany", + "Jozef", + "João", + "Juan", + "Juancarlos", + "Juanito", + "Jud", + "Judah", + "Judd", + "Jude", + "Juergen", + "Juice", + "Julian", + "Juliano", + "Julien", + "Julio", + "Julius", + "Jun", + "Junaid", + "Junior", + "Junito", + "Jurgen", + "Just", + "Justice", + "Justin", + "Justino", + "Justo", + "Justus", + "Jérry", + "Jérémie", + "Kaan", + "Kabir", + "Kadeem", + "Kadir", + "Kahlil", + "Kai", + "Kal", + "Kaleb", + "Kalvin", + "Kalyan", + "Kam", + "Kamal", + "Kamar", + "Kamau", + "Kamel", + "Kamen", + "Kameron", + "Kamil", + "Kamran", + "Kan", + "Kane", + "Kang", + "Kapil", + "Karan", + "Kareem", + "Karel", + "Karim", + "Karl", + "Karlo", + "Karlos", + "Karsten", + "Karthik", + "Kartik", + "Kaseem", + "Kash", + "Kashif", + "Kasper", + "Kaushal", + "Kaushik", + "Kayode", + "Kaz", + "Kazi", + "Keane", + "Kedar", + "Keegan", + "Keenan", + "Kei", + "Keir", + "Keith", + "Kelby", + "Kelechi", + "Kellan", + "Kellen", + "Kelvin", + "Kemal", + "Kemar", + "Ken", + "Kenan", + "Kendel", + "Kendell", + "Kendrick", + "Kenichi", + "Kenji", + "Kenn", + "Kennedy", + "Kenneth", + "Kenny", + "Kenrick", + "Kent", + "Kenta", + "Kentaro", + "Kenyatta", + "Kenyon", + "Keon", + "Kerby", + "Kerem", + "Kermit", + "Kern", + "Keron", + "Kerron", + "Kervin", + "Kerwin", + "Kester", + "Keston", + "Ketan", + "Kev", + "Kevan", + "Keven", + "Kevin", + "Kevon", + "Kevyn", + "Key", + "Keyon", + "Keyur", + "Kfir", + "Khaled", + "Khaleel", + "Khalid", + "Khalifa", + "Khalil", + "Khan", + "Khari", + "Khris", + "Khurram", + "Kiel", + "Kieran", + "Kike", + "Kiko", + "Kimani", + "Kin", + "King", + "Kingsley", + "Kip", + "Kirby", + "Kiril", + "Kirill", + "Kirk", + "Kirkland", + "Kirt", + "Kishan", + "Kishore", + "Klaus", + "Kleber", + "Klever", + "Knight", + "Ko", + "Kobe", + "Kobi", + "Koby", + "Kofi", + "Koji", + "Kojo", + "Kola", + "Kong", + "Konrad", + "Konstantin", + "Konstantinos", + "Kool", + "Koray", + "Korey", + "Kory", + "Kosta", + "Kostas", + "Kosuke", + "Kotaro", + "Kramer", + "Kreshnik", + "Kris", + "Krish", + "Krishna", + "Kristian", + "Kristof", + "Kristofer", + "Kristoffer", + "Kristopher", + "Krunal", + "Krystian", + "Krzysztof", + "Kubilay", + "Kujtim", + "Kumar", + "Kun", + "Kunal", + "Kunle", + "Kurt", + "Kurtis", + "Kush", + "Kushtrim", + "Kwabena", + "Kwadwo", + "Kwaku", + "Kwame", + "Kwan", + "Kwang", + "Kwasi", + "Kwesi", + "Kwok", + "Ky", + "Kyaw", + "Kyle", + "Kyron", + "Kyung", + "Labinot", + "Lam", + "Lamar", + "Lamarr", + "Lambert", + "Lamin", + "Lamont", + "Lance", + "Lancelot", + "Landon", + "Lane", + "Langston", + "Lanny", + "Lanre", + "Laquan", + "Laron", + "Larry", + "Lars", + "Laszlo", + "Lateef", + "Latif", + "Laurence", + "Laurent", + "Lauro", + "Lavon", + "Lawrence", + "Layton", + "Lazar", + "Lazaro", + "Leandro", + "Lee", + "Lefty", + "Leiby", + "Leif", + "Leighton", + "Lekan", + "Leland", + "Lemuel", + "Len", + "Lenard", + "Lenin", + "Lennie", + "Lennon", + "Lennox", + "Lenny", + "Lenworth", + "Leo", + "Leon", + "Leonardo", + "Leonel", + "Leonid", + "Leonidas", + "Leopold", + "Leopoldo", + "Leor", + "Leron", + "Leroy", + "Les", + "Lester", + "Lev", + "Levan", + "Levar", + "Levent", + "Levi", + "Levon", + "Levy", + "Lew", + "Lewis", + "Lex", + "Liam", + "Liang", + "Lincoln", + "Linden", + "Lino", + "Linton", + "Linus", + "Lionel", + "Lior", + "Liran", + "Lisandro", + "Lito", + "Livingston", + "Livio", + "Lloyd", + "Lobsang", + "Logan", + "Lon", + "Long", + "Lonnie", + "Lonny", + "Lord", + "Lorenzo", + "Lorne", + "Los", + "Lou", + "Louie", + "Louis", + "Lovell", + "Lowell", + "Luan", + "Luc", + "Luca", + "Lucas", + "Lucian", + "Luciano", + "Lucien", + "Lucio", + "Lucius", + "Lucky", + "Ludovic", + "Lui", + "Luigi", + "Luiz", + "Lukas", + "Lukasz", + "Luke", + "Luther", + "Luís", + "Lyle", + "Lyndon", + "Léonard", + "Maarten", + "Mac", + "Macho", + "Maciej", + "Maciek", + "Mack", + "Macky", + "Mad", + "Magdy", + "Maged", + "Magnus", + "Mahdi", + "Mahendra", + "Maher", + "Mahesh", + "Mahmood", + "Mahmoud", + "Mahmud", + "Mahmut", + "Maine", + "Majed", + "Majid", + "Major", + "Makoto", + "Maksim", + "Mal", + "Malachi", + "Malcolm", + "Malek", + "Malick", + "Malik", + "Malvin", + "Mamadou", + "Mamun", + "Man", + "Mandeep", + "Manfred", + "Manhattan", + "Manish", + "Manjit", + "Manny", + "Manoj", + "Manolo", + "Manpreet", + "Mansoor", + "Manu", + "Manuel", + "Maor", + "Marat", + "Marc", + "Marcel", + "Marcelino", + "Marcell", + "Marcello", + "Marcellus", + "Marcelo", + "Marcial", + "Marcin", + "Marcio", + "Marco", + "Marcos", + "Marcus", + "Marek", + "Mariano", + "Marino", + "Mario", + "Marios", + "Marius", + "Mariusz", + "Mark", + "Markie", + "Marko", + "Markos", + "Markus", + "Marlon", + "Marques", + "Marquis", + "Marquise", + "Marshall", + "Martin", + "Martinez", + "Marty", + "Marv", + "Marvelous", + "Marvin", + "Marwan", + "Masahiro", + "Masaki", + "Mason", + "Masood", + "Massimiliano", + "Massimo", + "Masud", + "Masum", + "Mat", + "Matan", + "Mateo", + "Mateusz", + "Mathew", + "Mathias", + "Mathieu", + "Matt", + "Matteo", + "Matthew", + "Matthias", + "Matthieu", + "Mattia", + "Matty", + "Matías", + "Maurice", + "Mauricio", + "Maurizio", + "Mauro", + "Maury", + "Maverick", + "Max", + "Maxime", + "Maximilian", + "Maximiliano", + "Maximillian", + "Maximo", + "Maximus", + "Maxwell", + "Maxx", + "Maxím", + "Mayank", + "Mayer", + "Mayur", + "Mazen", + "Mega", + "Mehdi", + "Mehmet", + "Mehul", + "Meir", + "Mel", + "Melvin", + "Menachem", + "Mendel", + "Mendy", + "Meng", + "Merlin", + "Mert", + "Merv", + "Mervin", + "Mervyn", + "Mesut", + "Mete", + "Metin", + "Meyer", + "Mic", + "Micah", + "Michael", + "Michaelangelo", + "Micheal", + "Michel", + "Michelangelo", + "Michiel", + "Mick", + "Mickael", + "Mickel", + "Mickey", + "Micky", + "Mihai", + "Mihir", + "Mikael", + "Mike", + "Mikel", + "Mikey", + "Mikhail", + "Miko", + "Milan", + "Milen", + "Miles", + "Miller", + "Milo", + "Milos", + "Milton", + "Minh", + "Minister", + "Mir", + "Mirko", + "Miroslav", + "Mirsad", + "Mirza", + "Misael", + "Mista", + "Mitch", + "Mitchel", + "Mitchell", + "Mitesh", + "Mo", + "Modesto", + "Moe", + "Mohamad", + "Mohamed", + "Mohammad", + "Mohammed", + "Mohan", + "Mohd", + "Mohit", + "Mohsin", + "Moises", + "Moishe", + "Mon", + "Monte", + "Montgomery", + "Monti", + "Monty", + "Moo", + "Moose", + "Mordecai", + "Mordechai", + "Mordy", + "Moreno", + "Moritz", + "Morris", + "Morton", + "Morty", + "Moses", + "Moshe", + "Mostafa", + "Moti", + "Mounir", + "Mourad", + "Moussa", + "Moustafa", + "Moustapha", + "Muhamed", + "Muhammad", + "Muhammed", + "Mukesh", + "Mukund", + "Munir", + "Murad", + "Murat", + "Murray", + "Murtaza", + "Musa", + "Mustafa", + "Mustapha", + "Myke", + "Myles", + "Myron", + "Mïgûél", + "Nabeel", + "Nabil", + "Nacho", + "Nadav", + "Nadeem", + "Nader", + "Nadim", + "Nadir", + "Naeem", + "Naftali", + "Nahum", + "Naim", + "Naj", + "Najee", + "Nalin", + "Nam", + "Naman", + "Nando", + "Naoki", + "Napoleon", + "Naquan", + "Narayan", + "Narciso", + "Narendra", + "Naresh", + "Nas", + "Nash", + "Nasir", + "Nasser", + "Nat", + "Natale", + "Natan", + "Nate", + "Nathan", + "Nathanael", + "Nathaniel", + "Nauman", + "Naveed", + "Naveen", + "Navin", + "Nazir", + "Nazmul", + "Neal", + "Ned", + "Neel", + "Neeraj", + "Neftali", + "Neil", + "Neill", + "Nelson", + "Nemo", + "Nenad", + "Neo", + "Ness", + "Nestor", + "Netanel", + "Neville", + "Nevin", + "New", + "Newton", + "Niall", + "Nic", + "Nicholas", + "Nick", + "Nickolas", + "Nico", + "Nicolai", + "Nicolo", + "Nicolás", + "Nigel", + "Nii", + "Nik", + "Nikhil", + "Nikko", + "Niklas", + "Niko", + "Nikola", + "Nikolai", + "Nikolaos", + "Nikolas", + "Nikolay", + "Nikos", + "Nile", + "Niles", + "Nilesh", + "Nils", + "Nimesh", + "Nimrod", + "Nino", + "Nir", + "Niraj", + "Nirav", + "Nishant", + "Nishit", + "Nissim", + "Nitin", + "Nitzan", + "Nixon", + "Nkosi", + "Nnamdi", + "No", + "Noah", + "Noam", + "Noble", + "Noe", + "Noel", + "Nolan", + "Noman", + "Norbert", + "Norberto", + "Norm", + "Norman", + "Norris", + "Nour", + "Nuno", + "Nunzio", + "Nuri", + "Ny", + "Nyc", + "Nyu", + "Obi", + "Obinna", + "Octavio", + "Odell", + "Ofer", + "Ofir", + "Oguz", + "Ohad", + "Okan", + "Oktay", + "Olaf", + "Olando", + "Ole", + "Oleg", + "Oli", + "Oliver", + "Olivier", + "Olu", + "Olufemi", + "Om", + "Omar", + "Omari", + "Omer", + "Omid", + "Omri", + "Oneal", + "Oneil", + "Onur", + "Or", + "Oral", + "Orel", + "Oren", + "Orestes", + "Orhan", + "Ori", + "Orin", + "Orion", + "Orlando", + "Orrin", + "Orson", + "Orville", + "Osama", + "Osei", + "Oshane", + "Osiris", + "Oskar", + "Osman", + "Osvaldo", + "Oswald", + "Oswaldo", + "Otis", + "Otto", + "Oumar", + "Ousmane", + "Owen", + "Oz", + "Ozan", + "Ozzie", + "Ozzy", + "Pa", + "Paa", + "Pablo", + "Paco", + "Paddy", + "Palmer", + "Pan", + "Panagiotis", + "Pankaj", + "Panos", + "Pantelis", + "Paolo", + "Papa", + "Pape", + "Papi", + "Papito", + "Papo", + "Parag", + "Paresh", + "Parker", + "Parth", + "Partha", + "Pasang", + "Pascal", + "Pascual", + "Pasha", + "Pasquale", + "Pastor", + "Patel", + "Patric", + "Patricio", + "Patrick", + "Patrik", + "Patryk", + "Paul", + "Paulie", + "Paulo", + "Pavan", + "Pavel", + "Pavlo", + "Pawan", + "Pawel", + "Pedro", + "Peng", + "Pepe", + "Percy", + "Pernell", + "Perry", + "Petar", + "Pete", + "Peter", + "Peterson", + "Petey", + "Petr", + "Petros", + "Phil", + "Philip", + "Philipp", + "Philippe", + "Phill", + "Phillip", + "Philly", + "Pierce", + "Piero", + "Pierre", + "Pieter", + "Pietro", + "Pinny", + "Piotr", + "Pito", + "Piyush", + "Polo", + "Pop", + "Porfirio", + "Power", + "Pradeep", + "Prakash", + "Pranav", + "Prasad", + "Prasanna", + "Prashant", + "Prashanth", + "Prateek", + "Pratik", + "Praveen", + "Pravin", + "Prem", + "Preston", + "Price", + "Prince", + "Przemyslaw", + "Puneet", + "Punit", + "Qamar", + "Qasim", + "Qiang", + "Qin", + "Quan", + "Quang", + "Que", + "Quentin", + "Quincy", + "Quintin", + "Quinton", + "Ra", + "Rabbi", + "Rachid", + "Rad", + "Radames", + "Radhames", + "Radu", + "Raf", + "Rafa", + "Rafael", + "Rafal", + "Raffaele", + "Raffi", + "Raffy", + "Rafi", + "Rafiq", + "Raghav", + "Raghu", + "Rah", + "Raheem", + "Rahiem", + "Rahim", + "Rahman", + "Rahmel", + "Rahsaan", + "Rahul", + "Rainer", + "Rainier", + "Raj", + "Raja", + "Rajan", + "Rajat", + "Rajeev", + "Rajendra", + "Rajesh", + "Rajib", + "Rajiv", + "Raju", + "Rakesh", + "Ralf", + "Ralph", + "Ralphie", + "Ralphy", + "Ralston", + "Ram", + "Raman", + "Ramazan", + "Ramel", + "Ramell", + "Ramesh", + "Ramez", + "Rami", + "Ramin", + "Ramiro", + "Ramon", + "Ramone", + "Ramsay", + "Ramses", + "Ramsey", + "Ramy", + "Ramzy", + "Ran", + "Rand", + "Randal", + "Randall", + "Randell", + "Randolph", + "Randy", + "Ranjit", + "Rany", + "Raoul", + "Raphael", + "Ras", + "Rasean", + "Rashaad", + "Rashaan", + "Rashad", + "Rashard", + "Rashaun", + "Rashawn", + "Rasheed", + "Rasheem", + "Rasheen", + "Rashid", + "Rashon", + "Ravi", + "Ravin", + "Ravinder", + "Ravindra", + "Rawle", + "Ray", + "Rayan", + "Raymon", + "Raymond", + "Raymundo", + "Raynard", + "Rayon", + "Rayshawn", + "Raz", + "Raza", + "Raúl", + "Real", + "Rebel", + "Red", + "Reda", + "Reece", + "Reed", + "Reg", + "Reggie", + "Reginald", + "Regis", + "Rehan", + "Reid", + "Reinaldo", + "Rell", + "Remi", + "Remon", + "Remy", + "Renaldo", + "Renan", + "Renard", + "Renato", + "Rene", + "Renny", + "Reno", + "Renzo", + "Reuben", + "Reuel", + "Reuven", + "Rex", + "Rey", + "Reyes", + "Reynaldo", + "Reynold", + "Reza", + "Rhys", + "Riad", + "Rian", + "Riaz", + "Ric", + "Ricardo", + "Riccardo", + "Rich", + "Richard", + "Richardson", + "Richie", + "Richmond", + "Richy", + "Rick", + "Rickey", + "Ricky", + "Rico", + "Ridwan", + "Rifat", + "Rigo", + "Rigoberto", + "Rik", + "Riley", + "Rino", + "Rip", + "Rishabh", + "Rishi", + "Ritchie", + "Rizwan", + "Rob", + "Robb", + "Robbie", + "Robby", + "Robert", + "Roberto", + "Robinson", + "Robson", + "Roby", + "Rocco", + "Rocko", + "Rocky", + "Rod", + "Roddy", + "Roderick", + "Rodger", + "Rodolfo", + "Rodrigo", + "Roee", + "Rogelio", + "Roger", + "Rohan", + "Rohit", + "Roi", + "Roland", + "Rolando", + "Rolf", + "Romain", + "Roman", + "Romano", + "Rome", + "Romel", + "Romeo", + "Romero", + "Rommel", + "Ron", + "Ronak", + "Ronald", + "Ronaldo", + "Ronan", + "Rondell", + "Ronen", + "Rong", + "Ronn", + "Ronnell", + "Ronnie", + "Ronny", + "Rony", + "Roody", + "Roosevelt", + "Roque", + "Rory", + "Roscoe", + "Rosendo", + "Roshan", + "Ross", + "Rostislav", + "Rowan", + "Roy", + "Royal", + "Royce", + "Rubens", + "Rubin", + "Rubén", + "Ruddy", + "Rudi", + "Rudolf", + "Rudolph", + "Rudy", + "Ruel", + "Rufus", + "Ruhul", + "Rui", + "Rupert", + "Rush", + "Ruslan", + "Russ", + "Russel", + "Russell", + "Rustam", + "Rusty", + "Ryan", + "Ryo", + "Ryota", + "Ryu", + "Ródney", + "Saad", + "Sabin", + "Sachin", + "Sadik", + "Saeed", + "Safet", + "Safi", + "Safraz", + "Sagar", + "Sahil", + "Said", + "Saif", + "Saiful", + "Saint", + "Sajal", + "Sajid", + "Sal", + "Salah", + "Saleem", + "Saleh", + "Salem", + "Salih", + "Salim", + "Salman", + "Salomon", + "Salvador", + "Salvatore", + "Salvo", + "Sam", + "Sameer", + "Sameh", + "Samer", + "Samet", + "Sami", + "Samir", + "Samit", + "Samm", + "Sammy", + "Sampath", + "Samson", + "Samuel", + "Samy", + "San", + "Sanchez", + "Sandeep", + "Sander", + "Sandip", + "Sandor", + "Sandro", + "Sanford", + "Sang", + "Sanjay", + "Sanjeev", + "Santhosh", + "Santi", + "Santiago", + "Santino", + "Santo", + "Santos", + "Santosh", + "Sapan", + "Sarwar", + "Sasa", + "Sascha", + "Sat", + "Satish", + "Satoshi", + "Saud", + "Saul", + "Saurabh", + "Saverio", + "Savvas", + "Sayed", + "Scooter", + "Scot", + "Scott", + "Scottie", + "Scotty", + "Sead", + "Seamus", + "Sean", + "Seb", + "Sebastian", + "Sebastiano", + "Sebastien", + "Sedat", + "Segun", + "Sekou", + "Selcuk", + "Selim", + "Selwyn", + "Semih", + "Sen", + "Senad", + "Seneca", + "Seon", + "Serdar", + "Serge", + "Sergei", + "Sergey", + "Sergio", + "Serkan", + "Seth", + "Seung", + "Seymour", + "Shaan", + "Shabazz", + "Shachar", + "Shad", + "Shadi", + "Shadrack", + "Shady", + "Shah", + "Shahar", + "Shahed", + "Shahid", + "Shahriar", + "Shahzad", + "Shai", + "Shailesh", + "Shain", + "Shaka", + "Shakeel", + "Shakeem", + "Shakil", + "Shakim", + "Shakir", + "Shalom", + "Shamar", + "Shamari", + "Shameek", + "Shameer", + "Shamel", + "Shamil", + "Shamim", + "Shamir", + "Shane", + "Shankar", + "Shantanu", + "Shao", + "Shaquille", + "Sharad", + "Sharath", + "Shareef", + "Sharif", + "Shariff", + "Sharod", + "Shashank", + "Shaul", + "Shaun", + "Shawn", + "Shayan", + "Sheik", + "Sheikh", + "Sheldon", + "Shelton", + "Shem", + "Sheng", + "Sherard", + "Sheraz", + "Sherif", + "Sherman", + "Sherwin", + "Shiloh", + "Shimi", + "Shimon", + "Shinya", + "Shiraz", + "Shiv", + "Shivam", + "Shlomi", + "Shlomo", + "Shmuel", + "Sho", + "Shoaib", + "Sholom", + "Shomari", + "Shon", + "Shotta", + "Showtime", + "Shun", + "Shyam", + "Si", + "Sid", + "Siddharth", + "Sidney", + "Sigmund", + "Silas", + "Silvestre", + "Silvio", + "Sim", + "Simba", + "Simcha", + "Simeon", + "Simo", + "Simón", + "Sinan", + "Sincere", + "Sion", + "Sixto", + "Skender", + "Skip", + "Sky", + "Skyler", + "Slava", + "Slawomir", + "Slick", + "Sly", + "Sneaker", + "Snoopy", + "Socrates", + "Sohail", + "Sohan", + "Sohel", + "Sokol", + "Sola", + "Solomon", + "Son", + "Soner", + "Sonny", + "Sonu", + "Soren", + "Sourav", + "Sparky", + "Spencer", + "Spike", + "Spiro", + "Spiros", + "Spyros", + "Sree", + "Sridhar", + "Srikanth", + "Srinivas", + "Sriram", + "Sruly", + "Stalin", + "Stan", + "Stanford", + "Stanislav", + "Stanley", + "Stanton", + "Stas", + "Stash", + "Stavros", + "Stay", + "Steeve", + "Stefan", + "Stefano", + "Stefanos", + "Steffan", + "Steffen", + "Steffon", + "Stefon", + "Stelios", + "Stephane", + "Stephen", + "Stephon", + "Sterling", + "Stevan", + "Steve", + "Steven", + "Stevens", + "Stevenson", + "Stewart", + "Stone", + "Storm", + "Street", + "Stu", + "Stuart", + "Stéphan", + "Sudesh", + "Sudhir", + "Sujan", + "Sujit", + "Suk", + "Sule", + "Sulejman", + "Suleyman", + "Sultan", + "Suman", + "Sumeet", + "Sumit", + "Sumon", + "Sundeep", + "Sungmin", + "Sunil", + "Sunny", + "Supa", + "Suraj", + "Surendra", + "Suresh", + "Sushil", + "Sven", + "Swapnil", + "Sy", + "Syd", + "Syed", + "Sylvain", + "Sylvester", + "Taco", + "Tad", + "Tae", + "Tafari", + "Tag", + "Tah", + "Taha", + "Tahir", + "Tahsin", + "Taimur", + "Taj", + "Taji", + "Taka", + "Takashi", + "Takeshi", + "Takuya", + "Tal", + "Talal", + "Talha", + "Tamas", + "Tamer", + "Tamir", + "Tan", + "Taner", + "Tang", + "Tanner", + "Tanveer", + "Tanvir", + "Tao", + "Tapan", + "Taras", + "Tarek", + "Tareq", + "Tarik", + "Tariq", + "Taro", + "Tarrell", + "Tarun", + "Tate", + "Taurean", + "Taye", + "Tayo", + "Taz", + "Ted", + "Tedd", + "Teddy", + "Teejay", + "Tejas", + "Telly", + "Tenzin", + "Teo", + "Terell", + "Terence", + "Teron", + "Terrance", + "Terrel", + "Terrell", + "Terrence", + "Terron", + "Tesfa", + "Tevin", + "Tevon", + "Tha", + "Thad", + "Thaddeus", + "Thai", + "Thanh", + "The", + "Theo", + "Theodore", + "Theophilus", + "Theron", + "Thiago", + "Thierry", + "Thom", + "Thomas", + "Thompson", + "Thor", + "Thupten", + "Tiago", + "Tibor", + "Tiger", + "Tim", + "Timmy", + "Timo", + "Timothy", + "Timur", + "Tino", + "Tito", + "Titus", + "Tobias", + "Tod", + "Todd", + "Tolga", + "Tom", + "Tomasz", + "Tomer", + "Tommaso", + "Tommy", + "Tomo", + "Tomás", + "Tone", + "Toney", + "Tong", + "Tonny", + "Tony", + "Topher", + "Tor", + "Torres", + "Torrey", + "Toshi", + "Trace", + "Travis", + "Travon", + "Tre", + "Tremaine", + "Tremayne", + "Trent", + "Trenton", + "Tres", + "Trevon", + "Trevor", + "Trey", + "Tri", + "Trip", + "Tripp", + "Tris", + "Tristan", + "Tristian", + "Troy", + "Truman", + "Trung", + "Tsering", + "Tu", + "Tuan", + "Tucker", + "Tudor", + "Tuna", + "Tunde", + "Tushar", + "Ty", + "Tye", + "Tyler", + "Tyquan", + "Tyree", + "Tyreek", + "Tyrel", + "Tyrell", + "Tyrese", + "Tyron", + "Tyrone", + "Tyshawn", + "Tyson", + "Tzvi", + "Uche", + "Uday", + "Udi", + "Ufuk", + "Ugo", + "Uli", + "Ulises", + "Ulrich", + "Ulysses", + "Umair", + "Umar", + "Umberto", + "Umer", + "Umesh", + "Umit", + "Umut", + "Uri", + "Uriah", + "Uriel", + "Usman", + "Utku", + "Uwe", + "Uzair", + "Uzi", + "Uğur", + "Vadim", + "Vaibhav", + "Valentin", + "Valentino", + "Valerio", + "Vamsi", + "Van", + "Vance", + "Varun", + "Vasili", + "Vasilios", + "Vasilis", + "Vasiliy", + "Vaughn", + "Vedat", + "Vega", + "Venu", + "Vern", + "Vernon", + "Vic", + "Vicente", + "Vick", + "Vidal", + "Vijay", + "Vik", + "Vikas", + "Vikash", + "Vikram", + "Viktor", + "Vimal", + "Vin", + "Vinay", + "Vince", + "Vincent", + "Vincenzo", + "Vineet", + "Vinh", + "Vinit", + "Vinnie", + "Vinny", + "Vinod", + "Vinson", + "Vipin", + "Vipul", + "Viraj", + "Virgil", + "Virgilio", + "Vishal", + "Vishnu", + "Vitaliy", + "Vitaly", + "Vito", + "Vittorio", + "Vivek", + "Vlad", + "Vladimir", + "Vladislav", + "Volkan", + "Volodymyr", + "Von", + "Vu", + "Víctor", + "Wade", + "Wael", + "Wagner", + "Wah", + "Wahid", + "Waldemar", + "Waldo", + "Waldy", + "Wale", + "Waleed", + "Walid", + "Walker", + "Wallace", + "Wally", + "Walt", + "Walter", + "Wang", + "Waqas", + "Ward", + "Warner", + "Warren", + "Waseem", + "Washington", + "Wayne", + "We", + "Webster", + "Wei", + "Wellington", + "Wendell", + "Werner", + "Wes", + "Wesley", + "Westley", + "Weston", + "Whit", + "White", + "Wil", + "Wilber", + "Wilbert", + "Wilberto", + "Wilbur", + "Wild", + "Wilder", + "Wiley", + "Wilfred", + "Wilfredo", + "Wilfrido", + "Wiliam", + "Wilkins", + "Will", + "Willam", + "Willard", + "Willem", + "William", + "Willie", + "Willis", + "Willy", + "Wilmer", + "Wilson", + "Wilton", + "Win", + "Winson", + "Winston", + "Wissam", + "Wojciech", + "Wojtek", + "Wolf", + "Wolfgang", + "Won", + "Wong", + "Woo", + "Woodley", + "Woodrow", + "Woody", + "Wu", + "Wyatt", + "Wylie", + "Wynn", + "Xander", + "Xavier", + "Xin", + "Xu", + "Yaakov", + "Yahya", + "Yair", + "Yakov", + "Yale", + "Yamil", + "Yamin", + "Yancy", + "Yaniv", + "Yanky", + "Yann", + "Yanni", + "Yannick", + "Yaron", + "Yaroslav", + "Yash", + "Yasha", + "Yasin", + "Yasir", + "Yasser", + "Yassin", + "Yassine", + "Yaw", + "Yaşar", + "Yechiel", + "Yefim", + "Yehuda", + "Yehudah", + "Yeon", + "Yevgeniy", + "Yianni", + "Yiannis", + "Yigal", + "Yilmaz", + "Yinka", + "Yisroel", + "Yitz", + "Yitzchok", + "Yitzy", + "Ylli", + "Yoann", + "Yoav", + "Yoel", + "Yoeli", + "Yoely", + "Yogesh", + "Yogi", + "Yohan", + "Yomi", + "Yonatan", + "Yong", + "Yoni", + "Yoram", + "York", + "Yosef", + "Yoshi", + "Yosi", + "Yossi", + "Yosuke", + "Yotam", + "You", + "Younes", + "Young", + "Yousef", + "Youssef", + "Yuji", + "Yung", + "Yunus", + "Yuriy", + "Yury", + "Yusef", + "Yusuf", + "Yusuke", + "Yuuki", + "Yuval", + "Yves", + "Zac", + "Zach", + "Zachariah", + "Zachary", + "Zack", + "Zafar", + "Zafer", + "Zaheer", + "Zahid", + "Zahir", + "Zaid", + "Zain", + "Zak", + "Zakaria", + "Zaki", + "Zakir", + "Zalman", + "Zane", + "Zap", + "Zee", + "Zeeshan", + "Zeke", + "Zeljko", + "Zeshan", + "Zeus", + "Zev", + "Zhe", + "Zhi", + "Zhuo", + "Ziad", + "Ziggy", + "Zion", + "Zohaib", + "Zohar", + "Zoltán", + "Zoran", + "Zsolt", + "Zubair", + "Zvi" +] + +const _last_names = [ + "Aaberg", + "Aalst", + "Aara", + "Aaren", + "Aarika", + "Aaron", + "Aaronson", + "Ab", + "Aba", + "Abad", + "Abagael", + "Abagail", + "Abana", + "Abate", + "Abba", + "Abbate", + "Abbe", + "Abbey", + "Abbi", + "Abbie", + "Abbot", + "Abbotsen", + "Abbotson", + "Abbotsun", + "Abbott", + "Abbottson", + "Abby", + "Abbye", + "Abdel", + "Abdella", + "Abdu", + "Abdul", + "Abdulla", + "Abe", + "Abebi", + "Abel", + "Abelard", + "Abell", + "Abercromby", + "Abernathy", + "Abernon", + "Abert", + "Abeu", + "Abey", + "Abie", + "Abigael", + "Abigail", + "Abigale", + "Abijah", + "Abisha", + "Abisia", + "Abixah", + "Abner", + "Aborn", + "Abott", + "Abra", + "Abraham", + "Abrahams", + "Abrahamsen", + "Abrahan", + "Abram", + "Abramo", + "Abrams", + "Abramson", + "Abran", + "Abroms", + "Absa", + "Absalom", + "Abshier", + "Acacia", + "Acalia", + "Accalia", + "Ace", + "Acey", + "Acherman", + "Achilles", + "Achorn", + "Acie", + "Acima", + "Acker", + "Ackerley", + "Ackerman", + "Ackler", + "Ackley", + "Acquah", + "Acus", + "Ad", + "Ada", + "Adabel", + "Adabelle", + "Adachi", + "Adah", + "Adaha", + "Adai", + "Adaiha", + "Adair", + "Adal", + "Adala", + "Adalai", + "Adalard", + "Adalbert", + "Adalheid", + "Adali", + "Adalia", + "Adaliah", + "Adalie", + "Adaline", + "Adall", + "Adallard", + "Adam", + "Adama", + "Adamec", + "Adamek", + "Adamik", + "Adamina", + "Adaminah", + "Adamis", + "Adamo", + "Adamok", + "Adams", + "Adamsen", + "Adamski", + "Adamson", + "Adamsun", + "Adan", + "Adao", + "Adar", + "Adara", + "Adaurd", + "Aday", + "Adda", + "Addam", + "Addi", + "Addia", + "Addie", + "Addiego", + "Addiel", + "Addis", + "Addison", + "Addy", + "Ade", + "Adebayo", + "Adel", + "Adela", + "Adelaida", + "Adelaide", + "Adelaja", + "Adelbert", + "Adele", + "Adelheid", + "Adelia", + "Adelice", + "Adelina", + "Adelind", + "Adeline", + "Adella", + "Adelle", + "Adelpho", + "Adelric", + "Adena", + "Ader", + "Adest", + "Adey", + "Adham", + "Adhamh", + "Adhern", + "Adi", + "Adiana", + "Adiel", + "Adiell", + "Adigun", + "Adila", + "Adim", + "Adin", + "Adina", + "Adine", + "Adis", + "Adkins", + "Adlai", + "Adlar", + "Adlare", + "Adlay", + "Adlee", + "Adlei", + "Adler", + "Adley", + "Adna", + "Adnah", + "Adne", + "Adnopoz", + "Ado", + "Adolf", + "Adolfo", + "Adolph", + "Adolphe", + "Adolpho", + "Adolphus", + "Adon", + "Adonis", + "Adora", + "Adore", + "Adoree", + "Adorl", + "Adorne", + "Adrea", + "Adrell", + "Adria", + "Adriaens", + "Adrial", + "Adrian", + "Adriana", + "Adriane", + "Adrianna", + "Adrianne", + "Adriano", + "Adriel", + "Adriell", + "Adrien", + "Adriena", + "Adriene", + "Adrienne", + "Adur", + "Aekerly", + "Aelber", + "Aenea", + "Aeneas", + "Aeneus", + "Aeniah", + "Aenneea", + "Aeriel", + "Aeriela", + "Aeriell", + "Affer", + "Affra", + "Affrica", + "Afra", + "Africa", + "Africah", + "Afrika", + "Afrikah", + "Afton", + "Ag", + "Agace", + "Agamemnon", + "Agan", + "Agata", + "Agate", + "Agatha", + "Agathe", + "Agathy", + "Agbogla", + "Agee", + "Aggappe", + "Aggappera", + "Aggappora", + "Aggarwal", + "Aggi", + "Aggie", + "Aggri", + "Aggy", + "Agle", + "Agler", + "Agna", + "Agnella", + "Agnes", + "Agnese", + "Agnesse", + "Agneta", + "Agnew", + "Agnola", + "Agostino", + "Agosto", + "Agretha", + "Agripina", + "Agrippina", + "Aguayo", + "Agueda", + "Aguie", + "Aguste", + "Agustin", + "Ahab", + "Aharon", + "Ahasuerus", + "Ahders", + "Ahearn", + "Ahern", + "Ahl", + "Ahlgren", + "Ahmad", + "Ahmar", + "Ahmed", + "Ahola", + "Aholah", + "Aholla", + "Ahoufe", + "Ahouh", + "Ahrendt", + "Ahrens", + "Ahron", + "Aia", + "Aida", + "Aidan", + "Aiden", + "Aiello", + "Aigneis", + "Aiken", + "Aila", + "Ailbert", + "Aile", + "Ailee", + "Aileen", + "Ailene", + "Ailey", + "Aili", + "Ailin", + "Ailina", + "Ailis", + "Ailsa", + "Ailssa", + "Ailsun", + "Ailyn", + "Aime", + "Aimee", + "Aimil", + "Aimo", + "Aindrea", + "Ainslee", + "Ainsley", + "Ainslie", + "Ainsworth", + "Airel", + "Aires", + "Airla", + "Airlee", + "Airlia", + "Airliah", + "Airlie", + "Aisha", + "Ajani", + "Ajax", + "Ajay", + "Ajit", + "Akanke", + "Akel", + "Akela", + "Aker", + "Akerboom", + "Akerley", + "Akers", + "Akeyla", + "Akeylah", + "Akili", + "Akim", + "Akin", + "Akins", + "Akira", + "Aklog", + "Aksel", + "Aksoyn", + "Al", + "Alabaster", + "Alage", + "Alain", + "Alaine", + "Alair", + "Alake", + "Alameda", + "Alan", + "Alana", + "Alanah", + "Aland", + "Alane", + "Alanna", + "Alano", + "Alansen", + "Alanson", + "Alard", + "Alaric", + "Alarice", + "Alarick", + "Alarise", + "Alasdair", + "Alastair", + "Alasteir", + "Alaster", + "Alatea", + "Alathia", + "Alayne", + "Alba", + "Alban", + "Albarran", + "Albemarle", + "Alben", + "Alber", + "Alberic", + "Alberik", + "Albers", + "Albert", + "Alberta", + "Albertina", + "Albertine", + "Alberto", + "Albertson", + "Albie", + "Albin", + "Albina", + "Albion", + "Alboran", + "Albrecht", + "Albric", + "Albright", + "Albur", + "Alburg", + "Alburga", + "Alby", + "Alcina", + "Alcine", + "Alcinia", + "Alcock", + "Alcot", + "Alcott", + "Alcus", + "Alda", + "Aldarcie", + "Aldarcy", + "Aldas", + "Alded", + "Alden", + "Aldercy", + "Alderman", + "Alderson", + "Aldin", + "Aldis", + "Aldo", + "Aldon", + "Aldora", + "Aldos", + "Aldous", + "Aldred", + "Aldredge", + "Aldric", + "Aldrich", + "Aldridge", + "Alduino", + "Aldus", + "Aldwin", + "Aldwon", + "Alec", + "Alecia", + "Aleck", + "Aleda", + "Aleece", + "Aleedis", + "Aleen", + "Aleetha", + "Alegre", + "Alejandra", + "Alejandrina", + "Alejandro", + "Alejo", + "Alejoa", + "Alek", + "Aleksandr", + "Alena", + "Alene", + "Alenson", + "Aleras", + "Aleris", + "Aleron", + "Alesandrini", + "Alessandra", + "Alessandro", + "Aleta", + "Aletha", + "Alethea", + "Alethia", + "Aletta", + "Alex", + "Alexa", + "Alexander", + "Alexandr", + "Alexandra", + "Alexandre", + "Alexandria", + "Alexandrina", + "Alexandro", + "Alexandros", + "Alexei", + "Alexi", + "Alexia", + "Alexina", + "Alexine", + "Alexio", + "Alexis", + "Aley", + "Aleydis", + "Alf", + "Alfeus", + "Alfi", + "Alfie", + "Alfons", + "Alfonse", + "Alfonso", + "Alfonzo", + "Alford", + "Alfred", + "Alfreda", + "Alfredo", + "Alfy", + "Algar", + "Alger", + "Algernon", + "Algie", + "Alguire", + "Algy", + "Ali", + "Alia", + "Aliber", + "Alic", + "Alica", + "Alice", + "Alicea", + "Alicia", + "Alick", + "Alida", + "Alidia", + "Alidis", + "Alidus", + "Alie", + "Alika", + "Alikee", + "Alina", + "Aline", + "Alinna", + "Alis", + "Alisa", + "Alisan", + "Alisander", + "Alisen", + "Alisha", + "Alisia", + "Alison", + "Alissa", + "Alistair", + "Alister", + "Alisun", + "Alita", + "Alitha", + "Alithea", + "Alithia", + "Alitta", + "Alius", + "Alix", + "Aliza", + "Alla", + "Allain", + "Allan", + "Allana", + "Allanson", + "Allard", + "Allare", + "Allayne", + "Allbee", + "Allcot", + "Alleen", + "Allegra", + "Allen", + "Allene", + "Alleras", + "Allerie", + "Alleris", + "Allerus", + "Alley", + "Alleyn", + "Alleyne", + "Alli", + "Allianora", + "Alliber", + "Allie", + "Allin", + "Allina", + "Allis", + "Allisan", + "Allison", + "Allissa", + "Allista", + "Allister", + "Allistir", + "Allix", + "Allmon", + "Allred", + "Allrud", + "Allsopp", + "Allsun", + "Allveta", + "Allwein", + "Allx", + "Ally", + "Allyce", + "Allyn", + "Allys", + "Allyson", + "Alma", + "Almallah", + "Almeda", + "Almeeta", + "Almeida", + "Almena", + "Almeria", + "Almeta", + "Almira", + "Almire", + "Almita", + "Almond", + "Almund", + "Alo", + "Alodee", + "Alodi", + "Alodie", + "Aloin", + "Aloise", + "Aloisia", + "Aloisius", + "Aloke", + "Alon", + "Alonso", + "Alonzo", + "Aloysia", + "Aloysius", + "Alper", + "Alpers", + "Alpert", + "Alphard", + "Alpheus", + "Alphonsa", + "Alphonse", + "Alphonsine", + "Alphonso", + "AlrZc", + "Alric", + "Alrich", + "Alrick", + "Alroi", + "Alroy", + "Also", + "Alston", + "Alsworth", + "Alta", + "Altaf", + "Alten", + "Althea", + "Althee", + "Altheta", + "Altis", + "Altman", + "Alton", + "Aluin", + "Aluino", + "Alurd", + "Alurta", + "Alva", + "Alvan", + "Alvar", + "Alvarez", + "Alver", + "Alvera", + "Alverson", + "Alverta", + "Alves", + "Alveta", + "Alviani", + "Alvie", + "Alvin", + "Alvina", + "Alvinia", + "Alvira", + "Alvis", + "Alvita", + "Alvord", + "Alvy", + "Alwin", + "Alwitt", + "Alwyn", + "Alyce", + "Alyda", + "Alyose", + "Alyosha", + "Alys", + "Alysa", + "Alyse", + "Alysia", + "Alyson", + "Alysoun", + "Alyss", + "Alyssa", + "Alyworth", + "Ama", + "Amabel", + "Amabelle", + "Amabil", + "Amadas", + "Amadeo", + "Amadeus", + "Amadis", + "Amado", + "Amador", + "Amadus", + "Amal", + "Amalbena", + "Amalberga", + "Amalbergas", + "Amalburga", + "Amalea", + "Amalee", + "Amaleta", + "Amalia", + "Amalie", + "Amalita", + "Amalle", + "Aman", + "Amand", + "Amanda", + "Amandi", + "Amandie", + "Amando", + "Amandy", + "Amann", + "Amar", + "Amara", + "Amaral", + "Amaras", + "Amarette", + "Amargo", + "Amari", + "Amarillas", + "Amarillis", + "Amaris", + "Amary", + "Amaryl", + "Amaryllis", + "Amasa", + "Amata", + "Amathist", + "Amathiste", + "Amati", + "Amato", + "Amatruda", + "Amaty", + "Amber", + "Amberly", + "Ambert", + "Ambie", + "Amble", + "Ambler", + "Ambrogino", + "Ambrogio", + "Ambros", + "Ambrosane", + "Ambrose", + "Ambrosi", + "Ambrosia", + "Ambrosine", + "Ambrosio", + "Ambrosius", + "Ambur", + "Amby", + "Ame", + "Amedeo", + "Amelia", + "Amelie", + "Amelina", + "Ameline", + "Amelita", + "Amena", + "Amend", + "Amerigo", + "Amero", + "Amersham", + "Amery", + "Ames", + "Amethist", + "Amethyst", + "Ami", + "Amias", + "Amice", + "Amick", + "Amie", + "Amiel", + "Amieva", + "Amii", + "Amil", + "Amin", + "Aminta", + "Amir", + "Amitie", + "Amity", + "Amling", + "Ammadas", + "Ammadis", + "Ammamaria", + "Ammann", + "Ammon", + "Amoakuh", + "Amor", + "Amora", + "Amoreta", + "Amorete", + "Amorette", + "Amorita", + "Amoritta", + "Amory", + "Amos", + "Amr", + "Amrita", + "Amsden", + "Amund", + "Amy", + "Amyas", + "Amye", + "Am�lie", + "An", + "Ana", + "Anabal", + "Anabel", + "Anabella", + "Anabelle", + "Anagnos", + "Analiese", + "Analise", + "Anallese", + "Anallise", + "Anana", + "Ananna", + "Anastas", + "Anastase", + "Anastasia", + "Anastasie", + "Anastasio", + "Anastasius", + "Anastassia", + "Anastatius", + "Anastice", + "Anastos", + "Anatol", + "Anatola", + "Anatole", + "Anatolio", + "Anatollo", + "Ancalin", + "Ancel", + "Ancelin", + "Anceline", + "Ancell", + "Anchie", + "Ancier", + "Ancilin", + "Andee", + "Andeee", + "Andel", + "Ander", + "Anderea", + "Anderegg", + "Anderer", + "Anders", + "Andersen", + "Anderson", + "Andert", + "Andi", + "Andie", + "Andonis", + "Andra", + "Andrade", + "Andras", + "Andre", + "Andrea", + "Andreana", + "Andreas", + "Andree", + "Andrei", + "Andrej", + "Andrel", + "Andres", + "Andrew", + "Andrews", + "Andrey", + "Andri", + "Andria", + "Andriana", + "Andrien", + "Andriette", + "Andris", + "Andromache", + "Andromada", + "Andromeda", + "Andromede", + "Andros", + "Androw", + "Andrus", + "Andryc", + "Andy", + "Anestassia", + "Anet", + "Anett", + "Anetta", + "Anette", + "Aney", + "Angadreme", + "Angadresma", + "Ange", + "Angel", + "Angela", + "Angele", + "Angeli", + "Angelia", + "Angelica", + "Angelico", + "Angelika", + "Angelina", + "Angeline", + "Angelique", + "Angelis", + "Angelita", + "Angell", + "Angelle", + "Angelo", + "Angi", + "Angie", + "Angil", + "Angle", + "Anglim", + "Anglo", + "Angrist", + "Angus", + "Angy", + "Anh", + "Ania", + "Aniakudo", + "Anica", + "Aniela", + "Anil", + "Anis", + "Anissa", + "Anita", + "Anitra", + "Aniweta", + "Anjali", + "Anjanette", + "Anjela", + "Ankeny", + "Ankney", + "Ann", + "Ann-Marie", + "Anna", + "Anna-Diana", + "Anna-Diane", + "Anna-Maria", + "Annabal", + "Annabel", + "Annabela", + "Annabell", + "Annabella", + "Annabelle", + "Annadiana", + "Annadiane", + "Annalee", + "Annaliese", + "Annalise", + "Annamaria", + "Annamarie", + "Anne", + "Anne-Corinne", + "Anne-Marie", + "Annecorinne", + "Anneliese", + "Annelise", + "Annemarie", + "Annetta", + "Annette", + "Anni", + "Annia", + "Annice", + "Annie", + "Anniken", + "Annis", + "Annissa", + "Annmaria", + "Annmarie", + "Annnora", + "Annora", + "Annorah", + "Annunciata", + "Anny", + "Anora", + "Anse", + "Ansel", + "Ansela", + "Ansell", + "Anselm", + "Anselma", + "Anselme", + "Anselmi", + "Anselmo", + "Ansilma", + "Ansilme", + "Ansley", + "Anson", + "Anstice", + "Anstus", + "Antebi", + "Anthe", + "Anthea", + "Anthia", + "Anthiathia", + "Anthony", + "Antin", + "Antipas", + "Antipus", + "Antoine", + "Antoinetta", + "Antoinette", + "Anton", + "Antone", + "Antonella", + "Antonetta", + "Antoni", + "Antonia", + "Antonie", + "Antonietta", + "Antonin", + "Antonina", + "Antonino", + "Antonio", + "Antonius", + "Antons", + "Antony", + "Antrim", + "Anurag", + "Anuska", + "Any", + "Anya", + "Anyah", + "Anzovin", + "Apfel", + "Apfelstadt", + "Apgar", + "Aphra", + "Aphrodite", + "Apicella", + "Apollo", + "Apollus", + "Apostles", + "Appel", + "Apple", + "Appleby", + "Appledorf", + "Applegate", + "Appleton", + "Appolonia", + "Apps", + "April", + "Aprile", + "Aprilette", + "Apthorp", + "Apul", + "Ara", + "Arabeila", + "Arabel", + "Arabela", + "Arabele", + "Arabella", + "Arabelle", + "Arad", + "Arakawa", + "Araldo", + "Aramanta", + "Aramen", + "Aramenta", + "Araminta", + "Aran", + "Arand", + "Arathorn", + "Arbe", + "Arber", + "Arbuckle", + "Arch", + "Archaimbaud", + "Archambault", + "Archangel", + "Archer", + "Archibald", + "Archibaldo", + "Archibold", + "Archie", + "Archle", + "Archy", + "Ard", + "Arda", + "Ardath", + "Arde", + "Ardeen", + "Ardeha", + "Ardehs", + "Ardel", + "Ardelia", + "Ardelis", + "Ardell", + "Ardella", + "Ardelle", + "Arden", + "Ardene", + "Ardenia", + "Ardeth", + "Ardie", + "Ardin", + "Ardine", + "Ardis", + "Ardisj", + "Ardith", + "Ardme", + "Ardolino", + "Ardra", + "Ardrey", + "Ardussi", + "Ardy", + "Ardyce", + "Ardys", + "Ardyth", + "Arel", + "Arela", + "Arella", + "Arelus", + "Aret", + "Areta", + "Aretha", + "Aretina", + "Aretta", + "Arette", + "Arezzini", + "Argent", + "Argile", + "Argus", + "Argyle", + "Argyres", + "Arhna", + "Ari", + "Aria", + "Ariadne", + "Ariana", + "Ariane", + "Arianie", + "Arianna", + "Arianne", + "Aribold", + "Aric", + "Arica", + "Arick", + "Aridatha", + "Arie", + "Ariel", + "Ariela", + "Ariella", + "Arielle", + "Ariew", + "Arin", + "Ario", + "Arissa", + "Aristotle", + "Arita", + "Arjan", + "Arjun", + "Ark", + "Arlan", + "Arlana", + "Arlee", + "Arleen", + "Arlen", + "Arlena", + "Arlene", + "Arleta", + "Arlette", + "Arley", + "Arleyne", + "Arlie", + "Arliene", + "Arlin", + "Arlina", + "Arlinda", + "Arline", + "Arlo", + "Arlon", + "Arluene", + "Arly", + "Arlyn", + "Arlyne", + "Arlynne", + "Armalda", + "Armalla", + "Armallas", + "Arman", + "Armand", + "Armanda", + "Armando", + "Armbrecht", + "Armbruster", + "Armelda", + "Armil", + "Armilda", + "Armilla", + "Armillas", + "Armillda", + "Armillia", + "Armin", + "Armington", + "Armitage", + "Armond", + "Armstrong", + "Armyn", + "Arnaldo", + "Arnaud", + "Arndt", + "Arne", + "Arnelle", + "Arney", + "Arni", + "Arnie", + "Arno", + "Arnold", + "Arnoldo", + "Arnon", + "Arnst", + "Arnuad", + "Arnulfo", + "Arny", + "Arola", + "Aron", + "Arondel", + "Arondell", + "Aronoff", + "Aronow", + "Aronson", + "Arquit", + "Arratoon", + "Arri", + "Arria", + "Arrio", + "Arron", + "Arst", + "Art", + "Arta", + "Artair", + "Artamas", + "Arte", + "Artema", + "Artemas", + "Artemis", + "Artemisa", + "Artemisia", + "Artemus", + "Arther", + "Arthur", + "Artie", + "Artima", + "Artimas", + "Artina", + "Artur", + "Arturo", + "Artus", + "Arty", + "Aruabea", + "Arun", + "Arundel", + "Arundell", + "Arv", + "Arva", + "Arvad", + "Arvell", + "Arvid", + "Arvie", + "Arvin", + "Arvind", + "Arvo", + "Arvonio", + "Arvy", + "Ary", + "Aryn", + "As", + "Asa", + "Asabi", + "Asante", + "Asaph", + "Asare", + "Aschim", + "Ase", + "Asel", + "Ash", + "Asha", + "Ashbaugh", + "Ashbey", + "Ashby", + "Ashelman", + "Ashely", + "Asher", + "Ashford", + "Ashia", + "Ashien", + "Ashil", + "Ashjian", + "Ashla", + "Ashlan", + "Ashlee", + "Ashleigh", + "Ashlen", + "Ashley", + "Ashli", + "Ashlie", + "Ashlin", + "Ashling", + "Ashly", + "Ashman", + "Ashmead", + "Ashok", + "Ashraf", + "Ashti", + "Ashton", + "Ashwell", + "Ashwin", + "Asia", + "Askari", + "Askwith", + "Aslam", + "Asp", + "Aspa", + "Aspasia", + "Aspia", + "Asquith", + "Assisi", + "Asta", + "Astera", + "Asteria", + "Astor", + "Astra", + "Astraea", + "Astrahan", + "Astrea", + "Astred", + "Astri", + "Astrid", + "Astrix", + "Astto", + "Asuncion", + "Atal", + "Atalanta", + "Atalante", + "Atalanti", + "Atalaya", + "Atalayah", + "Atalee", + "Ataliah", + "Atalie", + "Atalya", + "Atcliffe", + "Athal", + "Athalee", + "Athalia", + "Athalie", + "Athalla", + "Athallia", + "Athelstan", + "Athena", + "Athene", + "Athenian", + "Athey", + "Athiste", + "Atiana", + "Atkins", + "Atkinson", + "Atlanta", + "Atlante", + "Atlas", + "Atlee", + "Atonsah", + "Atrice", + "Atronna", + "Attah", + "Attalanta", + "Attalie", + "Attenborough", + "Attenweiler", + "Atterbury", + "Atthia", + "Attlee", + "Attwood", + "Atul", + "Atwater", + "Atwekk", + "Atwood", + "Atworth", + "Au", + "Aubarta", + "Aube", + "Auberbach", + "Auberon", + "Aubert", + "Auberta", + "Aubigny", + "Aubin", + "Aubine", + "Aubree", + "Aubreir", + "Aubrette", + "Aubrey", + "Aubrie", + "Aubry", + "Auburn", + "Auburta", + "Aubyn", + "Audette", + "Audi", + "Audie", + "Audley", + "Audly", + "Audra", + "Audras", + "Audre", + "Audres", + "Audrey", + "Audri", + "Audrie", + "Audris", + "Audrit", + "Audry", + "Audrye", + "Audsley", + "Audun", + "Audwen", + "Audwin", + "Audy", + "Auerbach", + "Aufmann", + "Augie", + "August", + "Augusta", + "Auguste", + "Augustin", + "Augustina", + "Augustine", + "Augusto", + "Augustus", + "Augy", + "Aulea", + "Auliffe", + "Aun", + "Aundrea", + "Aunson", + "Aura", + "Aurea", + "Aurel", + "Aurelea", + "Aurelia", + "Aurelie", + "Aurelio", + "Aurelius", + "Auria", + "Auric", + "Aurie", + "Aurilia", + "Aurita", + "Aurlie", + "Auroora", + "Aurora", + "Aurore", + "Aurthur", + "Ause", + "Austen", + "Austin", + "Austina", + "Austine", + "Auston", + "Australia", + "Austreng", + "Autrey", + "Autry", + "Autum", + "Autumn", + "Auvil", + "Av", + "Ava", + "Avan", + "Avaria", + "Ave", + "Avelin", + "Aveline", + "Avera", + "Averell", + "Averi", + "Averil", + "Averill", + "Averir", + "Avery", + "Averyl", + "Avi", + "Avictor", + "Avie", + "Avigdor", + "Avilla", + "Avis", + "Avitzur", + "Aviv", + "Aviva", + "Avivah", + "Avner", + "Avra", + "Avraham", + "Avram", + "Avril", + "Avrit", + "Avrom", + "Avron", + "Avruch", + "Awad", + "Ax", + "Axe", + "Axel", + "Aylmar", + "Aylmer", + "Aylsworth", + "Aylward", + "Aymer", + "Ayn", + "Aynat", + "Ayo", + "Ayres", + "Azal", + "Azalea", + "Azaleah", + "Azar", + "Azarcon", + "Azaria", + "Azarria", + "Azelea", + "Azeria", + "Aziza", + "Azpurua", + "Azral", + "Azriel", + "Baal", + "Baalbeer", + "Baalman", + "Bab", + "Babara", + "Babb", + "Babbette", + "Babbie", + "Babby", + "Babcock", + "Babette", + "Babita", + "Babs", + "Bac", + "Bacchus", + "Bach", + "Bachman", + "Backer", + "Backler", + "Bacon", + "Badger", + "Badr", + "Baecher", + "Bael", + "Baelbeer", + "Baer", + "Baerl", + "Baerman", + "Baese", + "Bagger", + "Baggett", + "Baggott", + "Baggs", + "Bagley", + "Bahner", + "Bahr", + "Baiel", + "Bail", + "Bailar", + "Bailey", + "Bailie", + "Baillie", + "Baillieu", + "Baily", + "Bain", + "Bainbridge", + "Bainbrudge", + "Bainter", + "Baird", + "Baiss", + "Bajaj", + "Bak", + "Bakeman", + "Bakemeier", + "Baker", + "Bakerman", + "Bakki", + "Bal", + "Bala", + "Balas", + "Balbinder", + "Balbur", + "Balcer", + "Balch", + "Balcke", + "Bald", + "Baldridge", + "Balduin", + "Baldwin", + "Bale", + "Baler", + "Balf", + "Balfore", + "Balfour", + "Balkin", + "Ball", + "Ballard", + "Balliett", + "Balling", + "Ballinger", + "Balliol", + "Ballman", + "Ballou", + "Balmuth", + "Balough", + "Balsam", + "Balthasar", + "Balthazar", + "Bamberger", + "Bambi", + "Bambie", + "Bamby", + "Bamford", + "Ban", + "Bancroft", + "Bandeen", + "Bander", + "Bandler", + "Bandur", + "Banebrudge", + "Banerjee", + "Bang", + "Bank", + "Banks", + "Banky", + "Banna", + "Bannasch", + "Bannerman", + "Bannister", + "Bannon", + "Banquer", + "Banwell", + "Baptist", + "Baptista", + "Baptiste", + "Baptlsta", + "Bar", + "Bara", + "Barabas", + "Barabbas", + "Baram", + "Baras", + "Barayon", + "Barb", + "Barbabas", + "Barbabra", + "Barbara", + "Barbara-Anne", + "Barbaraanne", + "Barbarese", + "Barbaresi", + "Barbe", + "Barbee", + "Barber", + "Barbette", + "Barbey", + "Barbi", + "Barbie", + "Barbour", + "Barboza", + "Barbra", + "Barbur", + "Barbuto", + "Barby", + "Barcellona", + "Barclay", + "Barcot", + "Barcroft", + "Barcus", + "Bard", + "Barde", + "Barden", + "Bardo", + "Barfuss", + "Barger", + "Bari", + "Barimah", + "Barina", + "Barker", + "Barkley", + "Barling", + "Barlow", + "Barmen", + "Barn", + "Barna", + "Barnaba", + "Barnabas", + "Barnabe", + "Barnaby", + "Barnard", + "Barncard", + "Barnebas", + "Barnes", + "Barnet", + "Barnett", + "Barney", + "Barnie", + "Barnum", + "Barny", + "Barolet", + "Baron", + "Barr", + "Barra", + "Barrada", + "Barram", + "Barraza", + "Barren", + "Barret", + "Barrett", + "Barri", + "Barrie", + "Barrington", + "Barris", + "Barron", + "Barrow", + "Barrus", + "Barry", + "Barsky", + "Barstow", + "Bart", + "Barta", + "Bartel", + "Barth", + "Barthel", + "Barthelemy", + "Barthol", + "Barthold", + "Bartholemy", + "Bartholomeo", + "Bartholomeus", + "Bartholomew", + "Bartie", + "Bartko", + "Bartle", + "Bartlet", + "Bartlett", + "Bartley", + "Bartolemo", + "Bartolome", + "Bartolomeo", + "Barton", + "Bartosch", + "Bartram", + "Barty", + "Baruch", + "Barvick", + "Bary", + "Baryram", + "Bascio", + "Bascomb", + "Base", + "Baseler", + "Basham", + "Bashee", + "Bashemath", + "Bashemeth", + "Bashuk", + "Basia", + "Basil", + "Basile", + "Basilio", + "Basilius", + "Basir", + "Baskett", + "Bass", + "Basset", + "Bassett", + "Basso", + "Bast", + "Bastian", + "Bastien", + "Bat", + "Batchelor", + "Bate", + "Baten", + "Bates", + "Batha", + "Bathelda", + "Bathesda", + "Bathilda", + "Batholomew", + "Bathsheb", + "Bathsheba", + "Bathsheeb", + "Bathulda", + "Batish", + "Batista", + "Batory", + "Batruk", + "Batsheva", + "Battat", + "Battista", + "Battiste", + "Batty", + "Baudelaire", + "Baudin", + "Baudoin", + "Bauer", + "Baugh", + "Baum", + "Baumann", + "Baumbaugh", + "Baun", + "Bausch", + "Bauske", + "Bautista", + "Bautram", + "Bax", + "Baxie", + "Baxter", + "Baxy", + "Bay", + "Bayard", + "Bayer", + "Bayless", + "Baylor", + "Bayly", + "Baynebridge", + "Bazar", + "Bazil", + "Bazluke", + "Bea", + "Beach", + "Beacham", + "Beal", + "Beale", + "Beall", + "Bealle", + "Bean", + "Beane", + "Beaner", + "Bear", + "Bearce", + "Beard", + "Beare", + "Bearnard", + "Beasley", + "Beaston", + "Beata", + "Beatrice", + "Beatrisa", + "Beatrix", + "Beatriz", + "Beattie", + "Beatty", + "Beau", + "Beauchamp", + "Beaudoin", + "Beaufert", + "Beaufort", + "Beaulieu", + "Beaumont", + "Beauregard", + "Beauvais", + "Beaver", + "Bebe", + "Beberg", + "Becca", + "Bechler", + "Becht", + "Beck", + "Becka", + "Becker", + "Beckerman", + "Becket", + "Beckett", + "Becki", + "Beckie", + "Beckman", + "Becky", + "Bedad", + "Bedelia", + "Bedell", + "Bedwell", + "Bee", + "Beebe", + "Beeck", + "Beedon", + "Beekman", + "Beera", + "Beesley", + "Beeson", + "Beetner", + "Beffrey", + "Bega", + "Begga", + "Beghtol", + "Behah", + "Behka", + "Behl", + "Behlau", + "Behlke", + "Behm", + "Behn", + "Behnken", + "Behre", + "Behrens", + "Beichner", + "Beilul", + "Bein", + "Beisel", + "Beitch", + "Beitnes", + "Beitris", + "Beitz", + "Beka", + "Bekah", + "Bekelja", + "Beker", + "Bekha", + "Bekki", + "Bel", + "Bela", + "Belak", + "Belamy", + "Belanger", + "Belayneh", + "Belcher", + "Belda", + "Belden", + "Belding", + "Belen", + "Belford", + "Belia", + "Belicia", + "Belier", + "Belinda", + "Belita", + "Bell", + "Bella", + "Bellamy", + "Bellanca", + "Bellaude", + "Bellda", + "Belldame", + "Belldas", + "Belle", + "Beller", + "Bellew", + "Bellina", + "Bellis", + "Bello", + "Belloir", + "Belmonte", + "Belshin", + "Belsky", + "Belter", + "Beltran", + "Belva", + "Belvia", + "Ben", + "Bena", + "Bencion", + "Benco", + "Bender", + "Bendick", + "Bendicta", + "Bendicty", + "Bendite", + "Bendix", + "Benedetta", + "Benedetto", + "Benedic", + "Benedick", + "Benedict", + "Benedicta", + "Benedicto", + "Benedikt", + "Benedikta", + "Benedix", + "Benenson", + "Benetta", + "Benge", + "Bengt", + "Benia", + "Beniamino", + "Benil", + "Benilda", + "Benildas", + "Benildis", + "Benioff", + "Benis", + "Benisch", + "Benita", + "Benito", + "Benjamen", + "Benjamin", + "Benji", + "Benjie", + "Benjy", + "Benkley", + "Benn", + "Bennet", + "Bennett", + "Benni", + "Bennie", + "Bennink", + "Bennion", + "Bennir", + "Benny", + "Benoit", + "Benoite", + "Bensen", + "Bensky", + "Benson", + "Bent", + "Bentlee", + "Bentley", + "Bently", + "Benton", + "Benyamin", + "Benzel", + "Beora", + "Beore", + "Ber", + "Berard", + "Berardo", + "Berck", + "Berenice", + "Beret", + "Berey", + "Berfield", + "Berg", + "Berga", + "Bergeman", + "Bergen", + "Berger", + "Bergerac", + "Bergeron", + "Bergess", + "Berget", + "Bergh", + "Berghoff", + "Bergin", + "Berglund", + "Bergman", + "Bergmann", + "Bergmans", + "Bergquist", + "Bergren", + "Bergstein", + "Bergstrom", + "Bergwall", + "Berhley", + "Berk", + "Berke", + "Berkeley", + "Berkie", + "Berkin", + "Berkley", + "Berkly", + "Berkman", + "Berkow", + "Berkshire", + "Berky", + "Berl", + "Berlauda", + "Berlin", + "Berlinda", + "Berliner", + "Berlyn", + "Berman", + "Bern", + "Berna", + "Bernadene", + "Bernadette", + "Bernadina", + "Bernadine", + "Bernard", + "Bernardi", + "Bernardina", + "Bernardine", + "Bernardo", + "Bernarr", + "Bernat", + "Berne", + "Bernelle", + "Berner", + "Berners", + "Berneta", + "Bernete", + "Bernetta", + "Bernette", + "Bernhard", + "Berni", + "Bernice", + "Bernie", + "Bernita", + "Bernj", + "Berns", + "Bernstein", + "Bernt", + "Berny", + "Berri", + "Berrie", + "Berriman", + "Berry", + "Berstine", + "Bert", + "Berta", + "Bertasi", + "Berte", + "Bertelli", + "Bertero", + "Bertha", + "Berthe", + "Berthold", + "Berthoud", + "Berti", + "Bertie", + "Bertila", + "Bertilla", + "Bertina", + "Bertine", + "Bertle", + "Bertold", + "Bertolde", + "Berton", + "Bertram", + "Bertrand", + "Bertrando", + "Bertsche", + "Berty", + "Berwick", + "Beryl", + "Beryle", + "Beshore", + "Besnard", + "Bess", + "Besse", + "Bessie", + "Bessy", + "Best", + "Beth", + "Bethanne", + "Bethany", + "Bethel", + "Bethena", + "Bethesda", + "Bethesde", + "Bethezel", + "Bethina", + "Betsey", + "Betsy", + "Betta", + "Bette", + "Bette-Ann", + "Betteann", + "Betteanne", + "Bettencourt", + "Betthel", + "Betthezel", + "Betthezul", + "Betti", + "Bettina", + "Bettine", + "Betty", + "Bettye", + "Bettzel", + "Betz", + "Beulah", + "Beuthel", + "Beutler", + "Beutner", + "Bev", + "Bevan", + "Bevash", + "Bever", + "Beverie", + "Beverle", + "Beverlee", + "Beverley", + "Beverlie", + "Beverly", + "Bevers", + "Bevin", + "Bevis", + "Bevon", + "Bevus", + "Bevvy", + "Beyer", + "Bezanson", + "Bhatt", + "Bhayani", + "Biagi", + "Biagio", + "Biamonte", + "Bianca", + "Biancha", + "Bianchi", + "Bianka", + "Bibbie", + "Bibby", + "Bibbye", + "Bibeau", + "Bibi", + "Bible", + "Bick", + "Bickart", + "Bicknell", + "Biddick", + "Biddie", + "Biddle", + "Biddy", + "Bidget", + "Bidle", + "Biebel", + "Biegel", + "Bierman", + "Biernat", + "Bigelow", + "Bigford", + "Bigg", + "Biggs", + "Bigler", + "Bigner", + "Bigod", + "Bigot", + "Bik", + "Bikales", + "Bil", + "Bilbe", + "Bilek", + "Biles", + "Bili", + "Bilicki", + "Bill", + "Billat", + "Bille", + "Billen", + "Billi", + "Billie", + "Billmyre", + "Bills", + "Billy", + "Billye", + "Bilow", + "Bilski", + "Bina", + "Binah", + "Bindman", + "Binetta", + "Binette", + "Bing", + "Bink", + "Binky", + "Binni", + "Binnie", + "Binnings", + "Binny", + "Biondo", + "Birch", + "Birchard", + "Birck", + "Bird", + "Birdella", + "Birdie", + "Birdt", + "Birecree", + "Birgit", + "Birgitta", + "Birk", + "Birkett", + "Birkle", + "Birkner", + "Birmingham", + "Biron", + "Bish", + "Bishop", + "Bissell", + "Bisset", + "Bithia", + "Bittencourt", + "Bitthia", + "Bittner", + "Bivins", + "Bixby", + "Bixler", + "Bjork", + "Bjorn", + "Black", + "Blackburn", + "Blackington", + "Blackman", + "Blackmore", + "Blackmun", + "Blackstock", + "Blackwell", + "Blader", + "Blain", + "Blaine", + "Blainey", + "Blair", + "Blaire", + "Blaise", + "Blake", + "Blakelee", + "Blakeley", + "Blakely", + "Blalock", + "Blanc", + "Blanca", + "Blanch", + "Blancha", + "Blanchard", + "Blanche", + "Blanchette", + "Bland", + "Blandina", + "Blanding", + "Blane", + "Blank", + "Blanka", + "Blankenship", + "Blas", + "Blase", + "Blaseio", + "Blasien", + "Blasius", + "Blatman", + "Blatt", + "Blau", + "Blayne", + "Blayze", + "Blaze", + "Bledsoe", + "Bleier", + "Blen", + "Blessington", + "Blight", + "Blim", + "Blinni", + "Blinnie", + "Blinny", + "Bliss", + "Blisse", + "Blithe", + "Bloch", + "Block", + "Blockus", + "Blodget", + "Blodgett", + "Bloem", + "Blondell", + "Blondelle", + "Blondie", + "Blondy", + "Blood", + "Bloom", + "Bloomer", + "Blossom", + "Blount", + "Bloxberg", + "Bluefarb", + "Bluefield", + "Bluh", + "Bluhm", + "Blum", + "Bluma", + "Blumenfeld", + "Blumenthal", + "Blunk", + "Blunt", + "Blus", + "Blynn", + "Blythe", + "Bo", + "Boak", + "Boar", + "Boardman", + "Boarer", + "Boaten", + "Boatwright", + "Bob", + "Bobbe", + "Bobbee", + "Bobbette", + "Bobbi", + "Bobbie", + "Bobby", + "Bobbye", + "Bobette", + "Bobina", + "Bobine", + "Bobinette", + "Bobker", + "Bobseine", + "Bock", + "Bocock", + "Bodi", + "Bodkin", + "Bodnar", + "Bodrogi", + "Bodwell", + "Body", + "Boehike", + "Boehmer", + "Boeke", + "Boelter", + "Boesch", + "Boeschen", + "Boff", + "Boffa", + "Bogart", + "Bogey", + "Boggers", + "Boggs", + "Bogie", + "Bogoch", + "Bogosian", + "Bogusz", + "Bohannon", + "Bohaty", + "Bohi", + "Bohlen", + "Bohlin", + "Bohman", + "Bohner", + "Bohon", + "Bohrer", + "Bohs", + "Bohun", + "Boice", + "Boigie", + "Boiney", + "Bois", + "Bolan", + "Boland", + "Bolanger", + "Bolen", + "Boles", + "Boleslaw", + "Boleyn", + "Bolger", + "Bolitho", + "Bollay", + "Bollen", + "Bolling", + "Bollinger", + "Bolme", + "Bolt", + "Bolte", + "Bolten", + "Bolton", + "Bomke", + "Bonacci", + "Bonaparte", + "Bonar", + "Bond", + "Bondie", + "Bondon", + "Bondy", + "Bone", + "Boni", + "Boniface", + "Bonilla", + "Bonina", + "Bonine", + "Bonis", + "Bonita", + "Bonn", + "Bonne", + "Bonneau", + "Bonnee", + "Bonnell", + "Bonner", + "Bonnes", + "Bonnette", + "Bonney", + "Bonni", + "Bonnibelle", + "Bonnice", + "Bonnie", + "Bonns", + "Bonny", + "Bonucci", + "Booker", + "Booma", + "Boone", + "Boonie", + "Boony", + "Boor", + "Boorer", + "Boorman", + "Boot", + "Boote", + "Booth", + "Boothe", + "Boothman", + "Booze", + "Bopp", + "Bor", + "Bora", + "Borchers", + "Borchert", + "Bord", + "Borden", + "Bordie", + "Bordiuk", + "Bordy", + "Bore", + "Borek", + "Borer", + "Bores", + "Borg", + "Borgeson", + "Boris", + "Bork", + "Borlase", + "Borlow", + "Borman", + "Born", + "Bornie", + "Bornstein", + "Borras", + "Borrell", + "Borreri", + "Borries", + "Borroff", + "Borszcz", + "Bortman", + "Bortz", + "Boru", + "Bosch", + "Bose", + "Boser", + "Bosson", + "Bostow", + "Boswall", + "Boswell", + "Botnick", + "Botsford", + "Bottali", + "Botti", + "Botzow", + "Bouchard", + "Boucher", + "Bouchier", + "Boudreaux", + "Bough", + "Boulanger", + "Bouldon", + "Bouley", + "Bound", + "Bounds", + "Bourgeois", + "Bourke", + "Bourn", + "Bourne", + "Bourque", + "Boutis", + "Bouton", + "Bouzoun", + "Bove", + "Bovill", + "Bow", + "Bowden", + "Bowe", + "Bowen", + "Bower", + "Bowerman", + "Bowers", + "Bowes", + "Bowie", + "Bowlds", + "Bowler", + "Bowles", + "Bowman", + "Bowne", + "Bowra", + "Bowrah", + "Bowyer", + "Box", + "Boy", + "Boyce", + "Boycey", + "Boycie", + "Boyd", + "Boyden", + "Boyer", + "Boyes", + "Boykins", + "Boylan", + "Boylston", + "Boynton", + "Boys", + "Boyse", + "Boyt", + "Bozovich", + "Bozuwa", + "Braasch", + "Brabazon", + "Braca", + "Bracci", + "Brace", + "Brackely", + "Brackett", + "Brad", + "Bradan", + "Brade", + "Braden", + "Bradeord", + "Brader", + "Bradford", + "Bradlee", + "Bradleigh", + "Bradley", + "Bradly", + "Bradman", + "Bradney", + "Bradshaw", + "Bradski", + "Bradstreet", + "Bradway", + "Bradwell", + "Brady", + "Braeunig", + "Brag", + "Brahear", + "Brainard", + "Bram", + "Bramwell", + "Bran", + "Brana", + "Branca", + "Branch", + "Brand", + "Brandais", + "Brande", + "Brandea", + "Branden", + "Brandenburg", + "Brander", + "Brandes", + "Brandi", + "Brandice", + "Brandie", + "Brandise", + "Brandon", + "Brandt", + "Brandtr", + "Brandwein", + "Brandy", + "Brandyn", + "Branen", + "Branham", + "Brannon", + "Branscum", + "Brant", + "Brantley", + "Brasca", + "Brass", + "Braswell", + "Brathwaite", + "Bratton", + "Braun", + "Braunstein", + "Brause", + "Bravar", + "Bravin", + "Brawley", + "Brawner", + "Bray", + "Braynard", + "Brazee", + "Breana", + "Breanne", + "Brear", + "Breban", + "Brebner", + "Brecher", + "Brechtel", + "Bred", + "Bree", + "Breech", + "Breed", + "Breen", + "Breena", + "Breeze", + "Breger", + "Brelje", + "Bremble", + "Bremen", + "Bremer", + "Bremser", + "Bren", + "Brena", + "Brenan", + "Brenda", + "Brendan", + "Brenden", + "Brendin", + "Brendis", + "Brendon", + "Brenk", + "Brenn", + "Brenna", + "Brennan", + "Brennen", + "Brenner", + "Brent", + "Brenton", + "Brentt", + "Brenza", + "Bresee", + "Breskin", + "Brest", + "Bret", + "Brett", + "Brew", + "Brewer", + "Brewster", + "Brey", + "Brezin", + "Bria", + "Brian", + "Briana", + "Brianna", + "Brianne", + "Briano", + "Briant", + "Brice", + "Brick", + "Bricker", + "Bride", + "Bridge", + "Bridges", + "Bridget", + "Bridgette", + "Bridgid", + "Bridie", + "Bridwell", + "Brie", + "Brien", + "Brier", + "Brieta", + "Brietta", + "Brig", + "Brigette", + "Brigg", + "Briggs", + "Brigham", + "Bright", + "Brightman", + "Brighton", + "Brigid", + "Brigida", + "Brigit", + "Brigitta", + "Brigitte", + "Brill", + "Brina", + "Brindell", + "Brindle", + "Brine", + "Briney", + "Bringhurst", + "Brink", + "Brinkema", + "Brinn", + "Brinna", + "Brinson", + "Briny", + "Brion", + "Briscoe", + "Bristow", + "Brit", + "Brita", + "Britney", + "Britni", + "Britt", + "Britta", + "Brittain", + "Brittan", + "Brittaney", + "Brittani", + "Brittany", + "Britte", + "Britteny", + "Brittne", + "Brittnee", + "Brittney", + "Brittni", + "Britton", + "Brnaba", + "Brnaby", + "Broadbent", + "Brock", + "Brockie", + "Brocklin", + "Brockwell", + "Brocky", + "Brod", + "Broddie", + "Broddy", + "Brodench", + "Broder", + "Broderic", + "Broderick", + "Brodeur", + "Brodie", + "Brodsky", + "Brody", + "Broeder", + "Broek", + "Broeker", + "Brogle", + "Broida", + "Brok", + "Brom", + "Bromleigh", + "Bromley", + "Bron", + "Bronder", + "Bronez", + "Bronk", + "Bronnie", + "Bronny", + "Bronson", + "Bronwen", + "Bronwyn", + "Brook", + "Brooke", + "Brookes", + "Brookhouse", + "Brooking", + "Brookner", + "Brooks", + "Broome", + "Brose", + "Brosine", + "Brost", + "Brosy", + "Brote", + "Brothers", + "Brotherson", + "Brott", + "Brottman", + "Broucek", + "Brout", + "Brouwer", + "Brower", + "Brown", + "Browne", + "Browning", + "Brownley", + "Brownson", + "Brozak", + "Brubaker", + "Bruce", + "Brucie", + "Bruckner", + "Bruell", + "Brufsky", + "Bruis", + "Brunell", + "Brunella", + "Brunelle", + "Bruner", + "Brunhild", + "Brunhilda", + "Brunhilde", + "Bruni", + "Bruning", + "Brunk", + "Brunn", + "Bruno", + "Bruns", + "Bruyn", + "Bryan", + "Bryana", + "Bryant", + "Bryanty", + "Bryce", + "Bryn", + "Bryna", + "Bryner", + "Brynn", + "Brynna", + "Brynne", + "Bryon", + "Buatti", + "Bubalo", + "Bubb", + "Bucella", + "Buchalter", + "Buchanan", + "Buchbinder", + "Bucher", + "Buchheim", + "Buck", + "Buckden", + "Buckels", + "Buckie", + "Buckingham", + "Buckler", + "Buckley", + "Bucky", + "Bud", + "Budd", + "Budde", + "Buddie", + "Budding", + "Buddy", + "Buderus", + "Budge", + "Budwig", + "Budworth", + "Buehler", + "Buehrer", + "Buell", + "Buerger", + "Bueschel", + "Buff", + "Buffo", + "Buffum", + "Buffy", + "Buford", + "Bugbee", + "Buhler", + "Bui", + "Buine", + "Buiron", + "Buke", + "Bull", + "Bullard", + "Bullen", + "Buller", + "Bulley", + "Bullion", + "Bullis", + "Bullivant", + "Bullock", + "Bullough", + "Bully", + "Bultman", + "Bum", + "Bumgardner", + "Buna", + "Bunce", + "Bunch", + "Bunde", + "Bunder", + "Bundy", + "Bunker", + "Bunni", + "Bunnie", + "Bunns", + "Bunny", + "Bunow", + "Bunting", + "Buonomo", + "Buote", + "Burack", + "Burbank", + "Burch", + "Burchett", + "Burck", + "Burd", + "Burdelle", + "Burdett", + "Burford", + "Burg", + "Burgener", + "Burger", + "Burgess", + "Burget", + "Burgwell", + "Burhans", + "Burk", + "Burke", + "Burkhard", + "Burkhardt", + "Burkhart", + "Burkitt", + "Burkle", + "Burkley", + "Burl", + "Burleigh", + "Burley", + "Burlie", + "Burman", + "Burn", + "Burnaby", + "Burnard", + "Burne", + "Burner", + "Burnett", + "Burney", + "Burnham", + "Burnie", + "Burnight", + "Burnley", + "Burns", + "Burnsed", + "Burnside", + "Burny", + "Buroker", + "Burr", + "Burra", + "Burrell", + "Burrill", + "Burris", + "Burroughs", + "Burrow", + "Burrows", + "Burrton", + "Burrus", + "Burt", + "Burta", + "Burtie", + "Burtis", + "Burton", + "Burty", + "Burwell", + "Bury", + "Busby", + "Busch", + "Buschi", + "Buseck", + "Busey", + "Bush", + "Bushey", + "Bushore", + "Bushweller", + "Busiek", + "Buskirk", + "Buskus", + "Bussey", + "Bussy", + "Bust", + "Butch", + "Butcher", + "Butler", + "Butta", + "Buttaro", + "Butte", + "Butterfield", + "Butterworth", + "Button", + "Buxton", + "Buyer", + "Buyers", + "Buyse", + "Buzz", + "Buzzell", + "Byers", + "Byler", + "Byram", + "Byran", + "Byrann", + "Byrd", + "Byrdie", + "Byrle", + "Byrn", + "Byrne", + "Byrom", + "Byron", + "Bysshe", + "Bywaters", + "Bywoods", + "Cacia", + "Cacie", + "Cacilia", + "Cacilie", + "Cacka", + "Cad", + "Cadal", + "Caddaric", + "Caddric", + "Cade", + "Cadel", + "Cadell", + "Cadman", + "Cadmann", + "Cadmar", + "Cadmarr", + "Caesar", + "Caesaria", + "Caffrey", + "Cagle", + "Cahan", + "Cahilly", + "Cahn", + "Cahra", + "Cai", + "Caia", + "Caiaphas", + "Cailean", + "Cailly", + "Cain", + "Caine", + "Caines", + "Cairistiona", + "Cairns", + "Caitlin", + "Caitrin", + "Cal", + "Calabrese", + "Calabresi", + "Calan", + "Calandra", + "Calandria", + "Calbert", + "Caldeira", + "Calder", + "Caldera", + "Calderon", + "Caldwell", + "Cale", + "Caleb", + "Calen", + "Calendra", + "Calendre", + "Calesta", + "Calhoun", + "Calia", + "Calica", + "Calida", + "Calie", + "Calisa", + "Calise", + "Calista", + "Call", + "Calla", + "Callahan", + "Callan", + "Callas", + "Calle", + "Callean", + "Callery", + "Calley", + "Calli", + "Callida", + "Callie", + "Callista", + "Calloway", + "Callum", + "Cally", + "Calmas", + "Calondra", + "Calore", + "Calv", + "Calva", + "Calvano", + "Calvert", + "Calvin", + "Calvina", + "Calvinna", + "Calvo", + "Calypso", + "Calysta", + "Cam", + "Camala", + "Camarata", + "Camden", + "Camel", + "Camella", + "Camellia", + "Cameron", + "Camey", + "Camfort", + "Cami", + "Camila", + "Camile", + "Camilia", + "Camilla", + "Camille", + "Camilo", + "Camm", + "Cammi", + "Cammie", + "Cammy", + "Camp", + "Campagna", + "Campball", + "Campbell", + "Campman", + "Campney", + "Campos", + "Campy", + "Camus", + "Can", + "Canada", + "Canale", + "Cand", + "Candace", + "Candi", + "Candice", + "Candida", + "Candide", + "Candie", + "Candis", + "Candless", + "Candra", + "Candy", + "Candyce", + "Caneghem", + "Canfield", + "Canica", + "Canice", + "Caniff", + "Cann", + "Cannell", + "Cannice", + "Canning", + "Cannon", + "Canon", + "Canotas", + "Canter", + "Cantlon", + "Cantone", + "Cantu", + "Canty", + "Canute", + "Capello", + "Caplan", + "Capon", + "Capone", + "Capp", + "Cappella", + "Cappello", + "Capps", + "Caprice", + "Capriola", + "Caputo", + "Caputto", + "Capwell", + "Car", + "Cara", + "Caralie", + "Caras", + "Caravette", + "Caraviello", + "Carberry", + "Carbo", + "Carbone", + "Carboni", + "Carbrey", + "Carce", + "Card", + "Carder", + "Cardew", + "Cardie", + "Cardinal", + "Cardon", + "Cardwell", + "Care", + "Careaga", + "Caren", + "Carena", + "Caresa", + "Caressa", + "Caresse", + "Carew", + "Carey", + "Cargian", + "Carhart", + "Cari", + "Caria", + "Carie", + "Caril", + "Carilla", + "Carilyn", + "Carin", + "Carina", + "Carine", + "Cariotta", + "Carisa", + "Carissa", + "Carita", + "Caritta", + "Carl", + "Carla", + "Carlee", + "Carleen", + "Carlen", + "Carlene", + "Carleton", + "Carley", + "Carli", + "Carlick", + "Carlie", + "Carlile", + "Carlin", + "Carlina", + "Carline", + "Carling", + "Carlisle", + "Carlita", + "Carlo", + "Carlock", + "Carlos", + "Carlota", + "Carlotta", + "Carlson", + "Carlstrom", + "Carlton", + "Carly", + "Carlye", + "Carlyle", + "Carlyn", + "Carlynn", + "Carlynne", + "Carma", + "Carman", + "Carmel", + "Carmela", + "Carmelia", + "Carmelina", + "Carmelita", + "Carmella", + "Carmelle", + "Carmelo", + "Carmen", + "Carmena", + "Carmencita", + "Carmina", + "Carmine", + "Carmita", + "Carmon", + "Carn", + "Carnahan", + "Carnay", + "Carnes", + "Carney", + "Carny", + "Caro", + "Carol", + "Carol-Jean", + "Carola", + "Carolan", + "Carolann", + "Carole", + "Carolee", + "Carolin", + "Carolina", + "Caroline", + "Carolle", + "Carolus", + "Carolyn", + "Carolyne", + "Carolynn", + "Carolynne", + "Caron", + "Carothers", + "Carpenter", + "Carper", + "Carpet", + "Carpio", + "Carr", + "Carree", + "Carrel", + "Carrelli", + "Carrew", + "Carri", + "Carrick", + "Carrie", + "Carrillo", + "Carrington", + "Carrissa", + "Carrnan", + "Carrol", + "Carroll", + "Carry", + "Carson", + "Cart", + "Cartan", + "Carter", + "Carthy", + "Cartie", + "Cartwell", + "Cartwright", + "Caruso", + "Carver", + "Carvey", + "Cary", + "Caryl", + "Caryn", + "Cas", + "Casabonne", + "Casady", + "Casaleggio", + "Casandra", + "Casanova", + "Casar", + "Casavant", + "Case", + "Casey", + "Cash", + "Casi", + "Casia", + "Casie", + "Casilda", + "Casilde", + "Casimir", + "Casimire", + "Casmey", + "Caspar", + "Casper", + "Cass", + "Cassady", + "Cassandra", + "Cassandre", + "Cassandry", + "Cassaundra", + "Cassell", + "Cassella", + "Cassey", + "Cassi", + "Cassiani", + "Cassidy", + "Cassie", + "Cassil", + "Cassilda", + "Cassius", + "Cassondra", + "Cassy", + "Casta", + "Castara", + "Casteel", + "Castera", + "Castillo", + "Castle", + "Castor", + "Castora", + "Castorina", + "Castra", + "Castro", + "Caswell", + "Cataldo", + "Catarina", + "Cate", + "Caterina", + "Cates", + "Cath", + "Catha", + "Catharina", + "Catharine", + "Cathe", + "Cathee", + "Catherin", + "Catherina", + "Catherine", + "Cathey", + "Cathi", + "Cathie", + "Cathleen", + "Cathlene", + "Cathrin", + "Cathrine", + "Cathryn", + "Cathy", + "Cathyleen", + "Cati", + "Catie", + "Catima", + "Catina", + "Catlaina", + "Catlee", + "Catlin", + "Cato", + "Caton", + "Catrina", + "Catriona", + "Catt", + "Cattan", + "Cattier", + "Cattima", + "Catto", + "Catton", + "Caty", + "Caughey", + "Caundra", + "Cavallaro", + "Cavan", + "Cavanagh", + "Cavanaugh", + "Cave", + "Caves", + "Cavil", + "Cavill", + "Cavit", + "Cavuoto", + "Cawley", + "Caye", + "Cayla", + "Caylor", + "Cayser", + "Caz", + "Cazzie", + "Cchaddie", + "Cece", + "Cecelia", + "Cecil", + "Cecile", + "Ceciley", + "Cecilia", + "Cecilio", + "Cecilius", + "Cecilla", + "Cecily", + "Ced", + "Cedar", + "Cedell", + "Cedric", + "Ceevah", + "Ceil", + "Cele", + "Celene", + "Celeski", + "Celesta", + "Celeste", + "Celestia", + "Celestina", + "Celestine", + "Celestyn", + "Celestyna", + "Celia", + "Celie", + "Celik", + "Celin", + "Celina", + "Celinda", + "Celine", + "Celinka", + "Celio", + "Celisse", + "Celka", + "Celle", + "Cello", + "Celtic", + "Cenac", + "Cence", + "Centeno", + "Center", + "Centonze", + "Ceporah", + "Cerallua", + "Cerelia", + "Cerell", + "Cerellia", + "Cerelly", + "Cerf", + "Cerracchio", + "Certie", + "Cerveny", + "Cerys", + "Cesar", + "Cesare", + "Cesaria", + "Cesaro", + "Cestar", + "Cesya", + "Cha", + "Chabot", + "Chace", + "Chad", + "Chadabe", + "Chadbourne", + "Chadburn", + "Chadd", + "Chaddie", + "Chaddy", + "Chader", + "Chadwick", + "Chae", + "Chafee", + "Chaffee", + "Chaffin", + "Chaffinch", + "Chaiken", + "Chaille", + "Chaim", + "Chainey", + "Chaing", + "Chak", + "Chaker", + "Chally", + "Chalmer", + "Chalmers", + "Chamberlain", + "Chamberlin", + "Chambers", + "Chamkis", + "Champ", + "Champagne", + "Champaigne", + "Chan", + "Chance", + "Chancellor", + "Chancelor", + "Chancey", + "Chanda", + "Chandal", + "Chandler", + "Chandless", + "Chandos", + "Chandra", + "Chane", + "Chaney", + "Chang", + "Changaris", + "Channa", + "Channing", + "Chansoo", + "Chantal", + "Chantalle", + "Chao", + "Chap", + "Chapa", + "Chapel", + "Chapell", + "Chapen", + "Chapin", + "Chapland", + "Chapman", + "Chapnick", + "Chappelka", + "Chappell", + "Chappie", + "Chappy", + "Chara", + "Charbonneau", + "Charbonnier", + "Chard", + "Chari", + "Charie", + "Charil", + "Charin", + "Chariot", + "Charis", + "Charissa", + "Charisse", + "Charita", + "Charity", + "Charla", + "Charlean", + "Charleen", + "Charlena", + "Charlene", + "Charles", + "Charlet", + "Charleton", + "Charley", + "Charlie", + "Charline", + "Charlot", + "Charlotta", + "Charlotte", + "Charlton", + "Charmain", + "Charmaine", + "Charmane", + "Charmian", + "Charmine", + "Charmion", + "Charo", + "Charpentier", + "Charron", + "Charry", + "Charteris", + "Charters", + "Charyl", + "Chas", + "Chase", + "Chasse", + "Chassin", + "Chastain", + "Chastity", + "Chatav", + "Chatterjee", + "Chatwin", + "Chaudoin", + "Chaunce", + "Chauncey", + "Chavaree", + "Chaves", + "Chavey", + "Chavez", + "Chaworth", + "Che", + "Cheadle", + "Cheatham", + "Checani", + "Chee", + "Cheffetz", + "Cheke", + "Chellman", + "Chelsae", + "Chelsea", + "Chelsey", + "Chelsie", + "Chelsy", + "Chelton", + "Chem", + "Chema", + "Chemar", + "Chemaram", + "Chemarin", + "Chemash", + "Chemesh", + "Chemosh", + "Chemush", + "Chen", + "Chenay", + "Chenee", + "Cheney", + "Cheng", + "Cher", + "Chere", + "Cherey", + "Cheri", + "Cheria", + "Cherian", + "Cherianne", + "Cherice", + "Cherida", + "Cherie", + "Cherilyn", + "Cherilynn", + "Cherin", + "Cherise", + "Cherish", + "Cherlyn", + "Chernow", + "Cherri", + "Cherrita", + "Cherry", + "Chery", + "Cherye", + "Cheryl", + "Ches", + "Cheshire", + "Cheslie", + "Chesna", + "Chesney", + "Chesnut", + "Chessa", + "Chessy", + "Chester", + "Cheston", + "Chet", + "Cheung", + "Chev", + "Chevalier", + "Chevy", + "Chew", + "Cheyne", + "Cheyney", + "Chi", + "Chiaki", + "Chiang", + "Chiarra", + "Chic", + "Chick", + "Chickie", + "Chicky", + "Chico", + "Chicoine", + "Chien", + "Chil", + "Chilcote", + "Child", + "Childers", + "Childs", + "Chiles", + "Chill", + "Chilson", + "Chilt", + "Chilton", + "Chimene", + "Chin", + "China", + "Ching", + "Chinua", + "Chiou", + "Chip", + "Chipman", + "Chiquia", + "Chiquita", + "Chirlin", + "Chisholm", + "Chita", + "Chitkara", + "Chivers", + "Chladek", + "Chlo", + "Chloe", + "Chloette", + "Chloras", + "Chlores", + "Chlori", + "Chloris", + "Cho", + "Chobot", + "Chon", + "Chong", + "Choo", + "Choong", + "Chor", + "Chouest", + "Chow", + "Chretien", + "Chris", + "Chrisman", + "Chrisoula", + "Chrissa", + "Chrisse", + "Chrissie", + "Chrissy", + "Christa", + "Christabel", + "Christabella", + "Christabelle", + "Christal", + "Christalle", + "Christan", + "Christean", + "Christel", + "Christen", + "Christensen", + "Christenson", + "Christi", + "Christian", + "Christiana", + "Christiane", + "Christianity", + "Christianna", + "Christiano", + "Christiansen", + "Christianson", + "Christie", + "Christin", + "Christina", + "Christine", + "Christis", + "Christmann", + "Christmas", + "Christoffer", + "Christoforo", + "Christoper", + "Christoph", + "Christophe", + "Christopher", + "Christos", + "Christy", + "Christye", + "Christyna", + "Chrisy", + "Chrotoem", + "Chrysa", + "Chrysler", + "Chrystal", + "Chryste", + "Chrystel", + "Chu", + "Chuah", + "Chubb", + "Chuch", + "Chucho", + "Chuck", + "Chud", + "Chui", + "Chuipek", + "Chun", + "Chung", + "Chura", + "Church", + "Churchill", + "Chute", + "Chuu", + "Chyou", + "Cia", + "Cianca", + "Ciapas", + "Ciapha", + "Ciaphus", + "Cibis", + "Ciccia", + "Cicely", + "Cicenia", + "Cicero", + "Cichocki", + "Cicily", + "Cid", + "Cida", + "Ciel", + "Cila", + "Cilka", + "Cilla", + "Cilo", + "Cilurzo", + "Cima", + "Cimah", + "Cimbura", + "Cinda", + "Cindee", + "Cindelyn", + "Cinderella", + "Cindi", + "Cindie", + "Cindra", + "Cindy", + "Cinelli", + "Cini", + "Cinnamon", + "Cioban", + "Cioffred", + "Ciprian", + "Circosta", + "Ciri", + "Cirilla", + "Cirillo", + "Cirilo", + "Ciro", + "Cirone", + "Cirri", + "Cis", + "Cissie", + "Cissiee", + "Cissy", + "Cita", + "Citarella", + "Citron", + "Clabo", + "Claiborn", + "Claiborne", + "Clair", + "Claire", + "Claman", + "Clance", + "Clancy", + "Clapp", + "Clapper", + "Clara", + "Clarabelle", + "Clarance", + "Clardy", + "Clare", + "Clarence", + "Claresta", + "Clareta", + "Claretta", + "Clarette", + "Clarey", + "Clarhe", + "Clari", + "Claribel", + "Clarice", + "Clarie", + "Clarinda", + "Clarine", + "Clarisa", + "Clarise", + "Clarissa", + "Clarisse", + "Clarita", + "Clark", + "Clarke", + "Clarkin", + "Clarkson", + "Clary", + "Claud", + "Clauddetta", + "Claude", + "Claudell", + "Claudelle", + "Claudetta", + "Claudette", + "Claudia", + "Claudian", + "Claudianus", + "Claudie", + "Claudina", + "Claudine", + "Claudio", + "Claudius", + "Claudy", + "Claus", + "Clausen", + "Clava", + "Clawson", + "Clay", + "Clayberg", + "Clayborn", + "Clayborne", + "Claybourne", + "Clayson", + "Clayton", + "Clea", + "Cleary", + "Cleasta", + "Cleave", + "Cleaves", + "Cleavland", + "Clein", + "Cleland", + "Clellan", + "Clem", + "Clemen", + "Clemence", + "Clemens", + "Clement", + "Clementas", + "Clemente", + "Clementi", + "Clementia", + "Clementina", + "Clementine", + "Clementis", + "Clementius", + "Clements", + "Clemmie", + "Clemmy", + "Cleo", + "Cleodal", + "Cleodel", + "Cleodell", + "Cleon", + "Cleopatra", + "Cleopatre", + "Clerc", + "Clercq", + "Clere", + "Cleres", + "Clerissa", + "Clerk", + "Cleti", + "Cletis", + "Cletus", + "Cleve", + "Cleveland", + "Clevey", + "Clevie", + "Clie", + "Cliff", + "Cliffes", + "Clifford", + "Clift", + "Clifton", + "Clim", + "Cline", + "Clint", + "Clintock", + "Clinton", + "Clio", + "Clippard", + "Clite", + "Clive", + "Clo", + "Cloe", + "Cloots", + "Clorinda", + "Clorinde", + "Cloris", + "Close", + "Clothilde", + "Clotilda", + "Clotilde", + "Clough", + "Clougher", + "Cloutman", + "Clova", + "Clovah", + "Clover", + "Clovis", + "Clower", + "Clute", + "Cly", + "Clyde", + "Clymer", + "Clynes", + "Clyte", + "Clyve", + "Clywd", + "Cnut", + "Coad", + "Coady", + "Coates", + "Coats", + "Cob", + "Cobb", + "Cobbie", + "Cobby", + "Coben", + "Cochard", + "Cochran", + "Cochrane", + "Cock", + "Cockburn", + "Cocke", + "Cocks", + "Coco", + "Codd", + "Codding", + "Codee", + "Codel", + "Codi", + "Codie", + "Cody", + "Coe", + "Coffee", + "Coffeng", + "Coffey", + "Coffin", + "Cofsky", + "Cogan", + "Cogen", + "Cogswell", + "Coh", + "Cohbath", + "Cohberg", + "Cohbert", + "Cohby", + "Cohdwell", + "Cohe", + "Coheman", + "Cohen", + "Cohette", + "Cohin", + "Cohl", + "Cohla", + "Cohleen", + "Cohlette", + "Cohlier", + "Cohligan", + "Cohn", + "Cointon", + "Coit", + "Coke", + "Col", + "Colan", + "Colas", + "Colb", + "Colbert", + "Colburn", + "Colby", + "Colbye", + "Cole", + "Coleen", + "Coleman", + "Colene", + "Colet", + "Coletta", + "Colette", + "Coleville", + "Colfin", + "Colier", + "Colin", + "Colinson", + "Colis", + "Collar", + "Collayer", + "Collbaith", + "Colleen", + "Collen", + "Collete", + "Collette", + "Colley", + "Collie", + "Collier", + "Colligan", + "Collimore", + "Collin", + "Colline", + "Collins", + "Collis", + "Collum", + "Colly", + "Collyer", + "Colman", + "Colner", + "Colombi", + "Colon", + "Colp", + "Colpin", + "Colson", + "Colston", + "Colt", + "Coltin", + "Colton", + "Coltson", + "Coltun", + "Columba", + "Columbine", + "Columbus", + "Columbyne", + "Colver", + "Colvert", + "Colville", + "Colvin", + "Colwell", + "Colwen", + "Colwin", + "Colyer", + "Combe", + "Combes", + "Combs", + "Comfort", + "Compte", + "Comptom", + "Compton", + "Comras", + "Comstock", + "Comyns", + "Con", + "Conah", + "Conal", + "Conall", + "Conan", + "Conant", + "Conard", + "Concepcion", + "Concettina", + "Concha", + "Conchita", + "Concoff", + "Concordia", + "Condon", + "Coney", + "Congdon", + "Conger", + "Coniah", + "Conias", + "Conlan", + "Conlee", + "Conlen", + "Conley", + "Conlin", + "Conlon", + "Conn", + "Connel", + "Connell", + "Connelley", + "Connelly", + "Conner", + "Conners", + "Connett", + "Conney", + "Conni", + "Connie", + "Connolly", + "Connor", + "Connors", + "Conny", + "Conover", + "Conrad", + "Conrade", + "Conrado", + "Conroy", + "Consalve", + "Consolata", + "Constance", + "Constancia", + "Constancy", + "Constant", + "Constanta", + "Constantia", + "Constantin", + "Constantina", + "Constantine", + "Constantino", + "Consuela", + "Consuelo", + "Conte", + "Conti", + "Converse", + "Convery", + "Conway", + "Cony", + "Conyers", + "Cooe", + "Cook", + "Cooke", + "Cookie", + "Cooley", + "Coombs", + "Coonan", + "Coop", + "Cooper", + "Cooperman", + "Coopersmith", + "Cooperstein", + "Cope", + "Copeland", + "Copland", + "Coplin", + "Copp", + "Coppinger", + "Coppins", + "Coppock", + "Coppola", + "Cora", + "Corabel", + "Corabella", + "Corabelle", + "Coral", + "Coralie", + "Coraline", + "Coralyn", + "Coray", + "Corbet", + "Corbett", + "Corbie", + "Corbin", + "Corby", + "Cord", + "Cordalia", + "Cordeelia", + "Cordelia", + "Cordelie", + "Cordell", + "Corder", + "Cordey", + "Cordi", + "Cordie", + "Cordier", + "Cordle", + "Cordova", + "Cordula", + "Cordy", + "Coreen", + "Corel", + "Corell", + "Corella", + "Corena", + "Corenda", + "Corene", + "Coretta", + "Corette", + "Corey", + "Cori", + "Coridon", + "Corie", + "Corilla", + "Corin", + "Corina", + "Corine", + "Corinna", + "Corinne", + "Coriss", + "Corissa", + "Corkhill", + "Corley", + "Corliss", + "Corly", + "Cormac", + "Cormack", + "Cormick", + "Cormier", + "Cornall", + "Corneille", + "Cornel", + "Cornela", + "Cornelia", + "Cornelie", + "Cornelius", + "Cornell", + "Cornelle", + "Cornew", + "Corney", + "Cornia", + "Cornie", + "Cornish", + "Cornwall", + "Cornwell", + "Corny", + "Corotto", + "Correna", + "Correy", + "Corri", + "Corrianne", + "Corrie", + "Corrina", + "Corrine", + "Corrinne", + "Corron", + "Corry", + "Corsetti", + "Corsiglia", + "Corso", + "Corson", + "Cort", + "Cortie", + "Cortney", + "Corty", + "Corvese", + "Corvin", + "Corwin", + "Corwun", + "Cory", + "Coryden", + "Corydon", + "Cos", + "Cosenza", + "Cosetta", + "Cosette", + "Coshow", + "Cosimo", + "Cosma", + "Cosme", + "Cosmo", + "Cost", + "Costa", + "Costanza", + "Costanzia", + "Costello", + "Coster", + "Costin", + "Cote", + "Cotsen", + "Cott", + "Cotter", + "Cotterell", + "Cottle", + "Cottrell", + "Coucher", + "Couchman", + "Coughlin", + "Coulombe", + "Coulson", + "Coulter", + "Coumas", + "Countess", + "Courcy", + "Court", + "Courtenay", + "Courtland", + "Courtnay", + "Courtney", + "Courtund", + "Cousin", + "Cousins", + "Coussoule", + "Couture", + "Covell", + "Coveney", + "Cowan", + "Coward", + "Cowden", + "Cowen", + "Cower", + "Cowey", + "Cowie", + "Cowles", + "Cowley", + "Cown", + "Cox", + "Coy", + "Coyle", + "Cozmo", + "Cozza", + "Crabb", + "Craddock", + "Craggie", + "Craggy", + "Craig", + "Crain", + "Cralg", + "Cram", + "Cramer", + "Cran", + "Crandale", + "Crandall", + "Crandell", + "Crane", + "Craner", + "Cranford", + "Cranston", + "Crary", + "Craven", + "Craw", + "Crawford", + "Crawley", + "Creamer", + "Crean", + "Creath", + "Creedon", + "Creigh", + "Creight", + "Creighton", + "Crelin", + "Crellen", + "Crenshaw", + "Cresa", + "Crescantia", + "Crescen", + "Crescentia", + "Crescin", + "Crescint", + "Cresida", + "Crespi", + "Crespo", + "Cressi", + "Cressida", + "Cressler", + "Cressy", + "Crichton", + "Crifasi", + "Crim", + "Crin", + "Cris", + "Crisey", + "Crispa", + "Crispas", + "Crispen", + "Crispin", + "Crissie", + "Crissy", + "Crist", + "Crista", + "Cristabel", + "Cristal", + "Cristen", + "Cristi", + "Cristian", + "Cristiano", + "Cristie", + "Cristin", + "Cristina", + "Cristine", + "Cristiona", + "Cristionna", + "Cristobal", + "Cristoforo", + "Cristy", + "Criswell", + "Critchfield", + "Critta", + "Crocker", + "Crockett", + "Crofoot", + "Croft", + "Crofton", + "Croix", + "Crompton", + "Cromwell", + "Croner", + "Cronin", + "Crooks", + "Croom", + "Crosby", + "Crosley", + "Cross", + "Crosse", + "Croteau", + "Crotty", + "Crow", + "Crowe", + "Crowell", + "Crowley", + "Crowns", + "Croydon", + "Cruce", + "Crudden", + "Cruickshank", + "Crutcher", + "Cruz", + "Cryan", + "Crysta", + "Crystal", + "Crystie", + "Cthrine", + "Cuda", + "Cudlip", + "Culberson", + "Culbert", + "Culbertson", + "Culhert", + "Cull", + "Cullan", + "Cullen", + "Culley", + "Cullie", + "Cullin", + "Culliton", + "Cully", + "Culosio", + "Culver", + "Cumine", + "Cumings", + "Cummine", + "Cummings", + "Cummins", + "Cung", + "Cunningham", + "Cupo", + "Curcio", + "Curhan", + "Curkell", + "Curley", + "Curnin", + "Curr", + "Curran", + "Curren", + "Currey", + "Currie", + "Currier", + "Curry", + "Curson", + "Curt", + "Curtice", + "Curtis", + "Curzon", + "Cusack", + "Cusick", + "Custer", + "Cut", + "Cutcheon", + "Cutcliffe", + "Cuthbert", + "Cuthbertson", + "Cuthburt", + "Cutler", + "Cutlerr", + "Cutlip", + "Cutlor", + "Cutter", + "Cuttie", + "Cuttler", + "Cutty", + "Cuyler", + "Cy", + "Cyb", + "Cybil", + "Cybill", + "Cychosz", + "Cyd", + "Cykana", + "Cyler", + "Cyma", + "Cymbre", + "Cyn", + "Cyna", + "Cynar", + "Cynara", + "Cynarra", + "Cynde", + "Cyndi", + "Cyndia", + "Cyndie", + "Cyndy", + "Cynera", + "Cynth", + "Cynthea", + "Cynthia", + "Cynthie", + "Cynthla", + "Cynthy", + "Cyprian", + "Cyprio", + "Cypro", + "Cyprus", + "Cyrano", + "Cyrie", + "Cyril", + "Cyrill", + "Cyrilla", + "Cyrille", + "Cyrillus", + "Cyrus", + "Czarra", + "D'Arcy", + "Dabbs", + "Daberath", + "Dabney", + "Dace", + "Dacey", + "Dachi", + "Dachia", + "Dachy", + "Dacia", + "Dacie", + "Dacy", + "Daegal", + "Dael", + "Daffi", + "Daffie", + "Daffodil", + "Daffy", + "Dafna", + "Dafodil", + "Dag", + "Dagall", + "Daggett", + "Daggna", + "Dagley", + "Dagmar", + "Dagna", + "Dagnah", + "Dagney", + "Dagny", + "Dahl", + "Dahle", + "Dahlia", + "Dahlstrom", + "Daigle", + "Dail", + "Daile", + "Dailey", + "Daisey", + "Daisi", + "Daisie", + "Daisy", + "Daitzman", + "Dal", + "Dale", + "Dalenna", + "Daley", + "Dalia", + "Dalila", + "Dalis", + "Dall", + "Dallas", + "Dalli", + "Dallis", + "Dallman", + "Dallon", + "Daloris", + "Dalpe", + "Dalston", + "Dalt", + "Dalton", + "Dalury", + "Daly", + "Dam", + "Damal", + "Damalas", + "Damales", + "Damali", + "Damalis", + "Damalus", + "Damara", + "Damaris", + "Damarra", + "Dambro", + "Dame", + "Damek", + "Damian", + "Damiani", + "Damiano", + "Damick", + "Damicke", + "Damien", + "Damita", + "Damle", + "Damon", + "Damour", + "Dan", + "Dana", + "Danae", + "Danaher", + "Danais", + "Danas", + "Danby", + "Danczyk", + "Dane", + "Danell", + "Danella", + "Danelle", + "Danete", + "Danette", + "Daney", + "Danforth", + "Dang", + "Dani", + "Dania", + "Daniala", + "Danialah", + "Danica", + "Danice", + "Danie", + "Daniel", + "Daniela", + "Daniele", + "Daniell", + "Daniella", + "Danielle", + "Daniels", + "Danielson", + "Danieu", + "Danika", + "Danila", + "Danit", + "Danita", + "Daniyal", + "Dann", + "Danna", + "Dannel", + "Danni", + "Dannica", + "Dannie", + "Dannon", + "Danny", + "Dannye", + "Dante", + "Danuloff", + "Danya", + "Danyelle", + "Danyette", + "Danyluk", + "Danzig", + "Danziger", + "Dao", + "Daph", + "Daphene", + "Daphie", + "Daphna", + "Daphne", + "Dar", + "Dara", + "Darach", + "Darb", + "Darbee", + "Darbie", + "Darby", + "Darce", + "Darcee", + "Darcey", + "Darci", + "Darcia", + "Darcie", + "Darcy", + "Darda", + "Dardani", + "Dare", + "Dareece", + "Dareen", + "Darees", + "Darell", + "Darelle", + "Daren", + "Dari", + "Daria", + "Darian", + "Darice", + "Darill", + "Darin", + "Dario", + "Darius", + "Darken", + "Darla", + "Darleen", + "Darlene", + "Darline", + "Darlleen", + "Darmit", + "Darn", + "Darnall", + "Darnell", + "Daron", + "Darooge", + "Darra", + "Darrel", + "Darrell", + "Darrelle", + "Darren", + "Darrey", + "Darrick", + "Darrill", + "Darrin", + "Darrow", + "Darryl", + "Darryn", + "Darsey", + "Darsie", + "Dart", + "Darton", + "Darwen", + "Darwin", + "Darya", + "Daryl", + "Daryle", + "Daryn", + "Dash", + "Dasha", + "Dasi", + "Dasie", + "Dasteel", + "Dasya", + "Datha", + "Datnow", + "Daub", + "Daugherty", + "Daughtry", + "Daukas", + "Daune", + "Dav", + "Dave", + "Daveda", + "Daveen", + "Daven", + "Davena", + "Davenport", + "Daveta", + "Davey", + "David", + "Davida", + "Davidde", + "Davide", + "Davidoff", + "Davidson", + "Davie", + "Davies", + "Davilman", + "Davin", + "Davina", + "Davine", + "Davis", + "Davison", + "Davita", + "Davon", + "Davy", + "Dawes", + "Dawkins", + "Dawn", + "Dawna", + "Dawson", + "Day", + "Daye", + "Dayle", + "Dayna", + "Ddene", + "De", + "De Witt", + "Deach", + "Deacon", + "Deadman", + "Dean", + "Deana", + "Deane", + "Deaner", + "Deanna", + "Deanne", + "Dearborn", + "Dearden", + "Dearman", + "Dearr", + "Deb", + "Debarath", + "Debbee", + "Debbi", + "Debbie", + "Debbra", + "Debby", + "Debee", + "Debera", + "Debi", + "Debor", + "Debora", + "Deborah", + "Deborath", + "Debra", + "Decamp", + "Decato", + "Decca", + "December", + "Decima", + "Deck", + "Decker", + "Deckert", + "Declan", + "Dede", + "Deden", + "Dedie", + "Dedra", + "Dedric", + "Dedrick", + "Dee", + "Dee Dee", + "DeeAnn", + "Deeann", + "Deeanne", + "Deedee", + "Deegan", + "Deena", + "Deenya", + "Deer", + "Deerdre", + "Deering", + "Deery", + "Deeyn", + "Defant", + "Dehlia", + "Dehnel", + "Deibel", + "Deidre", + "Deina", + "Deirdra", + "Deirdre", + "Dekeles", + "Dekow", + "Del", + "Dela", + "Delacourt", + "Delaine", + "Delainey", + "Delamare", + "Deland", + "Delaney", + "Delanie", + "Delano", + "Delanos", + "Delanty", + "Delaryd", + "Delastre", + "Delbert", + "Delcina", + "Delcine", + "Delfeena", + "Delfine", + "Delgado", + "Delia", + "Delija", + "Delila", + "Delilah", + "Delinda", + "Delisle", + "Dell", + "Della", + "Delle", + "Dellora", + "Delly", + "Delmar", + "Delmer", + "Delmor", + "Delmore", + "Delogu", + "Delora", + "Delorenzo", + "Delores", + "Deloria", + "Deloris", + "Delos", + "Delp", + "Delphina", + "Delphine", + "Delphinia", + "Delsman", + "Delwin", + "Delwyn", + "Demaggio", + "Demakis", + "Demaria", + "Demb", + "Demeter", + "Demetra", + "Demetre", + "Demetri", + "Demetria", + "Demetris", + "Demetrius", + "Demeyer", + "Deming", + "Demitria", + "Demmer", + "Demmy", + "Demodena", + "Demona", + "Demott", + "Demp", + "Dempsey", + "Dempster", + "Dempstor", + "Demy", + "Den", + "Dena", + "Denae", + "Denbrook", + "Denby", + "Dene", + "Deni", + "Denice", + "Denie", + "Denis", + "Denise", + "Denison", + "Denman", + "Denn", + "Denna", + "Dennard", + "Dennet", + "Dennett", + "Denney", + "Denni", + "Dennie", + "Dennis", + "Dennison", + "Denny", + "Denoting", + "Dent", + "Denten", + "Denton", + "Denver", + "Deny", + "Denys", + "Denyse", + "Denzil", + "Deonne", + "Depoliti", + "Deppy", + "Der", + "Deragon", + "Derayne", + "Derby", + "Dercy", + "Derek", + "Derian", + "Derick", + "Derina", + "Derinna", + "Derk", + "Derman", + "Dermot", + "Dermott", + "Derna", + "Deron", + "Deroo", + "Derr", + "Derrek", + "Derrick", + "Derriey", + "Derrik", + "Derril", + "Derron", + "Derry", + "Derte", + "Derward", + "Derwin", + "Derwon", + "Derwood", + "Deryl", + "Derzon", + "Des", + "Desai", + "Desberg", + "Descombes", + "Desdamona", + "Desdamonna", + "Desdee", + "Desdemona", + "Desi", + "Desimone", + "Desirae", + "Desirea", + "Desireah", + "Desiree", + "Desiri", + "Desma", + "Desmond", + "Desmund", + "Dessma", + "Desta", + "Deste", + "Destinee", + "Deth", + "Dett", + "Detta", + "Dettmer", + "Deuno", + "Deutsch", + "Dev", + "Deva", + "Devan", + "Devaney", + "Dever", + "Devi", + "Devin", + "Devina", + "Devine", + "Devinna", + "Devinne", + "Devitt", + "Devland", + "Devlen", + "Devlin", + "Devol", + "Devon", + "Devona", + "Devondra", + "Devonna", + "Devonne", + "Devora", + "Devy", + "Dew", + "Dewain", + "Dewar", + "Dewayne", + "Dewees", + "Dewey", + "Dewhirst", + "Dewhurst", + "Dewie", + "Dewitt", + "Dex", + "Dexter", + "Dey", + "Dhar", + "Dhiman", + "Dhiren", + "Dhruv", + "Dhu", + "Dhumma", + "Di", + "Diahann", + "Diamante", + "Diamond", + "Dian", + "Diana", + "Diandra", + "Diandre", + "Diane", + "Diane-Marie", + "Dianemarie", + "Diann", + "Dianna", + "Dianne", + "Diannne", + "Diantha", + "Dianthe", + "Diao", + "Diarmid", + "Diarmit", + "Diarmuid", + "Diaz", + "Dib", + "Diba", + "Dibb", + "Dibbell", + "Dibbrun", + "Dibri", + "Dibrin", + "Dibru", + "Dich", + "Dichy", + "Dick", + "Dickens", + "Dickenson", + "Dickerson", + "Dickey", + "Dickie", + "Dickinson", + "Dickman", + "Dicks", + "Dickson", + "Dicky", + "Didi", + "Didier", + "Dido", + "Dieball", + "Diego", + "Diehl", + "Diella", + "Dielle", + "Dielu", + "Diena", + "Dierdre", + "Dierolf", + "Diet", + "Dieter", + "Dieterich", + "Dietrich", + "Dietsche", + "Dietz", + "Dikmen", + "Dilan", + "Diley", + "Dilisio", + "Dilks", + "Dill", + "Dillie", + "Dillon", + "Dilly", + "Dimitri", + "Dimitris", + "Dimitry", + "Dimmick", + "Dimond", + "Dimphia", + "Dina", + "Dinah", + "Dinan", + "Dincolo", + "Dine", + "Dinerman", + "Dinesh", + "Dinin", + "Dinnage", + "Dinnie", + "Dinny", + "Dino", + "Dinsdale", + "Dinse", + "Dinsmore", + "Diogenes", + "Dion", + "Dione", + "Dionis", + "Dionisio", + "Dionne", + "Dionysus", + "Dippold", + "Dira", + "Dirk", + "Disario", + "Disharoon", + "Disini", + "Diskin", + "Diskson", + "Disraeli", + "Dita", + "Ditmore", + "Ditter", + "Dittman", + "Dituri", + "Ditzel", + "Diver", + "Divine", + "Dix", + "Dixie", + "Dixil", + "Dixon", + "Dmitri", + "Dniren", + "Doak", + "Doane", + "Dobb", + "Dobbins", + "Doble", + "Dobrinsky", + "Dobson", + "Docia", + "Docila", + "Docile", + "Docilla", + "Docilu", + "Dodd", + "Dodds", + "Dode", + "Dodge", + "Dodi", + "Dodie", + "Dodson", + "Dodwell", + "Dody", + "Doe", + "Doehne", + "Doelling", + "Doerrer", + "Doersten", + "Doggett", + "Dogs", + "Doherty", + "Doi", + "Doig", + "Dola", + "Dolan", + "Dole", + "Doley", + "Dolf", + "Dolhenty", + "Doll", + "Dollar", + "Dolley", + "Dolli", + "Dollie", + "Dolloff", + "Dolly", + "Dolora", + "Dolores", + "Dolorita", + "Doloritas", + "Dolph", + "Dolphin", + "Dom", + "Domash", + "Dombrowski", + "Domel", + "Domela", + "Domella", + "Domenech", + "Domenic", + "Domenico", + "Domeniga", + "Domineca", + "Dominga", + "Domingo", + "Domini", + "Dominic", + "Dominica", + "Dominick", + "Dominik", + "Dominique", + "Dominus", + "Dominy", + "Domonic", + "Domph", + "Don", + "Dona", + "Donadee", + "Donaghue", + "Donahoe", + "Donahue", + "Donal", + "Donald", + "Donaldson", + "Donall", + "Donalt", + "Donata", + "Donatelli", + "Donaugh", + "Donavon", + "Donegan", + "Donela", + "Donell", + "Donella", + "Donelle", + "Donelson", + "Donelu", + "Doner", + "Donetta", + "Dong", + "Donia", + "Donica", + "Donielle", + "Donn", + "Donna", + "Donnamarie", + "Donnell", + "Donnelly", + "Donnenfeld", + "Donni", + "Donnie", + "Donny", + "Donoghue", + "Donoho", + "Donohue", + "Donough", + "Donovan", + "Doolittle", + "Doone", + "Dopp", + "Dora", + "Doralia", + "Doralin", + "Doralyn", + "Doralynn", + "Doralynne", + "Doran", + "Dorca", + "Dorcas", + "Dorcea", + "Dorcia", + "Dorcus", + "Dorcy", + "Dore", + "Doreen", + "Dorelia", + "Dorella", + "Dorelle", + "Dorena", + "Dorene", + "Doretta", + "Dorette", + "Dorey", + "Dorfman", + "Dori", + "Doria", + "Dorian", + "Dorice", + "Dorie", + "Dorin", + "Dorina", + "Dorinda", + "Dorine", + "Dorion", + "Doris", + "Dorisa", + "Dorise", + "Dorison", + "Dorita", + "Dorkas", + "Dorkus", + "Dorlisa", + "Dorman", + "Dorn", + "Doro", + "Dorolice", + "Dorolisa", + "Dorotea", + "Doroteya", + "Dorothea", + "Dorothee", + "Dorothi", + "Dorothy", + "Dorr", + "Dorran", + "Dorree", + "Dorren", + "Dorri", + "Dorrie", + "Dorris", + "Dorry", + "Dorsey", + "Dorsman", + "Dorsy", + "Dorthea", + "Dorthy", + "Dorweiler", + "Dorwin", + "Dory", + "Doscher", + "Dosh", + "Dosi", + "Dosia", + "Doss", + "Dot", + "Doti", + "Dotson", + "Dott", + "Dotti", + "Dottie", + "Dotty", + "Doty", + "Doubler", + "Doug", + "Dougal", + "Dougald", + "Dougall", + "Dougherty", + "Doughman", + "Doughty", + "Dougie", + "Douglas", + "Douglass", + "Dougy", + "Douty", + "Douville", + "Dov", + "Dove", + "Dovev", + "Dow", + "Dowd", + "Dowdell", + "Dowell", + "Dowlen", + "Dowling", + "Down", + "Downall", + "Downe", + "Downes", + "Downey", + "Downing", + "Downs", + "Dowski", + "Dowzall", + "Doxia", + "Doy", + "Doykos", + "Doyle", + "Drabeck", + "Dragelin", + "Dragon", + "Dragone", + "Dragoon", + "Drain", + "Drais", + "Drake", + "Drandell", + "Drape", + "Draper", + "Dray", + "Dre", + "Dream", + "Dreda", + "Dreddy", + "Dredi", + "Dreeda", + "Dreher", + "Dremann", + "Drescher", + "Dressel", + "Dressler", + "Drew", + "Drewett", + "Drews", + "Drexler", + "Dreyer", + "Dric", + "Drice", + "Drida", + "Dripps", + "Driscoll", + "Driskill", + "Drisko", + "Drislane", + "Drobman", + "Drogin", + "Drolet", + "Drona", + "Dronski", + "Drooff", + "Dru", + "Druce", + "Druci", + "Drucie", + "Drucill", + "Drucilla", + "Drucy", + "Drud", + "Drue", + "Drugge", + "Drugi", + "Drummond", + "Drus", + "Drusi", + "Drusie", + "Drusilla", + "Drusus", + "Drusy", + "Dry", + "Dryden", + "Drye", + "Dryfoos", + "DuBois", + "Duane", + "Duarte", + "Duax", + "Dubenko", + "Dublin", + "Ducan", + "Duck", + "Dud", + "Dudden", + "Dudley", + "Duer", + "Duester", + "Duff", + "Duffie", + "Duffy", + "Dugaid", + "Dugald", + "Dugan", + "Dugas", + "Duggan", + "Duhl", + "Duke", + "Dukey", + "Dukie", + "Duky", + "Dulce", + "Dulcea", + "Dulci", + "Dulcia", + "Dulciana", + "Dulcie", + "Dulcine", + "Dulcinea", + "Dulcle", + "Dulcy", + "Duleba", + "Dulla", + "Dulsea", + "Duma", + "Dumah", + "Dumanian", + "Dumas", + "Dumm", + "Dumond", + "Dun", + "Dunaville", + "Dunc", + "Duncan", + "Dunham", + "Dunkin", + "Dunlavy", + "Dunn", + "Dunning", + "Dunseath", + "Dunson", + "Dunstan", + "Dunston", + "Dunton", + "Duntson", + "Duong", + "Dupaix", + "Dupin", + "Dupre", + "Dupuis", + "Dupuy", + "Duquette", + "Dur", + "Durand", + "Durant", + "Durante", + "Durarte", + "Durer", + "Durgy", + "Durham", + "Durkee", + "Durkin", + "Durman", + "Durnan", + "Durning", + "Durno", + "Durr", + "Durrace", + "Durrell", + "Durrett", + "Durst", + "Durstin", + "Durston", + "Durtschi", + "Durward", + "Durware", + "Durwin", + "Durwood", + "Durwyn", + "Dusa", + "Dusen", + "Dust", + "Dustan", + "Duster", + "Dustie", + "Dustin", + "Dustman", + "Duston", + "Dusty", + "Dusza", + "Dutch", + "Dutchman", + "Duthie", + "Duval", + "Duvall", + "Duwalt", + "Duwe", + "Duyne", + "Dwain", + "Dwaine", + "Dwan", + "Dwane", + "Dwayne", + "Dweck", + "Dwight", + "Dwinnell", + "Dworman", + "Dwyer", + "Dyal", + "Dyan", + "Dyana", + "Dyane", + "Dyann", + "Dyanna", + "Dyanne", + "Dyche", + "Dyer", + "Dygal", + "Dygall", + "Dygert", + "Dyke", + "Dyl", + "Dylan", + "Dylana", + "Dylane", + "Dymoke", + "Dympha", + "Dymphia", + "Dyna", + "Dynah", + "Dysart", + "Dyson", + "Dyun", + "Dzoba", + "Eachelle", + "Eachern", + "Eada", + "Eade", + "Eadie", + "Eadith", + "Eadmund", + "Eads", + "Eadwina", + "Eadwine", + "Eagle", + "Eal", + "Ealasaid", + "Eamon", + "Eanore", + "Earl", + "Earla", + "Earle", + "Earleen", + "Earlene", + "Earley", + "Earlie", + "Early", + "Eartha", + "Earvin", + "East", + "Easter", + "Eastlake", + "Eastman", + "Easton", + "Eaton", + "Eatton", + "Eaves", + "Eb", + "Eba", + "Ebarta", + "Ebba", + "Ebbarta", + "Ebberta", + "Ebbie", + "Ebby", + "Eben", + "Ebeneser", + "Ebenezer", + "Eberhard", + "Eberhart", + "Eberle", + "Eberly", + "Ebert", + "Eberta", + "Eberto", + "Ebner", + "Ebneter", + "Eboh", + "Ebonee", + "Ebony", + "Ebsen", + "Echikson", + "Echo", + "Eckardt", + "Eckart", + "Eckblad", + "Eckel", + "Eckhardt", + "Eckmann", + "Econah", + "Ed", + "Eda", + "Edan", + "Edana", + "Edbert", + "Edd", + "Edda", + "Eddana", + "Eddi", + "Eddie", + "Eddina", + "Eddra", + "Eddy", + "Ede", + "Edea", + "Edee", + "Edeline", + "Edelman", + "Edelson", + "Edelstein", + "Edelsten", + "Eden", + "Edette", + "Edgar", + "Edgard", + "Edgardo", + "Edge", + "Edgell", + "Edgerton", + "Edholm", + "Edi", + "Edie", + "Edik", + "Edin", + "Edina", + "Edison", + "Edita", + "Edith", + "Editha", + "Edithe", + "Ediva", + "Edla", + "Edlin", + "Edlun", + "Edlyn", + "Edmanda", + "Edme", + "Edmea", + "Edmead", + "Edmee", + "Edmon", + "Edmond", + "Edmonda", + "Edmondo", + "Edmonds", + "Edmund", + "Edmunda", + "Edna", + "Edny", + "Edora", + "Edouard", + "Edra", + "Edrea", + "Edrei", + "Edric", + "Edrick", + "Edris", + "Edrock", + "Edroi", + "Edsel", + "Edson", + "Eduard", + "Eduardo", + "Eduino", + "Edva", + "Edvard", + "Edveh", + "Edward", + "Edwards", + "Edwin", + "Edwina", + "Edwine", + "Edwyna", + "Edy", + "Edyth", + "Edythe", + "Effie", + "Effy", + "Efram", + "Efrem", + "Efren", + "Efron", + "Efthim", + "Egan", + "Egarton", + "Egbert", + "Egerton", + "Eggett", + "Eggleston", + "Egide", + "Egidio", + "Egidius", + "Egin", + "Eglanteen", + "Eglantine", + "Egon", + "Egor", + "Egwan", + "Egwin", + "Ehling", + "Ehlke", + "Ehman", + "Ehr", + "Ehrenberg", + "Ehrlich", + "Ehrman", + "Ehrsam", + "Ehud", + "Ehudd", + "Eichman", + "Eidson", + "Eiger", + "Eileen", + "Eilis", + "Eimile", + "Einberger", + "Einhorn", + "Eipper", + "Eirena", + "Eirene", + "Eisele", + "Eisen", + "Eisenberg", + "Eisenhart", + "Eisenstark", + "Eiser", + "Eisinger", + "Eisler", + "Eiten", + "Ekaterina", + "El", + "Ela", + "Elah", + "Elaina", + "Elaine", + "Elana", + "Elane", + "Elata", + "Elatia", + "Elayne", + "Elazaro", + "Elbart", + "Elberfeld", + "Elbert", + "Elberta", + "Elbertina", + "Elbertine", + "Elboa", + "Elbring", + "Elburr", + "Elburt", + "Elconin", + "Elda", + "Elden", + "Elder", + "Eldin", + "Eldon", + "Eldora", + "Eldorado", + "Eldoree", + "Eldoria", + "Eldred", + "Eldreda", + "Eldredge", + "Eldreeda", + "Eldrid", + "Eldrida", + "Eldridge", + "Eldwen", + "Eldwin", + "Eldwon", + "Eldwun", + "Eleanor", + "Eleanora", + "Eleanore", + "Eleazar", + "Electra", + "Eleen", + "Elena", + "Elene", + "Eleni", + "Elenore", + "Eleonora", + "Eleonore", + "Eleph", + "Elephus", + "Elery", + "Elexa", + "Elfie", + "Elfont", + "Elfreda", + "Elfrida", + "Elfrieda", + "Elfstan", + "Elga", + "Elgar", + "Eli", + "Elia", + "Eliades", + "Elianora", + "Elianore", + "Elias", + "Eliason", + "Eliath", + "Eliathan", + "Eliathas", + "Elicia", + "Elidad", + "Elie", + "Eliezer", + "Eliga", + "Elihu", + "Elijah", + "Elinor", + "Elinore", + "Eliot", + "Eliott", + "Elisa", + "Elisabet", + "Elisabeth", + "Elisabetta", + "Elise", + "Elisee", + "Eliseo", + "Elish", + "Elisha", + "Elison", + "Elissa", + "Elita", + "Eliza", + "Elizabet", + "Elizabeth", + "Elka", + "Elke", + "Elkin", + "Ella", + "Elladine", + "Ellan", + "Ellard", + "Ellary", + "Ellata", + "Elle", + "Ellen", + "Ellene", + "Ellerd", + "Ellerey", + "Ellersick", + "Ellery", + "Ellett", + "Ellette", + "Ellga", + "Elli", + "Ellicott", + "Ellie", + "Ellinger", + "Ellingston", + "Elliot", + "Elliott", + "Ellis", + "Ellison", + "Ellissa", + "Ellita", + "Ellmyer", + "Ellon", + "Ellora", + "Ellord", + "Ellswerth", + "Ellsworth", + "Ellwood", + "Elly", + "Ellyn", + "Ellynn", + "Elma", + "Elmajian", + "Elmaleh", + "Elman", + "Elmer", + "Elmina", + "Elmira", + "Elmo", + "Elmore", + "Elna", + "Elnar", + "Elnora", + "Elnore", + "Elo", + "Elodea", + "Elodia", + "Elodie", + "Eloisa", + "Eloise", + "Elon", + "Elonore", + "Elora", + "Elreath", + "Elrod", + "Elroy", + "Els", + "Elsa", + "Elsbeth", + "Else", + "Elset", + "Elsey", + "Elsi", + "Elsie", + "Elsinore", + "Elson", + "Elspet", + "Elspeth", + "Elstan", + "Elston", + "Elsworth", + "Elsy", + "Elton", + "Elum", + "Elurd", + "Elva", + "Elvah", + "Elvera", + "Elvia", + "Elvie", + "Elvin", + "Elvina", + "Elvira", + "Elvis", + "Elvyn", + "Elwaine", + "Elwee", + "Elwin", + "Elwina", + "Elwira", + "Elwood", + "Elwyn", + "Ely", + "Elyn", + "Elyse", + "Elysee", + "Elysha", + "Elysia", + "Elyssa", + "Em", + "Ema", + "Emad", + "Emalee", + "Emalia", + "Emanuel", + "Emanuela", + "Emanuele", + "Emarie", + "Embry", + "Emee", + "Emelda", + "Emelen", + "Emelia", + "Emelin", + "Emelina", + "Emeline", + "Emelita", + "Emelun", + "Emelyne", + "Emera", + "Emerald", + "Emeric", + "Emerick", + "Emersen", + "Emerson", + "Emery", + "Emie", + "Emil", + "Emile", + "Emilee", + "Emili", + "Emilia", + "Emilie", + "Emiline", + "Emilio", + "Emily", + "Emina", + "Emlen", + "Emlin", + "Emlyn", + "Emlynn", + "Emlynne", + "Emma", + "Emmalee", + "Emmaline", + "Emmalyn", + "Emmalynn", + "Emmalynne", + "Emmanuel", + "Emmeline", + "Emmer", + "Emmeram", + "Emmerich", + "Emmerie", + "Emmery", + "Emmet", + "Emmett", + "Emmey", + "Emmi", + "Emmie", + "Emmit", + "Emmons", + "Emmott", + "Emmuela", + "Emmy", + "Emmye", + "Emogene", + "Emory", + "Emrich", + "Emsmus", + "Emyle", + "Emylee", + "Enalda", + "Encrata", + "Encratia", + "Encratis", + "End", + "Ender", + "Endo", + "Endor", + "Endora", + "Endres", + "Enenstein", + "Eng", + "Engdahl", + "Engeddi", + "Engedi", + "Engedus", + "Engel", + "Engelbert", + "Engelhart", + "Engen", + "Engenia", + "England", + "Engle", + "Englebert", + "Engleman", + "Englis", + "English", + "Engracia", + "Engud", + "Engvall", + "Enid", + "Ennis", + "Eno", + "Enoch", + "Enos", + "Enrica", + "Enrichetta", + "Enrico", + "Enrika", + "Enrique", + "Enriqueta", + "Ensign", + "Ensoll", + "Entwistle", + "Enyedy", + "Eoin", + "Eolanda", + "Eolande", + "Eph", + "Ephraim", + "Ephram", + "Ephrayim", + "Ephrem", + "Epifano", + "Epner", + "Epp", + "Epperson", + "Eppes", + "Eppie", + "Epps", + "Epstein", + "Er", + "Eradis", + "Eran", + "Eras", + "Erasme", + "Erasmo", + "Erasmus", + "Erastatus", + "Eraste", + "Erastes", + "Erastus", + "Erb", + "Erbe", + "Erbes", + "Erda", + "Erdah", + "Erdda", + "Erde", + "Erdei", + "Erdman", + "Erdrich", + "Erek", + "Erelia", + "Erena", + "Erfert", + "Ergener", + "Erhard", + "Erhart", + "Eri", + "Eric", + "Erica", + "Erich", + "Ericha", + "Erick", + "Ericka", + "Ericksen", + "Erickson", + "Erida", + "Erie", + "Eriha", + "Erik", + "Erika", + "Erikson", + "Erin", + "Erina", + "Erine", + "Erinn", + "Erinna", + "Erkan", + "Erl", + "Erland", + "Erlandson", + "Erle", + "Erleena", + "Erlene", + "Erlewine", + "Erlin", + "Erlina", + "Erline", + "Erlinna", + "Erlond", + "Erma", + "Ermanno", + "Erme", + "Ermeena", + "Ermengarde", + "Ermentrude", + "Ermey", + "Ermin", + "Ermina", + "Ermine", + "Erminia", + "Erminie", + "Erminna", + "Ern", + "Erna", + "Ernald", + "Ernaldus", + "Ernaline", + "Ernest", + "Ernesta", + "Ernestine", + "Ernesto", + "Ernestus", + "Ernie", + "Ernst", + "Erny", + "Errecart", + "Errick", + "Errol", + "Erroll", + "Erskine", + "Ertha", + "Erund", + "Erv", + "ErvIn", + "Ervin", + "Ervine", + "Erving", + "Erwin", + "Eryn", + "Esau", + "Esbensen", + "Esbenshade", + "Esch", + "Esdras", + "Eshelman", + "Eshman", + "Eskil", + "Eskill", + "Esma", + "Esmaria", + "Esme", + "Esmeralda", + "Esmerelda", + "Esmerolda", + "Esmond", + "Espy", + "Esra", + "Essa", + "Essam", + "Essex", + "Essie", + "Essinger", + "Essy", + "Esta", + "Estas", + "Esteban", + "Estel", + "Estele", + "Estell", + "Estella", + "Estelle", + "Esten", + "Ester", + "Estes", + "Estevan", + "Estey", + "Esther", + "Estis", + "Estrella", + "Estrellita", + "Estren", + "Estrin", + "Estus", + "Eta", + "Etam", + "Etan", + "Etana", + "Etem", + "Ethan", + "Ethban", + "Ethben", + "Ethbin", + "Ethbinium", + "Ethbun", + "Ethe", + "Ethel", + "Ethelbert", + "Ethelda", + "Ethelin", + "Ethelind", + "Ethelinda", + "Etheline", + "Ethelred", + "Ethelstan", + "Ethelyn", + "Ethyl", + "Etienne", + "Etka", + "Etoile", + "Etom", + "Etra", + "Etrem", + "Etta", + "Ettari", + "Etti", + "Ettie", + "Ettinger", + "Ettore", + "Etty", + "Etz", + "Eudo", + "Eudoca", + "Eudocia", + "Eudora", + "Eudosia", + "Eudoxia", + "Euell", + "Eugen", + "Eugene", + "Eugenia", + "Eugenides", + "Eugenie", + "Eugenio", + "Eugenius", + "Eugeniusz", + "Eugenle", + "Eugine", + "Euh", + "Eula", + "Eulalee", + "Eulalia", + "Eulaliah", + "Eulalie", + "Eulau", + "Eunice", + "Eupheemia", + "Euphemia", + "Euphemiah", + "Euphemie", + "Euridice", + "Eurydice", + "Eusebio", + "Eustace", + "Eustache", + "Eustacia", + "Eustashe", + "Eustasius", + "Eustatius", + "Eustazio", + "Eustis", + "Euton", + "Ev", + "Eva", + "Evadne", + "Evadnee", + "Evaleen", + "Evalyn", + "Evan", + "Evander", + "Evangelia", + "Evangelin", + "Evangelina", + "Evangeline", + "Evangelist", + "Evania", + "Evanne", + "Evannia", + "Evans", + "Evante", + "Evanthe", + "Evars", + "Eve", + "Eveleen", + "Evelin", + "Evelina", + "Eveline", + "Evelinn", + "Evelunn", + "Evelyn", + "Even", + "Everara", + "Everard", + "Evered", + "Everest", + "Everett", + "Everick", + "Everrs", + "Evers", + "Eversole", + "Everson", + "Evetta", + "Evette", + "Evey", + "Evie", + "Evin", + "Evita", + "Evonne", + "Evoy", + "Evslin", + "Evvie", + "Evvy", + "Evy", + "Evyn", + "Ewald", + "Ewall", + "Ewan", + "Eward", + "Ewart", + "Ewell", + "Ewen", + "Ewens", + "Ewer", + "Ewold", + "Eyde", + "Eydie", + "Eyeleen", + "Eyla", + "Ez", + "Ezana", + "Ezar", + "Ezara", + "Ezaria", + "Ezarra", + "Ezarras", + "Ezechiel", + "Ezekiel", + "Ezequiel", + "Eziechiele", + "Ezmeralda", + "Ezra", + "Ezri", + "Ezzo", + "Fabe", + "Faber", + "Fabi", + "Fabian", + "Fabiano", + "Fabien", + "Fabio", + "Fabiola", + "Fabiolas", + "Fablan", + "Fabozzi", + "Fabri", + "Fabria", + "Fabriane", + "Fabrianna", + "Fabrianne", + "Fabrice", + "Fabrienne", + "Fabrin", + "Fabron", + "Fabyola", + "Fachan", + "Fachanan", + "Fachini", + "Fadden", + "Faden", + "Fadil", + "Fadiman", + "Fae", + "Fagaly", + "Fagan", + "Fagen", + "Fagin", + "Fahey", + "Fahland", + "Fahy", + "Fai", + "Faina", + "Fair", + "Fairbanks", + "Faires", + "Fairfax", + "Fairfield", + "Fairleigh", + "Fairley", + "Fairlie", + "Fairman", + "Fairweather", + "Faith", + "Fakieh", + "Falcone", + "Falconer", + "Falda", + "Faletti", + "Faline", + "Falito", + "Falk", + "Falkner", + "Fallon", + "Faludi", + "Falzetta", + "Fan", + "Fanchan", + "Fanchet", + "Fanchette", + "Fanchie", + "Fanchon", + "Fancie", + "Fancy", + "Fanechka", + "Fanestil", + "Fang", + "Fania", + "Fanni", + "Fannie", + "Fanning", + "Fanny", + "Fantasia", + "Fante", + "Fanya", + "Far", + "Fara", + "Farah", + "Farand", + "Farant", + "Farhi", + "Fari", + "Faria", + "Farica", + "Farika", + "Fariss", + "Farkas", + "Farl", + "Farland", + "Farlay", + "Farlee", + "Farleigh", + "Farley", + "Farlie", + "Farly", + "Farman", + "Farmann", + "Farmelo", + "Farmer", + "Farnham", + "Farnsworth", + "Farny", + "Faro", + "Farr", + "Farra", + "Farrah", + "Farrand", + "Farrar", + "Farrel", + "Farrell", + "Farrica", + "Farrington", + "Farris", + "Farrish", + "Farrison", + "Farro", + "Farron", + "Farrow", + "Faruq", + "Farver", + "Farwell", + "Fasano", + "Faso", + "Fassold", + "Fast", + "Fasta", + "Fasto", + "Fates", + "Fatima", + "Fatimah", + "Fatma", + "Fattal", + "Faubert", + "Faubion", + "Fauch", + "Faucher", + "Faulkner", + "Fauman", + "Faun", + "Faunia", + "Faunie", + "Faus", + "Faust", + "Fausta", + "Faustena", + "Faustina", + "Faustine", + "Faustus", + "Fauver", + "Faux", + "Favata", + "Favian", + "Favianus", + "Favien", + "Favin", + "Favrot", + "Fawcett", + "Fawcette", + "Fawn", + "Fawna", + "Fawne", + "Fawnia", + "Fax", + "Faxan", + "Faxen", + "Faxon", + "Faxun", + "Fay", + "Faydra", + "Faye", + "Fayette", + "Fayina", + "Fayola", + "Fayre", + "Fayth", + "Faythe", + "Fazeli", + "Fe", + "Featherstone", + "February", + "Fechter", + "Fedak", + "Federica", + "Federico", + "Fedirko", + "Fedora", + "Fee", + "Feeley", + "Feeney", + "Feer", + "Feigin", + "Feil", + "Fein", + "Feinberg", + "Feingold", + "Feinleib", + "Feinstein", + "Feld", + "Felder", + "Feldman", + "Feldstein", + "Feldt", + "Felecia", + "Feledy", + "Felic", + "Felicdad", + "Felice", + "Felicia", + "Felicidad", + "Felicie", + "Felicio", + "Felicity", + "Felicle", + "Felike", + "Feliks", + "Felipa", + "Felipe", + "Felise", + "Felisha", + "Felita", + "Felix", + "Feliza", + "Felizio", + "Fellner", + "Fellows", + "Felske", + "Felt", + "Felten", + "Feltie", + "Felton", + "Felty", + "Fem", + "Femi", + "Femmine", + "Fen", + "Fendig", + "Fenelia", + "Fenella", + "Fenn", + "Fennell", + "Fennelly", + "Fenner", + "Fennessy", + "Fennie", + "Fenny", + "Fenton", + "Fenwick", + "Feodor", + "Feodora", + "Feodore", + "Feola", + "Ferd", + "Ferde", + "Ferdie", + "Ferdinana", + "Ferdinand", + "Ferdinanda", + "Ferdinande", + "Ferdy", + "Fergus", + "Ferguson", + "Feriga", + "Ferino", + "Fermin", + "Fern", + "Ferna", + "Fernald", + "Fernand", + "Fernanda", + "Fernande", + "Fernandes", + "Fernandez", + "Fernandina", + "Fernando", + "Fernas", + "Ferne", + "Ferneau", + "Fernyak", + "Ferrand", + "Ferreby", + "Ferree", + "Ferrel", + "Ferrell", + "Ferren", + "Ferretti", + "Ferri", + "Ferrick", + "Ferrigno", + "Ferris", + "Ferriter", + "Ferro", + "Ferullo", + "Ferwerda", + "Festa", + "Festatus", + "Festus", + "Feucht", + "Feune", + "Fevre", + "Fey", + "Fi", + "Fia", + "Fiann", + "Fianna", + "Fidel", + "Fidela", + "Fidelas", + "Fidele", + "Fidelia", + "Fidelio", + "Fidelis", + "Fidelity", + "Fidellas", + "Fidellia", + "Fiden", + "Fidole", + "Fiedler", + "Fiedling", + "Field", + "Fielding", + "Fields", + "Fiertz", + "Fiester", + "Fife", + "Fifi", + "Fifine", + "Figge", + "Figone", + "Figueroa", + "Filbert", + "Filberte", + "Filberto", + "Filemon", + "Files", + "Filia", + "Filiano", + "Filide", + "Filip", + "Filipe", + "Filippa", + "Filippo", + "Fillander", + "Fillbert", + "Fillender", + "Filler", + "Fillian", + "Filmer", + "Filmore", + "Filomena", + "Fin", + "Fina", + "Finbar", + "Finbur", + "Findlay", + "Findley", + "Fine", + "Fineberg", + "Finegan", + "Finella", + "Fineman", + "Finer", + "Fini", + "Fink", + "Finkelstein", + "Finlay", + "Finley", + "Finn", + "Finnegan", + "Finnie", + "Finnigan", + "Finny", + "Finstad", + "Finzer", + "Fiona", + "Fionna", + "Fionnula", + "Fiora", + "Fiore", + "Fiorenza", + "Fiorenze", + "Firestone", + "Firman", + "Firmin", + "Firooc", + "Fisch", + "Fischer", + "Fish", + "Fishback", + "Fishbein", + "Fisher", + "Fishman", + "Fisk", + "Fiske", + "Fisken", + "Fitting", + "Fitton", + "Fitts", + "Fitz", + "Fitzger", + "Fitzgerald", + "Fitzhugh", + "Fitzpatrick", + "Fitzsimmons", + "Flagler", + "Flaherty", + "Flam", + "Flan", + "Flanagan", + "Flanders", + "Flanigan", + "Flann", + "Flanna", + "Flannery", + "Flatto", + "Flavia", + "Flavian", + "Flavio", + "Flavius", + "Fleck", + "Fleda", + "Fleece", + "Fleeman", + "Fleeta", + "Fleischer", + "Fleisher", + "Fleisig", + "Flem", + "Fleming", + "Flemings", + "Flemming", + "Flessel", + "Fleta", + "Fletch", + "Fletcher", + "Fleur", + "Fleurette", + "Flieger", + "Flight", + "Flin", + "Flinn", + "Flint", + "Flip", + "Flita", + "Flo", + "Floeter", + "Flor", + "Flora", + "Florance", + "Flore", + "Florella", + "Florence", + "Florencia", + "Florentia", + "Florenza", + "Florette", + "Flori", + "Floria", + "Florian", + "Florida", + "Floridia", + "Florie", + "Florin", + "Florina", + "Florinda", + "Florine", + "Florio", + "Floris", + "Floro", + "Florri", + "Florrie", + "Florry", + "Flory", + "Flosi", + "Floss", + "Flosser", + "Flossi", + "Flossie", + "Flossy", + "Flower", + "Flowers", + "Floyd", + "Flss", + "Flyn", + "Flynn", + "Foah", + "Fogarty", + "Fogel", + "Fogg", + "Fokos", + "Folberth", + "Foley", + "Folger", + "Follansbee", + "Follmer", + "Folly", + "Folsom", + "Fonda", + "Fondea", + "Fong", + "Fons", + "Fonseca", + "Fonsie", + "Fontana", + "Fontes", + "Fonville", + "Fonz", + "Fonzie", + "Foote", + "Forbes", + "Forcier", + "Ford", + "Fording", + "Forelli", + "Forest", + "Forester", + "Forkey", + "Forland", + "Forlini", + "Formenti", + "Formica", + "Fornof", + "Forras", + "Forrer", + "Forrest", + "Forrester", + "Forsta", + "Forster", + "Forsyth", + "Forta", + "Fortier", + "Fortin", + "Fortna", + "Fortuna", + "Fortunato", + "Fortune", + "Fortunia", + "Fortunio", + "Fortunna", + "Forward", + "Foscalina", + "Fosdick", + "Foskett", + "Fosque", + "Foss", + "Foster", + "Fotina", + "Fotinas", + "Fougere", + "Foulk", + "Four", + "Foushee", + "Fowkes", + "Fowle", + "Fowler", + "Fox", + "Foy", + "Fraase", + "Fradin", + "Frager", + "Frame", + "Fran", + "France", + "Francene", + "Frances", + "Francesca", + "Francesco", + "Franchot", + "Franci", + "Francie", + "Francine", + "Francis", + "Francisca", + "Franciscka", + "Francisco", + "Franciska", + "Franciskus", + "Franck", + "Francklin", + "Francklyn", + "Franckot", + "Francois", + "Francoise", + "Francyne", + "Franek", + "Frangos", + "Frank", + "Frankel", + "Frankhouse", + "Frankie", + "Franklin", + "Franklyn", + "Franky", + "Franni", + "Frannie", + "Franny", + "Frans", + "Fransen", + "Fransis", + "Fransisco", + "Frants", + "Frantz", + "Franz", + "Franza", + "Franzen", + "Franzoni", + "Frasch", + "Frasco", + "Fraser", + "Frasier", + "Frasquito", + "Fraya", + "Frayda", + "Frayne", + "Fraze", + "Frazer", + "Frazier", + "Frear", + "Freberg", + "Frech", + "Frechette", + "Fred", + "Freda", + "Freddi", + "Freddie", + "Freddy", + "Fredek", + "Fredel", + "Fredela", + "Fredelia", + "Fredella", + "Fredenburg", + "Frederic", + "Frederica", + "Frederich", + "Frederick", + "Fredericka", + "Frederico", + "Frederigo", + "Frederik", + "Frederiksen", + "Frederique", + "Fredette", + "Fredi", + "Fredia", + "Fredie", + "Fredkin", + "Fredra", + "Fredric", + "Fredrick", + "Fredrika", + "Free", + "Freeborn", + "Freed", + "Freedman", + "Freeland", + "Freeman", + "Freemon", + "Fregger", + "Freida", + "Freiman", + "Fremont", + "French", + "Frendel", + "Frentz", + "Frere", + "Frerichs", + "Fretwell", + "Freud", + "Freudberg", + "Frey", + "Freya", + "Freyah", + "Freytag", + "Frick", + "Fricke", + "Frida", + "Friday", + "Fridell", + "Fridlund", + "Fried", + "Frieda", + "Friedberg", + "Friede", + "Frieder", + "Friederike", + "Friedland", + "Friedlander", + "Friedly", + "Friedman", + "Friedrich", + "Friedrick", + "Friend", + "Frierson", + "Fries", + "Frisse", + "Frissell", + "Fritts", + "Fritz", + "Fritze", + "Fritzie", + "Fritzsche", + "Frodeen", + "Frodi", + "Frodin", + "Frodina", + "Frodine", + "Froehlich", + "Froemming", + "Froh", + "Frohman", + "Frohne", + "Frolick", + "Froma", + "Fromma", + "Fronia", + "Fronnia", + "Fronniah", + "Frost", + "Fruin", + "Frulla", + "Frum", + "Fruma", + "Fry", + "Fryd", + "Frydman", + "Frye", + "Frymire", + "Fu", + "Fuchs", + "Fugate", + "Fugazy", + "Fugere", + "Fuhrman", + "Fujio", + "Ful", + "Fulbert", + "Fulbright", + "Fulcher", + "Fuld", + "Fulks", + "Fuller", + "Fullerton", + "Fulmer", + "Fulmis", + "Fulton", + "Fulvi", + "Fulvia", + "Fulviah", + "Funch", + "Funda", + "Funk", + "Furey", + "Furgeson", + "Furie", + "Furiya", + "Furlani", + "Furlong", + "Furmark", + "Furnary", + "Furr", + "Furtek", + "Fusco", + "Gaal", + "Gabbert", + "Gabbey", + "Gabbi", + "Gabbie", + "Gabby", + "Gabe", + "Gabel", + "Gabey", + "Gabi", + "Gabie", + "Gable", + "Gabler", + "Gabor", + "Gabriel", + "Gabriela", + "Gabriele", + "Gabriell", + "Gabriella", + "Gabrielle", + "Gabrielli", + "Gabriellia", + "Gabriello", + "Gabrielson", + "Gabrila", + "Gaby", + "Gad", + "Gaddi", + "Gader", + "Gadmann", + "Gadmon", + "Gae", + "Gael", + "Gaelan", + "Gaeta", + "Gage", + "Gagliano", + "Gagne", + "Gagnon", + "Gahan", + "Gahl", + "Gaidano", + "Gaige", + "Gail", + "Gaile", + "Gaillard", + "Gainer", + "Gainor", + "Gaiser", + "Gaither", + "Gaivn", + "Gal", + "Gala", + "Galan", + "Galang", + "Galanti", + "Galasyn", + "Galatea", + "Galateah", + "Galatia", + "Gale", + "Galen", + "Galer", + "Galina", + "Galitea", + "Gall", + "Gallager", + "Gallagher", + "Gallard", + "Gallenz", + "Galliett", + "Galligan", + "Galloway", + "Gally", + "Galvan", + "Galven", + "Galvin", + "Gamages", + "Gamal", + "Gamali", + "Gamaliel", + "Gambell", + "Gamber", + "Gambrell", + "Gambrill", + "Gamin", + "Gan", + "Ganiats", + "Ganley", + "Gannes", + "Gannie", + "Gannon", + "Ganny", + "Gans", + "Gant", + "Gapin", + "Gar", + "Garald", + "Garate", + "Garaway", + "Garbe", + "Garber", + "Garbers", + "Garceau", + "Garcia", + "Garcon", + "Gard", + "Garda", + "Gardal", + "Gardas", + "Gardel", + "Gardell", + "Gardener", + "Gardia", + "Gardie", + "Gardiner", + "Gardner", + "Gardol", + "Gardy", + "Gare", + "Garek", + "Gareri", + "Gareth", + "Garett", + "Garey", + "Garfield", + "Garfinkel", + "Gargan", + "Garges", + "Garibald", + "Garibold", + "Garibull", + "Gariepy", + "Garik", + "Garin", + "Garlaand", + "Garlan", + "Garland", + "Garlanda", + "Garlen", + "Garlinda", + "Garling", + "Garmaise", + "Garneau", + "Garner", + "Garnes", + "Garnet", + "Garnett", + "Garnette", + "Garold", + "Garrard", + "Garratt", + "Garrek", + "Garret", + "Garreth", + "Garretson", + "Garrett", + "Garrick", + "Garrik", + "Garris", + "Garrison", + "Garrity", + "Garrot", + "Garrott", + "Garry", + "Garson", + "Garth", + "Garv", + "Garvey", + "Garvin", + "Garvy", + "Garwin", + "Garwood", + "Gary", + "Garzon", + "Gascony", + "Gaskill", + "Gaskin", + "Gaskins", + "Gaspar", + "Gaspard", + "Gasparo", + "Gasper", + "Gasperoni", + "Gass", + "Gasser", + "Gassman", + "Gastineau", + "Gaston", + "Gates", + "Gathard", + "Gathers", + "Gati", + "Gatian", + "Gatias", + "Gaudet", + "Gaudette", + "Gaughan", + "Gaul", + "Gauldin", + "Gaulin", + "Gault", + "Gaultiero", + "Gauntlett", + "Gausman", + "Gaut", + "Gautea", + "Gauthier", + "Gautier", + "Gautious", + "Gav", + "Gavan", + "Gaven", + "Gavette", + "Gavin", + "Gavini", + "Gavra", + "Gavrah", + "Gavriella", + "Gavrielle", + "Gavrila", + "Gavrilla", + "Gaw", + "Gawain", + "Gawen", + "Gawlas", + "Gay", + "Gaye", + "Gayel", + "Gayelord", + "Gayl", + "Gayla", + "Gayle", + "Gayleen", + "Gaylene", + "Gayler", + "Gaylor", + "Gaylord", + "Gayn", + "Gayner", + "Gaynor", + "Gazo", + "Gazzo", + "Geaghan", + "Gean", + "Geanine", + "Gearalt", + "Gearard", + "Gearhart", + "Gebelein", + "Gebhardt", + "Gebler", + "Geddes", + "Gee", + "Geehan", + "Geer", + "Geerts", + "Geesey", + "Gefell", + "Gefen", + "Geffner", + "Gehlbach", + "Gehman", + "Geibel", + "Geier", + "Geiger", + "Geilich", + "Geis", + "Geiss", + "Geithner", + "Gelasias", + "Gelasius", + "Gelb", + "Geldens", + "Gelhar", + "Geller", + "Gellman", + "Gelman", + "Gelya", + "Gemina", + "Gemini", + "Geminian", + "Geminius", + "Gemma", + "Gemmell", + "Gemoets", + "Gemperle", + "Gen", + "Gena", + "Genaro", + "Gene", + "Genesa", + "Genesia", + "Genet", + "Geneva", + "Genevieve", + "Genevra", + "Genia", + "Genie", + "Genisia", + "Genna", + "Gennaro", + "Genni", + "Gennie", + "Gennifer", + "Genny", + "Geno", + "Genovera", + "Gensler", + "Gensmer", + "Gent", + "Gentes", + "Gentilis", + "Gentille", + "Gentry", + "Genvieve", + "Geof", + "Geoff", + "Geoffrey", + "Geoffry", + "Georas", + "Geordie", + "Georg", + "George", + "Georgeanna", + "Georgeanne", + "Georgena", + "Georges", + "Georgeta", + "Georgetta", + "Georgette", + "Georgi", + "Georgia", + "Georgiana", + "Georgianna", + "Georgianne", + "Georgie", + "Georgina", + "Georgine", + "Georglana", + "Georgy", + "Ger", + "Geraint", + "Gerald", + "Geralda", + "Geraldina", + "Geraldine", + "Gerard", + "Gerardo", + "Geraud", + "Gerbold", + "Gerda", + "Gerdeen", + "Gerdi", + "Gerdy", + "Gere", + "Gerek", + "Gereld", + "Gereron", + "Gerfen", + "Gerge", + "Gerger", + "Gerhan", + "Gerhard", + "Gerhardine", + "Gerhardt", + "Geri", + "Gerianna", + "Gerianne", + "Gerick", + "Gerik", + "Gerita", + "Gerius", + "Gerkman", + "Gerlac", + "Gerladina", + "Germain", + "Germaine", + "German", + "Germana", + "Germann", + "Germano", + "Germaun", + "Germayne", + "Germin", + "Gernhard", + "Gerome", + "Gerrald", + "Gerrard", + "Gerri", + "Gerrie", + "Gerrilee", + "Gerrit", + "Gerry", + "Gersham", + "Gershom", + "Gershon", + "Gerson", + "Gerstein", + "Gerstner", + "Gert", + "Gerta", + "Gerti", + "Gertie", + "Gertrud", + "Gertruda", + "Gertrude", + "Gertrudis", + "Gerty", + "Gervais", + "Gervase", + "Gery", + "Gesner", + "Gessner", + "Getraer", + "Getter", + "Gettings", + "Gewirtz", + "Ghassan", + "Gherardi", + "Gherardo", + "Gherlein", + "Ghiselin", + "Giacamo", + "Giacinta", + "Giacobo", + "Giacomo", + "Giacopo", + "Giaimo", + "Giamo", + "Gian", + "Giana", + "Gianina", + "Gianna", + "Gianni", + "Giannini", + "Giarla", + "Giavani", + "Gib", + "Gibb", + "Gibbeon", + "Gibbie", + "Gibbon", + "Gibbons", + "Gibbs", + "Gibby", + "Gibe", + "Gibeon", + "Gibert", + "Gibrian", + "Gibson", + "Gibun", + "Giddings", + "Gide", + "Gideon", + "Giefer", + "Gies", + "Giesecke", + "Giess", + "Giesser", + "Giff", + "Giffard", + "Giffer", + "Gifferd", + "Giffie", + "Gifford", + "Giffy", + "Gigi", + "Giglio", + "Gignac", + "Giguere", + "Gil", + "Gilba", + "Gilbart", + "Gilbert", + "Gilberta", + "Gilberte", + "Gilbertina", + "Gilbertine", + "Gilberto", + "Gilbertson", + "Gilboa", + "Gilburt", + "Gilbye", + "Gilchrist", + "Gilcrest", + "Gilda", + "Gildas", + "Gildea", + "Gilder", + "Gildus", + "Gile", + "Gilead", + "Gilemette", + "Giles", + "Gilford", + "Gilges", + "Giliana", + "Giliane", + "Gill", + "Gillan", + "Gillead", + "Gilleod", + "Gilles", + "Gillespie", + "Gillett", + "Gilletta", + "Gillette", + "Gilli", + "Gilliam", + "Gillian", + "Gillie", + "Gilliette", + "Gilligan", + "Gillman", + "Gillmore", + "Gilly", + "Gilman", + "Gilmer", + "Gilmore", + "Gilmour", + "Gilpin", + "Gilroy", + "Gilson", + "Giltzow", + "Gilud", + "Gilus", + "Gimble", + "Gimpel", + "Gina", + "Ginder", + "Gine", + "Ginelle", + "Ginevra", + "Ginger", + "Gingras", + "Ginni", + "Ginnie", + "Ginnifer", + "Ginny", + "Gino", + "Ginsberg", + "Ginsburg", + "Gintz", + "Ginzburg", + "Gio", + "Giordano", + "Giorgi", + "Giorgia", + "Giorgio", + "Giovanna", + "Giovanni", + "Gipps", + "Gipson", + "Gipsy", + "Giralda", + "Giraldo", + "Girand", + "Girard", + "Girardi", + "Girardo", + "Giraud", + "Girhiny", + "Girish", + "Girovard", + "Girvin", + "Gisela", + "Giselbert", + "Gisele", + "Gisella", + "Giselle", + "Gish", + "Gisser", + "Gitel", + "Githens", + "Gitlow", + "Gitt", + "Gittel", + "Gittle", + "Giuditta", + "Giule", + "Giulia", + "Giuliana", + "Giulietta", + "Giulio", + "Giuseppe", + "Giustina", + "Giustino", + "Giusto", + "Given", + "Giverin", + "Giza", + "Gizela", + "Glaab", + "Glad", + "Gladdie", + "Gladdy", + "Gladi", + "Gladine", + "Gladis", + "Gladstone", + "Gladwin", + "Gladys", + "Glanti", + "Glantz", + "Glanville", + "Glarum", + "Glaser", + "Glasgo", + "Glass", + "Glassco", + "Glassman", + "Glaudia", + "Glavin", + "Gleason", + "Gleda", + "Gleeson", + "Gleich", + "Glen", + "Glenda", + "Glenden", + "Glendon", + "Glenine", + "Glenn", + "Glenna", + "Glennie", + "Glennis", + "Glennon", + "Glialentn", + "Glick", + "Glimp", + "Glinys", + "Glogau", + "Glori", + "Gloria", + "Gloriana", + "Gloriane", + "Glorianna", + "Glory", + "Glover", + "Glovsky", + "Gluck", + "Glyn", + "Glynas", + "Glynda", + "Glynias", + "Glynis", + "Glynn", + "Glynnis", + "Gmur", + "Gnni", + "Goar", + "Goat", + "Gobert", + "God", + "Goda", + "Godard", + "Godart", + "Godbeare", + "Godber", + "Goddard", + "Goddart", + "Godden", + "Godderd", + "Godding", + "Goddord", + "Godewyn", + "Godfree", + "Godfrey", + "Godfry", + "Godiva", + "Godliman", + "Godred", + "Godric", + "Godrich", + "Godspeed", + "Godwin", + "Goebel", + "Goeger", + "Goer", + "Goerke", + "Goeselt", + "Goetz", + "Goff", + "Goggin", + "Goines", + "Gokey", + "Golanka", + "Gold", + "Golda", + "Goldarina", + "Goldberg", + "Golden", + "Goldenberg", + "Goldfarb", + "Goldfinch", + "Goldi", + "Goldia", + "Goldie", + "Goldin", + "Goldina", + "Golding", + "Goldman", + "Goldner", + "Goldshell", + "Goldshlag", + "Goldsmith", + "Goldstein", + "Goldston", + "Goldsworthy", + "Goldwin", + "Goldy", + "Goles", + "Golightly", + "Gollin", + "Golliner", + "Golter", + "Goltz", + "Golub", + "Gomar", + "Gombach", + "Gombosi", + "Gomer", + "Gomez", + "Gona", + "Gonagle", + "Gone", + "Gonick", + "Gonnella", + "Gonroff", + "Gonsalve", + "Gonta", + "Gonyea", + "Gonzales", + "Gonzalez", + "Gonzalo", + "Goober", + "Good", + "Goodard", + "Goodden", + "Goode", + "Goodhen", + "Goodill", + "Goodkin", + "Goodman", + "Goodrich", + "Goodrow", + "Goodson", + "Goodspeed", + "Goodwin", + "Goody", + "Goodyear", + "Googins", + "Gora", + "Goran", + "Goraud", + "Gord", + "Gordan", + "Gorden", + "Gordie", + "Gordon", + "Gordy", + "Gore", + "Goren", + "Gorey", + "Gorga", + "Gorges", + "Gorlicki", + "Gorlin", + "Gorman", + "Gorrian", + "Gorrono", + "Gorski", + "Gorton", + "Gosnell", + "Gosney", + "Goss", + "Gosselin", + "Gosser", + "Gotcher", + "Goth", + "Gothar", + "Gothard", + "Gothart", + "Gothurd", + "Goto", + "Gottfried", + "Gotthard", + "Gotthelf", + "Gottlieb", + "Gottuard", + "Gottwald", + "Gough", + "Gould", + "Goulden", + "Goulder", + "Goulet", + "Goulette", + "Gove", + "Gow", + "Gower", + "Gowon", + "Gowrie", + "Graaf", + "Grace", + "Graces", + "Gracia", + "Gracie", + "Gracye", + "Gradeigh", + "Gradey", + "Grados", + "Grady", + "Grae", + "Graehl", + "Graehme", + "Graeme", + "Graf", + "Graff", + "Graham", + "Graig", + "Grail", + "Gram", + "Gran", + "Grand", + "Grane", + "Graner", + "Granese", + "Grange", + "Granger", + "Grani", + "Grania", + "Graniah", + "Graniela", + "Granlund", + "Grannia", + "Granniah", + "Grannias", + "Grannie", + "Granny", + "Granoff", + "Grant", + "Grantham", + "Granthem", + "Grantland", + "Grantley", + "Granville", + "Grassi", + "Grata", + "Grath", + "Grati", + "Gratia", + "Gratiana", + "Gratianna", + "Gratt", + "Graubert", + "Gravante", + "Graves", + "Gray", + "Graybill", + "Grayce", + "Grayson", + "Grazia", + "Greabe", + "Grearson", + "Gredel", + "Greeley", + "Green", + "Greenberg", + "Greenburg", + "Greene", + "Greenebaum", + "Greenes", + "Greenfield", + "Greenland", + "Greenleaf", + "Greenlee", + "Greenman", + "Greenquist", + "Greenstein", + "Greenwald", + "Greenwell", + "Greenwood", + "Greer", + "Greerson", + "Greeson", + "Grefe", + "Grefer", + "Greff", + "Greg", + "Grega", + "Gregg", + "Greggory", + "Greggs", + "Gregoire", + "Gregoor", + "Gregor", + "Gregorio", + "Gregorius", + "Gregory", + "Gregrory", + "Gregson", + "Greiner", + "Grekin", + "Grenier", + "Grenville", + "Gresham", + "Greta", + "Gretal", + "Gretchen", + "Grete", + "Gretel", + "Grethel", + "Gretna", + "Gretta", + "Grevera", + "Grew", + "Grewitz", + "Grey", + "Greyso", + "Greyson", + "Greysun", + "Grider", + "Gridley", + "Grier", + "Grieve", + "Griff", + "Griffie", + "Griffin", + "Griffis", + "Griffith", + "Griffiths", + "Griffy", + "Griggs", + "Grigson", + "Grim", + "Grimaldi", + "Grimaud", + "Grimbal", + "Grimbald", + "Grimbly", + "Grimes", + "Grimona", + "Grimonia", + "Grindlay", + "Grindle", + "Grinnell", + "Gris", + "Griselda", + "Griseldis", + "Grishilda", + "Grishilde", + "Grissel", + "Grissom", + "Gristede", + "Griswold", + "Griz", + "Grizel", + "Grizelda", + "Groark", + "Grobe", + "Grochow", + "Grodin", + "Grof", + "Grogan", + "Groh", + "Gromme", + "Grondin", + "Gronseth", + "Groome", + "Groos", + "Groot", + "Grory", + "Grosberg", + "Groscr", + "Grose", + "Grosmark", + "Gross", + "Grossman", + "Grosvenor", + "Grosz", + "Grote", + "Grounds", + "Grous", + "Grove", + "Groveman", + "Grover", + "Groves", + "Grubb", + "Grube", + "Gruber", + "Grubman", + "Gruchot", + "Grunberg", + "Grunenwald", + "Grussing", + "Gruver", + "Gschu", + "Guadalupe", + "Gualterio", + "Gualtiero", + "Guarino", + "Gudren", + "Gudrin", + "Gudrun", + "Guendolen", + "Guenevere", + "Guenna", + "Guenzi", + "Guerin", + "Guerra", + "Guevara", + "Guglielma", + "Guglielmo", + "Gui", + "Guibert", + "Guido", + "Guidotti", + "Guilbert", + "Guild", + "Guildroy", + "Guillaume", + "Guillema", + "Guillemette", + "Guillermo", + "Guimar", + "Guimond", + "Guinevere", + "Guinn", + "Guinna", + "Guise", + "Gujral", + "Gula", + "Gulgee", + "Gulick", + "Gun", + "Gunar", + "Gunas", + "Gundry", + "Gunilla", + "Gunn", + "Gunnar", + "Gunner", + "Gunning", + "Guntar", + "Gunter", + "Gunthar", + "Gunther", + "Gunzburg", + "Gupta", + "Gurango", + "Gurevich", + "Guria", + "Gurias", + "Gurl", + "Gurney", + "Gurolinick", + "Gurtner", + "Gus", + "Gusba", + "Gusella", + "Guss", + "Gussi", + "Gussie", + "Gussman", + "Gussy", + "Gusta", + "Gustaf", + "Gustafson", + "Gustafsson", + "Gustav", + "Gustave", + "Gustavo", + "Gustavus", + "Gusti", + "Gustie", + "Gustin", + "Gusty", + "Gut", + "Guthrey", + "Guthrie", + "Guthry", + "Gutow", + "Guttery", + "Guy", + "Guyer", + "Guyon", + "Guzel", + "Gwen", + "Gwendolen", + "Gwendolin", + "Gwendolyn", + "Gweneth", + "Gwenette", + "Gwenn", + "Gwenneth", + "Gwenni", + "Gwennie", + "Gwenny", + "Gwenora", + "Gwenore", + "Gwyn", + "Gwyneth", + "Gwynne", + "Gyasi", + "Gyatt", + "Gyimah", + "Gylys", + "Gypsie", + "Gypsy", + "Gytle", + "Ha", + "Haag", + "Haakon", + "Haas", + "Haase", + "Haberman", + "Hach", + "Hachman", + "Hachmann", + "Hachmin", + "Hackathorn", + "Hacker", + "Hackett", + "Hackney", + "Had", + "Haddad", + "Hadden", + "Haden", + "Hadik", + "Hadlee", + "Hadleigh", + "Hadley", + "Hadria", + "Hadrian", + "Hadsall", + "Hadwin", + "Hadwyn", + "Haeckel", + "Haerle", + "Haerr", + "Haff", + "Hafler", + "Hagai", + "Hagan", + "Hagar", + "Hagen", + "Hagerman", + "Haggai", + "Haggar", + "Haggerty", + "Haggi", + "Hagi", + "Hagood", + "Hahn", + "Hahnert", + "Hahnke", + "Haida", + "Haig", + "Haile", + "Hailee", + "Hailey", + "Haily", + "Haim", + "Haimes", + "Haines", + "Hak", + "Hakan", + "Hake", + "Hakeem", + "Hakim", + "Hako", + "Hakon", + "Hal", + "Haland", + "Halbeib", + "Halbert", + "Halda", + "Haldan", + "Haldane", + "Haldas", + "Haldeman", + "Halden", + "Haldes", + "Haldi", + "Haldis", + "Hale", + "Haleigh", + "Haletky", + "Haletta", + "Halette", + "Haley", + "Halfdan", + "Halfon", + "Halford", + "Hali", + "Halie", + "Halima", + "Halimeda", + "Hall", + "Halla", + "Hallagan", + "Hallam", + "Halland", + "Halle", + "Hallee", + "Hallerson", + "Hallett", + "Hallette", + "Halley", + "Halli", + "Halliday", + "Hallie", + "Hallock", + "Hallsy", + "Hallvard", + "Hally", + "Halona", + "Halonna", + "Halpern", + "Halsey", + "Halstead", + "Halsted", + "Halsy", + "Halvaard", + "Halverson", + "Ham", + "Hama", + "Hamachi", + "Hamal", + "Haman", + "Hamann", + "Hambley", + "Hamburger", + "Hamel", + "Hamer", + "Hamford", + "Hamforrd", + "Hamfurd", + "Hamid", + "Hamil", + "Hamilton", + "Hamish", + "Hamlani", + "Hamlen", + "Hamlet", + "Hamlin", + "Hammad", + "Hammel", + "Hammer", + "Hammerskjold", + "Hammock", + "Hammond", + "Hamner", + "Hamnet", + "Hamo", + "Hamon", + "Hampton", + "Hamrah", + "Hamrnand", + "Han", + "Hana", + "Hanae", + "Hanafee", + "Hanako", + "Hanan", + "Hance", + "Hancock", + "Handal", + "Handbook", + "Handel", + "Handler", + "Hands", + "Handy", + "Haney", + "Hanford", + "Hanforrd", + "Hanfurd", + "Hank", + "Hankins", + "Hanleigh", + "Hanley", + "Hanna", + "Hannah", + "Hannan", + "Hanni", + "Hannibal", + "Hannie", + "Hannis", + "Hannon", + "Hannover", + "Hannus", + "Hanny", + "Hanover", + "Hans", + "Hanschen", + "Hansel", + "Hanselka", + "Hansen", + "Hanser", + "Hanshaw", + "Hansiain", + "Hanson", + "Hanus", + "Hanway", + "Hanzelin", + "Happ", + "Happy", + "Hapte", + "Hara", + "Harald", + "Harbard", + "Harberd", + "Harbert", + "Harbird", + "Harbison", + "Harbot", + "Harbour", + "Harcourt", + "Hardan", + "Harday", + "Hardden", + "Hardej", + "Harden", + "Hardi", + "Hardie", + "Hardigg", + "Hardin", + "Harding", + "Hardman", + "Hardner", + "Hardunn", + "Hardwick", + "Hardy", + "Hare", + "Harelda", + "Harewood", + "Harhay", + "Harilda", + "Harim", + "Harl", + "Harlamert", + "Harlan", + "Harland", + "Harle", + "Harleigh", + "Harlen", + "Harlene", + "Harley", + "Harli", + "Harlie", + "Harlin", + "Harlow", + "Harman", + "Harmaning", + "Harmon", + "Harmonia", + "Harmonie", + "Harmony", + "Harms", + "Harned", + "Harneen", + "Harness", + "Harod", + "Harold", + "Harolda", + "Haroldson", + "Haroun", + "Harp", + "Harper", + "Harpole", + "Harpp", + "Harragan", + "Harrell", + "Harri", + "Harrie", + "Harriet", + "Harriett", + "Harrietta", + "Harriette", + "Harriman", + "Harrington", + "Harriot", + "Harriott", + "Harris", + "Harrison", + "Harrod", + "Harrow", + "Harrus", + "Harry", + "Harshman", + "Harsho", + "Hart", + "Harte", + "Hartfield", + "Hartill", + "Hartley", + "Hartman", + "Hartmann", + "Hartmunn", + "Hartnett", + "Harts", + "Hartwell", + "Harty", + "Hartzel", + "Hartzell", + "Hartzke", + "Harv", + "Harvard", + "Harve", + "Harvey", + "Harvie", + "Harvison", + "Harwell", + "Harwill", + "Harwilll", + "Harwin", + "Hasan", + "Hasen", + "Hasheem", + "Hashim", + "Hashimoto", + "Hashum", + "Hasin", + "Haskel", + "Haskell", + "Haskins", + "Haslam", + "Haslett", + "Hasseman", + "Hassett", + "Hassi", + "Hassin", + "Hastie", + "Hastings", + "Hasty", + "Haswell", + "Hatch", + "Hatcher", + "Hatfield", + "Hathaway", + "Hathcock", + "Hatti", + "Hattie", + "Hatty", + "Hau", + "Hauck", + "Hauge", + "Haugen", + "Hauger", + "Haughay", + "Haukom", + "Hauser", + "Hausmann", + "Hausner", + "Havard", + "Havelock", + "Haveman", + "Haven", + "Havener", + "Havens", + "Havstad", + "Hawger", + "Hawk", + "Hawken", + "Hawker", + "Hawkie", + "Hawkins", + "Hawley", + "Hawthorn", + "Hax", + "Hay", + "Haya", + "Hayashi", + "Hayden", + "Haydon", + "Haye", + "Hayes", + "Hayley", + "Hayman", + "Haymes", + "Haymo", + "Hayne", + "Haynes", + "Haynor", + "Hayott", + "Hays", + "Hayse", + "Hayton", + "Hayward", + "Haywood", + "Hayyim", + "Hazaki", + "Hazard", + "Haze", + "Hazeghi", + "Hazel", + "Hazelton", + "Hazem", + "Hazen", + "Hazlett", + "Hazlip", + "Head", + "Heady", + "Healey", + "Healion", + "Heall", + "Healy", + "Heaps", + "Hearn", + "Hearsh", + "Heater", + "Heath", + "Heathcote", + "Heather", + "Hebbe", + "Hebe", + "Hebel", + "Heber", + "Hebert", + "Hebner", + "Hebrew", + "Hecht", + "Heck", + "Hecker", + "Hecklau", + "Hector", + "Heda", + "Hedberg", + "Hedda", + "Heddi", + "Heddie", + "Heddy", + "Hedelman", + "Hedgcock", + "Hedges", + "Hedi", + "Hedley", + "Hedva", + "Hedvah", + "Hedve", + "Hedveh", + "Hedvig", + "Hedvige", + "Hedwig", + "Hedwiga", + "Hedy", + "Heeley", + "Heer", + "Heffron", + "Hefter", + "Hegarty", + "Hege", + "Heger", + "Hegyera", + "Hehre", + "Heid", + "Heida", + "Heidi", + "Heidie", + "Heidt", + "Heidy", + "Heigho", + "Heigl", + "Heilman", + "Heilner", + "Heim", + "Heimer", + "Heimlich", + "Hein", + "Heindrick", + "Heiner", + "Heiney", + "Heinrich", + "Heinrick", + "Heinrik", + "Heinrike", + "Heins", + "Heintz", + "Heise", + "Heisel", + "Heiskell", + "Heisser", + "Hekker", + "Hekking", + "Helaina", + "Helaine", + "Helali", + "Helban", + "Helbon", + "Helbona", + "Helbonia", + "Helbonna", + "Helbonnah", + "Helbonnas", + "Held", + "Helen", + "Helena", + "Helene", + "Helenka", + "Helfand", + "Helfant", + "Helga", + "Helge", + "Helgeson", + "Hellene", + "Heller", + "Helli", + "Hellman", + "Helm", + "Helman", + "Helmer", + "Helms", + "Helmut", + "Heloise", + "Helprin", + "Helsa", + "Helse", + "Helsell", + "Helsie", + "Helve", + "Helyn", + "Heman", + "Hembree", + "Hemingway", + "Hemminger", + "Hemphill", + "Hen", + "Hendel", + "Henden", + "Henderson", + "Hendon", + "Hendren", + "Hendrick", + "Hendricks", + "Hendrickson", + "Hendrik", + "Hendrika", + "Hendrix", + "Hendry", + "Henebry", + "Heng", + "Hengel", + "Henghold", + "Henig", + "Henigman", + "Henka", + "Henke", + "Henleigh", + "Henley", + "Henn", + "Hennahane", + "Hennebery", + "Hennessey", + "Hennessy", + "Henni", + "Hennie", + "Henning", + "Henri", + "Henricks", + "Henrie", + "Henrieta", + "Henrietta", + "Henriette", + "Henriha", + "Henrik", + "Henrion", + "Henrique", + "Henriques", + "Henry", + "Henryetta", + "Henryk", + "Henryson", + "Henson", + "Hentrich", + "Hephzibah", + "Hephzipa", + "Hephzipah", + "Heppman", + "Hepsiba", + "Hepsibah", + "Hepza", + "Hepzi", + "Hera", + "Herald", + "Herb", + "Herbert", + "Herbie", + "Herbst", + "Herby", + "Herc", + "Hercule", + "Hercules", + "Herculie", + "Hereld", + "Heriberto", + "Heringer", + "Herm", + "Herman", + "Hermann", + "Hermes", + "Hermia", + "Hermie", + "Hermina", + "Hermine", + "Herminia", + "Hermione", + "Hermon", + "Hermosa", + "Hermy", + "Hernandez", + "Hernando", + "Hernardo", + "Herod", + "Herodias", + "Herold", + "Heron", + "Herr", + "Herra", + "Herrah", + "Herrera", + "Herrick", + "Herries", + "Herring", + "Herrington", + "Herriott", + "Herrle", + "Herrmann", + "Herrod", + "Hersch", + "Herschel", + "Hersh", + "Hershel", + "Hershell", + "Herson", + "Herstein", + "Herta", + "Hertberg", + "Hertha", + "Hertz", + "Hertzfeld", + "Hertzog", + "Herv", + "Herve", + "Hervey", + "Herwick", + "Herwig", + "Herwin", + "Herzberg", + "Herzel", + "Herzen", + "Herzig", + "Herzog", + "Hescock", + "Heshum", + "Hesketh", + "Hesky", + "Hesler", + "Hesper", + "Hess", + "Hessler", + "Hessney", + "Hesta", + "Hester", + "Hesther", + "Hestia", + "Heti", + "Hett", + "Hetti", + "Hettie", + "Hetty", + "Heurlin", + "Heuser", + "Hew", + "Hewart", + "Hewe", + "Hewes", + "Hewet", + "Hewett", + "Hewie", + "Hewitt", + "Hey", + "Heyde", + "Heydon", + "Heyer", + "Heyes", + "Heyman", + "Heymann", + "Heyward", + "Heywood", + "Hezekiah", + "Hi", + "Hibben", + "Hibbert", + "Hibbitts", + "Hibbs", + "Hickey", + "Hickie", + "Hicks", + "Hidie", + "Hieronymus", + "Hiett", + "Higbee", + "Higginbotham", + "Higgins", + "Higginson", + "Higgs", + "High", + "Highams", + "Hightower", + "Higinbotham", + "Higley", + "Hijoung", + "Hike", + "Hilaire", + "Hilar", + "Hilaria", + "Hilario", + "Hilarius", + "Hilary", + "Hilbert", + "Hild", + "Hilda", + "Hildagard", + "Hildagarde", + "Hilde", + "Hildebrandt", + "Hildegaard", + "Hildegard", + "Hildegarde", + "Hildick", + "Hildie", + "Hildy", + "Hilel", + "Hill", + "Hillard", + "Hillari", + "Hillary", + "Hilleary", + "Hillegass", + "Hillel", + "Hillell", + "Hiller", + "Hillery", + "Hillhouse", + "Hilliard", + "Hilliary", + "Hillie", + "Hillier", + "Hillinck", + "Hillman", + "Hills", + "Hilly", + "Hillyer", + "Hiltan", + "Hilten", + "Hiltner", + "Hilton", + "Him", + "Hime", + "Himelman", + "Hinch", + "Hinckley", + "Hinda", + "Hindorff", + "Hindu", + "Hines", + "Hinkel", + "Hinkle", + "Hinman", + "Hinson", + "Hintze", + "Hinze", + "Hippel", + "Hirai", + "Hiram", + "Hirasuna", + "Hiro", + "Hiroko", + "Hiroshi", + "Hirsch", + "Hirschfeld", + "Hirsh", + "Hirst", + "Hirz", + "Hirza", + "Hisbe", + "Hitchcock", + "Hite", + "Hitoshi", + "Hitt", + "Hittel", + "Hizar", + "Hjerpe", + "Hluchy", + "Ho", + "Hoag", + "Hoagland", + "Hoang", + "Hoashis", + "Hoban", + "Hobard", + "Hobart", + "Hobbie", + "Hobbs", + "Hobey", + "Hobie", + "Hochman", + "Hock", + "Hocker", + "Hodess", + "Hodge", + "Hodges", + "Hodgkinson", + "Hodgson", + "Hodosh", + "Hoebart", + "Hoeg", + "Hoehne", + "Hoem", + "Hoenack", + "Hoes", + "Hoeve", + "Hoffarth", + "Hoffer", + "Hoffert", + "Hoffman", + "Hoffmann", + "Hofmann", + "Hofstetter", + "Hogan", + "Hogarth", + "Hogen", + "Hogg", + "Hogle", + "Hogue", + "Hoi", + "Hoisch", + "Hokanson", + "Hola", + "Holbrook", + "Holbrooke", + "Holcman", + "Holcomb", + "Holden", + "Holder", + "Holds", + "Hole", + "Holey", + "Holladay", + "Hollah", + "Holland", + "Hollander", + "Holle", + "Hollenbeck", + "Holleran", + "Hollerman", + "Holli", + "Hollie", + "Hollinger", + "Hollingsworth", + "Hollington", + "Hollis", + "Hollister", + "Holloway", + "Holly", + "Holly-Anne", + "Hollyanne", + "Holman", + "Holmann", + "Holmen", + "Holmes", + "Holms", + "Holmun", + "Holna", + "Holofernes", + "Holsworth", + "Holt", + "Holton", + "Holtorf", + "Holtz", + "Holub", + "Holzman", + "Homans", + "Home", + "Homer", + "Homere", + "Homerus", + "Homovec", + "Honan", + "Honebein", + "Honey", + "Honeyman", + "Honeywell", + "Hong", + "Honig", + "Honna", + "Honniball", + "Honor", + "Honora", + "Honoria", + "Honorine", + "Hoo", + "Hooge", + "Hook", + "Hooke", + "Hooker", + "Hoon", + "Hoopen", + "Hooper", + "Hoopes", + "Hootman", + "Hoover", + "Hope", + "Hopfinger", + "Hopkins", + "Hoppe", + "Hopper", + "Horace", + "Horacio", + "Horan", + "Horatia", + "Horatio", + "Horatius", + "Horbal", + "Horgan", + "Horick", + "Horlacher", + "Horn", + "Horne", + "Horner", + "Hornstein", + "Horodko", + "Horowitz", + "Horsey", + "Horst", + "Hort", + "Horten", + "Hortensa", + "Hortense", + "Hortensia", + "Horter", + "Horton", + "Horvitz", + "Horwath", + "Horwitz", + "Hosbein", + "Hose", + "Hosea", + "Hoseia", + "Hosfmann", + "Hoshi", + "Hoskinson", + "Hospers", + "Hotchkiss", + "Hotze", + "Hough", + "Houghton", + "Houlberg", + "Hound", + "Hourigan", + "Hourihan", + "Housen", + "Houser", + "Houston", + "Housum", + "Hovey", + "How", + "Howard", + "Howarth", + "Howe", + "Howell", + "Howenstein", + "Howes", + "Howey", + "Howie", + "Howlan", + "Howland", + "Howlend", + "Howlond", + "Howlyn", + "Howund", + "Howzell", + "Hoxie", + "Hoxsie", + "Hoy", + "Hoye", + "Hoyt", + "Hrutkay", + "Hsu", + "Hu", + "Huai", + "Huan", + "Huang", + "Huba", + "Hubbard", + "Hubble", + "Hube", + "Huber", + "Huberman", + "Hubert", + "Huberto", + "Huberty", + "Hubey", + "Hubie", + "Hubing", + "Hubsher", + "Huckaby", + "Huda", + "Hudgens", + "Hudis", + "Hudnut", + "Hudson", + "Huebner", + "Huei", + "Huesman", + "Hueston", + "Huey", + "Huff", + "Hufnagel", + "Huggins", + "Hugh", + "Hughes", + "Hughett", + "Hughie", + "Hughmanick", + "Hugibert", + "Hugo", + "Hugon", + "Hugues", + "Hui", + "Hujsak", + "Hukill", + "Hulbard", + "Hulbert", + "Hulbig", + "Hulburt", + "Hulda", + "Huldah", + "Hulen", + "Hull", + "Hullda", + "Hultgren", + "Hultin", + "Hulton", + "Hum", + "Humbert", + "Humberto", + "Humble", + "Hume", + "Humfrey", + "Humfrid", + "Humfried", + "Hummel", + "Humo", + "Hump", + "Humpage", + "Humph", + "Humphrey", + "Hun", + "Hunfredo", + "Hung", + "Hungarian", + "Hunger", + "Hunley", + "Hunsinger", + "Hunt", + "Hunter", + "Huntingdon", + "Huntington", + "Huntlee", + "Huntley", + "Huoh", + "Huppert", + "Hurd", + "Hurff", + "Hurlbut", + "Hurlee", + "Hurleigh", + "Hurless", + "Hurley", + "Hurlow", + "Hurst", + "Hurty", + "Hurwit", + "Hurwitz", + "Husain", + "Husch", + "Husein", + "Husha", + "Huskamp", + "Huskey", + "Hussar", + "Hussein", + "Hussey", + "Huston", + "Hut", + "Hutchings", + "Hutchins", + "Hutchinson", + "Hutchison", + "Hutner", + "Hutson", + "Hutt", + "Huttan", + "Hutton", + "Hux", + "Huxham", + "Huxley", + "Hwang", + "Hwu", + "Hy", + "Hyacinth", + "Hyacintha", + "Hyacinthe", + "Hyacinthia", + "Hyacinthie", + "Hyams", + "Hyatt", + "Hyde", + "Hylan", + "Hyland", + "Hylton", + "Hyman", + "Hymen", + "Hymie", + "Hynda", + "Hynes", + "Hyo", + "Hyozo", + "Hyps", + "Hyrup", + "Iago", + "Iain", + "Iams", + "Ian", + "Iand", + "Ianteen", + "Ianthe", + "Iaria", + "Iaverne", + "Ib", + "Ibbetson", + "Ibbie", + "Ibbison", + "Ibby", + "Ibrahim", + "Ibson", + "Ichabod", + "Icken", + "Id", + "Ida", + "Idalia", + "Idalina", + "Idaline", + "Idalla", + "Idden", + "Iddo", + "Ide", + "Idel", + "Idelia", + "Idell", + "Idelle", + "Idelson", + "Iden", + "Idette", + "Idleman", + "Idola", + "Idolah", + "Idolla", + "Idona", + "Idonah", + "Idonna", + "Idou", + "Idoux", + "Idzik", + "Iene", + "Ier", + "Ierna", + "Ieso", + "Ietta", + "Iey", + "Ifill", + "Igal", + "Igenia", + "Iggie", + "Iggy", + "Iglesias", + "Ignace", + "Ignacia", + "Ignacio", + "Ignacius", + "Ignatia", + "Ignatius", + "Ignatz", + "Ignatzia", + "Ignaz", + "Ignazio", + "Igor", + "Ihab", + "Iiette", + "Iila", + "Iinde", + "Iinden", + "Iives", + "Ike", + "Ikeda", + "Ikey", + "Ikkela", + "Ilaire", + "Ilan", + "Ilana", + "Ilario", + "Ilarrold", + "Ilbert", + "Ileana", + "Ileane", + "Ilene", + "Iline", + "Ilise", + "Ilka", + "Ilke", + "Illa", + "Illene", + "Illona", + "Illyes", + "Ilona", + "Ilonka", + "Ilowell", + "Ilsa", + "Ilse", + "Ilwain", + "Ilysa", + "Ilyse", + "Ilyssa", + "Im", + "Ima", + "Imalda", + "Iman", + "Imelda", + "Imelida", + "Imena", + "Immanuel", + "Imogen", + "Imogene", + "Imojean", + "Imray", + "Imre", + "Imtiaz", + "Ina", + "Incrocci", + "Indihar", + "Indira", + "Inerney", + "Ines", + "Inesita", + "Ineslta", + "Inessa", + "Inez", + "Infeld", + "Infield", + "Ing", + "Inga", + "Ingaberg", + "Ingaborg", + "Ingalls", + "Ingamar", + "Ingar", + "Inge", + "Ingeberg", + "Ingeborg", + "Ingelbert", + "Ingemar", + "Inger", + "Ingham", + "Inglebert", + "Ingles", + "Inglis", + "Ingmar", + "Ingold", + "Ingra", + "Ingraham", + "Ingram", + "Ingrid", + "Ingrim", + "Ingunna", + "Ingvar", + "Inigo", + "Inkster", + "Inman", + "Inna", + "Innes", + "Inness", + "Innis", + "Inoue", + "Intisar", + "Intosh", + "Intyre", + "Inverson", + "Iny", + "Ioab", + "Iolande", + "Iolanthe", + "Iolenta", + "Ion", + "Iona", + "Iong", + "Iorgo", + "Iorgos", + "Iorio", + "Iormina", + "Iosep", + "Ioved", + "Iover", + "Ioves", + "Iow", + "Ioyal", + "Iphagenia", + "Iphigenia", + "Iphigeniah", + "Iphlgenia", + "Ira", + "Iran", + "Irby", + "Iredale", + "Ireland", + "Irena", + "Irene", + "Irfan", + "Iridis", + "Iridissa", + "Irina", + "Iris", + "Irisa", + "Irish", + "Irita", + "Irma", + "Irme", + "Irmgard", + "Irmina", + "Irmine", + "Irra", + "Irv", + "Irvin", + "Irvine", + "Irving", + "Irwin", + "Irwinn", + "Isa", + "Isaac", + "Isaacs", + "Isaacson", + "Isaak", + "Isabea", + "Isabeau", + "Isabel", + "Isabelita", + "Isabella", + "Isabelle", + "Isac", + "Isacco", + "Isador", + "Isadora", + "Isadore", + "Isahella", + "Isaiah", + "Isak", + "Isbel", + "Isbella", + "Isborne", + "Iseabal", + "Isherwood", + "Ishii", + "Ishmael", + "Ishmul", + "Isia", + "Isiah", + "Isiahi", + "Isidor", + "Isidora", + "Isidore", + "Isidoro", + "Isidro", + "Isis", + "Isla", + "Islaen", + "Island", + "Isle", + "Islean", + "Isleana", + "Isleen", + "Islek", + "Isma", + "Isman", + "Isobel", + "Isola", + "Isolda", + "Isolde", + "Isolt", + "Israel", + "Israeli", + "Issi", + "Issiah", + "Issie", + "Issy", + "Ita", + "Itagaki", + "Itch", + "Ithaman", + "Ithnan", + "Itin", + "Iva", + "Ivah", + "Ivan", + "Ivana", + "Ivanah", + "Ivanna", + "Ivar", + "Ivatts", + "Ive", + "Ivens", + "Iver", + "Ivers", + "Iverson", + "Ives", + "Iveson", + "Ivett", + "Ivette", + "Ivetts", + "Ivey", + "Ivie", + "Ivo", + "Ivon", + "Ivonne", + "Ivor", + "Ivory", + "Ivy", + "Iy", + "Iyre", + "Iz", + "Izaak", + "Izabel", + "Izak", + "Izawa", + "Izy", + "Izzy", + "Ja", + "Jaal", + "Jaala", + "Jaan", + "Jaban", + "Jabe", + "Jabez", + "Jabin", + "Jablon", + "Jabon", + "Jac", + "Jacenta", + "Jacey", + "Jacie", + "Jacinda", + "Jacinta", + "Jacintha", + "Jacinthe", + "Jacinto", + "Jack", + "Jackelyn", + "Jacki", + "Jackie", + "Jacklin", + "Jacklyn", + "Jackquelin", + "Jackqueline", + "Jackson", + "Jacky", + "Jaclin", + "Jaclyn", + "Jaco", + "Jacob", + "Jacoba", + "Jacobah", + "Jacobba", + "Jacobina", + "Jacobine", + "Jacobo", + "Jacobs", + "Jacobsen", + "Jacobsohn", + "Jacobson", + "Jacoby", + "Jacquelin", + "Jacqueline", + "Jacquelyn", + "Jacquelynn", + "Jacquenetta", + "Jacquenette", + "Jacques", + "Jacquet", + "Jacquetta", + "Jacquette", + "Jacqui", + "Jacquie", + "Jacy", + "Jacynth", + "Jada", + "Jadd", + "Jadda", + "Jaddan", + "Jaddo", + "Jade", + "Jadwiga", + "Jae", + "Jaeger", + "Jaehne", + "Jael", + "Jaela", + "Jaella", + "Jaenicke", + "Jaf", + "Jaffe", + "Jagir", + "Jago", + "Jahdai", + "Jahdal", + "Jahdiel", + "Jahdol", + "Jahn", + "Jahncke", + "Jaime", + "Jaime ", + "Jaimie", + "Jain", + "Jaine", + "Jair", + "Jairia", + "Jake", + "Jakie", + "Jakob", + "Jakoba", + "Jala", + "Jalbert", + "Jallier", + "Jamaal", + "Jamal", + "Jamel", + "James", + "Jameson", + "Jamesy", + "Jamey", + "Jami", + "Jamie", + "Jamieson", + "Jamil", + "Jamila", + "Jamill", + "Jamilla", + "Jamille", + "Jamima", + "Jamin", + "Jamison", + "Jammal", + "Jammie", + "Jammin", + "Jamnes", + "Jamnis", + "Jan", + "Jana", + "Janaya", + "Janaye", + "Jandel", + "Jandy", + "Jane", + "Janean", + "Janeczka", + "Janeen", + "Janek", + "Janel", + "Janela", + "Janella", + "Janelle", + "Janene", + "Janenna", + "Janerich", + "Janessa", + "Janet", + "Janeta", + "Janetta", + "Janette", + "Janeva", + "Janey", + "Jangro", + "Jania", + "Janice", + "Janicki", + "Janie", + "Janifer", + "Janik", + "Janina", + "Janine", + "Janis", + "Janith", + "Janiuszck", + "Janka", + "Jankell", + "Jankey", + "Jann", + "Janna", + "Jannel", + "Jannelle", + "Jannery", + "Janos", + "Janot", + "Jansen", + "Jansson", + "Januarius", + "January", + "Januisz", + "Janus", + "Jany", + "Janyte", + "Japeth", + "Japha", + "Japheth", + "Jaqitsch", + "Jaquelin", + "Jaquelyn", + "Jaquenetta", + "Jaquenette", + "Jaquiss", + "Jaquith", + "Jara", + "Jarad", + "Jard", + "Jardena", + "Jareb", + "Jared", + "Jarek", + "Jaret", + "Jari", + "Jariah", + "Jarib", + "Jarid", + "Jarietta", + "Jarita", + "Jarl", + "Jarlath", + "Jarlathus", + "Jarlen", + "Jarnagin", + "Jarrad", + "Jarred", + "Jarrell", + "Jarret", + "Jarrett", + "Jarrid", + "Jarrod", + "Jarrow", + "Jarv", + "Jarvey", + "Jarvis", + "Jary", + "Jase", + "Jasen", + "Jasik", + "Jasisa", + "Jasmin", + "Jasmina", + "Jasmine", + "Jason", + "Jasper", + "Jasun", + "Jauch", + "Jaunita", + "Javed", + "Javier", + "Javler", + "Jaworski", + "Jay", + "Jaycee", + "Jaye", + "Jaylene", + "Jayme", + "Jaymee", + "Jaymie", + "Jayne", + "Jaynell", + "Jaynes", + "Jayson", + "Jazmin", + "Jdavie", + "Jea", + "Jean", + "Jean-Claude", + "Jeana", + "Jeane", + "Jeanelle", + "Jeanette", + "Jeanie", + "Jeanine", + "Jeanna", + "Jeanne", + "Jeannette", + "Jeannie", + "Jeannine", + "Jeavons", + "Jeaz", + "Jeb", + "Jecho", + "Jecoa", + "Jecon", + "Jeconiah", + "Jed", + "Jedd", + "Jeddy", + "Jedediah", + "Jedidiah", + "Jedlicka", + "Jedthus", + "Jeff", + "Jeffcott", + "Jefferey", + "Jeffers", + "Jefferson", + "Jeffery", + "Jeffie", + "Jeffrey", + "Jeffries", + "Jeffry", + "Jeffy", + "Jegar", + "Jeggar", + "Jegger", + "Jehanna", + "Jehiah", + "Jehial", + "Jehias", + "Jehiel", + "Jehius", + "Jehoash", + "Jehovah", + "Jehu", + "Jelena", + "Jelene", + "Jelks", + "Jelle", + "Jelsma", + "Jem", + "Jemena", + "Jemie", + "Jemima", + "Jemimah", + "Jemina", + "Jeminah", + "Jemine", + "Jemma", + "Jemmie", + "Jemmy", + "Jempty", + "Jemy", + "Jen", + "Jena", + "Jenda", + "Jenei", + "Jenelle", + "Jenesia", + "Jenette", + "Jeni", + "Jenica", + "Jeniece", + "Jenifer", + "Jeniffer", + "Jenilee", + "Jenine", + "Jenkel", + "Jenkins", + "Jenks", + "Jenn", + "Jenna", + "Jenne", + "Jennee", + "Jenness", + "Jennette", + "Jenni", + "Jennica", + "Jennie", + "Jennifer", + "Jennilee", + "Jennine", + "Jennings", + "Jenny", + "Jeno", + "Jens", + "Jensen", + "Jentoft", + "Jephthah", + "Jephum", + "Jepson", + "Jepum", + "Jer", + "Jerad", + "Jerald", + "Jeraldine", + "Jeralee", + "Jeramey", + "Jeramie", + "Jere", + "Jereld", + "Jereme", + "Jeremiah", + "Jeremias", + "Jeremie", + "Jeremy", + "Jeri", + "Jeritah", + "Jermain", + "Jermaine", + "Jerman", + "Jermayne", + "Jermyn", + "Jerol", + "Jerold", + "Jeroma", + "Jerome", + "Jeromy", + "Jerri", + "Jerrie", + "Jerrilee", + "Jerrilyn", + "Jerrine", + "Jerrol", + "Jerrold", + "Jerroll", + "Jerrome", + "Jerry", + "Jerrylee", + "Jerusalem", + "Jervis", + "Jerz", + "Jesh", + "Jesher", + "Jess", + "Jessa", + "Jessabell", + "Jessalin", + "Jessalyn", + "Jessamine", + "Jessamyn", + "Jesse", + "Jessee", + "Jesselyn", + "Jessen", + "Jessey", + "Jessi", + "Jessica", + "Jessie", + "Jessika", + "Jessy", + "Jestude", + "Jesus", + "Jeth", + "Jethro", + "Jeu", + "Jeunesse", + "Jeuz", + "Jevon", + "Jew", + "Jewel", + "Jewell", + "Jewelle", + "Jewett", + "Jews", + "Jez", + "Jezabel", + "Jezabella", + "Jezabelle", + "Jezebel", + "Jezreel", + "Ji", + "Jill", + "Jillana", + "Jillane", + "Jillayne", + "Jilleen", + "Jillene", + "Jilli", + "Jillian", + "Jillie", + "Jilly", + "Jim", + "Jimmie", + "Jimmy", + "Jinny", + "Jit", + "Jo", + "Jo Ann", + "Jo-Ann", + "Jo-Anne", + "JoAnn", + "JoAnne", + "Joab", + "Joachim", + "Joachima", + "Joacima", + "Joacimah", + "Joan", + "Joana", + "Joane", + "Joanie", + "Joann", + "Joanna", + "Joanne", + "Joannes", + "Joao", + "Joappa", + "Joaquin", + "Joash", + "Joashus", + "Job", + "Jobe", + "Jobey", + "Jobi", + "Jobie", + "Jobina", + "Joby", + "Jobye", + "Jobyna", + "Jocelin", + "Joceline", + "Jocelyn", + "Jocelyne", + "Jochbed", + "Jochebed", + "Jock", + "Jocko", + "Jodee", + "Jodi", + "Jodie", + "Jodoin", + "Jody", + "Joe", + "Joeann", + "Joed", + "Joel", + "Joela", + "Joelie", + "Joell", + "Joella", + "Joelle", + "Joellen", + "Joelly", + "Joellyn", + "Joelynn", + "Joerg", + "Joete", + "Joette", + "Joey", + "Joh", + "Johan", + "Johanan", + "Johann", + "Johanna", + "Johannah", + "Johannes", + "Johannessen", + "Johansen", + "Johathan", + "Johen", + "Johiah", + "Johm", + "John", + "Johna", + "Johnath", + "Johnathan", + "Johnathon", + "Johnette", + "Johnna", + "Johnnie", + "Johnny", + "Johns", + "Johnson", + "Johnsson", + "Johnsten", + "Johnston", + "Johnstone", + "Johny", + "Johppa", + "Johppah", + "Johst", + "Joice", + "Joiner", + "Jojo", + "Joktan", + "Jola", + "Jolanta", + "Jolda", + "Jolee", + "Joleen", + "Jolene", + "Jolenta", + "Joletta", + "Joli", + "Jolie", + "Joliet", + "Joline", + "Jollanta", + "Jollenta", + "Joly", + "Jolyn", + "Jolynn", + "Jon", + "Jona", + "Jonah", + "Jonas", + "Jonathan", + "Jonathon", + "Jonati", + "Jone", + "Jonell", + "Jones", + "Jonette", + "Joni", + "Jonie", + "Jonina", + "Jonis", + "Jonme", + "Jonna", + "Jonny", + "Joo", + "Joon", + "Joost", + "Jopa", + "Jordain", + "Jordan", + "Jordana", + "Jordanna", + "Jordans", + "Jordanson", + "Jordison", + "Jordon", + "Jorey", + "Jorgan", + "Jorge", + "Jorgensen", + "Jorgenson", + "Jori", + "Jorie", + "Jorin", + "Joris", + "Jorrie", + "Jorry", + "Jory", + "Jos", + "Joscelin", + "Jose", + "Josee", + "Josefa", + "Josefina", + "Joseito", + "Joselow", + "Joselyn", + "Joseph", + "Josepha", + "Josephina", + "Josephine", + "Josephson", + "Joses", + "Josey", + "Josh", + "Joshi", + "Joshia", + "Joshua", + "Joshuah", + "Josi", + "Josiah", + "Josias", + "Josie", + "Josler", + "Joslyn", + "Josselyn", + "Josy", + "Jotham", + "Joub", + "Joung", + "Jourdain", + "Jourdan", + "Jovi", + "Jovia", + "Jovita", + "Jovitah", + "Jovitta", + "Jowett", + "Joy", + "Joya", + "Joyan", + "Joyann", + "Joyce", + "Joycelin", + "Joye", + "Jozef", + "Jsandye", + "Juan", + "Juana", + "Juanita", + "Juanne", + "Juback", + "Jud", + "Judah", + "Judas", + "Judd", + "Jude", + "Judenberg", + "Judi", + "Judie", + "Judith", + "Juditha", + "Judon", + "Judsen", + "Judson", + "Judus", + "Judy", + "Judye", + "Jueta", + "Juetta", + "Juieta", + "Jule", + "Julee", + "Jules", + "Juley", + "Juli", + "Julia", + "Julian", + "Juliana", + "Juliane", + "Juliann", + "Julianna", + "Julianne", + "Juliano", + "Julide", + "Julie", + "Julienne", + "Juliet", + "Julieta", + "Julietta", + "Juliette", + "Julina", + "Juline", + "Julio", + "Julis", + "Julissa", + "Julita", + "Julius", + "Jumbala", + "Jump", + "Jun", + "Juna", + "June", + "Junette", + "Jung", + "Juni", + "Junia", + "Junie", + "Junieta", + "Junina", + "Junius", + "Junji", + "Junko", + "Junna", + "Junno", + "Juno", + "Jurdi", + "Jurgen", + "Jurkoic", + "Just", + "Justen", + "Juster", + "Justicz", + "Justin", + "Justina", + "Justine", + "Justinian", + "Justinn", + "Justino", + "Justis", + "Justus", + "Juta", + "Jutta", + "Juxon", + "Jyoti", + "Kablesh", + "Kacerek", + "Kacey", + "Kachine", + "Kacie", + "Kacy", + "Kaczer", + "Kaden", + "Kadner", + "Kado", + "Kaela", + "Kaenel", + "Kaete", + "Kafka", + "Kahaleel", + "Kahl", + "Kahle", + "Kahler", + "Kahlil", + "Kahn", + "Kai", + "Kaia", + "Kaila", + "Kaile", + "Kailey", + "Kain", + "Kaine", + "Kaiser", + "Kaitlin", + "Kaitlyn", + "Kaitlynn", + "Kaiulani", + "Kaja", + "Kajdan", + "Kakalina", + "Kal", + "Kala", + "Kalagher", + "Kalasky", + "Kalb", + "Kalbli", + "Kale", + "Kaleb", + "Kaleena", + "Kalfas", + "Kali", + "Kalie", + "Kalikow", + "Kalil", + "Kalila", + "Kalin", + "Kalina", + "Kalinda", + "Kalindi", + "Kaliope", + "Kaliski", + "Kalk", + "Kall", + "Kalle", + "Kalli", + "Kallick", + "Kallista", + "Kallman", + "Kally", + "Kalman", + "Kalmick", + "Kaltman", + "Kalvin", + "Kalvn", + "Kam", + "Kama", + "Kamal", + "Kamaria", + "Kamat", + "Kameko", + "Kamerman", + "Kamila", + "Kamilah", + "Kamillah", + "Kamin", + "Kammerer", + "Kamp", + "Kampmann", + "Kampmeier", + "Kan", + "Kanal", + "Kancler", + "Kandace", + "Kandy", + "Kane", + "Kania", + "Kannan", + "Kannry", + "Kano", + "Kant", + "Kanter", + "Kantor", + "Kantos", + "Kanya", + "Kape", + "Kaplan", + "Kapoor", + "Kapor", + "Kappel", + "Kappenne", + "Kara", + "Kara-Lynn", + "Karalee", + "Karalynn", + "Karame", + "Karas", + "Karb", + "Kare", + "Karee", + "Kareem", + "Karel", + "Karen", + "Karena", + "Kari", + "Karia", + "Karie", + "Karil", + "Karilla", + "Karilynn", + "Karim", + "Karin", + "Karina", + "Karine", + "Kariotta", + "Karisa", + "Karissa", + "Karita", + "Karl", + "Karla", + "Karlan", + "Karlee", + "Karleen", + "Karlen", + "Karlene", + "Karlens", + "Karli", + "Karlie", + "Karlik", + "Karlin", + "Karlis", + "Karlise", + "Karlotta", + "Karlotte", + "Karlow", + "Karly", + "Karlyn", + "Karmen", + "Karna", + "Karney", + "Karol", + "Karola", + "Karole", + "Karolina", + "Karoline", + "Karoly", + "Karolyn", + "Karon", + "Karp", + "Karr", + "Karrah", + "Karrie", + "Karry", + "Karsten", + "Kartis", + "Karwan", + "Kary", + "Karyl", + "Karylin", + "Karyn", + "Kasevich", + "Kasey", + "Kashden", + "Kask", + "Kaslik", + "Kaspar", + "Kasper", + "Kass", + "Kassab", + "Kassandra", + "Kassaraba", + "Kassel", + "Kassey", + "Kassi", + "Kassia", + "Kassie", + "Kassity", + "Kast", + "Kat", + "Kata", + "Katalin", + "Kataway", + "Kate", + "Katee", + "Katerina", + "Katerine", + "Katey", + "Kath", + "Katha", + "Katharina", + "Katharine", + "Katharyn", + "Kathe", + "Katherin", + "Katherina", + "Katherine", + "Katheryn", + "Kathi", + "Kathie", + "Kathleen", + "Kathlene", + "Kathlin", + "Kathrine", + "Kathryn", + "Kathryne", + "Kathy", + "Kathye", + "Kati", + "Katie", + "Katina", + "Katine", + "Katinka", + "Katlaps", + "Katleen", + "Katlin", + "Kato", + "Katonah", + "Katrina", + "Katrine", + "Katrinka", + "Katsuyama", + "Katt", + "Katti", + "Kattie", + "Katuscha", + "Katusha", + "Katushka", + "Katy", + "Katya", + "Katz", + "Katzen", + "Katzir", + "Katzman", + "Kauffman", + "Kauffmann", + "Kaufman", + "Kaufmann", + "Kaule", + "Kauppi", + "Kauslick", + "Kavanagh", + "Kavanaugh", + "Kavita", + "Kawai", + "Kawasaki", + "Kay", + "Kaya", + "Kaycee", + "Kaye", + "Kayla", + "Kayle", + "Kaylee", + "Kayley", + "Kaylil", + "Kaylyn", + "Kayne", + "Kaz", + "Kazim", + "Kazimir", + "Kazmirci", + "Kazue", + "Kealey", + "Kean", + "Keane", + "Keare", + "Kearney", + "Keary", + "Keating", + "Keavy", + "Kee", + "Keefe", + "Keefer", + "Keegan", + "Keel", + "Keelby", + "Keele", + "Keeler", + "Keeley", + "Keelia", + "Keelin", + "Keely", + "Keen", + "Keenan", + "Keene", + "Keener", + "Keese", + "Keeton", + "Keever", + "Keffer", + "Keg", + "Kegan", + "Keheley", + "Kehoe", + "Kehr", + "Kei", + "Keifer", + "Keiko", + "Keil", + "Keily", + "Keir", + "Keisling", + "Keith", + "Keithley", + "Kela", + "Kelbee", + "Kelby", + "Kelcey", + "Kelci", + "Kelcie", + "Kelcy", + "Kelda", + "Keldah", + "Keldon", + "Kele", + "Keli", + "Keligot", + "Kelila", + "Kella", + "Kellby", + "Kellda", + "Kelleher", + "Kellen", + "Kellene", + "Keller", + "Kelley", + "Kelli", + "Kellia", + "Kellie", + "Kellina", + "Kellsie", + "Kelly", + "Kellyann", + "Kellyn", + "Kelsey", + "Kelsi", + "Kelson", + "Kelsy", + "Kelton", + "Kelula", + "Kelvin", + "Kelwen", + "Kelwin", + "Kelwunn", + "Kemble", + "Kemeny", + "Kemme", + "Kemp", + "Kempe", + "Kemppe", + "Ken", + "Kenay", + "Kenaz", + "Kendal", + "Kendall", + "Kendell", + "Kendra", + "Kendrah", + "Kendre", + "Kendrick", + "Kendricks", + "Kendry", + "Kendy", + "Kendyl", + "Kenelm", + "Kenison", + "Kenji", + "Kenlay", + "Kenlee", + "Kenleigh", + "Kenley", + "Kenn", + "Kenna", + "Kennan", + "Kennard", + "Kennedy", + "Kennet", + "Kenneth", + "Kennett", + "Kenney", + "Kennie", + "Kennith", + "Kenny", + "Kenon", + "Kenric", + "Kenrick", + "Kensell", + "Kent", + "Kenta", + "Kenti", + "Kentiga", + "Kentigera", + "Kentigerma", + "Kentiggerma", + "Kenton", + "Kenward", + "Kenway", + "Kenwee", + "Kenweigh", + "Kenwood", + "Kenwrick", + "Kenyon", + "Kenzi", + "Kenzie", + "Keon", + "Kepner", + "Keppel", + "Ker", + "Kerby", + "Kerek", + "Kerekes", + "Kerge", + "Keri", + "Keriann", + "Kerianne", + "Kerin", + "Kerk", + "Kerman", + "Kermie", + "Kermit", + "Kermy", + "Kern", + "Kernan", + "Kerns", + "Kerr", + "Kerri", + "Kerrie", + "Kerril", + "Kerrill", + "Kerrin", + "Kerrison", + "Kerry", + "Kersten", + "Kerstin", + "Kerwin", + "Kerwinn", + "Kerwon", + "Kery", + "Kesia", + "Kesley", + "Keslie", + "Kessel", + "Kessia", + "Kessiah", + "Kessler", + "Kester", + "Ketchan", + "Ketchum", + "Ketti", + "Kettie", + "Ketty", + "Keung", + "Kev", + "Kevan", + "Keven", + "Keverian", + "Keverne", + "Kevin", + "Kevina", + "Kevon", + "Kevyn", + "Key", + "Keyek", + "Keyes", + "Keynes", + "Keyser", + "Keyte", + "Kezer", + "Khai", + "Khajeh", + "Khalid", + "Khalil", + "Khalin", + "Khalsa", + "Khan", + "Khanna", + "Khano", + "Khichabia", + "Kho", + "Khorma", + "Khosrow", + "Khoury", + "Khudari", + "Ki", + "Kiah", + "Kial", + "Kidd", + "Kidder", + "Kiefer", + "Kieffer", + "Kieger", + "Kiehl", + "Kiel", + "Kiele", + "Kielty", + "Kienan", + "Kier", + "Kieran", + "Kiernan", + "Kiersten", + "Kikelia", + "Kiker", + "Kiki", + "Kila", + "Kilah", + "Kilan", + "Kilar", + "Kilbride", + "Kilby", + "Kile", + "Kiley", + "Kilgore", + "Kilian", + "Kilk", + "Killam", + "Killarney", + "Killen", + "Killian", + "Killie", + "Killigrew", + "Killion", + "Killoran", + "Killy", + "Kilmarx", + "Kilroy", + "Kim", + "Kimball", + "Kimbell", + "Kimber", + "Kimberlee", + "Kimberley", + "Kimberli", + "Kimberly", + "Kimberlyn", + "Kimble", + "Kimbra", + "Kimitri", + "Kimmel", + "Kimmi", + "Kimmie", + "Kimmy", + "Kimon", + "Kimura", + "Kin", + "Kinata", + "Kincaid", + "Kinch", + "Kinchen", + "Kind", + "Kindig", + "Kinelski", + "King", + "Kingdon", + "Kinghorn", + "Kingsbury", + "Kingsley", + "Kingsly", + "Kingston", + "Kinna", + "Kinnard", + "Kinney", + "Kinnie", + "Kinnon", + "Kinny", + "Kinsler", + "Kinsley", + "Kinsman", + "Kinson", + "Kinzer", + "Kiona", + "Kip", + "Kipp", + "Kippar", + "Kipper", + "Kippie", + "Kippy", + "Kipton", + "Kira", + "Kiran", + "Kirbee", + "Kirbie", + "Kirby", + "Kirch", + "Kirchner", + "Kiri", + "Kirima", + "Kirimia", + "Kirit", + "Kirk", + "Kirkpatrick", + "Kirkwood", + "Kironde", + "Kirsch", + "Kirschner", + "Kirshbaum", + "Kirst", + "Kirsten", + "Kirsteni", + "Kirsti", + "Kirstin", + "Kirstyn", + "Kirt", + "Kirtley", + "Kirven", + "Kirwin", + "Kisor", + "Kissee", + "Kissel", + "Kissiah", + "Kissie", + "Kissner", + "Kistner", + "Kisung", + "Kit", + "Kitchen", + "Kitti", + "Kittie", + "Kitty", + "Kiyohara", + "Kiyoshi", + "Kizzee", + "Kizzie", + "Kjersti", + "Klapp", + "Klara", + "Klarika", + "Klarrisa", + "Klatt", + "Klaus", + "Klayman", + "Klecka", + "Kleeman", + "Klehm", + "Kleiman", + "Klein", + "Kleinstein", + "Klemens", + "Klement", + "Klemm", + "Klemperer", + "Klenk", + "Kleon", + "Klepac", + "Kleper", + "Kletter", + "Kliber", + "Kliman", + "Kliment", + "Klimesh", + "Klina", + "Kline", + "Kling", + "Klingel", + "Klinger", + "Klinges", + "Klockau", + "Kloman", + "Klos", + "Kloster", + "Klotz", + "Klug", + "Kluge", + "Klump", + "Klusek", + "Klute", + "Knapp", + "Kneeland", + "Knepper", + "Knick", + "Knight", + "Knighton", + "Knipe", + "Knitter", + "Knobloch", + "Knoll", + "Knorring", + "Knowland", + "Knowle", + "Knowles", + "Knowling", + "Knowlton", + "Knox", + "Knudson", + "Knut", + "Knute", + "Knuth", + "Knutson", + "Ko", + "Koa", + "Koah", + "Koal", + "Koball", + "Kobe", + "Kobi", + "Koblas", + "Koblick", + "Koby", + "Kobylak", + "Koch", + "Koehler", + "Koenig", + "Koeninger", + "Koenraad", + "Koeppel", + "Koerlin", + "Koerner", + "Koetke", + "Koffler", + "Koffman", + "Koh", + "Kohl", + "Kohler", + "Kohn", + "Kokaras", + "Kokoruda", + "Kolb", + "Kolivas", + "Kolk", + "Koller", + "Kolnick", + "Kolnos", + "Kolodgie", + "Kolosick", + "Koloski", + "Kolva", + "Komara", + "Komarek", + "Komsa", + "Kondon", + "Kone", + "Kong", + "Konikow", + "Kono", + "Konopka", + "Konrad", + "Konstance", + "Konstantin", + "Konstantine", + "Konstanze", + "Konyn", + "Koo", + "Kooima", + "Koosis", + "Kopans", + "Kopaz", + "Kopp", + "Koppel", + "Kopple", + "Kora", + "Koral", + "Koralie", + "Koralle", + "Koran", + "Kordula", + "Kore", + "Korella", + "Koren", + "Korenblat", + "Koressa", + "Korey", + "Korff", + "Korfonta", + "Kori", + "Korie", + "Korman", + "Korney", + "Kornher", + "Korns", + "Korrie", + "Korry", + "Kort", + "Korten", + "Korwin", + "Korwun", + "Kory", + "Kosak", + "Kosaka", + "Kosel", + "Koser", + "Kosey", + "Kosiur", + "Koslo", + "Koss", + "Kosse", + "Kostival", + "Kostman", + "Kotick", + "Kotta", + "Kotto", + "Kotz", + "Kovacev", + "Kovacs", + "Koval", + "Kovar", + "Kowal", + "Kowalski", + "Kowatch", + "Kowtko", + "Koy", + "Koziara", + "Koziarz", + "Koziel", + "Kozloski", + "Kraft", + "Kragh", + "Krahling", + "Krahmer", + "Krakow", + "Krall", + "Kramer", + "Kramlich", + "Krantz", + "Kraska", + "Krasner", + "Krasnoff", + "Kraul", + "Kraus", + "Krause", + "Krauss", + "Kravits", + "Krawczyk", + "Kreager", + "Krebs", + "Kreda", + "Kreegar", + "Krefetz", + "Kreg", + "Kreiker", + "Krein", + "Kreindler", + "Kreiner", + "Kreis", + "Kreit", + "Kreitman", + "Krell", + "Kremer", + "Krenek", + "Krenn", + "Kresic", + "Kress", + "Krever", + "Kries", + "Krigsman", + "Krilov", + "Kris", + "Krischer", + "Krisha", + "Krishna", + "Krishnah", + "Krispin", + "Kriss", + "Krissie", + "Krissy", + "Krista", + "Kristal", + "Kristan", + "Kriste", + "Kristel", + "Kristen", + "Kristi", + "Kristian", + "Kristianson", + "Kristie", + "Kristien", + "Kristin", + "Kristina", + "Kristine", + "Kristo", + "Kristof", + "Kristofer", + "Kristoffer", + "Kristofor", + "Kristoforo", + "Kristopher", + "Kristos", + "Kristy", + "Kristyn", + "Krock", + "Kroll", + "Kronfeld", + "Krongold", + "Kronick", + "Kroo", + "Krucik", + "Krueger", + "Krug", + "Kruger", + "Krum", + "Krusche", + "Kruse", + "Krute", + "Kruter", + "Krutz", + "Krys", + "Kryska", + "Krysta", + "Krystal", + "Krystalle", + "Krystin", + "Krystle", + "Krystyna", + "Ku", + "Kubetz", + "Kubiak", + "Kubis", + "Kucik", + "Kudva", + "Kuebbing", + "Kuehn", + "Kuehnel", + "Kuhlman", + "Kuhn", + "Kulda", + "Kulseth", + "Kulsrud", + "Kumagai", + "Kumar", + "Kumler", + "Kung", + "Kunin", + "Kunkle", + "Kunz", + "Kuo", + "Kurland", + "Kurman", + "Kurr", + "Kursh", + "Kurt", + "Kurth", + "Kurtis", + "Kurtz", + "Kurtzig", + "Kurtzman", + "Kurys", + "Kurzawa", + "Kus", + "Kushner", + "Kusin", + "Kuska", + "Kussell", + "Kuster", + "Kutchins", + "Kuth", + "Kutzenco", + "Kutzer", + "Kwabena", + "Kwan", + "Kwang", + "Kwapong", + "Kwarteng", + "Kwasi", + "Kwei", + "Kwok", + "Kwon", + "Ky", + "Kyd", + "Kyl", + "Kyla", + "Kylah", + "Kylander", + "Kyle", + "Kylen", + "Kylie", + "Kylila", + "Kylstra", + "Kylynn", + "Kym", + "Kynan", + "Kyne", + "Kynthia", + "Kyriako", + "Kyrstin", + "Kyte", + "La", + "La Verne", + "LaBaw", + "LaMee", + "LaMonica", + "LaMori", + "LaRue", + "LaSorella", + "Laaspere", + "Laban", + "Labana", + "Laband", + "Labanna", + "Labannah", + "Labors", + "Lacagnia", + "Lacee", + "Lacefield", + "Lacey", + "Lach", + "Lachance", + "Lachish", + "Lachlan", + "Lachman", + "Lachus", + "Lacie", + "Lacombe", + "Lacy", + "Lad", + "Ladd", + "Laddie", + "Laddy", + "Laden", + "Ladew", + "Ladonna", + "Lady", + "Lael", + "Laetitia", + "Laflam", + "Lafleur", + "Laforge", + "Lagas", + "Lagasse", + "Lahey", + "Lai", + "Laidlaw", + "Lail", + "Laina", + "Laine", + "Lainey", + "Laing", + "Laird", + "Lais", + "Laise", + "Lait", + "Laith", + "Laius", + "Lakin", + "Laks", + "Laktasic", + "Lal", + "Lala", + "Lalage", + "Lali", + "Lalise", + "Lalita", + "Lalitta", + "Lalittah", + "Lalla", + "Lallage", + "Lally", + "Lalo", + "Lam", + "Lamar", + "Lamarre", + "Lamb", + "Lambard", + "Lambart", + "Lambert", + "Lamberto", + "Lambertson", + "Lambrecht", + "Lamdin", + "Lammond", + "Lamond", + "Lamont", + "Lamoree", + "Lamoureux", + "Lamp", + "Lampert", + "Lamphere", + "Lamprey", + "Lamrert", + "Lamrouex", + "Lamson", + "Lan", + "Lana", + "Lanae", + "Lanam", + "Lananna", + "Lancaster", + "Lance", + "Lancelle", + "Lancelot", + "Lancey", + "Lanctot", + "Land", + "Landa", + "Landahl", + "Landan", + "Landau", + "Landbert", + "Landel", + "Lander", + "Landers", + "Landes", + "Landing", + "Landis", + "Landmeier", + "Landon", + "Landre", + "Landri", + "Landrum", + "Landry", + "Landsman", + "Landy", + "Lane", + "Lanette", + "Laney", + "Lanford", + "Lanfri", + "Lang", + "Langan", + "Langbehn", + "Langdon", + "Lange", + "Langelo", + "Langer", + "Langham", + "Langill", + "Langille", + "Langley", + "Langsdon", + "Langston", + "Lani", + "Lanie", + "Lanita", + "Lankton", + "Lanna", + "Lanni", + "Lannie", + "Lanny", + "Lansing", + "Lanta", + "Lantha", + "Lanti", + "Lantz", + "Lanza", + "Lapham", + "Lapides", + "Lapointe", + "Lapotin", + "Lara", + "Laraine", + "Larcher", + "Lardner", + "Lareena", + "Lareine", + "Larena", + "Larentia", + "Laresa", + "Largent", + "Lari", + "Larianna", + "Larimer", + "Larimor", + "Larimore", + "Larina", + "Larine", + "Laris", + "Larisa", + "Larissa", + "Lark", + "Larkin", + "Larkins", + "Larner", + "Larochelle", + "Laroy", + "Larrabee", + "Larrie", + "Larrisa", + "Larry", + "Lars", + "Larsen", + "Larson", + "Laryssa", + "Lasala", + "Lash", + "Lashar", + "Lashoh", + "Lashond", + "Lashonda", + "Lashonde", + "Lashondra", + "Lasko", + "Lasky", + "Lasley", + "Lasonde", + "Laspisa", + "Lasser", + "Lassiter", + "Laszlo", + "Lat", + "Latashia", + "Latea", + "Latham", + "Lathan", + "Lathe", + "Lathrop", + "Lathrope", + "Lati", + "Latia", + "Latif", + "Latimer", + "Latimore", + "Latin", + "Latini", + "Latisha", + "Latona", + "Latonia", + "Latoniah", + "Latouche", + "Latoya", + "Latoye", + "Latoyia", + "Latreece", + "Latreese", + "Latrell", + "Latrena", + "Latreshia", + "Latrice", + "Latricia", + "Latrina", + "Latt", + "Latta", + "Latterll", + "Lattie", + "Lattimer", + "Latton", + "Lattonia", + "Latty", + "Latvina", + "Lau", + "Lauber", + "Laubin", + "Laud", + "Lauder", + "Lauer", + "Laufer", + "Laughlin", + "Laughry", + "Laughton", + "Launce", + "Launcelot", + "Laundes", + "Laura", + "Lauraine", + "Laural", + "Lauralee", + "Laurance", + "Laure", + "Lauree", + "Laureen", + "Laurel", + "Laurella", + "Lauren", + "Laurena", + "Laurence", + "Laurene", + "Laurens", + "Laurent", + "Laurentia", + "Laurentium", + "Lauretta", + "Laurette", + "Lauri", + "Laurianne", + "Laurice", + "Laurie", + "Laurin", + "Laurinda", + "Laurita", + "Lauritz", + "Lauro", + "Lauryn", + "Lauter", + "Laux", + "Lauzon", + "Laval", + "Laveen", + "Lavella", + "Lavelle", + "Laven", + "Lavena", + "Lavern", + "Laverna", + "Laverne", + "Lavery", + "Lavina", + "Lavine", + "Lavinia", + "Lavinie", + "Lavoie", + "Lavona", + "Law", + "Lawford", + "Lawler", + "Lawley", + "Lawlor", + "Lawrence", + "Lawrenson", + "Lawry", + "Laws", + "Lawson", + "Lawton", + "Lawtun", + "Lay", + "Layla", + "Layman", + "Layne", + "Layney", + "Layton", + "Lazar", + "Lazare", + "Lazaro", + "Lazaruk", + "Lazarus", + "Lazes", + "Lazor", + "Lazos", + "Le", + "LeCroy", + "LeDoux", + "LeMay", + "LeRoy", + "LeVitus", + "Lea", + "Leach", + "Leacock", + "Leah", + "Leahey", + "Leake", + "Leal", + "Lean", + "Leanard", + "Leander", + "Leandra", + "Leandre", + "Leandro", + "Leann", + "Leanna", + "Leanne", + "Leanor", + "Leanora", + "Leaper", + "Lear", + "Leary", + "Leasia", + "Leatri", + "Leatrice", + "Leavelle", + "Leavitt", + "Leavy", + "Leban", + "Lebar", + "Lebaron", + "Lebbie", + "Leblanc", + "Lebna", + "Leboff", + "Lechner", + "Lecia", + "Leckie", + "Leclair", + "Lectra", + "Leda", + "Ledah", + "Ledda", + "Leddy", + "Ledeen", + "Lederer", + "Lee", + "LeeAnn", + "Leeann", + "Leeanne", + "Leede", + "Leeke", + "Leela", + "Leelah", + "Leeland", + "Leena", + "Leesa", + "Leese", + "Leesen", + "Leeth", + "Leff", + "Leffen", + "Leffert", + "Lefkowitz", + "Lefton", + "Leftwich", + "Lefty", + "Leggat", + "Legge", + "Leggett", + "Legra", + "Lehet", + "Lehman", + "Lehmann", + "Lehrer", + "Leia", + "Leibman", + "Leicester", + "Leid", + "Leif", + "Leifer", + "Leifeste", + "Leigh", + "Leigha", + "Leighland", + "Leighton", + "Leila", + "Leilah", + "Leilani", + "Leipzig", + "Leis", + "Leiser", + "Leisha", + "Leitao", + "Leith", + "Leitman", + "Lejeune", + "Lek", + "Lela", + "Lelah", + "Leland", + "Leler", + "Lelia", + "Lelith", + "Lello", + "Lem", + "Lema", + "Lemaceon", + "Lemal", + "Lemar", + "Lemcke", + "Lemieux", + "Lemire", + "Lemkul", + "Lemmie", + "Lemmuela", + "Lemmueu", + "Lemmy", + "Lemon", + "Lempres", + "Lemuel", + "Lemuela", + "Lemuelah", + "Len", + "Lena", + "Lenard", + "Lenci", + "Lenee", + "Lenes", + "Lenette", + "Lengel", + "Lenhard", + "Lenhart", + "Lenka", + "Lenna", + "Lennard", + "Lenni", + "Lennie", + "Lenno", + "Lennon", + "Lennox", + "Lenny", + "Leno", + "Lenora", + "Lenore", + "Lenox", + "Lenrow", + "Lenssen", + "Lentha", + "Lenwood", + "Lenz", + "Lenzi", + "Leo", + "Leod", + "Leodora", + "Leoine", + "Leola", + "Leoline", + "Leon", + "Leona", + "Leonanie", + "Leonard", + "Leonardi", + "Leonardo", + "Leone", + "Leonelle", + "Leonerd", + "Leong", + "Leonhard", + "Leoni", + "Leonid", + "Leonidas", + "Leonie", + "Leonor", + "Leonora", + "Leonore", + "Leonsis", + "Leonteen", + "Leontina", + "Leontine", + "Leontyne", + "Leopold", + "Leopoldeen", + "Leopoldine", + "Leor", + "Leora", + "Leotie", + "Lepine", + "Lepley", + "Lepp", + "Lepper", + "Lerner", + "Leroi", + "Leroy", + "Les", + "Lesak", + "Leschen", + "Lesh", + "Leshia", + "Lesko", + "Leslee", + "Lesley", + "Lesli", + "Leslie", + "Lesly", + "Lessard", + "Lesser", + "Lesslie", + "Lester", + "Lesya", + "Let", + "Leta", + "Letch", + "Letha", + "Lethia", + "Leticia", + "Letisha", + "Letitia", + "Letizia", + "Letreece", + "Letrice", + "Letsou", + "Letta", + "Lette", + "Letti", + "Lettie", + "Letty", + "Leund", + "Leupold", + "Lev", + "Levan", + "Levana", + "Levania", + "Levenson", + "Leventhal", + "Leventis", + "Leverett", + "Leverick", + "Leveridge", + "Leveroni", + "Levesque", + "Levey", + "Levi", + "Levin", + "Levina", + "Levine", + "Levins", + "Levinson", + "Levison", + "Levitan", + "Levitt", + "Levon", + "Levona", + "Levy", + "Lew", + "Lewak", + "Lewan", + "Lewanna", + "Lewellen", + "Lewendal", + "Lewert", + "Lewes", + "Lewie", + "Lewin", + "Lewis", + "Lewison", + "Lewiss", + "Lewls", + "Lewse", + "Lexi", + "Lexie", + "Lexine", + "Lexis", + "Lexy", + "Ley", + "Leyes", + "Leyla", + "Lezley", + "Lezlie", + "Lhary", + "Li", + "Lia", + "Liam", + "Lian", + "Liana", + "Liane", + "Lianna", + "Lianne", + "Lias", + "Liatrice", + "Liatris", + "Lib", + "Liba", + "Libb", + "Libbey", + "Libbi", + "Libbie", + "Libbna", + "Libby", + "Libenson", + "Liberati", + "Libna", + "Libnah", + "Liborio", + "Libove", + "Libre", + "Licastro", + "Licha", + "Licht", + "Lichtenfeld", + "Lichter", + "Licko", + "Lida", + "Lidah", + "Lidda", + "Liddie", + "Liddle", + "Liddy", + "Lidia", + "Lidstone", + "Lieberman", + "Liebermann", + "Liebman", + "Liebowitz", + "Liederman", + "Lief", + "Lienhard", + "Liesa", + "Lietman", + "Liew", + "Lifton", + "Ligetti", + "Liggett", + "Liggitt", + "Light", + "Lightfoot", + "Lightman", + "Lil", + "Lila", + "Lilac", + "Lilah", + "Lilas", + "Lili", + "Lilia", + "Lilian", + "Liliane", + "Lilias", + "Lilith", + "Lilithe", + "Lilla", + "Lilli", + "Lillian", + "Lillie", + "Lillis", + "Lillith", + "Lilllie", + "Lilly", + "Lillywhite", + "Lily", + "Lilyan", + "Lilybel", + "Lilybelle", + "Lim", + "Liman", + "Limann", + "Limber", + "Limbert", + "Limemann", + "Limoli", + "Lin", + "Lina", + "Linc", + "Lincoln", + "Lind", + "Linda", + "Lindahl", + "Lindberg", + "Lindblad", + "Lindbom", + "Lindeberg", + "Lindell", + "Lindemann", + "Linden", + "Linder", + "Linders", + "Lindgren", + "Lindholm", + "Lindi", + "Lindie", + "Lindley", + "Lindly", + "Lindner", + "Lindo", + "Lindon", + "Lindsay", + "Lindsey", + "Lindsley", + "Lindsy", + "Lindy", + "Line", + "Linea", + "Linehan", + "Linell", + "Linet", + "Linetta", + "Linette", + "Ling", + "Lingwood", + "Linis", + "Link", + "Linker", + "Linkoski", + "Linn", + "Linnea", + "Linnell", + "Linneman", + "Linnet", + "Linnette", + "Linnie", + "Linoel", + "Linsk", + "Linskey", + "Linson", + "Linus", + "Linzer", + "Linzy", + "Lion", + "Lionel", + "Lionello", + "Lipcombe", + "Lipfert", + "Lipinski", + "Lipkin", + "Lipman", + "Liponis", + "Lipp", + "Lippold", + "Lipps", + "Lipscomb", + "Lipsey", + "Lipski", + "Lipson", + "Lira", + "Liris", + "Lisa", + "Lisabet", + "Lisabeth", + "Lisan", + "Lisandra", + "Lisbeth", + "Liscomb", + "Lise", + "Lisetta", + "Lisette", + "Lisha", + "Lishe", + "Lisk", + "Lisle", + "Liss", + "Lissa", + "Lissak", + "Lissi", + "Lissie", + "Lissner", + "Lissy", + "Lister", + "Lita", + "Litch", + "Litha", + "Lithea", + "Litman", + "Litt", + "Litta", + "Littell", + "Little", + "Littlejohn", + "Littman", + "Litton", + "Liu", + "Liuka", + "Liv", + "Liva", + "Livesay", + "Livi", + "Livia", + "Livingston", + "Livingstone", + "Livvi", + "Livvie", + "Livvy", + "Livvyy", + "Livy", + "Liz", + "Liza", + "Lizabeth", + "Lizbeth", + "Lizette", + "Lizzie", + "Lizzy", + "Ljoka", + "Llewellyn", + "Llovera", + "Lloyd", + "Llywellyn", + "Loar", + "Loats", + "Lobel", + "Lobell", + "Lochner", + "Lock", + "Locke", + "Lockhart", + "Locklin", + "Lockwood", + "Lodge", + "Lodhia", + "Lodi", + "Lodie", + "Lodmilla", + "Lodovico", + "Lody", + "Loeb", + "Loella", + "Loesceke", + "Loferski", + "Loftis", + "Loftus", + "Logan", + "Loggia", + "Loggins", + "Loginov", + "Lohman", + "Lohner", + "Lohrman", + "Lohse", + "Lois", + "Loise", + "Lola", + "Lolande", + "Lolanthe", + "Lole", + "Loleta", + "Lolita", + "Lolly", + "Loma", + "Lomasi", + "Lomax", + "Lombard", + "Lombardi", + "Lombardo", + "Lombardy", + "Lon", + "Lona", + "London", + "Londoner", + "Lonee", + "Lonergan", + "Long", + "Longan", + "Longawa", + "Longerich", + "Longfellow", + "Longley", + "Longmire", + "Longo", + "Longtin", + "Longwood", + "Loni", + "Lonier", + "Lonna", + "Lonnard", + "Lonne", + "Lonni", + "Lonnie", + "Lonny", + "Lontson", + "Loomis", + "Loos", + "Lopes", + "Lopez", + "Lora", + "Lorain", + "Loraine", + "Loralee", + "Loralie", + "Loralyn", + "Loram", + "Lorant", + "Lord", + "Lordan", + "Loredana", + "Loredo", + "Loree", + "Loreen", + "Lorelei", + "Lorelie", + "Lorelle", + "Loren", + "Lorena", + "Lorene", + "Lorens", + "Lorenz", + "Lorenza", + "Lorenzana", + "Lorenzo", + "Loresz", + "Loretta", + "Lorette", + "Lori", + "Loria", + "Lorianna", + "Lorianne", + "Lorie", + "Lorien", + "Lorilee", + "Lorilyn", + "Lorimer", + "Lorin", + "Lorinda", + "Lorine", + "Loriner", + "Loring", + "Loris", + "Lorita", + "Lorn", + "Lorna", + "Lorne", + "Lorola", + "Lorolla", + "Lorollas", + "Lorou", + "Lorraine", + "Lorrayne", + "Lorri", + "Lorrie", + "Lorrimer", + "Lorrimor", + "Lorrin", + "Lorry", + "Lorsung", + "Lorusso", + "Lory", + "Lose", + "Loseff", + "Loss", + "Lossa", + "Losse", + "Lot", + "Lothair", + "Lothaire", + "Lothar", + "Lothario", + "Lotson", + "Lotta", + "Lotte", + "Lotti", + "Lottie", + "Lotty", + "Lotus", + "Lotz", + "Lou", + "Louanna", + "Louanne", + "Louella", + "Lough", + "Lougheed", + "Loughlin", + "Louie", + "Louis", + "Louisa", + "Louise", + "Louisette", + "Louls", + "Lounge", + "Lourdes", + "Lourie", + "Louth", + "Loutitia", + "Loux", + "Lovash", + "Lovato", + "Love", + "Lovel", + "Lovell", + "Loveridge", + "Lovering", + "Lovett", + "Lovich", + "Lovmilla", + "Low", + "Lowe", + "Lowell", + "Lowenstein", + "Lowenstern", + "Lower", + "Lowery", + "Lowis", + "Lowndes", + "Lowney", + "Lowrance", + "Lowrie", + "Lowry", + "Lowson", + "Loy", + "Loyce", + "Loydie", + "Lozano", + "Lozar", + "Lu", + "Luana", + "Luane", + "Luann", + "Luanne", + "Luanni", + "Luba", + "Lubba", + "Lubbi", + "Lubbock", + "Lubeck", + "Luben", + "Lubet", + "Lubin", + "Lubow", + "Luby", + "Luca", + "Lucais", + "Lucania", + "Lucas", + "Lucchesi", + "Luce", + "Lucey", + "Lucho", + "Luci", + "Lucia", + "Lucian", + "Luciana", + "Luciano", + "Lucias", + "Lucic", + "Lucie", + "Lucien", + "Lucienne", + "Lucier", + "Lucila", + "Lucilia", + "Lucilla", + "Lucille", + "Lucina", + "Lucinda", + "Lucine", + "Lucio", + "Lucita", + "Lucius", + "Luckett", + "Luckin", + "Lucky", + "Lucrece", + "Lucretia", + "Lucy", + "Lud", + "Ludeman", + "Ludewig", + "Ludie", + "Ludlew", + "Ludlow", + "Ludly", + "Ludmilla", + "Ludovick", + "Ludovico", + "Ludovika", + "Ludvig", + "Ludwig", + "Ludwigg", + "Ludwog", + "Luebke", + "Luedtke", + "Luehrmann", + "Luella", + "Luelle", + "Lugar", + "Lugo", + "Luhe", + "Luhey", + "Luht", + "Luigi", + "Luigino", + "Luing", + "Luis", + "Luisa", + "Luise", + "Luiza", + "Lukas", + "Lukash", + "Lukasz", + "Luke", + "Lukey", + "Lukin", + "Lula", + "Lulita", + "Lull", + "Lulu", + "Lumbard", + "Lumbye", + "Lumpkin", + "Luna", + "Lund", + "Lundberg", + "Lundeen", + "Lundell", + "Lundgren", + "Lundin", + "Lundquist", + "Lundt", + "Lune", + "Lunetta", + "Lunette", + "Lunn", + "Lunna", + "Lunneta", + "Lunnete", + "Lunseth", + "Lunsford", + "Lunt", + "Luo", + "Lupe", + "Lupee", + "Lupien", + "Lupita", + "Lura", + "Lurette", + "Lurie", + "Lurleen", + "Lurlene", + "Lurline", + "Lusa", + "Lussi", + "Lussier", + "Lust", + "Lustick", + "Lustig", + "Lusty", + "Lutero", + "Luthanen", + "Luther", + "Luttrell", + "Luwana", + "Lux", + "Luz", + "Luzader", + "Ly", + "Lyall", + "Lyckman", + "Lyda", + "Lydell", + "Lydia", + "Lydie", + "Lydon", + "Lyell", + "Lyford", + "Lyle", + "Lyman", + "Lymann", + "Lymn", + "Lyn", + "Lynch", + "Lynd", + "Lynda", + "Lynde", + "Lyndel", + "Lyndell", + "Lynden", + "Lyndes", + "Lyndon", + "Lyndsay", + "Lyndsey", + "Lyndsie", + "Lyndy", + "Lynea", + "Lynelle", + "Lynett", + "Lynette", + "Lynn", + "Lynna", + "Lynne", + "Lynnea", + "Lynnell", + "Lynnelle", + "Lynnet", + "Lynnett", + "Lynnette", + "Lynnworth", + "Lyns", + "Lynsey", + "Lynus", + "Lyon", + "Lyons", + "Lyontine", + "Lyris", + "Lysander", + "Lyssa", + "Lytle", + "Lytton", + "Lyudmila", + "Ma", + "Maag", + "Mab", + "Mabel", + "Mabelle", + "Mable", + "Mac", + "MacCarthy", + "MacDermot", + "MacDonald", + "MacDonell", + "MacDougall", + "MacEgan", + "MacFadyn", + "MacFarlane", + "MacGregor", + "MacGuiness", + "MacIlroy", + "MacIntosh", + "MacIntyre", + "MacKay", + "MacKenzie", + "MacLaine", + "MacLay", + "MacLean", + "MacLeod", + "MacMahon", + "MacMillan", + "MacMullin", + "MacNair", + "MacNamara", + "MacPherson", + "MacRae", + "MacSwan", + "Macario", + "Maccarone", + "Mace", + "Macegan", + "Macey", + "Machos", + "Machute", + "Machutte", + "Mack", + "Mackenie", + "Mackenzie", + "Mackey", + "Mackie", + "Mackintosh", + "Mackler", + "Macknair", + "Mackoff", + "Macnair", + "Macomber", + "Macri", + "Macur", + "Macy", + "Mada", + "Madai", + "Madaih", + "Madalena", + "Madalyn", + "Madancy", + "Madaras", + "Maddalena", + "Madden", + "Maddeu", + "Maddi", + "Maddie", + "Maddis", + "Maddock", + "Maddocks", + "Maddox", + "Maddy", + "Madea", + "Madel", + "Madelaine", + "Madeleine", + "Madelena", + "Madelene", + "Madelin", + "Madelina", + "Madeline", + "Madella", + "Madelle", + "Madelon", + "Madelyn", + "Madge", + "Madi", + "Madian", + "Madid", + "Madigan", + "Madison", + "Madlen", + "Madlin", + "Madoc", + "Madonia", + "Madonna", + "Madora", + "Madox", + "Madra", + "Madriene", + "Madson", + "Mady", + "Mae", + "Maegan", + "Maeve", + "Mafala", + "Mafalda", + "Maffa", + "Maffei", + "Mag", + "Magan", + "Magas", + "Magavern", + "Magbie", + "Magda", + "Magdaia", + "Magdala", + "Magdalen", + "Magdalena", + "Magdalene", + "Magdau", + "Magee", + "Magel", + "Magen", + "Magena", + "Mages", + "Maggee", + "Maggi", + "Maggie", + "Maggio", + "Maggs", + "Maggy", + "Maghutte", + "Magill", + "Magna", + "Magner", + "Magnien", + "Magnolia", + "Magnum", + "Magnus", + "Magnuson", + "Magnusson", + "Magocsi", + "Magree", + "Maguire", + "Magulac", + "Mahala", + "Mahalia", + "Mahan", + "Mahau", + "Maher", + "Mahla", + "Mahmoud", + "Mahmud", + "Mahon", + "Mahoney", + "Maia", + "Maiah", + "Maibach", + "Maible", + "Maice", + "Maida", + "Maidel", + "Maidie", + "Maidy", + "Maier", + "Maiga", + "Maighdiln", + "Maighdlin", + "Mailand", + "Main", + "Mainis", + "Maiocco", + "Mair", + "Maire", + "Maise", + "Maisel", + "Maisey", + "Maisie", + "Maison", + "Maite", + "Maitilde", + "Maitland", + "Maitund", + "Maje", + "Majka", + "Major", + "Mak", + "Makell", + "Maker", + "Mal", + "Mala", + "Malachi", + "Malachy", + "Malamud", + "Malamut", + "Malan", + "Malanie", + "Malarkey", + "Malaspina", + "Malca", + "Malcah", + "Malchus", + "Malchy", + "Malcolm", + "Malcom", + "Malda", + "Maleeny", + "Malek", + "Maleki", + "Malena", + "Malet", + "Maletta", + "Mali", + "Malia", + "Malik", + "Malin", + "Malina", + "Malinda", + "Malinde", + "Malinin", + "Malinowski", + "Malissa", + "Malissia", + "Malita", + "Malka", + "Malkah", + "Malkin", + "Mall", + "Mallen", + "Maller", + "Malley", + "Mallin", + "Mallina", + "Mallis", + "Mallissa", + "Malloch", + "Mallon", + "Mallorie", + "Mallory", + "Malloy", + "Malo", + "Malone", + "Maloney", + "Malonis", + "Malony", + "Malorie", + "Malory", + "Maloy", + "Malti", + "Maltz", + "Maltzman", + "Malva", + "Malvia", + "Malvie", + "Malvin", + "Malvina", + "Malvino", + "Malynda", + "Mame", + "Mamie", + "Mamoun", + "Man", + "Manaker", + "Manara", + "Manard", + "Manchester", + "Mancino", + "Manda", + "Mandal", + "Mandel", + "Mandelbaum", + "Mandell", + "Mandeville", + "Mandi", + "Mandie", + "Mandle", + "Mandler", + "Mandy", + "Mandych", + "Manella", + "Manfred", + "Manheim", + "Mani", + "Manley", + "Manlove", + "Manly", + "Mann", + "Mannes", + "Mannie", + "Manning", + "Manno", + "Mannos", + "Mannuela", + "Manny", + "Mano", + "Manoff", + "Manolo", + "Manon", + "Manouch", + "Mansfield", + "Manson", + "Mansoor", + "Mansur", + "Manthei", + "Manton", + "Manuel", + "Manuela", + "Manus", + "Manvel", + "Manvell", + "Manvil", + "Manville", + "Manwell", + "Manya", + "Mapel", + "Mapes", + "Maples", + "Mar", + "Mara", + "Marabel", + "Marabelle", + "Marala", + "Marasco", + "Marashio", + "Marbut", + "Marc", + "Marceau", + "Marcel", + "Marcela", + "Marcelia", + "Marcell", + "Marcella", + "Marcelle", + "Marcellina", + "Marcelline", + "Marcello", + "Marcellus", + "Marcelo", + "March", + "Marchak", + "Marchal", + "Marchall", + "Marchelle", + "Marchese", + "Marci", + "Marcia", + "Marciano", + "Marcie", + "Marcile", + "Marcille", + "Marcin", + "Marco", + "Marcos", + "Marcoux", + "Marcus", + "Marcy", + "Marden", + "Marder", + "Marduk", + "Mareah", + "Marek", + "Marela", + "Mareld", + "Marelda", + "Marella", + "Marelya", + "Maren", + "Marena", + "Marentic", + "Maressa", + "Maretz", + "Marga", + "Margalit", + "Margalo", + "Margaret", + "Margareta", + "Margarete", + "Margaretha", + "Margarethe", + "Margaretta", + "Margarette", + "Margarida", + "Margarita", + "Margaux", + "Marge", + "Margeaux", + "Margery", + "Marget", + "Margette", + "Margetts", + "Margherita", + "Margi", + "Margie", + "Margit", + "Margo", + "Margot", + "Margret", + "Margreta", + "Marguerie", + "Marguerita", + "Marguerite", + "Margy", + "Mari", + "Maria", + "Mariam", + "Marian", + "Mariana", + "Mariand", + "Mariande", + "Mariandi", + "Mariann", + "Marianna", + "Marianne", + "Mariano", + "Maribel", + "Maribelle", + "Maribeth", + "Marice", + "Maridel", + "Marie", + "Marie-Ann", + "Marie-Jeanne", + "Marieann", + "Mariejeanne", + "Mariel", + "Mariele", + "Marielle", + "Mariellen", + "Marienthal", + "Marietta", + "Mariette", + "Marigold", + "Marigolda", + "Marigolde", + "Marijane", + "Marijn", + "Marijo", + "Marika", + "Mariken", + "Mariko", + "Maril", + "Marilee", + "Marilin", + "Marilla", + "Marillin", + "Marilou", + "Marilyn", + "Marin", + "Marina", + "Marinelli", + "Marinna", + "Marino", + "Mario", + "Marion", + "Mariquilla", + "Maris", + "Marisa", + "Mariska", + "Marissa", + "Marita", + "Maritsa", + "Marius", + "Mariya", + "Marj", + "Marja", + "Marjana", + "Marje", + "Marji", + "Marjie", + "Marjorie", + "Marjory", + "Marjy", + "Mark", + "Market", + "Marketa", + "Markland", + "Markman", + "Marko", + "Markos", + "Markowitz", + "Marks", + "Markson", + "Markus", + "Marl", + "Marla", + "Marlane", + "Marlea", + "Marleah", + "Marlee", + "Marleen", + "Marlen", + "Marlena", + "Marlene", + "Marler", + "Marlette", + "Marley", + "Marlie", + "Marlin", + "Marline", + "Marlo", + "Marlon", + "Marlow", + "Marlowe", + "Marlyn", + "Marmaduke", + "Marmawke", + "Marmion", + "Marna", + "Marne", + "Marney", + "Marni", + "Marnia", + "Marnie", + "Maro", + "Marola", + "Marolda", + "Maroney", + "Marou", + "Marozas", + "Marozik", + "Marpet", + "Marquardt", + "Marquet", + "Marquez", + "Marquis", + "Marquita", + "Marr", + "Marra", + "Marras", + "Marrilee", + "Marrin", + "Marriott", + "Marris", + "Marrissa", + "Marron", + "Mars", + "Marsden", + "Marsh", + "Marsha", + "Marshal", + "Marshall", + "Marsiella", + "Marsland", + "Marston", + "Mart", + "Marta", + "Martainn", + "Marte", + "Marteena", + "Martel", + "Martell", + "Martella", + "Martelle", + "Martelli", + "Marten", + "Martens", + "Martguerita", + "Martha", + "Marthe", + "Marthena", + "Marti", + "Martica", + "Martie", + "Martijn", + "Martin", + "Martina", + "Martine", + "Martineau", + "Martinelli", + "Martinez", + "Martinic", + "Martino", + "Martinsen", + "Martinson", + "Martita", + "Martres", + "Martsen", + "Marty", + "Martyn", + "Martynne", + "Martz", + "Marucci", + "Marutani", + "Marv", + "Marva", + "Marve", + "Marvel", + "Marvella", + "Marven", + "Marvin", + "Marwin", + "Marx", + "Mary", + "Marya", + "Maryann", + "Maryanna", + "Maryanne", + "Marybella", + "Marybelle", + "Marybeth", + "Maryellen", + "Maryjane", + "Maryjo", + "Maryl", + "Marylee", + "Marylin", + "Marylinda", + "Marylou", + "Maryly", + "Marylynne", + "Maryn", + "Maryrose", + "Marys", + "Marysa", + "Marzi", + "Mas", + "Masao", + "Mascia", + "Masera", + "Masha", + "Mashe", + "Mason", + "Masry", + "Massarelli", + "Massey", + "Massie", + "Massimiliano", + "Massimo", + "Massingill", + "Masson", + "Mast", + "Mastat", + "Masterson", + "Mastic", + "Mastrianni", + "Mat", + "Mata", + "Matazzoni", + "Matejka", + "Matelda", + "Mateo", + "Materi", + "Materse", + "Mateusz", + "Mateya", + "Mathe", + "Matheny", + "Mather", + "Matheson", + "Mathew", + "Mathews", + "Mathi", + "Mathia", + "Mathian", + "Mathias", + "Mathilda", + "Mathilde", + "Mathis", + "Mathre", + "Mathur", + "Matias", + "Matilda", + "Matilde", + "Matland", + "Matless", + "Matlick", + "Matrona", + "Matronna", + "Matt", + "Matta", + "Mattah", + "Matteo", + "Matthaeus", + "Matthaus", + "Matthei", + "Mattheus", + "Matthew", + "Matthews", + "Matthia", + "Matthias", + "Matthieu", + "Matthiew", + "Matthus", + "Matti", + "Mattias", + "Mattie", + "Mattland", + "Mattox", + "Mattson", + "Matty", + "Matusow", + "Mauceri", + "Mauchi", + "Maud", + "Maude", + "Maudie", + "Mauer", + "Mauldon", + "Maunsell", + "Maupin", + "Maura", + "Mauralia", + "Maure", + "Maureen", + "Maureene", + "Maurene", + "Maurer", + "Mauretta", + "Maurey", + "Mauri", + "Maurice", + "Mauricio", + "Maurie", + "Maurili", + "Maurilia", + "Maurilla", + "Maurine", + "Maurise", + "Maurita", + "Maurits", + "Maurizia", + "Maurizio", + "Mauro", + "Maurreen", + "Maury", + "Mauve", + "Mavilia", + "Mavis", + "Mavra", + "Max", + "Maxa", + "Maxama", + "Maxantia", + "Maxentia", + "Maxey", + "Maxfield", + "Maxi", + "Maxia", + "Maxie", + "Maxim", + "Maxima", + "Maximilian", + "Maximilianus", + "Maximilien", + "Maximo", + "Maxine", + "Maxma", + "Maxwell", + "Maxy", + "May", + "Maya", + "Maybelle", + "Mayberry", + "Mayce", + "Mayda", + "Maye", + "Mayeda", + "Mayer", + "Mayes", + "Mayfield", + "Mayhew", + "Mayman", + "Maynard", + "Mayne", + "Maynord", + "Mayor", + "Mays", + "Mayworm", + "Maze", + "Mazel", + "Maziar", + "Mazlack", + "Mazman", + "Mazonson", + "Mazur", + "Mazurek", + "McAdams", + "McAfee", + "McAllister", + "McArthur", + "McBride", + "McCafferty", + "McCahill", + "McCall", + "McCallion", + "McCallum", + "McCandless", + "McCartan", + "McCarthy", + "McCarty", + "McClain", + "McClary", + "McClees", + "McClelland", + "McClenaghan", + "McClenon", + "McClimans", + "McClish", + "McClure", + "McCollum", + "McComb", + "McConaghy", + "McConnell", + "McCord", + "McCormac", + "McCormick", + "McCourt", + "McCowyn", + "McCoy", + "McCready", + "McCreary", + "McCreery", + "McCulloch", + "McCullough", + "McCully", + "McCurdy", + "McCutcheon", + "McDade", + "McDermott", + "McDonald", + "McDougall", + "McDowell", + "McEvoy", + "McFadden", + "McFarland", + "McFerren", + "McGannon", + "McGaw", + "McGean", + "McGee", + "McGill", + "McGinnis", + "McGrath", + "McGraw", + "McGray", + "McGregor", + "McGrody", + "McGruter", + "McGuire", + "McGurn", + "McHail", + "McHale", + "McHenry", + "McHugh", + "McIlroy", + "McIntosh", + "McIntyre", + "McKale", + "McKay", + "McKee", + "McKenna", + "McKenzie", + "McKeon", + "McKinney", + "McKnight", + "McLain", + "McLaughlin", + "McLaurin", + "McLeod", + "McLeroy", + "McLoughlin", + "McLyman", + "McMahon", + "McMaster", + "McMath", + "McMillan", + "McMullan", + "McMurry", + "McNair", + "McNalley", + "McNally", + "McNamara", + "McNamee", + "McNeely", + "McNeil", + "McNelly", + "McNully", + "McNutt", + "McQuade", + "McQuillin", + "McQuoid", + "McRipley", + "McRoberts", + "McSpadden", + "McTyre", + "McWherter", + "McWilliams", + "Mead", + "Meade", + "Meador", + "Meadow", + "Meadows", + "Meagan", + "Meaghan", + "Meagher", + "Meakem", + "Means", + "Meara", + "Meares", + "Mears", + "Meave", + "Mechelle", + "Mechling", + "Mecke", + "Meda", + "Medarda", + "Medardas", + "Medea", + "Medeah", + "Medin", + "Medina", + "Medlin", + "Medor", + "Medora", + "Medorra", + "Medovich", + "Medrek", + "Medwin", + "Meece", + "Meehan", + "Meek", + "Meeker", + "Meeks", + "Meenen", + "Meg", + "Megan", + "Megargee", + "Megdal", + "Megen", + "Meggi", + "Meggie", + "Meggs", + "Meggy", + "Meghan", + "Meghann", + "Mehala", + "Mehalek", + "Mehalick", + "Mehetabel", + "Mehitable", + "Mehta", + "Mei", + "Meibers", + "Meier", + "Meijer", + "Meilen", + "Meill", + "Meingolda", + "Meingoldas", + "Meir", + "Meisel", + "Meit", + "Mel", + "Mela", + "Melamed", + "Melamie", + "Melan", + "Melania", + "Melanie", + "Melantha", + "Melany", + "Melar", + "Melba", + "Melborn", + "Melbourne", + "Melburn", + "Melcher", + "Melda", + "Meldoh", + "Meldon", + "Melena", + "Melentha", + "Melesa", + "Melessa", + "Meletius", + "Melgar", + "Meli", + "Melia", + "Melicent", + "Melina", + "Melinda", + "Melinde", + "Melisa", + "Melisande", + "Melisandra", + "Melise", + "Melisenda", + "Melisent", + "Melissa", + "Melisse", + "Melita", + "Melitta", + "Mell", + "Mella", + "Mellar", + "Mellen", + "Melleta", + "Mellette", + "Melli", + "Mellicent", + "Mellie", + "Mellins", + "Mellisa", + "Mellisent", + "Mellitz", + "Mellman", + "Mello", + "Melloney", + "Melly", + "Melmon", + "Melnick", + "Melodee", + "Melodie", + "Melody", + "Melone", + "Melonie", + "Melony", + "Melosa", + "Melquist", + "Melton", + "Melva", + "Melvena", + "Melville", + "Melvin", + "Melvina", + "Melvyn", + "Memberg", + "Memory", + "Mena", + "Menard", + "Menashem", + "Mencher", + "Mendel", + "Mendelsohn", + "Mendelson", + "Mendes", + "Mendez", + "Mendie", + "Mendive", + "Mendoza", + "Mendy", + "Meneau", + "Menedez", + "Menell", + "Menendez", + "Meng", + "Menides", + "Menis", + "Menken", + "Menon", + "Mensch", + "Menzies", + "Mera", + "Meraree", + "Merari", + "Meras", + "Merat", + "Merc", + "Mercado", + "Merce", + "Mercedes", + "Merceer", + "Mercer", + "Merchant", + "Merci", + "Mercie", + "Mercier", + "Mercola", + "Mercorr", + "Mercuri", + "Mercy", + "Merdith", + "Meredeth", + "Meredi", + "Meredith", + "Meredithe", + "Merell", + "Merete", + "Meri", + "Meridel", + "Merideth", + "Meridith", + "Meriel", + "Merilee", + "Merill", + "Merilyn", + "Meris", + "Merissa", + "Merkle", + "Merkley", + "Merl", + "Merla", + "Merle", + "Merlin", + "Merlina", + "Merline", + "Merna", + "Merola", + "Merow", + "Merralee", + "Merras", + "Merrel", + "Merrell", + "Merri", + "Merriam", + "Merrick", + "Merridie", + "Merrie", + "Merrielle", + "Merril", + "Merrile", + "Merrilee", + "Merrili", + "Merrill", + "Merrily", + "Merriman", + "Merriott", + "Merritt", + "Merrow", + "Merry", + "Mersey", + "Mert", + "Merta", + "Merth", + "Merton", + "Merv", + "Mervin", + "Merwin", + "Merwyn", + "Meryl", + "Mesics", + "Messere", + "Messing", + "Meta", + "Metabel", + "Metcalf", + "Meter", + "Methuselah", + "Metsky", + "Mettah", + "Metts", + "Metzgar", + "Metzger", + "Meunier", + "Meurer", + "Meuse", + "Meuser", + "Meyer", + "Meyeroff", + "Meyers", + "Mezoff", + "Mia", + "Mic", + "Micaela", + "Micah", + "Micco", + "Mich", + "Michael", + "Michaela", + "Michaele", + "Michaelina", + "Michaeline", + "Michaella", + "Michaeu", + "Michail", + "Michal", + "Michale", + "Michaud", + "Miche", + "Micheal", + "Micheil", + "Michel", + "Michele", + "Michelina", + "Micheline", + "Michell", + "Michella", + "Michelle", + "Michelsen", + "Michey", + "Michi", + "Michigan", + "Michiko", + "Michon", + "Mick", + "Mickelson", + "Mickey", + "Micki", + "Mickie", + "Micky", + "Micro", + "Miculek", + "Midas", + "Middendorf", + "Middle", + "Middlesworth", + "Middleton", + "Mide", + "Midge", + "Midian", + "Midis", + "Mientao", + "Miett", + "Migeon", + "Mighell", + "Mignon", + "Mignonne", + "Miguel", + "Miguela", + "Miguelita", + "Mihalco", + "Mihe", + "Mika", + "Mikael", + "Mikaela", + "Mikal", + "Mike", + "Mikel", + "Mikes", + "Mikey", + "Miki", + "Mikihisa", + "Mikiso", + "Mikkanen", + "Mikkel", + "Miko", + "Mikol", + "Miksen", + "Mil", + "Mila", + "Milan", + "Milano", + "Milburn", + "Milburr", + "Milburt", + "Milda", + "Milde", + "Mildred", + "Mildrid", + "Mile", + "Milena", + "Miles", + "Milewski", + "Milford", + "Milicent", + "Milinda", + "Milissa", + "Milissent", + "Milka", + "Milks", + "Mill", + "Milla", + "Millan", + "Millar", + "Millard", + "Millburn", + "Millda", + "Miller", + "Millford", + "Millham", + "Millhon", + "Milli", + "Millian", + "Millicent", + "Millie", + "Millisent", + "Millman", + "Mills", + "Millur", + "Millwater", + "Milly", + "Milman", + "Milo", + "Milon", + "Milone", + "Milore", + "Milson", + "Milstone", + "Milt", + "Miltie", + "Milton", + "Milty", + "Milurd", + "Milzie", + "Mima", + "Mimi", + "Min", + "Mina", + "Minabe", + "Minardi", + "Minda", + "Mindi", + "Mindy", + "Miner", + "Minerva", + "Mines", + "Minetta", + "Minette", + "Ming", + "Mingche", + "Mini", + "Minica", + "Minier", + "Minna", + "Minnaminnie", + "Minne", + "Minni", + "Minnie", + "Minnnie", + "Minny", + "Minor", + "Minoru", + "Minsk", + "Minta", + "Minton", + "Mintun", + "Mintz", + "Miof Mela", + "Miquela", + "Mir", + "Mira", + "Mirabel", + "Mirabella", + "Mirabelle", + "Miran", + "Miranda", + "Mireielle", + "Mireille", + "Mirella", + "Mirelle", + "Miriam", + "Mirielle", + "Mirilla", + "Mirisola", + "Mirna", + "Mirth", + "Miru", + "Mischa", + "Misha", + "Mishaan", + "Missi", + "Missie", + "Missy", + "Misti", + "Mistrot", + "Misty", + "Mita", + "Mitch", + "Mitchael", + "Mitchel", + "Mitchell", + "Mitchiner", + "Mitinger", + "Mitman", + "Mitran", + "Mittel", + "Mitzi", + "Mitzie", + "Mitzl", + "Miun", + "Mixie", + "Miyasawa", + "Mizuki", + "Mlawsky", + "Mllly", + "Moazami", + "Moberg", + "Mobley", + "Mochun", + "Mode", + "Modern", + "Modesta", + "Modeste", + "Modestia", + "Modestine", + "Modesty", + "Modie", + "Modla", + "Moe", + "Moersch", + "Moffat", + "Moffit", + "Moffitt", + "Mogerly", + "Moguel", + "Mohamed", + "Mohammad", + "Mohammed", + "Mohandas", + "Mohandis", + "Mohl", + "Mohn", + "Mohr", + "Mohsen", + "Mohun", + "Moia", + "Moina", + "Moir", + "Moira", + "Moise", + "Moises", + "Moishe", + "Moitoso", + "Mojgan", + "Mok", + "Mokas", + "Molini", + "Moll", + "Mollee", + "Molli", + "Mollie", + "Molloy", + "Molly", + "Molton", + "Mommy", + "Mona", + "Monaco", + "Monafo", + "Monagan", + "Monah", + "Monahan", + "Monahon", + "Monarski", + "Moncear", + "Mond", + "Monda", + "Moneta", + "Monetta", + "Mongeau", + "Monia", + "Monica", + "Monie", + "Monika", + "Monique", + "Monjan", + "Monjo", + "Monk", + "Monney", + "Monreal", + "Monro", + "Monroe", + "Monroy", + "Monson", + "Monsour", + "Mont", + "Montagna", + "Montagu", + "Montague", + "Montana", + "Montanez", + "Montano", + "Monte", + "Monteith", + "Monteria", + "Montford", + "Montfort", + "Montgomery", + "Monti", + "Monto", + "Monty", + "Moody", + "Mook", + "Moon", + "Mooney", + "Moonier", + "Moor", + "Moore", + "Moorefield", + "Moorish", + "Mor", + "Mora", + "Moran", + "Mord", + "Mordecai", + "Mordy", + "Moreen", + "Morehouse", + "Morel", + "Moreland", + "Morell", + "Morena", + "Moreno", + "Morentz", + "Moreta", + "Moretta", + "Morette", + "Moreville", + "Morey", + "Morez", + "Morgan", + "Morgana", + "Morganica", + "Morganne", + "Morganstein", + "Morgen", + "Morgenthaler", + "Morgun", + "Mori", + "Moria", + "Moriah", + "Moriarty", + "Morice", + "Morie", + "Morissa", + "Morita", + "Moritz", + "Moriyama", + "Morlee", + "Morley", + "Morly", + "Morna", + "Morocco", + "Morra", + "Morrell", + "Morrie", + "Morril", + "Morrill", + "Morris", + "Morrison", + "Morrissey", + "Morry", + "Morse", + "Mort", + "Morten", + "Mortensen", + "Mortie", + "Mortimer", + "Morton", + "Morty", + "Morven", + "Morville", + "Morvin", + "Mosa", + "Mosby", + "Moscow", + "Mose", + "Moseley", + "Moselle", + "Mosenthal", + "Moser", + "Mosera", + "Moses", + "Moshe", + "Moshell", + "Mosier", + "Mosira", + "Moskow", + "Mosley", + "Mosora", + "Mosra", + "Moss", + "Mossberg", + "Mossman", + "Most", + "Motch", + "Moth", + "Mott", + "Motteo", + "Mou", + "Moulden", + "Mouldon", + "Moule", + "Moulton", + "Mount", + "Mountford", + "Mountfort", + "Mourant", + "Moureaux", + "Mowbray", + "Moya", + "Moyer", + "Moyers", + "Moyna", + "Moynahan", + "Moyra", + "Mozart", + "Mozelle", + "Mozes", + "Mozza", + "Mraz", + "Mroz", + "Mueller", + "Muffin", + "Mufi", + "Mufinella", + "Muhammad", + "Muir", + "Muire", + "Muirhead", + "Mukerji", + "Mukul", + "Mukund", + "Mulcahy", + "Mulderig", + "Muldon", + "Mulford", + "Mullane", + "Mullen", + "Muller", + "Mulligan", + "Mullins", + "Mulloy", + "Mulry", + "Mulvihill", + "Mumford", + "Mun", + "Muna", + "Munafo", + "Muncey", + "Mundford", + "Mundt", + "Mundy", + "Munford", + "Mungo", + "Mungovan", + "Munmro", + "Munn", + "Munniks", + "Munro", + "Munroe", + "Muns", + "Munsey", + "Munshi", + "Munson", + "Munster", + "Munt", + "Mur", + "Murage", + "Muraida", + "Murat", + "Murdocca", + "Murdoch", + "Murdock", + "Mureil", + "Muriah", + "Murial", + "Muriel", + "Murielle", + "Murphy", + "Murrah", + "Murray", + "Murrell", + "Murry", + "Murtagh", + "Murtha", + "Murton", + "Murvyn", + "Musa", + "Muscolo", + "Musetta", + "Musette", + "Mushro", + "Muslim", + "Musser", + "Mussman", + "Mutz", + "My", + "Mya", + "Myca", + "Mycah", + "Mychael", + "Mychal", + "Myer", + "Myers", + "Myke", + "Mylan", + "Mylander", + "Myles", + "Mylo", + "Mylor", + "Myna", + "Myo", + "Myra", + "Myrah", + "Myranda", + "Myriam", + "Myrilla", + "Myrle", + "Myrlene", + "Myrna", + "Myron", + "Myrt", + "Myrta", + "Myrtia", + "Myrtice", + "Myrtie", + "Myrtle", + "Myrvyn", + "Myrwyn", + "Na", + "Naam", + "Naaman", + "Naamana", + "Naamann", + "Naara", + "Naarah", + "Naashom", + "Nabal", + "Nabala", + "Nabalas", + "Nabila", + "Nace", + "Nachison", + "Nada", + "Nadab", + "Nadaba", + "Nadabas", + "Nadabb", + "Nadabus", + "Nadaha", + "Nadbus", + "Nadda", + "Nadean", + "Nadeau", + "Nadeen", + "Nader", + "Nadia", + "Nadine", + "Nadiya", + "Nadler", + "Nador", + "Nady", + "Nadya", + "Nafis", + "Naga", + "Nagel", + "Nagey", + "Nagle", + "Nagy", + "Nahama", + "Nahamas", + "Nahshon", + "Nahshu", + "Nahshun", + "Nahshunn", + "Nahtanha", + "Nahum", + "Naiditch", + "Naima", + "Naji", + "Nakada", + "Nakashima", + "Nakasuji", + "Nalani", + "Nalda", + "Naldo", + "Nalepka", + "Nally", + "Nalor", + "Nam", + "Naman", + "Namara", + "Names", + "Nan", + "Nana", + "Nananne", + "Nance", + "Nancee", + "Nancey", + "Nanci", + "Nancie", + "Nancy", + "Nandor", + "Nanete", + "Nanette", + "Nani", + "Nanice", + "Nanine", + "Nanji", + "Nannette", + "Nanni", + "Nannie", + "Nanny", + "Nanon", + "Naoma", + "Naomi", + "Naor", + "Nap", + "Napier", + "Naples", + "Napoleon", + "Nappie", + "Nappy", + "Naquin", + "Nara", + "Narah", + "Narayan", + "Narcho", + "Narcis", + "Narcissus", + "Narda", + "Naresh", + "Nari", + "Nariko", + "Narine", + "Narra", + "Narton", + "Nary", + "Nash", + "Nashbar", + "Nashner", + "Nasho", + "Nashom", + "Nashoma", + "Nasia", + "Nason", + "Nassi", + "Nassir", + "Nastassia", + "Nasya", + "Nat", + "Nata", + "Natal", + "Natala", + "Natale", + "Natalee", + "Natalia", + "Natalie", + "Natalina", + "Nataline", + "Natalya", + "Nataniel", + "Natascha", + "Natasha", + "Natassia", + "Nate", + "Natelson", + "Nath", + "Nathalia", + "Nathalie", + "Nathan", + "Nathanael", + "Nathanial", + "Nathaniel", + "Nathanil", + "Nathanson", + "Natica", + "Natie", + "Natiha", + "Natika", + "Nations", + "Natividad", + "Natka", + "Nattie", + "Natty", + "Nava", + "Navada", + "Naval", + "Navarro", + "Nawrocki", + "Nay", + "Naylor", + "Nazar", + "Nazario", + "Nazarius", + "Nazler", + "Nea", + "Neal", + "Neala", + "Nealah", + "Neale", + "Nealey", + "Neall", + "Nealon", + "Nealson", + "Nealy", + "Neau", + "Ned", + "Neda", + "Nedda", + "Neddie", + "Neddra", + "Neddy", + "Nedi", + "Nedra", + "Nedrah", + "Nedrud", + "Nedry", + "Nee", + "Neel", + "Neela", + "Neelon", + "Neely", + "Neeoma", + "Nefen", + "Neff", + "Negris", + "Nehemiah", + "Neibart", + "Neidhardt", + "Neil", + "Neila", + "Neile", + "Neill", + "Neilla", + "Neille", + "Neils", + "Neilson", + "Neiman", + "Neisa", + "Nel", + "Nela", + "Nelan", + "Nelda", + "Nelia", + "Nelie", + "Nell", + "Nella", + "Nellda", + "Nelle", + "Nelli", + "Nellie", + "Nellir", + "Nelly", + "Nelrsa", + "Nels", + "Nelsen", + "Nelson", + "Nema", + "Nemhauser", + "Nena", + "Nenney", + "Neo", + "Neom", + "Neoma", + "Neomah", + "Neona", + "Nepean", + "Nepil", + "Nereen", + "Nereids", + "Nereus", + "Neri", + "Nerin", + "Nerine", + "Nerissa", + "Nerita", + "Nerland", + "Nero", + "Neron", + "Nert", + "Nerta", + "Nerte", + "Nerti", + "Nertie", + "Nerty", + "Nesbitt", + "Nesline", + "Neslund", + "Ness", + "Nessa", + "Nessi", + "Nessie", + "Nessim", + "Nessy", + "Nesta", + "Nester", + "Nesto", + "Nestor", + "Nett", + "Netta", + "Nette", + "Netti", + "Nettie", + "Nettle", + "Netty", + "Neu", + "Neuberger", + "Neuburger", + "Neufer", + "Neukam", + "Neumann", + "Neumark", + "Neumeyer", + "Neurath", + "Nev", + "Neva", + "Nevada", + "Nevai", + "Neve", + "Neveda", + "Nevil", + "Nevile", + "Neville", + "Nevin", + "Nevins", + "Nevlin", + "Nevsa", + "New", + "Newberry", + "Newbill", + "Newbold", + "Newby", + "Newcomb", + "Newcomer", + "Newel", + "Newell", + "Newfeld", + "Newhall", + "Newkirk", + "Newlin", + "Newman", + "Newmann", + "Newmark", + "Newsom", + "Newton", + "Neysa", + "Ng", + "Ngo", + "Nguyen", + "Niabi", + "Nial", + "Niall", + "Nibbs", + "Nic", + "Nica", + "Niccolo", + "Nich", + "Nichani", + "Nichol", + "Nichola", + "Nicholas", + "Nichole", + "Nicholl", + "Nicholle", + "Nichols", + "Nicholson", + "Nichy", + "Nick", + "Nickelsen", + "Nickerson", + "Nickey", + "Nicki", + "Nickie", + "Nickles", + "Nicko", + "Nickola", + "Nickolai", + "Nickolas", + "Nickolaus", + "Nicks", + "Nicky", + "Nico", + "Nicodemus", + "Nicol", + "Nicola", + "Nicolai", + "Nicolais", + "Nicolas", + "Nicolau", + "Nicole", + "Nicolea", + "Nicolella", + "Nicolette", + "Nicoli", + "Nicolina", + "Nicoline", + "Nicolis", + "Nicolle", + "Nidia", + "Nidorf", + "Nieberg", + "Niehaus", + "Niel", + "Niela", + "Niels", + "Nielsen", + "Nielson", + "Nierman", + "Nies", + "Nievelt", + "Nigel", + "Nightingale", + "Nihhi", + "Nihi", + "Nika", + "Nikaniki", + "Nike", + "Niki", + "Nikita", + "Nikki", + "Nikkie", + "Niklaus", + "Niko", + "Nikola", + "Nikolai", + "Nikolaos", + "Nikolas", + "Nikolaus", + "Nikoletta", + "Nikolia", + "Nikolos", + "Nikos", + "Nil", + "Nila", + "Nile", + "Niles", + "Nilla", + "Nils", + "Nilson", + "Nimesh", + "Nimocks", + "Nims", + "Nina", + "Nine", + "Ninetta", + "Ninette", + "Ninnetta", + "Ninnette", + "Nino", + "Ninon", + "Ninos", + "Niobe", + "Nipha", + "Niple", + "Nisa", + "Nisbet", + "Nisen", + "Nishi", + "Nissa", + "Nisse", + "Nissensohn", + "Nissie", + "Nissy", + "Nita", + "Nitin", + "Nitz", + "Nitza", + "Niu", + "Niven", + "Nixie", + "Nixon", + "Noach", + "Noah", + "Noak", + "Noakes", + "Noam", + "Noami", + "Nobe", + "Nobel", + "Nobell", + "Nobie", + "Nobile", + "Noble", + "Noby", + "Nochur", + "Nodab", + "Nodababus", + "Nodarse", + "Noe", + "Noel", + "Noelani", + "Noell", + "Noella", + "Noelle", + "Noellyn", + "Noelyn", + "Noemi", + "Nogas", + "Noguchi", + "Nola", + "Nolan", + "Nolana", + "Noland", + "Nole", + "Noleta", + "Noletta", + "Noli", + "Nolie", + "Nolita", + "Nolitta", + "Noll", + "Nollie", + "Nolly", + "Nolte", + "Noma", + "Noman", + "Nomi", + "Nona", + "Nonah", + "Noni", + "Nonie", + "Nonna", + "Nonnah", + "Noonan", + "Noonberg", + "Nor", + "Nora", + "Norah", + "Norbert", + "Norbie", + "Norby", + "Nord", + "Nordgren", + "Nordin", + "Nordine", + "Nore", + "Norean", + "Noreen", + "Norene", + "Norford", + "Norina", + "Norine", + "Norita", + "Nork", + "Norling", + "Norm", + "Norma", + "Normalie", + "Norman", + "Normand", + "Normandy", + "Normi", + "Normie", + "Normy", + "Norri", + "Norrie", + "Norris", + "Norrv", + "Norry", + "Norse", + "North", + "Northey", + "Northington", + "Northrop", + "Northrup", + "Northway", + "Norton", + "Norty", + "Norval", + "Norvall", + "Norvan", + "Norvell", + "Norven", + "Norvil", + "Norvin", + "Norvol", + "Norvun", + "Norward", + "Norwood", + "Norword", + "Nottage", + "Nova", + "Novah", + "Novak", + "Novelia", + "Novello", + "Novia", + "Novick", + "Novikoff", + "Nowell", + "Noyes", + "Nozicka", + "Nudd", + "Nugent", + "Nuli", + "Nunci", + "Nuncia", + "Nunciata", + "Nunes", + "Nunnery", + "Nur", + "Nuri", + "Nuriel", + "Nuris", + "Nurse", + "Nussbaum", + "Nutter", + "Nuzzi", + "Nyberg", + "Nydia", + "Nye", + "Nyhagen", + "Nysa", + "Nyssa", + "O'Hara", + "O'Neill", + "Oak", + "Oakes", + "Oakie", + "Oakleil", + "Oakley", + "Oakman", + "Oaks", + "Oates", + "Oatis", + "Oba", + "Obadiah", + "Obadias", + "Obala", + "Oballa", + "Obara", + "Obau", + "Obaza", + "Obbard", + "Obe", + "Obed", + "Obeded", + "Obediah", + "Obel", + "Obelia", + "Obellia", + "Obeng", + "Ober", + "Oberg", + "Oberheim", + "Oberon", + "Oberstone", + "Obidiah", + "Obie", + "Obla", + "Obola", + "Obrien", + "Oby", + "Oca", + "Ocana", + "Ochs", + "Ocker", + "Ocko", + "Oconnor", + "Octave", + "Octavia", + "Octavian", + "Octavie", + "Octavius", + "Octavla", + "Octavus", + "Odab", + "Odawa", + "Ode", + "Odeen", + "Odel", + "Odele", + "Odelet", + "Odelia", + "Odelinda", + "Odell", + "Odella", + "Odelle", + "Odericus", + "Odessa", + "Odetta", + "Odette", + "Odey", + "Odie", + "Odilia", + "Odille", + "Odilo", + "Odin", + "Odine", + "Odlo", + "Odo", + "Odom", + "Odoric", + "Odrick", + "Ody", + "Odysseus", + "Odyssey", + "Oech", + "Oeflein", + "Oehsen", + "Ofelia", + "Ofella", + "Offen", + "Ofilia", + "Ofori", + "Og", + "Ogata", + "Ogawa", + "Ogdan", + "Ogden", + "Ogdon", + "Ogg", + "Ogilvie", + "Ogilvy", + "Oglesby", + "Ogren", + "Ohara", + "Ohare", + "Ohaus", + "Ohl", + "Oilla", + "Oina", + "Oira", + "Okajima", + "Okechuku", + "Okubo", + "Okun", + "Okwu", + "Ola", + "Olaf", + "Olag", + "Olatha", + "Olathe", + "Olav", + "Olcott", + "Old", + "Older", + "Olds", + "Ole", + "Oleg", + "Olen", + "Olenka", + "Olenolin", + "Olenta", + "Oler", + "Oleta", + "Oletha", + "Olethea", + "Oletta", + "Olette", + "Olfe", + "Olga", + "Olia", + "Oliana", + "Olimpia", + "Olin", + "Olinde", + "Oliva", + "Olivann", + "Olive", + "Oliver", + "Olivero", + "Olivette", + "Olivia", + "Olivie", + "Olivier", + "Oliviero", + "Oliy", + "Ollayos", + "Olli", + "Ollie", + "Olly", + "Olmstead", + "Olmsted", + "Olnay", + "Olnee", + "Olnek", + "Olney", + "Olnton", + "Olodort", + "Olpe", + "Olsen", + "Olsewski", + "Olshausen", + "Olson", + "Olsson", + "Olva", + "Olvan", + "Olwen", + "Olwena", + "Oly", + "Olympe", + "Olympia", + "Olympias", + "Olympie", + "Olympium", + "Om", + "Oman", + "Omar", + "Omari", + "Omarr", + "Omer", + "Omero", + "Omidyar", + "Omland", + "Omor", + "Omora", + "Omura", + "On", + "Ona", + "Onder", + "Ondine", + "Ondrea", + "Ondrej", + "Oneal", + "Oneida", + "Oneil", + "Oneill", + "Onfre", + "Onfroi", + "Ong", + "Ongun", + "Oni", + "Onia", + "Onida", + "Oniskey", + "Onofredo", + "Onstad", + "Ontina", + "Ontine", + "Onyx", + "Oona", + "Opal", + "Opalina", + "Opaline", + "Ophelia", + "Ophelie", + "Oppen", + "Opportina", + "Opportuna", + "Ora", + "Orabel", + "Orabelle", + "Oralee", + "Oralia", + "Oralie", + "Oralla", + "Oralle", + "Oram", + "Oran", + "Orazio", + "Orbadiah", + "Orban", + "Ordway", + "Orel", + "Orelee", + "Orelia", + "Orelie", + "Orella", + "Orelle", + "Orelu", + "Oren", + "Orest", + "Oreste", + "Orestes", + "Orferd", + "Orfield", + "Orfinger", + "Orford", + "Orfurd", + "Orgel", + "Orgell", + "Ori", + "Oria", + "Orian", + "Oriana", + "Oriane", + "Orianna", + "Oribel", + "Oribella", + "Oribelle", + "Oriel", + "Orin", + "Oringa", + "Oringas", + "Oriole", + "Orion", + "Orit", + "Orji", + "Orlan", + "Orland", + "Orlando", + "Orlanta", + "Orlantha", + "Orlena", + "Orlene", + "Orlina", + "Orling", + "Orlosky", + "Orlov", + "Orly", + "Orman", + "Ormand", + "Orme", + "Ormiston", + "Ormond", + "Orms", + "Ormsby", + "Orna", + "Ornas", + "Ornie", + "Ornstead", + "Orola", + "Orose", + "Orozco", + "Orpah", + "Orpha", + "Orpheus", + "Orr", + "Orran", + "Orren", + "Orrin", + "Orsa", + "Orsay", + "Orsini", + "Orsino", + "Orsola", + "Orson", + "Orten", + "Ortensia", + "Orth", + "Orthman", + "Ortiz", + "Orton", + "Ortrud", + "Ortrude", + "Oruntha", + "Orv", + "Orva", + "Orvah", + "Orvan", + "Orvas", + "Orvie", + "Orvil", + "Orville", + "Orwin", + "Os", + "Osana", + "Osanna", + "Osber", + "Osbert", + "Osborn", + "Osborne", + "Osbourn", + "Osbourne", + "Oscar", + "Osei", + "Osgood", + "Osher", + "Oshinski", + "Osi", + "Osithe", + "Oskar", + "Osman", + "Osmen", + "Osmo", + "Osmond", + "Osmund", + "Osric", + "Osrick", + "Osrock", + "Ossie", + "Osswald", + "Ossy", + "Ostap", + "Oster", + "Osterhus", + "Ostler", + "Ostraw", + "Osugi", + "Oswal", + "Oswald", + "Oswell", + "Oswin", + "Osy", + "Osyth", + "Ot", + "Otero", + "Otes", + "Otha", + "Othe", + "Othelia", + "Othella", + "Othello", + "Other", + "Othilia", + "Othilie", + "Otho", + "Otila", + "Otilia", + "Otina", + "Otis", + "Ott", + "Ottavia", + "Otte", + "Otter", + "Otti", + "Ottie", + "Ottilie", + "Ottillia", + "Ottinger", + "Otto", + "Oulman", + "Outhe", + "Outlaw", + "Ovid", + "Ovida", + "Owades", + "Owain", + "Owen", + "Owena", + "Owens", + "Oxford", + "Oxley", + "Oys", + "Oz", + "Oza", + "Ozan", + "Ozen", + "Ozkum", + "Ozmo", + "Ozzie", + "Ozzy", + "O'Brien", + "O'Callaghan", + "O'Carroll", + "O'Connell", + "O'Conner", + "O'Connor", + "O'Dell", + "O'Doneven", + "O'Donnell", + "O'Donoghue", + "O'Donovan", + "O'Driscoll", + "O'Gowan", + "O'Grady", + "O'Hara", + "O'Kelly", + "O'Mahony", + "O'Malley", + "O'Meara", + "O'Neil", + "O'Neill", + "O'Reilly", + "O'Rourke", + "O'Shee", + "O'Toole", + "Paapanen", + "Pablo", + "Pace", + "Pacheco", + "Pachston", + "Pachton", + "Pacian", + "Pacien", + "Pacifa", + "Pacifica", + "Pacificas", + "Pacificia", + "Pack", + "Packer", + "Packston", + "Packton", + "Paco", + "Pacorro", + "Paddie", + "Paddy", + "Padegs", + "Paderna", + "Padget", + "Padgett", + "Padraic", + "Padraig", + "Padriac", + "Paff", + "Pagas", + "Page", + "Pages", + "Paget", + "Pahl", + "Paige", + "Paik", + "Pail", + "Pain", + "Paine", + "Painter", + "Palecek", + "Palermo", + "Palestine", + "Paley", + "Palgrave", + "Palila", + "Pall", + "Palla", + "Palladin", + "Pallas", + "Pallaten", + "Pallaton", + "Pallua", + "Palm", + "Palma", + "Palmer", + "Palmira", + "Palmore", + "Palocz", + "Paloma", + "Pals", + "Palua", + "Paluas", + "Palumbo", + "Pam", + "Pamela", + "Pamelina", + "Pamella", + "Pammi", + "Pammie", + "Pammy", + "Pampuch", + "Pan", + "Panaggio", + "Panayiotis", + "Panchito", + "Pancho", + "Pandich", + "Pandolfi", + "Pandora", + "Pang", + "Pangaro", + "Pani", + "Pansie", + "Pansir", + "Pansy", + "Panta", + "Panter", + "Panthea", + "Pantheas", + "Panther", + "Panthia", + "Pantia", + "Pantin", + "Paola", + "Paolina", + "Paolo", + "Papagena", + "Papageno", + "Pape", + "Papert", + "Papke", + "Papotto", + "Papp", + "Pappano", + "Pappas", + "Papst", + "Paquito", + "Par", + "Paradies", + "Parcel", + "Pardew", + "Pardner", + "Pardo", + "Pardoes", + "Pare", + "Parent", + "Paresh", + "Parette", + "Parfitt", + "Parhe", + "Parik", + "Paris", + "Parish", + "Park", + "Parke", + "Parker", + "Parks", + "Parlin", + "Parnas", + "Parnell", + "Parrie", + "Parris", + "Parrisch", + "Parrish", + "Parrnell", + "Parrott", + "Parry", + "Parsaye", + "Parshall", + "Parsifal", + "Parsons", + "Partan", + "Parthen", + "Parthena", + "Parthenia", + "Parthinia", + "Particia", + "Partridge", + "Paryavi", + "Pas", + "Pasadis", + "Pasahow", + "Pascal", + "Pascale", + "Pascasia", + "Pascha", + "Paschasia", + "Pascia", + "Pasco", + "Pascoe", + "Pasho", + "Pasia", + "Paske", + "Pasol", + "Pasquale", + "Pass", + "Past", + "Pastelki", + "Pat", + "Pate", + "Paten", + "Paterson", + "Pathe", + "Patience", + "Patin", + "Patman", + "Patnode", + "Paton", + "Patric", + "Patrica", + "Patrice", + "Patrich", + "Patricia", + "Patricio", + "Patrick", + "Patrizia", + "Patrizio", + "Patrizius", + "Patsis", + "Patsy", + "Patt", + "Pattani", + "Patten", + "Patterman", + "Patterson", + "Patti", + "Pattie", + "Pattin", + "Pattison", + "Patton", + "Patty", + "Paucker", + "Paugh", + "Pauiie", + "Paul", + "Paula", + "Paule", + "Pauletta", + "Paulette", + "Pauli", + "Paulie", + "Paulina", + "Pauline", + "Paulita", + "Paulo", + "Paulsen", + "Paulson", + "Pauly", + "Pauwles", + "Pavel", + "Paver", + "Pavia", + "Pavier", + "Pavior", + "Paviour", + "Pavkovic", + "Pavla", + "Pavlish", + "Pavlov", + "Pavyer", + "Pawsner", + "Pax", + "Paxon", + "Paxton", + "Paymar", + "Payne", + "Paynter", + "Payson", + "Payton", + "Paz", + "Paza", + "Pazia", + "Pazice", + "Pazit", + "Peace", + "Peacock", + "Peadar", + "Peale", + "Pearce", + "Pearl", + "Pearla", + "Pearle", + "Pearline", + "Pearlman", + "Pearlstein", + "Pearman", + "Pears", + "Pearse", + "Pearson", + "Pease", + "Peatroy", + "Pebrook", + "Peck", + "Peckham", + "Pedaiah", + "Pedaias", + "Peddada", + "Peder", + "Pedersen", + "Pederson", + "Pedrick", + "Pedro", + "Pedrotti", + "Pedroza", + "Peer", + "Peers", + "Peery", + "Peg", + "Pega", + "Pegasus", + "Pegeen", + "Pegg", + "Peggi", + "Peggie", + "Peggir", + "Peggy", + "Pegma", + "Peh", + "Peirce", + "Peirsen", + "Peisch", + "Pejsach", + "Pelag", + "Pelaga", + "Pelage", + "Pelagi", + "Pelagia", + "Pelagias", + "Pell", + "Pellegrini", + "Pellet", + "Pelletier", + "Pelligrini", + "Pellikka", + "Pelmas", + "Pelpel", + "Pelson", + "Peltier", + "Peltz", + "Pember", + "Pembroke", + "Pembrook", + "Pen", + "Pena", + "Pence", + "Pendergast", + "Pendleton", + "Penelopa", + "Penelope", + "Pengelly", + "Penhall", + "Penland", + "Penman", + "Penn", + "Pennebaker", + "Penney", + "Penni", + "Pennie", + "Pennington", + "Penny", + "Penoyer", + "Penrod", + "Penrose", + "Pentha", + "Penthea", + "Pentheam", + "Pentheas", + "Peonir", + "Peony", + "Peoples", + "Pepe", + "Peper", + "Pepi", + "Pepillo", + "Pepin", + "Pepita", + "Pepito", + "Peppard", + "Peppel", + "Pepper", + "Peppi", + "Peppie", + "Peppy", + "Per", + "Perce", + "Perceval", + "Percival", + "Percy", + "Perdita", + "Peregrine", + "Pergrim", + "Peri", + "Peria", + "Perice", + "Perkin", + "Perkins", + "Perkoff", + "Perl", + "Perla", + "Perle", + "Perlie", + "Perlis", + "Perlman", + "Perloff", + "Pernas", + "Pernell", + "Perni", + "Pernick", + "Pero", + "Perot", + "Perpetua", + "Perr", + "Perreault", + "Perren", + "Perretta", + "Perri", + "Perrie", + "Perrin", + "Perrine", + "Perrins", + "Perron", + "Perry", + "Persas", + "Perseus", + "Persian", + "Persis", + "Persons", + "Persse", + "Persson", + "Perusse", + "Perzan", + "Pesek", + "Peskoff", + "Pessa", + "Pestana", + "Pet", + "Peta", + "Pete", + "Peter", + "Peterec", + "Peterman", + "Peters", + "Petersen", + "Peterson", + "Peterus", + "Petes", + "Petey", + "Peti", + "Petie", + "Petigny", + "Petit", + "Petite", + "Petr", + "Petra", + "Petracca", + "Petras", + "Petrick", + "Petrie", + "Petrina", + "Petrine", + "Petromilli", + "Petronella", + "Petronia", + "Petronilla", + "Petronille", + "Petta", + "Pettifer", + "Pettiford", + "Pettit", + "Petty", + "Petua", + "Petula", + "Petulah", + "Petulia", + "Petunia", + "Petuu", + "Peugia", + "Peursem", + "Pevzner", + "Peyter", + "Peyton", + "Pfaff", + "Pfeffer", + "Pfeifer", + "Pfister", + "Pfosi", + "Phaedra", + "Phaidra", + "Phaih", + "Phail", + "Phalan", + "Pharaoh", + "Phare", + "Phares", + "Phebe", + "Phedra", + "Phelan", + "Phelgen", + "Phelgon", + "Phelia", + "Phelips", + "Phelps", + "Phemia", + "Phene", + "Pheni", + "Phenica", + "Phenice", + "Phi", + "Phia", + "Phil", + "Phila", + "Philan", + "Philana", + "Philander", + "Philbert", + "Philbin", + "Philbo", + "Philbrook", + "Philcox", + "Philemol", + "Philemon", + "Philender", + "Philina", + "Philine", + "Philip", + "Philipa", + "Philipines", + "Philipp", + "Philippa", + "Philippe", + "Philippine", + "Philipps", + "Philips", + "Philipson", + "Philis", + "Phillada", + "Phillane", + "Phillida", + "Phillie", + "Phillip", + "Phillipe", + "Phillipp", + "Phillips", + "Phillis", + "Philly", + "Philo", + "Philomena", + "Philoo", + "Philpot", + "Philps", + "Phina", + "Phineas", + "Phio", + "Phiona", + "Phionna", + "Phip", + "Phippen", + "Phipps", + "Phira", + "Phoebe", + "Phonsa", + "Photima", + "Photina", + "Phox", + "Phyl", + "Phylis", + "Phyllida", + "Phyllis", + "Phyllys", + "Phylys", + "Pia", + "Piane", + "Picardi", + "Picco", + "Pich", + "Pickar", + "Pickard", + "Pickens", + "Picker", + "Pickering", + "Pickett", + "Pickford", + "Piderit", + "Piefer", + "Piegari", + "Pier", + "Pierce", + "Pierette", + "Piero", + "Pierpont", + "Pierre", + "Pierrepont", + "Pierrette", + "Pierro", + "Piers", + "Pierson", + "Pieter", + "Pietje", + "Pietra", + "Pietrek", + "Pietro", + "Pigeon", + "Piggy", + "Pike", + "Pilar", + "Pilloff", + "Pillow", + "Pillsbury", + "Pimbley", + "Pincas", + "Pinchas", + "Pincince", + "Pinckney", + "Pincus", + "Pine", + "Pinebrook", + "Pineda", + "Pinelli", + "Pinette", + "Ping", + "Pinkerton", + "Pinkham", + "Pinsky", + "Pinter", + "Pinto", + "Pinzler", + "Piotr", + "Pip", + "Piper", + "Pippa", + "Pippas", + "Pippo", + "Pippy", + "Pirali", + "Pirbhai", + "Pirnot", + "Pironi", + "Pirozzo", + "Pirri", + "Pirzada", + "Pisano", + "Pisarik", + "Piscatelli", + "Piselli", + "Pish", + "Pitarys", + "Pitchford", + "Pitt", + "Pittel", + "Pittman", + "Pitts", + "Pitzer", + "Pius", + "Piwowar", + "Pizor", + "Placeeda", + "Placia", + "Placida", + "Placidia", + "Placido", + "Plafker", + "Plank", + "Plantagenet", + "Plante", + "Platas", + "Plate", + "Plath", + "Plato", + "Platon", + "Platt", + "Platto", + "Platus", + "Player", + "Pleasant", + "Pleione", + "Plerre", + "Pliam", + "Pliner", + "Pliske", + "Ploch", + "Ploss", + "Plossl", + "Plotkin", + "Plumbo", + "Plume", + "Plunkett", + "Plusch", + "Podvin", + "Pogue", + "Poirer", + "Pokorny", + "Pol", + "Polad", + "Polak", + "Poland", + "Polard", + "Polash", + "Poler", + "Poliard", + "Polik", + "Polinski", + "Polish", + "Politi", + "Polito", + "Polivy", + "Polk", + "Polky", + "Poll", + "Pollack", + "Pollak", + "Pollard", + "Pollerd", + "Pollie", + "Pollitt", + "Polloch", + "Pollock", + "Pollux", + "Polly", + "Pollyanna", + "Pomcroy", + "Pomeroy", + "Pomfret", + "Pomfrey", + "Pomona", + "Pompea", + "Pompei", + "Ponce", + "Pond", + "Pontias", + "Pontius", + "Ponton", + "Pontone", + "Pontus", + "Ponzo", + "Poock", + "Pooh", + "Pooi", + "Pool", + "Poole", + "Pooley", + "Poore", + "Pope", + "Popele", + "Popelka", + "Poppas", + "Popper", + "Poppo", + "Poppy", + "Porche", + "Porcia", + "Poree", + "Porett", + "Port", + "Porta", + "Porte", + "Porter", + "Portia", + "Portie", + "Portingale", + "Portland", + "Portugal", + "Portuna", + "Portwin", + "Portwine", + "Porty", + "Porush", + "Posehn", + "Posner", + "Possing", + "Post", + "Postman", + "Potash", + "Potter", + "Potts", + "Poucher", + "Poul", + "Poulter", + "Pouncey", + "Pournaras", + "Powder", + "Powe", + "Powel", + "Powell", + "Power", + "Powers", + "Pownall", + "Poyssick", + "Pozzy", + "Pradeep", + "Prader", + "Prady", + "Prager", + "Prakash", + "Prasad", + "Pratt", + "Pratte", + "Pravit", + "Prebo", + "Preciosa", + "Preiser", + "Prem", + "Premer", + "Pren", + "Prendergast", + "Prent", + "Prentice", + "Prentiss", + "Presber", + "Prescott", + "Presley", + "Press", + "Pressey", + "Pressman", + "Prestige", + "Preston", + "Pretrice", + "Preuss", + "Previdi", + "Prevot", + "Price", + "Prichard", + "Pricilla", + "Pride", + "Priebe", + "Priest", + "Priestley", + "Prima", + "Primalia", + "Primavera", + "Primaveras", + "Primaveria", + "Primo", + "Primrosa", + "Primrose", + "Prince", + "Princess", + "Prinz", + "Prior", + "Pris", + "Prisca", + "Priscella", + "Priscilla", + "Prisilla", + "Prissie", + "Prissy", + "Pritchard", + "Pritchett", + "Prober", + "Prochora", + "Prochoras", + "Procora", + "Procter", + "Procto", + "Proctor", + "Profant", + "Proffitt", + "Pronty", + "Pros", + "Prosper", + "Prospero", + "Prosperus", + "Prosser", + "Proud", + "Proudfoot", + "Proudlove", + "Proudman", + "Proulx", + "Prouty", + "Prowel", + "Pru", + "Pruchno", + "Prud", + "Prudence", + "Prudhoe", + "Prudi", + "Prudie", + "Prudy", + "Prue", + "Prunella", + "Prussian", + "Pruter", + "Pry", + "Pryce", + "Pryor", + "Psyche", + "Pubilis", + "Publea", + "Publia", + "Publias", + "Publius", + "Publus", + "Pucida", + "Pudendas", + "Pudens", + "Puduns", + "Puett", + "Pufahl", + "Puff", + "Pugh", + "Puglia", + "Puiia", + "Puklich", + "Pul", + "Pulcheria", + "Pulchi", + "Pulchia", + "Pulling", + "Pulsifer", + "Pump", + "Punak", + "Punke", + "Purcell", + "Purdum", + "Purdy", + "Puri", + "Purington", + "Puritan", + "Purity", + "Purpura", + "Purse", + "Purvis", + "Putnam", + "Putnem", + "Puto", + "Putscher", + "Puttergill", + "Py", + "Pyle", + "Pylle", + "Pyne", + "Pyotr", + "Pyszka", + "Pytlik", + "Quackenbush", + "Quar", + "Quarta", + "Quartana", + "Quartas", + "Quartet", + "Quartis", + "Quartus", + "Queen", + "Queena", + "Queenie", + "Quenby", + "Quenna", + "Quennie", + "Quent", + "Quentin", + "Queri", + "Querida", + "Queridas", + "Questa", + "Queston", + "Quick", + "Quickel", + "Quickman", + "Quigley", + "Quill", + "Quillan", + "Quillon", + "Quin", + "Quinby", + "Quince", + "Quincey", + "Quincy", + "Quinlan", + "Quinn", + "Quint", + "Quinta", + "Quintana", + "Quintessa", + "Quintie", + "Quintilla", + "Quintin", + "Quintina", + "Quinton", + "Quintus", + "Quirita", + "Quirk", + "Quita", + "Quiteri", + "Quiteria", + "Quiteris", + "Quitt", + "Qulllon", + "Raab", + "Raama", + "Raasch", + "Rab", + "Rabah", + "Rabassa", + "Rabbi", + "Rabelais", + "Rabi", + "Rabiah", + "Rabin", + "Rabjohn", + "Rabkin", + "Rabush", + "Race", + "Rachaba", + "Rachael", + "Rachel", + "Rachele", + "Rachelle", + "Racklin", + "Rad", + "Radack", + "Radborne", + "Radbourne", + "Radbun", + "Radburn", + "Radcliffe", + "Raddatz", + "Raddi", + "Raddie", + "Raddy", + "Radferd", + "Radford", + "Radie", + "Radke", + "Radley", + "Radloff", + "Radman", + "Radmen", + "Radmilla", + "Radu", + "Rae", + "Raeann", + "Raf", + "Rafa", + "Rafael", + "Rafaela", + "Rafaelia", + "Rafaelita", + "Rafaelle", + "Rafaellle", + "Rafaello", + "Rafaelof", + "Rafat", + "Rafe", + "Raff", + "Raffaello", + "Raffarty", + "Rafferty", + "Raffin", + "Raffo", + "Rafi", + "Rafiq", + "Rafter", + "Ragan", + "Ragen", + "Ragg", + "Ragland", + "Ragnar", + "Ragouzis", + "Ragucci", + "Rahal", + "Rahel", + "Rahm", + "Rahman", + "Rahmann", + "Rahr", + "Rai", + "Raila", + "Raimes", + "Raimondo", + "Raimund", + "Raimundo", + "Raina", + "Rainah", + "Raine", + "Rainer", + "Raines", + "Rainger", + "Rainie", + "Rains", + "Rainwater", + "Rajewski", + "Raji", + "Rajiv", + "Rakel", + "Rakia", + "Ralaigh", + "Raleigh", + "Ralf", + "Ralfston", + "Ralina", + "Ralleigh", + "Ralli", + "Ralph", + "Ralston", + "Ram", + "Rama", + "Ramah", + "Raman", + "Ramberg", + "Rambert", + "Rambort", + "Rambow", + "Ramburt", + "Rame", + "Ramey", + "Ramiah", + "Ramin", + "Ramon", + "Ramona", + "Ramonda", + "Ramos", + "Ramsay", + "Ramsdell", + "Ramsden", + "Ramses", + "Ramsey", + "Ramunni", + "Ran", + "Rana", + "Rance", + "Rancell", + "Ranchod", + "Rand", + "Randa", + "Randal", + "Randall", + "Randee", + "Randell", + "Randene", + "Randi", + "Randie", + "Randolf", + "Randolph", + "Randy", + "Ranee", + "Raney", + "Range", + "Rangel", + "Ranger", + "Rani", + "Rania", + "Ranice", + "Ranie", + "Ranique", + "Ranit", + "Ranita", + "Ranite", + "Ranitta", + "Ranjiv", + "Rankin", + "Rann", + "Ranna", + "Ransell", + "Ransom", + "Ransome", + "Ranson", + "Ranzini", + "Rao", + "Raouf", + "Raoul", + "Rap", + "Rape", + "Raphael", + "Raphaela", + "Rapp", + "Raquel", + "Raquela", + "Ras", + "Raseda", + "Raseta", + "Rashida", + "Rashidi", + "Rasia", + "Rask", + "Raskin", + "Raskind", + "Rasla", + "Rasmussen", + "Rastus", + "Rasure", + "Ratcliff", + "Ratcliffe", + "Ratha", + "Rather", + "Ratib", + "Rattan", + "Rattray", + "Rauch", + "Raul", + "Rausch", + "Rauscher", + "Raveaux", + "Raven", + "Ravens", + "Ravi", + "Ravid", + "Raviv", + "Ravo", + "Rawdan", + "Rawden", + "Rawdin", + "Rawdon", + "Rawley", + "Rawlinson", + "Ray", + "Raybin", + "Raybourne", + "Rayburn", + "Raychel", + "Raycher", + "Raye", + "Rayford", + "Rayle", + "Raymond", + "Raymonds", + "Raymund", + "Rayna", + "Raynah", + "Raynard", + "Raynata", + "Raynell", + "Rayner", + "Raynold", + "Raynor", + "Rayshell", + "Razid", + "Rea", + "Reace", + "Read", + "Reade", + "Readus", + "Ready", + "Reagan", + "Reagen", + "Reahard", + "Reames", + "Reamonn", + "Reamy", + "Reave", + "Reba", + "Rebah", + "Rebak", + "Rebane", + "Rebba", + "Rebbecca", + "Rebe", + "Rebeca", + "Rebecca", + "Rebecka", + "Rebeka", + "Rebekah", + "Rebekkah", + "Rebel", + "Rebhun", + "Rech", + "Recha", + "Rechaba", + "Reckford", + "Recor", + "Rector", + "Red", + "Redd", + "Reddin", + "Reddy", + "Redfield", + "Redford", + "Redman", + "Redmer", + "Redmond", + "Redmund", + "Redvers", + "Redwine", + "Ree", + "Reeba", + "Reece", + "Reed", + "Reede", + "Reedy", + "Reeher", + "Reel", + "Reena", + "Rees", + "Reese", + "Reeta", + "Reeva", + "Reeve", + "Reeves", + "Reg", + "Regan", + "Regazzi", + "Regen", + "Reger", + "Reggi", + "Reggie", + "Reggis", + "Reggy", + "Regina", + "Reginald", + "Reginauld", + "Regine", + "Rego", + "Rehm", + "Rehnberg", + "Reich", + "Reiche", + "Reichel", + "Reichert", + "Reid", + "Reidar", + "Reider", + "Reifel", + "Reiko", + "Reilly", + "Reimer", + "Rein", + "Reina", + "Reinald", + "Reinaldo", + "Reinaldos", + "Reine", + "Reiner", + "Reiners", + "Reinert", + "Reinertson", + "Reinhard", + "Reinhardt", + "Reinhart", + "Reinhold", + "Reinke", + "Reinold", + "Reinwald", + "Reis", + "Reisch", + "Reiser", + "Reisfield", + "Reisinger", + "Reisman", + "Reiss", + "Reiter", + "Reitman", + "Reld", + "Rella", + "Rellia", + "Relly", + "Rem", + "Rema", + "Remde", + "Remington", + "Remmer", + "Rempe", + "Remsen", + "Remus", + "Remy", + "Rena", + "Renado", + "Renae", + "Renaldo", + "Renard", + "Renata", + "Renate", + "Renato", + "Renaud", + "Renault", + "Renckens", + "Rene", + "Renee", + "Renell", + "Renelle", + "Reneta", + "Renferd", + "Renfred", + "Reni", + "Renick", + "Renie", + "Renita", + "Reniti", + "Rennane", + "Renner", + "Rennie", + "Rennold", + "Renny", + "Rento", + "Rentsch", + "Rentschler", + "Renwick", + "Renzo", + "Reo", + "Resa", + "Rese", + "Reseda", + "Resee", + "Reseta", + "Resor", + "Ress", + "Ressler", + "Reste", + "Restivo", + "Reta", + "Retha", + "Rett", + "Rettig", + "Rettke", + "Reube", + "Reuben", + "Reuven", + "Revell", + "Reviel", + "Reviere", + "Revkah", + "Rew", + "Rex", + "Rexana", + "Rexanna", + "Rexanne", + "Rexer", + "Rexferd", + "Rexford", + "Rexfourd", + "Rey", + "Reyna", + "Reynard", + "Reynold", + "Reynolds", + "Rezzani", + "Rhea", + "Rheba", + "Rhee", + "Rheims", + "Rheingold", + "Rheinlander", + "Rheta", + "Rhett", + "Rhetta", + "Rhiamon", + "Rhiana", + "Rhianna", + "Rhianon", + "Rhine", + "Rhines", + "Rhoades", + "Rhoads", + "Rhoda", + "Rhodes", + "Rhodia", + "Rhodie", + "Rhody", + "Rhona", + "Rhonda", + "Rhu", + "Rhynd", + "Rhyne", + "Rhyner", + "Rhys", + "Ri", + "Ria", + "Riana", + "Riancho", + "Riane", + "Rianna", + "Riannon", + "Rianon", + "Riba", + "Ribal", + "Ribaudo", + "Ribble", + "Ric", + "Rica", + "Ricard", + "Ricarda", + "Ricardama", + "Ricardo", + "Ricca", + "Riccardo", + "Riccio", + "Rice", + "Rich", + "Richara", + "Richard", + "Richarda", + "Richardo", + "Richards", + "Richardson", + "Richart", + "Richel", + "Richela", + "Richella", + "Richelle", + "Richer", + "Richers", + "Richey", + "Richia", + "Richie", + "Richlad", + "Richma", + "Richmal", + "Richman", + "Richmond", + "Richmound", + "Richter", + "Richy", + "Rici", + "Rick", + "Rickard", + "Rickart", + "Ricker", + "Rickert", + "Ricketts", + "Rickey", + "Ricki", + "Rickie", + "Ricky", + "Rico", + "Ricoriki", + "Rida", + "Riddle", + "Rider", + "Ridglea", + "Ridglee", + "Ridgley", + "Ridinger", + "Ridley", + "Rie", + "Riebling", + "Riedel", + "Riegel", + "Rieger", + "Riehl", + "Riella", + "Ries", + "Riesman", + "Riess", + "Rieth", + "Riffle", + "Rifkin", + "Rigby", + "Rigdon", + "Riggall", + "Riggins", + "Riggs", + "Riha", + "Rihana", + "Rik", + "Rika", + "Riker", + "Riki", + "Rikki", + "Rilda", + "Riley", + "Rillings", + "Rillis", + "Rima", + "Rimas", + "Rimma", + "Rimola", + "Rina", + "Rinaldo", + "Rind", + "Rinee", + "Ring", + "Ringe", + "Ringler", + "Ringo", + "Ringsmuth", + "Rinna", + "Rintoul", + "Riobard", + "Riocard", + "Rior", + "Riordan", + "Riorsson", + "Rip", + "Ripleigh", + "Riplex", + "Ripley", + "Ripp", + "Risa", + "Rise", + "Risley", + "Rissa", + "Risser", + "Rist", + "Risteau", + "Rita", + "Ritch", + "Ritchie", + "Riti", + "Ritter", + "Ritz", + "Riva", + "Rivalee", + "Rivard", + "River", + "Rivera", + "Rivers", + "Rives", + "Rivi", + "Rivkah", + "Rivy", + "Rizas", + "Rizika", + "Rizzi", + "Rizzo", + "Ro", + "Roach", + "Roana", + "Roane", + "Roanna", + "Roanne", + "Roarke", + "Roath", + "Rob", + "Robaina", + "Robb", + "Robbert", + "Robbi", + "Robbie", + "Robbin", + "Robbins", + "Robby", + "Robbyn", + "Robena", + "Robenia", + "Robers", + "Roberson", + "Robert", + "Roberta", + "Roberto", + "Roberts", + "Robertson", + "Robet", + "Robi", + "Robillard", + "Robin", + "Robina", + "Robinet", + "Robinett", + "Robinetta", + "Robinette", + "Robinia", + "Robins", + "Robinson", + "Robison", + "Robson", + "Roby", + "Robyn", + "Rocca", + "Rocco", + "Roch", + "Roche", + "Rochell", + "Rochella", + "Rochelle", + "Rochemont", + "Rocher", + "Rochester", + "Rochette", + "Rochkind", + "Rochus", + "Rock", + "Rockafellow", + "Rockefeller", + "Rockel", + "Rocker", + "Rockey", + "Rockie", + "Rockwell", + "Rockwood", + "Rocky", + "Rocray", + "Rod", + "Roda", + "Rodd", + "Roddie", + "Roddy", + "Rodenhouse", + "Roderic", + "Roderica", + "Roderich", + "Roderick", + "Roderigo", + "Rodge", + "Rodger", + "Rodgers", + "Rodi", + "Rodie", + "Rodina", + "Rodl", + "Rodman", + "Rodmann", + "Rodmun", + "Rodmur", + "Rodney", + "Rodolfo", + "Rodolph", + "Rodolphe", + "Rodrich", + "Rodrick", + "Rodrigo", + "Rodriguez", + "Rodrique", + "Roe", + "Roede", + "Roee", + "Roehm", + "Roer", + "Roeser", + "Rog", + "Roger", + "Rogerio", + "Rogers", + "Rogerson", + "Rogovy", + "Rogozen", + "Rohn", + "Roi", + "Roice", + "Roid", + "Rois", + "Rojas", + "Rokach", + "Rola", + "Rolan", + "Roland", + "Rolanda", + "Rolando", + "Rolandson", + "Roldan", + "Roley", + "Rolf", + "Rolfe", + "Rolfston", + "Rolland", + "Rollet", + "Rollie", + "Rollin", + "Rollins", + "Rollo", + "Rolo", + "Rolph", + "Roma", + "Romain", + "Romaine", + "Romalda", + "Roman", + "Romanas", + "Romano", + "Rombert", + "Rome", + "Romelda", + "Romelle", + "Romeo", + "Romeon", + "Romeu", + "Romeyn", + "Romie", + "Romilda", + "Romilly", + "Romina", + "Romine", + "Romito", + "Romney", + "Romo", + "Romola", + "Romona", + "Romonda", + "Romulus", + "Romy", + "Ron", + "Rona", + "Ronal", + "Ronald", + "Ronalda", + "Ronda", + "Rondi", + "Rondon", + "Ronel", + "Ronen", + "Ronica", + "Ronn", + "Ronna", + "Ronnholm", + "Ronni", + "Ronnica", + "Ronnie", + "Ronny", + "Roobbie", + "Rooke", + "Rooker", + "Rooney", + "Roos", + "Roose", + "Roosevelt", + "Root", + "Roots", + "Roper", + "Roque", + "Rora", + "Rori", + "Rorie", + "Rorke", + "Rorry", + "Rorrys", + "Rory", + "Ros", + "Rosa", + "Rosabel", + "Rosabella", + "Rosabelle", + "Rosalba", + "Rosalee", + "Rosaleen", + "Rosalia", + "Rosalie", + "Rosalind", + "Rosalinda", + "Rosalinde", + "Rosaline", + "Rosalyn", + "Rosalynd", + "Rosamond", + "Rosamund", + "Rosana", + "Rosane", + "Rosanna", + "Rosanne", + "Rosario", + "Rosati", + "Rosco", + "Roscoe", + "Rose", + "Roseann", + "Roseanna", + "Roseanne", + "Rosecan", + "Rosel", + "Roselane", + "Roselani", + "Roselba", + "Roselia", + "Roselin", + "Roseline", + "Rosella", + "Roselle", + "Roselyn", + "Rosemare", + "Rosemari", + "Rosemaria", + "Rosemarie", + "Rosemary", + "Rosemonde", + "Rosen", + "Rosena", + "Rosenbaum", + "Rosenberg", + "Rosenberger", + "Rosenblast", + "Rosenblatt", + "Rosenblum", + "Rosene", + "Rosenfeld", + "Rosenkrantz", + "Rosenkranz", + "Rosenquist", + "Rosenstein", + "Rosenthal", + "Rosenwald", + "Rosenzweig", + "Rosetta", + "Rosette", + "Roshan", + "Roshelle", + "Rosie", + "Rosina", + "Rosinski", + "Rosio", + "Rosita", + "Roskes", + "Roslyn", + "Rosmarin", + "Rosmunda", + "Rosner", + "Rosol", + "Ross", + "Rosse", + "Rossen", + "Rossi", + "Rossie", + "Rossing", + "Rossner", + "Rossuck", + "Rossy", + "Rostand", + "Roswald", + "Roswell", + "Rosy", + "Rotberg", + "Roter", + "Roth", + "Rothberg", + "Rothenberg", + "Rother", + "Rothmuller", + "Rothschild", + "Rothstein", + "Rothwell", + "Roti", + "Rotman", + "Rotow", + "Roumell", + "Rourke", + "Routh", + "Rouvin", + "Roux", + "Rovelli", + "Rovit", + "Rovner", + "Row", + "Rowan", + "Rowe", + "Rowell", + "Rowen", + "Rowena", + "Rowland", + "Rowley", + "Rowney", + "Rox", + "Roxana", + "Roxane", + "Roxanna", + "Roxanne", + "Roxi", + "Roxie", + "Roxine", + "Roxy", + "Roy", + "Royal", + "Royall", + "Roybn", + "Royce", + "Royd", + "Roydd", + "Royden", + "Roye", + "Royo", + "Roz", + "Rozalie", + "Rozalin", + "Rozamond", + "Rozanna", + "Rozanne", + "Roze", + "Rozek", + "Rozele", + "Rozella", + "Rozelle", + "Rozina", + "Rriocard", + "Ru", + "Rubbico", + "Rube", + "Rubel", + "Ruben", + "Rubens", + "Rubenstein", + "Ruberta", + "Rubetta", + "Rubi", + "Rubia", + "Rubie", + "Rubin", + "Rubina", + "Rubinstein", + "Rubio", + "Ruby", + "Rucker", + "Ruckman", + "Rudd", + "Ruddie", + "Ruddy", + "Rudelson", + "Ruder", + "Rudich", + "Rudie", + "Rudiger", + "Rudin", + "Rudman", + "Rudolf", + "Rudolfo", + "Rudolph", + "Rudwik", + "Rudy", + "Rudyard", + "Rue", + "Ruel", + "Ruella", + "Ruelle", + "Ruelu", + "Rufe", + "Rufena", + "Ruff", + "Ruffi", + "Ruffin", + "Ruffina", + "Ruffo", + "Rufford", + "Rufina", + "Ruford", + "Rufus", + "Rugen", + "Rugg", + "Ruggiero", + "Ruhl", + "Ruhnke", + "Ruiz", + "Rumery", + "Rumilly", + "Rumney", + "Rumpf", + "Runck", + "Rundgren", + "Runkel", + "Runkle", + "Runstadler", + "Rupert", + "Ruperta", + "Ruperto", + "Ruphina", + "Ruprecht", + "Rurik", + "Rus", + "Ruscher", + "Ruscio", + "Rusel", + "Rusell", + "Rusert", + "Rush", + "Rushing", + "Ruskin", + "Russ", + "Russel", + "Russell", + "Russi", + "Russia", + "Russian", + "Russo", + "Russom", + "Russon", + "Rust", + "Rustice", + "Rusticus", + "Rustie", + "Rustin", + "Rusty", + "Rutan", + "Rutger", + "Ruth", + "Ruthann", + "Ruthanne", + "Ruthe", + "Rutherford", + "Rutherfurd", + "Ruthi", + "Ruthie", + "Ruthven", + "Ruthy", + "Rutledge", + "Rutter", + "Ruttger", + "Ruvolo", + "Ruy", + "Ruyle", + "Ruzich", + "Ryan", + "Ryann", + "Rycca", + "Rydder", + "Ryder", + "Rye", + "Ryle", + "Ryley", + "Ryon", + "Rysler", + "Ryter", + "Ryun", + "Saba", + "Sabah", + "Sabba", + "Sabec", + "Sabella", + "Sabelle", + "Saber", + "Saberhagen", + "Saberio", + "Sabian", + "Sabina", + "Sabine", + "Sabino", + "Sabir", + "Sabra", + "Sabrina", + "Sabsay", + "Sabu", + "Sacci", + "Sacha", + "Sachi", + "Sachiko", + "Sachs", + "Sachsse", + "Sacken", + "Sackey", + "Sackman", + "Sacks", + "Sacksen", + "Sackville", + "Sacttler", + "Sad", + "Sada", + "Saddler", + "Sadella", + "Sadick", + "Sadie", + "Sadira", + "Sadirah", + "Sadiras", + "Sadler", + "Sadoc", + "Sadoff", + "Sadonia", + "Sadowski", + "Sadye", + "Saeger", + "Saffian", + "Saffier", + "Saffren", + "Safier", + "Safir", + "Safire", + "Safko", + "Sage", + "Sager", + "Sagerman", + "Saidee", + "Saidel", + "Saideman", + "Saied", + "Saiff", + "Sailesh", + "Saimon", + "Saint", + "Sair", + "Saire", + "Saito", + "Sajovich", + "Sakhuja", + "Sakmar", + "Sakovich", + "Saks", + "Sal", + "Salahi", + "Salaidh", + "Salamanca", + "Salamone", + "Salangi", + "Salangia", + "Salas", + "Salazar", + "Salba", + "Salbu", + "Salchunas", + "Sale", + "Saleem", + "Salem", + "Salema", + "Saleme", + "Salena", + "Salene", + "Salesin", + "Salim", + "Salina", + "Salinas", + "Salisbarry", + "Salisbury", + "Salita", + "Sall", + "Sallee", + "Salli", + "Sallie", + "Sally", + "Sallyann", + "Sallyanne", + "Salman", + "Salmon", + "Saloma", + "Salome", + "Salomi", + "Salomie", + "Salomo", + "Salomon", + "Salomone", + "Salot", + "Salsbury", + "Salter", + "Saltsman", + "Saltzman", + "Salvador", + "Salvadore", + "Salvatore", + "Salvay", + "Salvidor", + "Salvucci", + "Salzhauer", + "Sam", + "Sama", + "Samal", + "Samala", + "Samale", + "Samalla", + "Samantha", + "Samanthia", + "Samara", + "Samaria", + "Samau", + "Samella", + "Samford", + "Sami", + "Samira", + "Sammer", + "Sammie", + "Sammons", + "Sammy", + "Samp", + "Sampson", + "Sams", + "Samson", + "Samuel", + "Samuela", + "Samuele", + "Samuella", + "Samuelson", + "Samul", + "Samy", + "Sanalda", + "Sanbo", + "Sanborn", + "Sanborne", + "Sanburn", + "Sancha", + "Sanchez", + "Sancho", + "Sand", + "Sandberg", + "Sande", + "Sandeep", + "Sandell", + "Sander", + "Sanders", + "Sanderson", + "Sandi", + "Sandie", + "Sandler", + "Sandon", + "Sandor", + "Sandra", + "Sandro", + "Sandry", + "Sands", + "Sandstrom", + "Sandy", + "Sandye", + "Sanferd", + "Sanfo", + "Sanford", + "Sanfourd", + "Sanfred", + "Sang", + "Sanger", + "Sanjay", + "Sanjiv", + "Sankaran", + "Sankey", + "Sansbury", + "Sansen", + "Sanson", + "Sansone", + "Santa", + "Santana", + "Santiago", + "Santini", + "Santoro", + "Santos", + "Sanyu", + "Sapers", + "Saphra", + "Sapienza", + "Sapowith", + "Sapphera", + "Sapphira", + "Sapphire", + "Sara", + "Sara-Ann", + "Saraann", + "Sarad", + "Sarah", + "Saraiya", + "Sarajane", + "Sarazen", + "Sarchet", + "Sardella", + "Saree", + "Sarena", + "Sarene", + "Saretta", + "Sarette", + "Sarge", + "Sargent", + "Sari", + "Sarid", + "Sarilda", + "Sarina", + "Sarine", + "Sarita", + "Sarkaria", + "Sarnoff", + "Sarson", + "Sartin", + "Sascha", + "Sasha", + "Sashenka", + "Sasnett", + "Sass", + "Sassan", + "Sateia", + "Sathrum", + "Sato", + "Satterfield", + "Satterlee", + "Saturday", + "Saucy", + "Sauder", + "Saudra", + "Sauer", + "Sauers", + "Saul", + "Sauls", + "Saum", + "Sauncho", + "Saunder", + "Saunders", + "Saunderson", + "Saundra", + "Sausa", + "Sauveur", + "Savadove", + "Savage", + "Saval", + "Savanna", + "Savannah", + "Savdeep", + "Savell", + "Savick", + "Savil", + "Savill", + "Saville", + "Savina", + "Savior", + "Savitt", + "Savory", + "Saw", + "Sawtelle", + "Sawyer", + "Sawyere", + "Sawyor", + "Sax", + "Saxe", + "Saxen", + "Saxena", + "Saxon", + "Say", + "Sayce", + "Sayed", + "Sayer", + "Sayers", + "Sayette", + "Sayles", + "Saylor", + "Sayre", + "Sayres", + "Scales", + "Scammon", + "Scandura", + "Scarface", + "Scarito", + "Scarlet", + "Scarlett", + "Scarrow", + "Scever", + "Scevo", + "Scevor", + "Scevour", + "Schaab", + "Schaaff", + "Schach", + "Schacker", + "Schaefer", + "Schaeffer", + "Schafer", + "Schaffel", + "Schaffer", + "Schalles", + "Schaper", + "Schapira", + "Scharaga", + "Scharf", + "Scharff", + "Schargel", + "Schatz", + "Schaumberger", + "Schear", + "Schechinger", + "Schechter", + "Scheck", + "Schecter", + "Scheer", + "Scheers", + "Scheider", + "Scheld", + "Schell", + "Schellens", + "Schenck", + "Scherle", + "Scherman", + "Schertz", + "Schick", + "Schiff", + "Schiffman", + "Schifra", + "Schild", + "Schilit", + "Schilling", + "Schilt", + "Schindler", + "Schinica", + "Schiro", + "Schlenger", + "Schlesinger", + "Schlessel", + "Schlessinger", + "Schlicher", + "Schlosser", + "Schluter", + "Schmeltzer", + "Schmidt", + "Schmitt", + "Schmitz", + "Schnabel", + "Schnapp", + "Schnell", + "Schnorr", + "Schnur", + "Schnurr", + "Schober", + "Schoenberg", + "Schoenburg", + "Schoenfelder", + "Schoening", + "Schofield", + "Scholem", + "Scholz", + "Schonfeld", + "Schonfield", + "Schonthal", + "Schoof", + "Schott", + "Schou", + "Schouten", + "Schrader", + "Schram", + "Schramke", + "Schreck", + "Schreib", + "Schreibe", + "Schreiber", + "Schreibman", + "Schrick", + "Schriever", + "Schroder", + "Schroeder", + "Schroer", + "Schroth", + "Schubert", + "Schug", + "Schuh", + "Schulein", + "Schuler", + "Schulman", + "Schultz", + "Schulz", + "Schulze", + "Schuman", + "Schumer", + "Schurman", + "Schuster", + "Schuyler", + "Schwab", + "Schwartz", + "Schwarz", + "Schweiker", + "Schweitzer", + "Schwejda", + "Schwenk", + "Schwerin", + "Schwing", + "Schwinn", + "Schwitzer", + "Scibert", + "Sclar", + "Sclater", + "Scoles", + "Scopp", + "Scornik", + "Scot", + "Scoter", + "Scotney", + "Scott", + "Scotti", + "Scottie", + "Scotty", + "Scoville", + "Screens", + "Scribner", + "Scriven", + "Scrivenor", + "Scrivens", + "Scrivings", + "Scrogan", + "Scrope", + "Sculley", + "Scully", + "Scurlock", + "Scutt", + "Seabrook", + "Seabrooke", + "Seabury", + "Seaddon", + "Seaden", + "Seadon", + "Seafowl", + "Seagrave", + "Seagraves", + "Seale", + "Seaman", + "Seamus", + "Sean", + "Seana", + "Searby", + "Searcy", + "Searle", + "Sears", + "Season", + "Seaton", + "Seaver", + "Seavey", + "Seavir", + "Sebastian", + "Sebastiano", + "Sebastien", + "Sebbie", + "Secor", + "Secrest", + "Secunda", + "Secundas", + "Seda", + "Sedberry", + "Sedda", + "Sedgewake", + "Sedgewick", + "Sedgewinn", + "Sedlik", + "See", + "Seebeck", + "Seed", + "Seedman", + "Seel", + "Seely", + "Seem", + "Seema", + "Seen", + "Seena", + "Seessel", + "Seeto", + "Seften", + "Sefton", + "Seftton", + "Segal", + "Segalman", + "Seiber", + "Seibold", + "Seidel", + "Seiden", + "Seidler", + "Seidule", + "Seif", + "Seigel", + "Seigler", + "Seiter", + "Seitz", + "Seka", + "Seko", + "Sekofski", + "Sekyere", + "Sela", + "Selassie", + "Selby", + "Selda", + "Seldan", + "Selden", + "Seldon", + "Seldun", + "Selemas", + "Selena", + "Selene", + "Selestina", + "Seleta", + "Selfridge", + "Selhorst", + "Selia", + "Selie", + "Selig", + "Seligman", + "Seligmann", + "Selima", + "Selimah", + "Selina", + "Selinda", + "Seline", + "Selinski", + "Sell", + "Sella", + "Selle", + "Sellers", + "Sellma", + "Sello", + "Sells", + "Selma", + "Selmner", + "Selmore", + "Selry", + "Seltzer", + "Selway", + "Selwin", + "Selwyn", + "Semela", + "Semele", + "Semmes", + "Sena", + "Senalda", + "Sender", + "Senecal", + "Senhauser", + "Senior", + "Senn", + "Sension", + "Senskell", + "Senzer", + "Seow", + "Sephira", + "Seppala", + "September", + "Septima", + "Sera", + "Serafina", + "Serafine", + "Seraphim", + "Seraphina", + "Seraphine", + "Serena", + "Serene", + "Serg", + "Serge", + "Sergeant", + "Sergei", + "Sergent", + "Sergias", + "Sergio", + "Sergius", + "Sergo", + "Sergu", + "Serica", + "Serilda", + "Serle", + "Serles", + "Seroka", + "Serra", + "Serrano", + "Serrell", + "Servais", + "Server", + "Servetnick", + "Service", + "Sessler", + "Seta", + "Seth", + "Sethi", + "Sethrida", + "Seto", + "Seton", + "Settera", + "Settle", + "Seumas", + "Sev", + "Seve", + "Severen", + "Severin", + "Severn", + "Severson", + "Sevik", + "Seward", + "Sewel", + "Sewell", + "Sewellyn", + "Sewole", + "Sewoll", + "Sexton", + "Seyler", + "Seymour", + "Seys", + "Sezen", + "Shabbir", + "Shaddock", + "Shadow", + "Shae", + "Shaefer", + "Shaeffer", + "Shaer", + "Shafer", + "Shaff", + "Shaffer", + "Shaffert", + "Shah", + "Shaia", + "Shaikh", + "Shaina", + "Shaine", + "Shakespeare", + "Shakti", + "Shalna", + "Shalne", + "Shalom", + "Shama", + "Shamma", + "Shamrao", + "Shamus", + "Shana", + "Shanahan", + "Shanan", + "Shanda", + "Shandee", + "Shandeigh", + "Shandie", + "Shandra", + "Shandy", + "Shane", + "Shaner", + "Shani", + "Shanie", + "Shank", + "Shanks", + "Shanleigh", + "Shanley", + "Shanly", + "Shanna", + "Shannah", + "Shannan", + "Shannen", + "Shanney", + "Shannon", + "Shanon", + "Shanta", + "Shantee", + "Shantha", + "Shaper", + "Shapiro", + "Shara", + "Sharai", + "Shargel", + "Shari", + "Sharia", + "Sharity", + "Sharl", + "Sharla", + "Sharleen", + "Sharlene", + "Sharline", + "Sharma", + "Sharman", + "Sharon", + "Sharona", + "Sharos", + "Sharp", + "Sharpe", + "Sharron", + "Sharyl", + "Shatzer", + "Shaughn", + "Shaughnessy", + "Shaum", + "Shaun", + "Shauna", + "Shaver", + "Shaw", + "Shawn", + "Shawna", + "Shawnee", + "Shay", + "Shaya", + "Shayla", + "Shaylah", + "Shaylyn", + "Shaylynn", + "Shayn", + "Shayna", + "Shayne", + "Shea", + "Sheaff", + "Shear", + "Sheba", + "Shedd", + "Sheeb", + "Sheedy", + "Sheehan", + "Sheela", + "Sheelagh", + "Sheelah", + "Sheena", + "Sheepshanks", + "Sheeran", + "Sheeree", + "Sheets", + "Sheff", + "Sheffie", + "Sheffield", + "Sheffy", + "Sheila", + "Sheilah", + "Shel", + "Shela", + "Shelagh", + "Shelah", + "Shelba", + "Shelbi", + "Shelburne", + "Shelby", + "Shelden", + "Sheldon", + "Sheley", + "Shelia", + "Sheline", + "Shell", + "Shellans", + "Shelley", + "Shelli", + "Shellie", + "Shelly", + "Shelman", + "Shelton", + "Shem", + "Shena", + "Shenan", + "Sheng", + "Shep", + "Shepard", + "Shepherd", + "Shepley", + "Sheply", + "Shepp", + "Sheppard", + "Shepperd", + "Sher", + "Sherar", + "Sherard", + "Sherborn", + "Sherborne", + "Sherburn", + "Sherburne", + "Shere", + "Sheree", + "Sherer", + "Shererd", + "Sherfield", + "Sheri", + "Sheridan", + "Sherie", + "Sherill", + "Sherilyn", + "Sherj", + "Sherl", + "Sherline", + "Sherlock", + "Sherlocke", + "Sherm", + "Sherman", + "Shermie", + "Shermy", + "Sherourd", + "Sherr", + "Sherrard", + "Sherrer", + "Sherri", + "Sherrie", + "Sherrill", + "Sherris", + "Sherrod", + "Sherry", + "Sherurd", + "Sherwin", + "Sherwood", + "Sherwynd", + "Sherye", + "Sheryl", + "Sheryle", + "Shetrit", + "Shevlo", + "Shewchuk", + "Shewmaker", + "Sheya", + "Shiau", + "Shieh", + "Shiekh", + "Shields", + "Shien", + "Shiff", + "Shifra", + "Shifrah", + "Shig", + "Shih", + "Shiller", + "Shimberg", + "Shimkus", + "Shina", + "Shinberg", + "Shing", + "Shipley", + "Shipman", + "Shipp", + "Shippee", + "Shir", + "Shira", + "Shirah", + "Shirberg", + "Shiri", + "Shirk", + "Shirl", + "Shirlee", + "Shirleen", + "Shirlene", + "Shirley", + "Shirlie", + "Shirline", + "Shiroma", + "Shishko", + "Shiverick", + "Shivers", + "Shlomo", + "Shoemaker", + "Shoifet", + "Sholeen", + "Sholem", + "Sholes", + "Sholley", + "Sholom", + "Shore", + "Shornick", + "Short", + "Shorter", + "Shoshana", + "Shoshanna", + "Shotton", + "Showker", + "Shreeves", + "Shreve", + "Shrier", + "Shriner", + "Shriver", + "Shu", + "Shue", + "Shugart", + "Shulamith", + "Shulem", + "Shuler", + "Shulins", + "Shull", + "Shulman", + "Shulock", + "Shult", + "Shultz", + "Shum", + "Shuma", + "Shuman", + "Shumway", + "Shuping", + "Shurlock", + "Shurlocke", + "Shurwood", + "Shushan", + "Shute", + "Shutz", + "Shwalb", + "Shyamal", + "Si", + "Siana", + "Sianna", + "Sib", + "Sibbie", + "Sibby", + "Sibeal", + "Sibel", + "Sibell", + "Sibella", + "Sibelle", + "Siberson", + "Sibie", + "Sibilla", + "Sible", + "Siblee", + "Sibley", + "Sibyl", + "Sibylla", + "Sibylle", + "Sibyls", + "Sicard", + "Sices", + "Siclari", + "Sicular", + "Sid", + "Sida", + "Siddon", + "Siddra", + "Sidell", + "Sidhu", + "Sidky", + "Sidman", + "Sidnee", + "Sidney", + "Sidoma", + "Sidon", + "Sidoney", + "Sidonia", + "Sidonie", + "Sidonius", + "Sidonnie", + "Sidoon", + "Sidra", + "Sidran", + "Sidras", + "Sidwel", + "Sidwell", + "Sidwohl", + "Sieber", + "Siegel", + "Siegfried", + "Siegler", + "Sielen", + "Sieracki", + "Sierra", + "Siesser", + "Sievert", + "Siffre", + "Sig", + "Sigfrid", + "Sigfried", + "Sigismond", + "Sigismondo", + "Sigismund", + "Sigismundo", + "Sigler", + "Sigmund", + "Signe", + "Sigrid", + "Sigsmond", + "Sigvard", + "Sihon", + "Sihonn", + "Sihun", + "Sihunn", + "Sik", + "Sikata", + "Sikes", + "Sikko", + "Sikorski", + "Sil", + "Silas", + "Silber", + "Silberman", + "Silda", + "Silden", + "Sile", + "Sileas", + "Silin", + "Sill", + "Sillsby", + "Silma", + "Siloa", + "Siloam", + "Siloum", + "Silsby", + "Silsbye", + "Silva", + "Silvain", + "Silvan", + "Silvana", + "Silvano", + "Silvanus", + "Silver", + "Silverman", + "Silvers", + "Silverstein", + "Silverts", + "Silvester", + "Silvestro", + "Silvia", + "Silvie", + "Silvio", + "Sim", + "Sima", + "Simah", + "Simdars", + "Simeon", + "Simmie", + "Simmonds", + "Simmons", + "Simon", + "Simona", + "Simone", + "Simonetta", + "Simonette", + "Simonne", + "Simons", + "Simonsen", + "Simpkins", + "Simpson", + "Sims", + "Simsar", + "Simson", + "Sinai", + "Sinclair", + "Sinclare", + "Sindee", + "Sine", + "Sinegold", + "Singband", + "Singer", + "Singh", + "Singhal", + "Singleton", + "Sink", + "Sinnard", + "Siobhan", + "Sion", + "Sioux", + "Siouxie", + "Sipple", + "Sirkin", + "Sirmons", + "Sirois", + "Sirotek", + "Sisak", + "Sisco", + "Sisely", + "Sisile", + "Siskind", + "Sissel", + "Sissie", + "Sisson", + "Sissy", + "Sisto", + "Sitarski", + "Sitnik", + "Sitra", + "Siubhan", + "Siusan", + "Sivia", + "Sivie", + "Siward", + "Sjoberg", + "Skantze", + "Skardol", + "Skees", + "Skeie", + "Skell", + "Skelly", + "Skelton", + "Skerl", + "Skiba", + "Skier", + "Skiest", + "Skilken", + "Skill", + "Skillern", + "Skinner", + "Skip", + "Skipp", + "Skipper", + "Skippie", + "Skippy", + "Skipton", + "Sklar", + "Skolnik", + "Skricki", + "Skurnik", + "Skutchan", + "Skvorak", + "Sky", + "Skye", + "Skyla", + "Skylar", + "Skyler", + "Slaby", + "Slack", + "Slade", + "Sladen", + "Slater", + "Slaughter", + "Slavic", + "Slavin", + "Slayton", + "Sldney", + "Slemmer", + "Sletten", + "Slifka", + "Slinkman", + "Sliwa", + "Sloan", + "Sloane", + "Sloatman", + "Slocum", + "Slosberg", + "Slotnick", + "Sluiter", + "Sly", + "Slyke", + "Smail", + "Small", + "Smalley", + "Smallman", + "Smart", + "Smiga", + "Smiley", + "Smith", + "Smitt", + "Smitty", + "Smoot", + "Smukler", + "Snapp", + "Snashall", + "Sneed", + "Snell", + "Snider", + "Snoddy", + "Snodgrass", + "Snook", + "Snow", + "Snowber", + "Snowman", + "Snyder", + "So", + "Soane", + "Sobel", + "Soble", + "Socha", + "Socher", + "Sochor", + "Socrates", + "Soelch", + "Sofer", + "Sofia", + "Sofie", + "Sofko", + "Soinski", + "Sokil", + "Sokul", + "Sol", + "Sola", + "Solana", + "Solange", + "Solberg", + "Solenne", + "Solis", + "Solita", + "Solitta", + "Soll", + "Sollars", + "Solley", + "Sollie", + "Sollows", + "Solly", + "Solnit", + "Soloma", + "Soloman", + "Solomon", + "Solon", + "Soluk", + "Som", + "Somerset", + "Somerville", + "Sommer", + "Sommers", + "Son", + "Sondra", + "Soneson", + "Song", + "Soni", + "Sonia", + "Sonja", + "Sonni", + "Sonnie", + "Sonnnie", + "Sonny", + "Sonstrom", + "Sontag", + "Sontich", + "Sonya", + "Soo", + "Soph", + "Sopher", + "Sophey", + "Sophi", + "Sophia", + "Sophie", + "Sophronia", + "Sophy", + "Soracco", + "Soraya", + "Sorce", + "Sorcha", + "Sorci", + "Sorcim", + "Sorel", + "Soren", + "Sorensen", + "Sorenson", + "Sorilda", + "Sorkin", + "Sorrows", + "Sosanna", + "Sosna", + "Sosthena", + "Sosthenna", + "Sosthina", + "Sothena", + "Sotos", + "Sou", + "Soule", + "Soulier", + "Sousa", + "Southard", + "Southworth", + "Soutor", + "Souvaine", + "Souza", + "Sowell", + "Sower", + "Spada", + "Spain", + "Spalding", + "Spalla", + "Spancake", + "Spanjian", + "Spanos", + "Sparhawk", + "Spark", + "Sparke", + "Sparkie", + "Sparks", + "Sparky", + "Sparrow", + "Spatola", + "Spatz", + "Spaulding", + "Spear", + "Spearing", + "Spearman", + "Spears", + "Specht", + "Spector", + "Spence", + "Spencer", + "Spense", + "Spenser", + "Sperling", + "Speroni", + "Sperry", + "Spevek", + "Spiegel", + "Spiegelman", + "Spiegleman", + "Spieler", + "Spielman", + "Spiers", + "Spike", + "Spillar", + "Spindell", + "Spiro", + "Spiros", + "Spitzer", + "Spohr", + "Spooner", + "Spoor", + "Spracklen", + "Sprage", + "Spragens", + "Sprague", + "Spratt", + "Spring", + "Springer", + "Sproul", + "Sprung", + "Spurgeon", + "Squier", + "Squire", + "Squires", + "Srini", + "Staal", + "Stace", + "Stacee", + "Stacey", + "Staci", + "Stacia", + "Stacie", + "Stacy", + "Stafani", + "Staffan", + "Staffard", + "Stafford", + "Staford", + "Stag", + "Stagg", + "Stahl", + "Stalder", + "Staley", + "Stalk", + "Stalker", + "Stallworth", + "Stamata", + "Stambaugh", + "Stan", + "Stander", + "Standford", + "Standice", + "Standing", + "Standish", + "Standley", + "Standush", + "Stanfield", + "Stanfill", + "Stanford", + "Stanhope", + "Stanislas", + "Stanislaus", + "Stanislaw", + "Stanleigh", + "Stanley", + "Stanly", + "Stannfield", + "Stannwood", + "Stanton", + "Stanway", + "Stanwin", + "Stanwinn", + "Stanwood", + "Stanzel", + "Star", + "Starbuck", + "Stargell", + "Starinsky", + "Stark", + "Starkey", + "Starks", + "Starla", + "Starlene", + "Starlin", + "Starling", + "Starobin", + "Starr", + "Stasny", + "Staten", + "Statis", + "Stauder", + "Stauffer", + "Stav", + "Stavro", + "Stavros", + "Staw", + "Stclair", + "Stead", + "Steady", + "Stearn", + "Stearne", + "Stearns", + "Steck", + "Steddman", + "Stedman", + "Stedmann", + "Stedt", + "Steel", + "Steele", + "Steen", + "Steep", + "Steere", + "Stefa", + "Stefan", + "Stefanac", + "Stefania", + "Stefanie", + "Stefano", + "Steffane", + "Steffen", + "Steffi", + "Steffie", + "Steffin", + "Steffy", + "Stegman", + "Stein", + "Steinberg", + "Steiner", + "Steinke", + "Steinman", + "Steinway", + "Stella", + "Stelle", + "Stelmach", + "Stelu", + "Stempien", + "Stempson", + "Stenger", + "Stent", + "Stepha", + "Stephan", + "Stephana", + "Stephani", + "Stephania", + "Stephanie", + "Stephannie", + "Stephanus", + "Stephen", + "Stephenie", + "Stephens", + "Stephenson", + "Stephi", + "Stephie", + "Stephine", + "Sterling", + "Stern", + "Sternberg", + "Sterne", + "Sterner", + "Sternick", + "Sternlight", + "Sterrett", + "Stesha", + "Stets", + "Stetson", + "Stevana", + "Steve", + "Steven", + "Stevena", + "Stevens", + "Stevenson", + "Stevie", + "Stevy", + "Stew", + "Steward", + "Stewardson", + "Stewart", + "Stich", + "Stichter", + "Stickney", + "Stiegler", + "Stieglitz", + "Stier", + "Stig", + "Stila", + "Stiles", + "Still", + "Stilla", + "Stillas", + "Stillman", + "Stillmann", + "Stilu", + "Stilwell", + "Stimson", + "Stine", + "Stinky", + "Stinson", + "Stirling", + "Stoat", + "Stochmal", + "Stock", + "Stockmon", + "Stockton", + "Stockwell", + "Stoddard", + "Stoddart", + "Stodder", + "Stoeber", + "Stoecker", + "Stoffel", + "Stokes", + "Stoll", + "Stoller", + "Stolzer", + "Stone", + "Stoneham", + "Stoneman", + "Stonwin", + "Stoops", + "Storer", + "Storfer", + "Storm", + "Stormi", + "Stormie", + "Stormy", + "Stortz", + "Story", + "Storz", + "Stouffer", + "Stoughton", + "Stout", + "Stovall", + "Stover", + "Strade", + "Strader", + "Strage", + "Strain", + "Strait", + "Stralka", + "Strander", + "Strang", + "Stranger", + "Stratton", + "Straub", + "Straus", + "Strauss", + "Strawn", + "Streeter", + "Streetman", + "Streeto", + "Strenta", + "Strep", + "Strephon", + "Strephonn", + "Strepphon", + "Stretch", + "Stricklan", + "Strickland", + "Strickler", + "Strickman", + "Stringer", + "Strohbehn", + "Strohben", + "Strohl", + "Stromberg", + "Strong", + "Stronski", + "Stroud", + "Stroup", + "Struve", + "Stryker", + "Stu", + "Stuart", + "Stubbs", + "Stubstad", + "Stucker", + "Stuckey", + "Studdard", + "Studley", + "Studner", + "Studnia", + "Stulin", + "Stultz", + "Stuppy", + "Sturdivant", + "Sturges", + "Sturrock", + "Stutman", + "Stutsman", + "Stutzman", + "Styles", + "Su", + "Suanne", + "Subak", + "Subir", + "Sublett", + "Suchta", + "Suckow", + "Sucy", + "Sudbury", + "Sudderth", + "Sudhir", + "Sudnor", + "Sue", + "Suellen", + "Suelo", + "Sugar", + "Sugden", + "Sugihara", + "Suh", + "Suhail", + "Suilmann", + "Suk", + "Sukey", + "Sukhum", + "Suki", + "Sukin", + "Sula", + "Sulamith", + "Sullivan", + "Sully", + "Sum", + "Sumer", + "Sumerlin", + "Summer", + "Summers", + "Summons", + "Sumner", + "Sunda", + "Sunday", + "Sundberg", + "Sunderland", + "Sundin", + "Sundstrom", + "Suneya", + "Sung", + "Sunil", + "Sunny", + "Sunshine", + "Sup", + "Supat", + "Supen", + "Supple", + "Sura", + "Surbeck", + "Surovy", + "Survance", + "Susan", + "Susana", + "Susanetta", + "Susann", + "Susanna", + "Susannah", + "Susanne", + "Susette", + "Susi", + "Susie", + "Sussi", + "Sussman", + "Sussna", + "Susumu", + "Susy", + "Suter", + "Sutherlan", + "Sutherland", + "Sutphin", + "Sutton", + "Suu", + "Suzan", + "Suzann", + "Suzanna", + "Suzanne", + "Suzetta", + "Suzette", + "Suzi", + "Suzie", + "Suzy", + "Suzzy", + "Sven", + "Svend", + "Svensen", + "Sverre", + "Svetlana", + "Svoboda", + "Swagerty", + "Swain", + "Swaine", + "Swainson", + "Swamy", + "Swan", + "Swane", + "Swanhilda", + "Swanhildas", + "Swann", + "Swanson", + "Swart", + "Swarts", + "Swartz", + "Swayder", + "Swayne", + "Sweatt", + "Swec", + "Swee", + "Sweeney", + "Sweet", + "Swen", + "Swenson", + "Swetiana", + "Swetlana", + "Sweyn", + "Swiercz", + "Swift", + "Swigart", + "Swihart", + "Swinton", + "Swirsky", + "Swisher", + "Swithbart", + "Swithbert", + "Swithin", + "Switzer", + "Swope", + "Swor", + "Swords", + "Sy", + "Sybil", + "Sybila", + "Sybilla", + "Sybille", + "Sybley", + "Sybyl", + "Syck", + "Syd", + "Sydel", + "Sydelle", + "Sydney", + "Sykes", + "Syl", + "Sylas", + "Sylvan", + "Sylvanus", + "Sylvester", + "Sylvia", + "Sylvie", + "Syman", + "Symer", + "Symon", + "Symons", + "Synn", + "Syst", + "Syverson", + "TEirtza", + "Taam", + "Tab", + "Tabatha", + "Tabb", + "Tabbatha", + "Tabber", + "Tabbi", + "Tabbie", + "Tabbitha", + "Tabby", + "Taber", + "Tabib", + "Tabina", + "Tabitha", + "Tabor", + "Tabshey", + "Tace", + "Tacita", + "Tacklind", + "Tacy", + "Tacye", + "Tad", + "Tada", + "Tadashi", + "Tadd", + "Taddeo", + "Taddeusz", + "Tade", + "Tadeas", + "Tadeo", + "Tades", + "Tadich", + "Tadio", + "Taffy", + "Taft", + "Tager", + "Taggart", + "Tahmosh", + "Tai", + "Tailor", + "Taima", + "Taimi", + "Tait", + "Taite", + "Tak", + "Taka", + "Takakura", + "Takara", + "Takashi", + "Takeo", + "Takeshi", + "Takken", + "Tal", + "Tala", + "Talanian", + "Talanta", + "Talbert", + "Talbot", + "Talbott", + "Tali", + "Talia", + "Talich", + "Talie", + "Tallbot", + "Tallbott", + "Talley", + "Tallia", + "Tallie", + "Tallou", + "Tallu", + "Tallula", + "Tallulah", + "Tally", + "Talmud", + "Talya", + "Talyah", + "Tam", + "Tama", + "Tamah", + "Tamanaha", + "Tamar", + "Tamara", + "Tamarah", + "Tamarra", + "Tamaru", + "Tamas", + "Tamberg", + "Tamer", + "Tamera", + "Tami", + "Tamiko", + "Tamis", + "Tamma", + "Tammany", + "Tammara", + "Tammi", + "Tammie", + "Tammy", + "Tamqrah", + "Tamra", + "Tamsky", + "Tan", + "Tana", + "Tanah", + "Tanaka", + "Tanberg", + "Tandi", + "Tandie", + "Tandy", + "Tanhya", + "Tani", + "Tania", + "Tanitansy", + "Tankoos", + "Tann", + "Tannen", + "Tannenbaum", + "Tannenwald", + "Tanner", + "Tanney", + "Tannie", + "Tanny", + "Tansey", + "Tansy", + "Tanya", + "Tapes", + "Tara", + "Tarabar", + "Tarah", + "Taran", + "Tarazi", + "Tare", + "Tareyn", + "Targett", + "Tarkany", + "Taro", + "Tarr", + "Tarra", + "Tarrah", + "Tarrance", + "Tarrant", + "Tarrel", + "Tarrsus", + "Tarryn", + "Tarsus", + "Tarsuss", + "Tartaglia", + "Tartan", + "Tarton", + "Tarttan", + "Taryn", + "Taryne", + "Tasha", + "Tasia", + "Tasiana", + "Tat", + "Tate", + "Tati", + "Tatia", + "Tatiana", + "Tatianas", + "Tatiania", + "Tatianna", + "Tatman", + "Tattan", + "Tatum", + "Taub", + "Tav", + "Taveda", + "Tavey", + "Tavi", + "Tavia", + "Tavie", + "Tavis", + "Tavish", + "Tavy", + "Tawney", + "Tawnya", + "Tawsha", + "Tay", + "Tayib", + "Tayler", + "Taylor", + "Tayyebeb", + "Tchao", + "Teador", + "Teagan", + "Teage", + "Teague", + "Teahan", + "Teak", + "Tearle", + "Tecla", + "Tecu", + "Ted", + "Tedd", + "Tedda", + "Tedder", + "Teddi", + "Teddie", + "Teddman", + "Teddy", + "Tedi", + "Tedie", + "Tedman", + "Tedmann", + "Tedmund", + "Tedra", + "Tedric", + "Teece", + "Teena", + "Teerell", + "Teeter", + "Teevens", + "Teferi", + "Tega", + "Tegan", + "Teillo", + "Teilo", + "Tekla", + "Telfer", + "Telford", + "Telfore", + "Tella", + "Tellford", + "Tem", + "Tema", + "Temp", + "Tempa", + "Tempest", + "Templa", + "Templas", + "Temple", + "Templer", + "Templeton", + "Templia", + "Ten", + "Tena", + "Tench", + "Tenenbaum", + "Tengdin", + "Tengler", + "Tenn", + "Tenner", + "Tennes", + "Tenney", + "Tennies", + "Teodoor", + "Teodor", + "Teodora", + "Teodorico", + "Teodoro", + "Teplica", + "Teplitz", + "Tepper", + "Tera", + "Terbecki", + "Terchie", + "Terena", + "Terence", + "Terencio", + "Teresa", + "Terese", + "Teresina", + "Teresita", + "Teressa", + "Terhune", + "Teri", + "Teria", + "Teriann", + "Terina", + "Terle", + "Ternan", + "Terpstra", + "Terr", + "Terra", + "Terrance", + "Terrel", + "Terrell", + "Terrena", + "Terrence", + "Terrene", + "Terri", + "Terrie", + "Terrijo", + "Terrill", + "Terrilyn", + "Terris", + "Terriss", + "Territus", + "Terry", + "Terrye", + "Terryl", + "Terryn", + "Tersina", + "Terti", + "Tertia", + "Tertias", + "Tertius", + "Teryl", + "Teryn", + "Terza", + "Terzas", + "Tesler", + "Tess", + "Tessa", + "Tessi", + "Tessie", + "Tessler", + "Tessy", + "Teteak", + "Teufert", + "Teuton", + "Tevis", + "Tewell", + "Tewfik", + "Tews", + "Thacher", + "Thacker", + "Thackeray", + "Thad", + "Thaddaus", + "Thaddeus", + "Thaddus", + "Thadeus", + "Thagard", + "Thain", + "Thaine", + "Thais", + "Thalassa", + "Thalia", + "Tham", + "Thamora", + "Thamos", + "Thanasi", + "Thane", + "Thanh", + "Thanos", + "Thant", + "Thapa", + "Thar", + "Tharp", + "Thatch", + "Thatcher", + "Thaxter", + "Thay", + "Thayer", + "Thayne", + "The", + "Thea", + "Theadora", + "Theall", + "Thebault", + "Thecla", + "Theda", + "Thedric", + "Thedrick", + "Theis", + "Thekla", + "Thelma", + "Thema", + "Themis", + "Thenna", + "Theo", + "Theobald", + "Theodor", + "Theodora", + "Theodore", + "Theodoric", + "Theodosia", + "Theola", + "Theona", + "Theone", + "Thera", + "Theran", + "Theresa", + "Therese", + "Theresina", + "Theresita", + "Theressa", + "Therine", + "Theron", + "Therron", + "Thesda", + "Thessa", + "Theta", + "Thetes", + "Thetis", + "Thetisa", + "Thetos", + "Theurer", + "Theurich", + "Thevenot", + "Thia", + "Thibaud", + "Thibault", + "Thibaut", + "Thielen", + "Thier", + "Thierry", + "Thilda", + "Thilde", + "Thill", + "Thin", + "Thinia", + "Thirion", + "Thirza", + "Thirzi", + "Thirzia", + "Thisbe", + "Thisbee", + "Thissa", + "Thistle", + "Thoer", + "Thom", + "Thoma", + "Thomajan", + "Thomas", + "Thomasa", + "Thomasin", + "Thomasina", + "Thomasine", + "Thomey", + "Thompson", + "Thomsen", + "Thomson", + "Thor", + "Thora", + "Thorbert", + "Thordia", + "Thordis", + "Thorfinn", + "Thorin", + "Thorlay", + "Thorley", + "Thorlie", + "Thorma", + "Thorman", + "Thormora", + "Thorn", + "Thornburg", + "Thorncombe", + "Thorndike", + "Thorne", + "Thorner", + "Thornie", + "Thornton", + "Thorny", + "Thorpe", + "Thorr", + "Thorrlow", + "Thorstein", + "Thorsten", + "Thorvald", + "Thorwald", + "Thrasher", + "Three", + "Threlkeld", + "Thrift", + "Thun", + "Thunell", + "Thurber", + "Thurlough", + "Thurlow", + "Thurman", + "Thurmann", + "Thurmond", + "Thurnau", + "Thursby", + "Thurstan", + "Thurston", + "Thury", + "Thynne", + "Tia", + "Tiana", + "Tibbetts", + "Tibbitts", + "Tibbs", + "Tibold", + "Tica", + "Tice", + "Tichon", + "Tichonn", + "Ticknor", + "Ticon", + "Tidwell", + "Tiebold", + "Tiebout", + "Tiedeman", + "Tiemroth", + "Tien", + "Tiena", + "Tierell", + "Tiernan", + "Tierney", + "Tiersten", + "Tiertza", + "Tierza", + "Tifanie", + "Tiff", + "Tiffa", + "Tiffani", + "Tiffanie", + "Tiffanle", + "Tiffany", + "Tiffi", + "Tiffie", + "Tiffy", + "Tiga", + "Tigges", + "Tila", + "Tilda", + "Tilden", + "Tildi", + "Tildie", + "Tildy", + "Tiler", + "Tilford", + "Till", + "Tilla", + "Tillford", + "Tillfourd", + "Tillie", + "Tillinger", + "Tillio", + "Tillion", + "Tillman", + "Tillo", + "Tilly", + "Tilney", + "Tiloine", + "Tim", + "Tima", + "Timi", + "Timmi", + "Timmie", + "Timmons", + "Timms", + "Timmy", + "Timofei", + "Timon", + "Timoteo", + "Timothea", + "Timothee", + "Timotheus", + "Timothy", + "Tina", + "Tinaret", + "Tindall", + "Tine", + "Tingey", + "Tingley", + "Tini", + "Tiny", + "Tinya", + "Tiossem", + "Tiphane", + "Tiphani", + "Tiphanie", + "Tiphany", + "Tippets", + "Tips", + "Tipton", + "Tirrell", + "Tirza", + "Tirzah", + "Tisbe", + "Tisbee", + "Tisdale", + "Tish", + "Tisha", + "Tisman", + "Tita", + "Titania", + "Tito", + "Titos", + "Titus", + "Tizes", + "Tjaden", + "Tjader", + "Tjon", + "Tletski", + "Toback", + "Tobe", + "Tobey", + "Tobi", + "Tobiah", + "Tobias", + "Tobie", + "Tobin", + "Tobit", + "Toby", + "Tobye", + "Tocci", + "Tod", + "Todd", + "Toddie", + "Toddy", + "Todhunter", + "Toffey", + "Toffic", + "Toft", + "Toh", + "Toiboid", + "Toinette", + "Tol", + "Toland", + "Tolkan", + "Toll", + "Tolland", + "Tolley", + "Tolliver", + "Tollman", + "Tollmann", + "Tolmach", + "Tolman", + "Tolmann", + "Tom", + "Toma", + "Tomas", + "Tomasina", + "Tomasine", + "Tomaso", + "Tomasz", + "Tombaugh", + "Tomchay", + "Tome", + "Tomi", + "Tomkiel", + "Tomkin", + "Tomkins", + "Tomlin", + "Tomlinson", + "Tommi", + "Tommie", + "Tommy", + "Tompkins", + "Toms", + "Toney", + "Tongue", + "Toni", + "Tonia", + "Tonie", + "Tonina", + "Tonjes", + "Tonkin", + "Tonl", + "Tonneson", + "Tonnie", + "Tonry", + "Tony", + "Tonya", + "Tonye", + "Toogood", + "Toole", + "Tooley", + "Toolis", + "Toomay", + "Toombs", + "Toomin", + "Toor", + "Tootsie", + "Topliffe", + "Topper", + "Topping", + "Tor", + "Torbart", + "Torbert", + "Tore", + "Torey", + "Torhert", + "Tori", + "Torie", + "Torin", + "Tormoria", + "Torosian", + "Torp", + "Torr", + "Torrance", + "Torras", + "Torray", + "Torre", + "Torrell", + "Torrence", + "Torres", + "Torrey", + "Torrie", + "Torrin", + "Torrlow", + "Torruella", + "Torry", + "Torto", + "Tortosa", + "Tory", + "Toscano", + "Tosch", + "Toshiko", + "Toth", + "Touber", + "Toulon", + "Tound", + "Tova", + "Tove", + "Towbin", + "Tower", + "Towers", + "Towill", + "Towland", + "Town", + "Towne", + "Towney", + "Townie", + "Townsend", + "Townshend", + "Towny", + "Towrey", + "Towroy", + "Toy", + "Trabue", + "Tracay", + "Trace", + "Tracee", + "Tracey", + "Traci", + "Tracie", + "Tracy", + "Trager", + "Trahern", + "Trahurn", + "Trainer", + "Trainor", + "Trakas", + "Trammel", + "Tran", + "Tranquada", + "Trant", + "Trask", + "Tratner", + "Trauner", + "Trautman", + "Travax", + "Traver", + "Travers", + "Travis", + "Travus", + "Traweek", + "Tray", + "Treacy", + "Treat", + "Trefler", + "Trefor", + "Treharne", + "Treiber", + "Trela", + "Trella", + "Trellas", + "Trelu", + "Tremain", + "Tremaine", + "Tremann", + "Tremayne", + "Trembly", + "Tremml", + "Trenna", + "Trent", + "Trenton", + "Tresa", + "Trescha", + "Trescott", + "Tressa", + "Tressia", + "Treulich", + "Trev", + "Treva", + "Trevah", + "Trevar", + "Trever", + "Trevethick", + "Trevor", + "Trevorr", + "Trey", + "Tri", + "Trici", + "Tricia", + "Trilbee", + "Trilbi", + "Trilbie", + "Trilby", + "Triley", + "Trill", + "Trillbee", + "Trillby", + "Trilley", + "Trilly", + "Trimble", + "Trimmer", + "Trin", + "Trina", + "Trinatte", + "Trinee", + "Trinetta", + "Trinette", + "Trini", + "Trinia", + "Trinidad", + "Trinity", + "Trinl", + "Triny", + "Trip", + "Triplett", + "Tripp", + "Tris", + "Trisa", + "Trish", + "Trisha", + "Trista", + "Tristam", + "Tristan", + "Tristas", + "Tristis", + "Tristram", + "Trix", + "Trixi", + "Trixie", + "Trixy", + "Trocki", + "Trojan", + "Trometer", + "Tronna", + "Troth", + "Trotta", + "Trotter", + "Trout", + "Trovillion", + "Trow", + "Troxell", + "Troy", + "Troyes", + "Trstram", + "Trubow", + "Truc", + "Truda", + "Trude", + "Trudey", + "Trudi", + "Trudie", + "Trudnak", + "Trudy", + "True", + "Trueblood", + "Truelove", + "Trueman", + "Truitt", + "Trula", + "Trumaine", + "Truman", + "Trumann", + "Truscott", + "Trust", + "Trutko", + "Tryck", + "Trygve", + "Tsai", + "Tsan", + "Tse", + "Tseng", + "Tshombe", + "Tsuda", + "Tsui", + "Tu", + "Tubb", + "Tuchman", + "Tuck", + "Tucker", + "Tuckie", + "Tucky", + "Tuddor", + "Tudela", + "Tudor", + "Tuesday", + "Tufts", + "Tugman", + "Tuinenga", + "Tull", + "Tulley", + "Tullius", + "Tullus", + "Tullusus", + "Tully", + "Tumer", + "Tuneberg", + "Tung", + "Tunnell", + "Tupler", + "Tuppeny", + "Turino", + "Turk", + "Turley", + "Turmel", + "Turnbull", + "Turne", + "Turner", + "Turnheim", + "Turoff", + "Turpin", + "Turrell", + "Turro", + "Turtle", + "Tut", + "Tutankhamen", + "Tutt", + "Tuttle", + "Tutto", + "Twedy", + "Twelve", + "Twila", + "Twitt", + "Twum", + "Twyla", + "Ty", + "Tybald", + "Tybalt", + "Tybi", + "Tybie", + "Tychon", + "Tychonn", + "Tye", + "Tyika", + "Tyler", + "Tymes", + "Tymon", + "Tymothy", + "Tynan", + "Tyne", + "Tyra", + "Tyre", + "Tyree", + "Tyrone", + "Tyrrell", + "Tyrus", + "Tyson", + "Tzong", + "Ubald", + "Uball", + "Ubana", + "Ube", + "Uchida", + "Uchish", + "Uda", + "Udale", + "Udall", + "Udela", + "Udele", + "Udell", + "Udella", + "Udelle", + "Uel", + "Uela", + "Uella", + "Ugo", + "Uird", + "Uis", + "Uke", + "Ul", + "Ula", + "Ulah", + "Ulane", + "Ulani", + "Ulberto", + "Ulda", + "Ule", + "Ulick", + "Ulises", + "Ulita", + "Ulla", + "Ulland", + "Ullman", + "Ullund", + "Ullyot", + "Ulphi", + "Ulphia", + "Ulphiah", + "Ulric", + "Ulrica", + "Ulrich", + "Ulrick", + "Ulrika", + "Ulrikaumeko", + "Ulrike", + "Ultan", + "Ultann", + "Ultima", + "Ultun", + "Ulu", + "Ulund", + "Ulysses", + "Umberto", + "Ume", + "Umeh", + "Umeko", + "Ummersen", + "Umont", + "Un", + "Una", + "Unders", + "Underwood", + "Undine", + "Undis", + "Undry", + "Une", + "Ungley", + "Uni", + "Unity", + "Unni", + "Uno", + "Upali", + "Uphemia", + "Upshaw", + "Upton", + "Urana", + "Urania", + "Uranie", + "Urata", + "Urba", + "Urbai", + "Urbain", + "Urban", + "Urbana", + "Urbani", + "Urbanna", + "Urbannai", + "Urbannal", + "Urbano", + "Urbanus", + "Urbas", + "Uri", + "Uria", + "Uriah", + "Urial", + "Urian", + "Urias", + "Uriel", + "Urien", + "Uriia", + "Uriiah", + "Uriisa", + "Urina", + "Urion", + "Urissa", + "Urita", + "Urquhart", + "Ursa", + "Ursal", + "Ursala", + "Ursas", + "Ursel", + "Ursi", + "Ursola", + "Urson", + "Ursula", + "Ursulette", + "Ursulina", + "Ursuline", + "Ury", + "Usanis", + "Ushijima", + "Uta", + "Utas", + "Ute", + "Utham", + "Uthrop", + "Utica", + "Uticas", + "Utimer", + "Utley", + "Utta", + "Uttasta", + "Utter", + "Uttica", + "Uuge", + "Uund", + "Uwton", + "Uyekawa", + "Uzia", + "Uzial", + "Uziel", + "Uzzi", + "Uzzia", + "Uzzial", + "Uzziel", + "Va", + "Vaas", + "Vaasta", + "Vachel", + "Vachell", + "Vachil", + "Vachill", + "Vacla", + "Vaclav", + "Vaclava", + "Vacuva", + "Vada", + "Vaden", + "Vadim", + "Vadnee", + "Vaenfila", + "Vahe", + "Vaientina", + "Vail", + "Vaios", + "Vaish", + "Val", + "Vala", + "Valaree", + "Valaria", + "Valda", + "Valdas", + "Valdemar", + "Valdes", + "Valdis", + "Vale", + "Valeda", + "Valenba", + "Valencia", + "Valene", + "Valenka", + "Valenta", + "Valente", + "Valentia", + "Valentijn", + "Valentin", + "Valentina", + "Valentine", + "Valentino", + "Valenza", + "Valer", + "Valera", + "Valeria", + "Valerian", + "Valerie", + "Valerio", + "Valerlan", + "Valerle", + "Valery", + "Valerye", + "Valeta", + "Valiant", + "Valida", + "Valina", + "Valle", + "Valleau", + "Vallery", + "Valley", + "Valli", + "Vallie", + "Vallo", + "Vallonia", + "Vally", + "Valma", + "Valonia", + "Valoniah", + "Valora", + "Valorie", + "Valry", + "Valtin", + "Van", + "VanHook", + "Vance", + "Vanda", + "Vanden", + "Vander", + "Vanderhoek", + "Vandervelde", + "Vandyke", + "Vanessa", + "Vange", + "Vanhomrigh", + "Vani", + "Vania", + "Vanna", + "Vanni", + "Vannie", + "Vanny", + "Vano", + "Vanthe", + "Vanya", + "Vanzant", + "Varden", + "Vardon", + "Vareck", + "Vargas", + "Varhol", + "Varian", + "Varick", + "Varien", + "Varini", + "Varion", + "Varipapa", + "Varney", + "Varrian", + "Vary", + "Vas", + "Vashtee", + "Vashti", + "Vashtia", + "Vasileior", + "Vasilek", + "Vasili", + "Vasiliki", + "Vasilis", + "Vasiliu", + "Vasily", + "Vasos", + "Vasquez", + "Vassar", + "Vassaux", + "Vassell", + "Vassili", + "Vassily", + "Vasta", + "Vastah", + "Vastha", + "Vasti", + "Vasya", + "Vasyuta", + "Vaughan", + "Vaughn", + "Vaules", + "Veal", + "Veator", + "Veats", + "Veda", + "Vedetta", + "Vedette", + "Vedi", + "Vedis", + "Veedis", + "Velasco", + "Velda", + "Veleda", + "Velick", + "Veljkov", + "Velleman", + "Velma", + "Velvet", + "Vena", + "Venable", + "Venator", + "Venditti", + "Veneaux", + "Venetia", + "Venetis", + "Venezia", + "Venice", + "Venita", + "Venn", + "Veno", + "Venola", + "Venterea", + "Vento", + "Ventre", + "Ventura", + "Venu", + "Venus", + "Venuti", + "Ver", + "Vera", + "Verada", + "Veradi", + "Veradia", + "Veradis", + "Verbenia", + "Verda", + "Verdha", + "Verdi", + "Verdie", + "Vere", + "Verena", + "Verene", + "Verge", + "Verger", + "Vergil", + "Vergne", + "Vergos", + "Veriee", + "Verile", + "Verina", + "Verine", + "Verity", + "Verla", + "Verlee", + "Verlie", + "Vern", + "Verna", + "Verne", + "Vernen", + "Verner", + "Verneuil", + "Verney", + "Vernice", + "Vernier", + "Vernita", + "Vernon", + "Vernor", + "Veron", + "Veronica", + "Veronika", + "Veronike", + "Veronique", + "Verras", + "Vershen", + "Vescuso", + "Vesta", + "Veta", + "Vetter", + "Vevay", + "Vevina", + "Vevine", + "Vey", + "Vezza", + "Vharat", + "Vi", + "Viafore", + "Vial", + "Vic", + "Viccora", + "Vick", + "Vickey", + "Vicki", + "Vickie", + "Vicky", + "Victoir", + "Victor", + "Victoria", + "Victorie", + "Victorine", + "Victory", + "Vida", + "Vidal", + "Vidda", + "Viddah", + "Vidovic", + "Vidovik", + "Viehmann", + "Viens", + "Vierno", + "Vieva", + "Vig", + "Vigen", + "Viglione", + "Vigor", + "Viguerie", + "Viki", + "Viking", + "Vikki", + "Vikky", + "Vilberg", + "Vilhelmina", + "Villada", + "Villiers", + "Vilma", + "Vin", + "Vina", + "Vinaya", + "Vince", + "Vincelette", + "Vincent", + "Vincenta", + "Vincentia", + "Vincents", + "Vincenty", + "Vincenz", + "Vine", + "Vinia", + "Vinita", + "Vinn", + "Vinna", + "Vinni", + "Vinnie", + "Vinny", + "Vins", + "Vinson", + "Viola", + "Violante", + "Viole", + "Violet", + "Violeta", + "Violetta", + "Violette", + "Vipul", + "Viquelia", + "Viradis", + "Virendra", + "Virg", + "Virge", + "Virgel", + "Virgie", + "Virgil", + "Virgilia", + "Virgilio", + "Virgin", + "Virgina", + "Virginia", + "Virginie", + "Virgy", + "Viridi", + "Viridis", + "Viridissa", + "Virnelli", + "Viscardi", + "Vish", + "Vita", + "Vitale", + "Vitalis", + "Vite", + "Vitek", + "Vitia", + "Vitkun", + "Vito", + "Vitoria", + "Vittoria", + "Vittorio", + "Vitus", + "Viv", + "Viva", + "Viveca", + "Vivi", + "Vivia", + "Vivian", + "Viviana", + "Viviane", + "Vivianna", + "Vivianne", + "Vivica", + "Vivie", + "Vivien", + "Viviene", + "Vivienne", + "Viviyan", + "Vivl", + "Vivle", + "Vivyan", + "Vivyanne", + "Vizza", + "Vizzone", + "Vlad", + "Vlada", + "Vladamar", + "Vladamir", + "Vladi", + "Vladimar", + "Vladimir", + "Voccola", + "Voe", + "Vogel", + "Vogele", + "Vogeley", + "Vola", + "Volding", + "Voleta", + "Voletta", + "Volin", + "Volkan", + "Volnak", + "Volnay", + "Volney", + "Volny", + "Volotta", + "Volpe", + "Voltmer", + "Voltz", + "Von", + "Vona", + "Vonni", + "Vonnie", + "Vonny", + "Vookles", + "Voorhis", + "Vorfeld", + "Vories", + "Vorster", + "Voss", + "Votaw", + "Vowel", + "Vrablik", + "Vtarj", + "Vtehsta", + "Vudimir", + "Vullo", + "Vyky", + "Vyner", + "Vyse", + "Waal", + "Wachtel", + "Wachter", + "Wack", + "Waddell", + "Waddington", + "Waddle", + "Wade", + "Wadell", + "Wadesworth", + "Wadleigh", + "Wadlinger", + "Wadsworth", + "Waechter", + "Waers", + "Wager", + "Wagner", + "Wagoner", + "Wagshul", + "Wagstaff", + "Wahkuna", + "Wahl", + "Wahlstrom", + "Wailoo", + "Wain", + "Waine", + "Wainwright", + "Wait", + "Waite", + "Waiter", + "Wake", + "Wakeen", + "Wakefield", + "Wakerly", + "Waki", + "Walburga", + "Walcoff", + "Walcott", + "Walczak", + "Wald", + "Waldack", + "Waldemar", + "Walden", + "Waldman", + "Waldner", + "Waldo", + "Waldon", + "Waldos", + "Waldron", + "Wales", + "Walford", + "Waligore", + "Walke", + "Walker", + "Walkling", + "Wall", + "Wallace", + "Wallach", + "Wallache", + "Wallack", + "Wallas", + "Waller", + "Walley", + "Wallford", + "Walli", + "Wallie", + "Walling", + "Wallinga", + "Wallis", + "Walliw", + "Wallraff", + "Walls", + "Wally", + "Walrath", + "Walsh", + "Walston", + "Walt", + "Walter", + "Walters", + "Walther", + "Waltner", + "Walton", + "Walworth", + "Waly", + "Wampler", + "Wamsley", + "Wan", + "Wanda", + "Wandie", + "Wandis", + "Wandy", + "Wane", + "Waneta", + "Wanfried", + "Wang", + "Wanids", + "Wanonah", + "Wanyen", + "Wappes", + "Warchaw", + "Ward", + "Warde", + "Warden", + "Warder", + "Wardieu", + "Wardlaw", + "Wardle", + "Ware", + "Wareing", + "Warenne", + "Warfeld", + "Warfield", + "Warfold", + "Warford", + "Warfore", + "Warfourd", + "Warga", + "Warila", + "Waring", + "Warms", + "Warner", + "Warp", + "Warram", + "Warren", + "Warrenne", + "Warrick", + "Warrin", + "Warring", + "Warthman", + "Warton", + "Wartow", + "Warwick", + "Wash", + "Washburn", + "Washington", + "Washko", + "Wasserman", + "Wasson", + "Wassyngton", + "Wat", + "Watanabe", + "Waterer", + "Waterman", + "Waters", + "Watkin", + "Watkins", + "Watson", + "Watt", + "Wattenberg", + "Watters", + "Watts", + "Waugh", + "Wauters", + "Wavell", + "Waverley", + "Waverly", + "Wawro", + "Waxler", + "Waxman", + "Way", + "Waylan", + "Wayland", + "Waylen", + "Waylin", + "Waylon", + "Waynant", + "Wayne", + "Wayolle", + "Weaks", + "Wearing", + "Weasner", + "Weatherby", + "Weatherley", + "Weathers", + "Weaver", + "Web", + "Webb", + "Webber", + "Weber", + "Webster", + "Wedurn", + "Weed", + "Weeks", + "Wehner", + "Wehrle", + "Wei", + "Weibel", + "Weidar", + "Weide", + "Weider", + "Weidman", + "Weidner", + "Weig", + "Weight", + "Weigle", + "Weihs", + "Weikert", + "Weil", + "Weiler", + "Weiman", + "Wein", + "Weinberg", + "Weiner", + "Weinert", + "Weingarten", + "Weingartner", + "Weinhardt", + "Weinman", + "Weinreb", + "Weinrich", + "Weinshienk", + "Weinstein", + "Weinstock", + "Weintrob", + "Weir", + "Weirick", + "Weisbart", + "Weisberg", + "Weisbrodt", + "Weisburgh", + "Weiser", + "Weisler", + "Weisman", + "Weismann", + "Weiss", + "Weissberg", + "Weissman", + "Weissmann", + "Weitman", + "Weitzman", + "Weixel", + "Weksler", + "Welbie", + "Welby", + "Welch", + "Welcher", + "Welcome", + "Welcy", + "Weld", + "Weldon", + "Welford", + "Welker", + "Welles", + "Wellesley", + "Wellington", + "Wells", + "Welsh", + "Welton", + "Wenda", + "Wendall", + "Wendalyn", + "Wende", + "Wendel", + "Wendelin", + "Wendelina", + "Wendeline", + "Wendell", + "Wendi", + "Wendie", + "Wendin", + "Wendolyn", + "Wendt", + "Wendy", + "Wendye", + "Wenger", + "Wengert", + "Wenn", + "Wennerholn", + "Wenoa", + "Wenona", + "Wenonah", + "Wentworth", + "Wenz", + "Wera", + "Werbel", + "Werby", + "Werner", + "Wernher", + "Wernick", + "Wernsman", + "Werra", + "Wershba", + "Wertheimer", + "Wertz", + "Wes", + "Wesa", + "Wescott", + "Wesla", + "Wesle", + "Weslee", + "Wesley", + "Wessling", + "West", + "Westberg", + "Westbrook", + "Westbrooke", + "Wester", + "Westerfield", + "Westfahl", + "Westfall", + "Westhead", + "Westland", + "Westleigh", + "Westley", + "Westlund", + "Westmoreland", + "Westney", + "Weston", + "Westphal", + "Wetzel", + "Wetzell", + "Wexler", + "Wey", + "Weyermann", + "Weylin", + "Weywadt", + "Whale", + "Whalen", + "Whall", + "Whallon", + "Whang", + "Wharton", + "Whatley", + "Wheaton", + "Wheeler", + "Wheelwright", + "Whelan", + "Whetstone", + "Whiffen", + "Whiney", + "Whipple", + "Whit", + "Whitaker", + "Whitby", + "Whitcher", + "Whitcomb", + "White", + "Whitebook", + "Whitehouse", + "Whitehurst", + "Whitelaw", + "Whiteley", + "Whitford", + "Whiting", + "Whitman", + "Whitnell", + "Whitney", + "Whitson", + "Whittaker", + "Whittemore", + "Whitten", + "Whitver", + "Whorton", + "Whyte", + "Wiatt", + "Wiburg", + "Wichern", + "Wichman", + "Wickham", + "Wickman", + "Wickner", + "Wicks", + "Widera", + "Wie", + "Wiebmer", + "Wieche", + "Wiedmann", + "Wiencke", + "Wiener", + "Wier", + "Wieren", + "Wiersma", + "Wiese", + "Wiggins", + "Wight", + "Wightman", + "Wil", + "Wilber", + "Wilbert", + "Wilbur", + "Wilburn", + "Wilburt", + "Wilcox", + "Wilda", + "Wilde", + "Wildee", + "Wilden", + "Wilder", + "Wildermuth", + "Wildon", + "Wileen", + "Wilek", + "Wilen", + "Wiles", + "Wiley", + "Wilfred", + "Wilfreda", + "Wilfrid", + "Wilhelm", + "Wilhelmina", + "Wilhelmine", + "Wilhide", + "Wilie", + "Wilinski", + "Wilkens", + "Wilkey", + "Wilkie", + "Wilkins", + "Wilkinson", + "Wilkison", + "Will", + "Willa", + "Willabella", + "Willamina", + "Willard", + "Willcox", + "Willdon", + "Willem", + "Willet", + "Willett", + "Willetta", + "Willette", + "Willey", + "Willi", + "William", + "Williams", + "Williamsen", + "Williamson", + "Willie", + "Willin", + "Willing", + "Willis", + "Willman", + "Willmert", + "Willms", + "Willner", + "Willock", + "Willow", + "Wills", + "Willtrude", + "Willumsen", + "Willy", + "Willyt", + "Wilma", + "Wilmar", + "Wilmer", + "Wilmette", + "Wilmott", + "Wilona", + "Wilonah", + "Wilone", + "Wilow", + "Wilscam", + "Wilser", + "Wilsey", + "Wilson", + "Wilt", + "Wilterdink", + "Wilton", + "Wiltsey", + "Wiltshire", + "Wiltz", + "Wimsatt", + "Win", + "Wina", + "Wincer", + "Winchell", + "Winchester", + "Wind", + "Windham", + "Windsor", + "Windy", + "Windzer", + "Winebaum", + "Winer", + "Winfield", + "Winfred", + "Winfrid", + "Wing", + "Wini", + "Winifield", + "Winifred", + "Winikka", + "Winn", + "Winna", + "Winnah", + "Winne", + "Winni", + "Winnick", + "Winnie", + "Winnifred", + "Winny", + "Winograd", + "Winola", + "Winona", + "Winonah", + "Winou", + "Winser", + "Winshell", + "Winslow", + "Winson", + "Winsor", + "Winston", + "Winstonn", + "Winter", + "Winterbottom", + "Winters", + "Winther", + "Winthorpe", + "Winthrop", + "Winton", + "Winwaloe", + "Winzler", + "Wira", + "Wirth", + "Wise", + "Wiseman", + "Wiskind", + "Wisnicki", + "Wistrup", + "Wit", + "Witcher", + "Witha", + "Witherspoon", + "Witkin", + "Witt", + "Witte", + "Wittenburg", + "Wittie", + "Witty", + "Wivestad", + "Wivina", + "Wivinah", + "Wivinia", + "Wixted", + "Woehick", + "Woermer", + "Wohlen", + "Wohlert", + "Wojak", + "Wojcik", + "Wolbrom", + "Wolcott", + "Wolenik", + "Wolf", + "Wolfe", + "Wolff", + "Wolfgang", + "Wolfgram", + "Wolfie", + "Wolford", + "Wolfort", + "Wolfram", + "Wolfson", + "Wolfy", + "Wolgast", + "Wolk", + "Woll", + "Wollis", + "Wolpert", + "Wolsky", + "Womack", + "Won", + "Wonacott", + "Wong", + "Woo", + "Wood", + "Woodall", + "Woodberry", + "Woodcock", + "Woodford", + "Woodhead", + "Woodhouse", + "Woodie", + "Woodley", + "Woodman", + "Woodring", + "Woodrow", + "Woodruff", + "Woods", + "Woodson", + "Woodsum", + "Woodward", + "Woody", + "Woolcott", + "Wooldridge", + "Woolley", + "Woolson", + "Wooster", + "Wootan", + "Woothen", + "Wootten", + "Worden", + "Worl", + "Worlock", + "Worrell", + "Worsham", + "Worth", + "Worthington", + "Worthy", + "Wrand", + "Wren", + "Wrench", + "Wrennie", + "Wright", + "Wrightson", + "Wrigley", + "Wsan", + "Wu", + "Wulf", + "Wulfe", + "Wun", + "Wunder", + "Wurst", + "Wurster", + "Wurtz", + "Wyatan", + "Wyatt", + "Wyck", + "Wycoff", + "Wye", + "Wylde", + "Wylen", + "Wyler", + "Wylie", + "Wylma", + "Wyly", + "Wymore", + "Wyn", + "Wyndham", + "Wyne", + "Wynn", + "Wynne", + "Wynnie", + "Wynny", + "Wyon", + "Wystand", + "Xantha", + "Xanthe", + "Xanthus", + "Xavier", + "Xaviera", + "Xavler", + "Xena", + "Xenia", + "Xeno", + "Xenophon", + "Xenos", + "Xerxes", + "Xever", + "Ximena", + "Ximenes", + "Ximenez", + "Xylia", + "Xylina", + "Xylon", + "Xymenes", + "Yaakov", + "Yablon", + "Yacano", + "Yacov", + "Yaeger", + "Yael", + "Yager", + "Yahiya", + "Yaker", + "Yale", + "Yalonda", + "Yam", + "Yamauchi", + "Yanaton", + "Yance", + "Yancey", + "Yancy", + "Yand", + "Yank", + "Yankee", + "Yann", + "Yarak", + "Yard", + "Yardley", + "Yaron", + "Yarvis", + "Yasmeen", + "Yasmin", + "Yasmine", + "Yasu", + "Yasui", + "Yate", + "Yates", + "Yatzeck", + "Yaya", + "Yazbak", + "Yeargain", + "Yearwood", + "Yeaton", + "Yecies", + "Yee", + "Yeh", + "Yehudi", + "Yehudit", + "Yelena", + "Yelich", + "Yelmene", + "Yemane", + "Yeo", + "Yeorgi", + "Yerga", + "Yerkovich", + "Yerxa", + "Yesima", + "Yeta", + "Yetac", + "Yetah", + "Yetta", + "Yetti", + "Yettie", + "Yetty", + "Yeung", + "Yevette", + "Yi", + "Yila", + "Yim", + "Yirinec", + "Ylla", + "Ynes", + "Ynez", + "Yoho", + "Yoko", + "Yokoyama", + "Yokum", + "Yolanda", + "Yolande", + "Yolane", + "Yolanthe", + "Yona", + "Yonah", + "Yonatan", + "Yong", + "Yonina", + "Yonit", + "Yonita", + "Yoo", + "Yoong", + "Yordan", + "Yorgen", + "Yorgo", + "Yorgos", + "Yorick", + "York", + "Yorke", + "Yorker", + "Yoshi", + "Yoshiko", + "Yoshio", + "Youlton", + "Young", + "Younger", + "Youngman", + "Youngran", + "Yousuf", + "Yovonnda", + "Ysabel", + "Yseult", + "Yseulta", + "Yseulte", + "Yuhas", + "Yuille", + "Yuji", + "Yuk", + "Yukio", + "Yul", + "Yule", + "Yulma", + "Yuma", + "Yumuk", + "Yun", + "Yunfei", + "Yung", + "Yunick", + "Yup", + "Yuri", + "Yuria", + "Yurik", + "Yursa", + "Yurt", + "Yusem", + "Yusuk", + "Yuu", + "Yuzik", + "Yves", + "Yvette", + "Yvon", + "Yvonne", + "Yvonner", + "Yvor", + "Zabrina", + "Zabrine", + "Zacarias", + "Zaccaria", + "Zacek", + "Zach", + "Zachar", + "Zacharia", + "Zachariah", + "Zacharias", + "Zacharie", + "Zachary", + "Zacherie", + "Zachery", + "Zack", + "Zackariah", + "Zacks", + "Zadack", + "Zadoc", + "Zahara", + "Zahavi", + "Zaid", + "Zailer", + "Zak", + "Zakaria", + "Zakarias", + "Zalea", + "Zales", + "Zaller", + "Zalucki", + "Zamir", + "Zamora", + "Zampardi", + "Zampino", + "Zandra", + "Zandt", + "Zane", + "Zaneski", + "Zaneta", + "Zannini", + "Zantos", + "Zanze", + "Zara", + "Zaragoza", + "Zarah", + "Zared", + "Zaremski", + "Zarger", + "Zaria", + "Zarla", + "Zashin", + "Zaslow", + "Zasuwa", + "Zavala", + "Zavras", + "Zawde", + "Zea", + "Zealand", + "Zeb", + "Zeba", + "Zebada", + "Zebadiah", + "Zebapda", + "Zebe", + "Zebedee", + "Zebulen", + "Zebulon", + "Zechariah", + "Zeculon", + "Zed", + "Zedekiah", + "Zeeba", + "Zeena", + "Zehe", + "Zeidman", + "Zeiger", + "Zeiler", + "Zeitler", + "Zeke", + "Zel", + "Zela", + "Zelazny", + "Zelda", + "Zelde", + "Zelig", + "Zelikow", + "Zelle", + "Zellner", + "Zelma", + "Zelten", + "Zena", + "Zenas", + "Zenda", + "Zendah", + "Zenger", + "Zenia", + "Zennas", + "Zennie", + "Zenobia", + "Zeph", + "Zephan", + "Zephaniah", + "Zeralda", + "Zerelda", + "Zerk", + "Zerla", + "Zerlina", + "Zerline", + "Zeta", + "Zetana", + "Zetes", + "Zetta", + "Zeus", + "Zhang", + "Zia", + "Ziagos", + "Zicarelli", + "Ziegler", + "Zielsdorf", + "Zigmund", + "Zigrang", + "Ziguard", + "Zilber", + "Zildjian", + "Zilla", + "Zillah", + "Zilvia", + "Zima", + "Zimmer", + "Zimmerman", + "Zimmermann", + "Zina", + "Zinah", + "Zinck", + "Zindman", + "Zingale", + "Zingg", + "Zink", + "Zinn", + "Zinnes", + "Zins", + "Zipah", + "Zipnick", + "Zippel", + "Zippora", + "Zipporah", + "Zirkle", + "Zischke", + "Zita", + "Zitah", + "Zitella", + "Zitvaa", + "Ziwot", + "Zoa", + "Zoara", + "Zoarah", + "Zoba", + "Zobe", + "Zobias", + "Zobkiw", + "Zoe", + "Zoeller", + "Zoellick", + "Zoes", + "Zoha", + "Zohar", + "Zohara", + "Zoi", + "Zoie", + "Zoila", + "Zoilla", + "Zola", + "Zoldi", + "Zoller", + "Zollie", + "Zolly", + "Zolnay", + "Zolner", + "Zoltai", + "Zonda", + "Zondra", + "Zonnya", + "Zora", + "Zorah", + "Zorana", + "Zorina", + "Zorine", + "Zosema", + "Zosi", + "Zosima", + "Zoubek", + "Zrike", + "Zsa", + "Zsa Zsa", + "Zsazsa", + "Zsolway", + "Zubkoff", + "Zucker", + "Zuckerman", + "Zug", + "Zulch", + "Zuleika", + "Zulema", + "Zullo", + "Zumstein", + "Zumwalt", + "Zurek", + "Zurheide", + "Zurkow", + "Zurn", + "Zusman", + "Zuzana", + "Zwart", + "Zweig", + "Zwick", + "Zwiebel", + "Zysk" +] diff --git a/common/name_generator.gd.uid b/common/name_generator.gd.uid new file mode 100644 index 00000000..51bfa0e1 --- /dev/null +++ b/common/name_generator.gd.uid @@ -0,0 +1 @@ +uid://fr6cpihs6dcx diff --git a/common/nodes/node_bucket.gd b/common/nodes/node_bucket.gd new file mode 100644 index 00000000..3fa368ba --- /dev/null +++ b/common/nodes/node_bucket.gd @@ -0,0 +1,123 @@ +extends Node + +const DEFAULT_NODES_LOCATION := "res://nodes/" + +var _descriptors: Dictionary = {} +var _is_initialized: bool = false + + +func register_descriptor(descriptor) -> void: + if descriptor == null: + push_warning("Attempted to register a null GraphNodeDescriptor.") + return + if descriptor.name.is_empty(): + push_warning("GraphNodeDescriptor missing name.") + return + if _descriptors.has(descriptor.name): + push_warning("GraphNodeDescriptor '%s' already registered." % descriptor.name) + return + _descriptors[descriptor.name] = descriptor + + +func get_descriptor(descriptor_name: String): + _ensure_initialized() + return _descriptors.get(descriptor_name) + + +func list_descriptors() -> Array: + _ensure_initialized() + var values: Array = _descriptors.values() + values.sort_custom(_sort_descriptors) + return values + + +func list_metadata() -> Array[Dictionary]: + return list_descriptors().map(func(desc) -> Dictionary: return desc.to_metadata()) + + +func get_categories() -> PackedStringArray: + _ensure_initialized() + var categories: PackedStringArray = [] + for descriptor in _descriptors.values(): + if descriptor.category in categories: + continue + categories.append(descriptor.category) + categories.sort() + return categories + + +func get_descriptors_by_category(category: String) -> Array: + _ensure_initialized() + var result: Array = [] + for descriptor in _descriptors.values(): + if descriptor.category == category: + result.append(descriptor) + result.sort_custom(_sort_descriptors) + return result + + +func create_node(descriptor_name: String, history: CommandManager) -> InspectableNode: + var descriptor = get_descriptor(descriptor_name) + if descriptor: + return descriptor.instantiate_node(history) + push_warning("No node descriptor registered for '%s'." % descriptor_name) + return null + + +func refresh_registry() -> void: + _is_initialized = false + _descriptors.clear() + _ensure_initialized() + + +func _ensure_initialized() -> void: + if _is_initialized: + return + _search_nodes() + _is_initialized = true + + +func _search_nodes() -> void: + var directories: Array = DirAccess.get_directories_at(DEFAULT_NODES_LOCATION) + for dir_path: String in directories: + var index_path := DEFAULT_NODES_LOCATION.path_join(dir_path).path_join("index.gd") + if not FileAccess.file_exists(index_path): + continue + var index_script: Script = load(index_path) + if index_script == null: + push_warning("Failed to load node indexer at %s" % index_path) + continue + var indexer = index_script.new() + var descriptor = _descriptor_from_indexer(indexer) + if descriptor: + register_descriptor(descriptor) + + +func _descriptor_from_indexer(indexer): + if not indexer: + return null + if indexer.has_method("get_metadata"): + var metadata: Dictionary = indexer.call("get_metadata") + if metadata.get("type") != MonologueIndexer.ObjectType.NODE: + return null + var descriptor_name: String = metadata.get("name", "") + if descriptor_name.is_empty(): + return null + var script_resource: Script + if indexer.has_method("get_node_script"): + script_resource = indexer.call("get_node_script") + elif metadata.has("script"): + var raw_script = metadata.get("script") + if raw_script is Script: + script_resource = raw_script + elif raw_script is String and not raw_script.is_empty(): + script_resource = load(raw_script) + if script_resource == null: + push_warning("Indexer for '%s' missing script reference." % descriptor_name) + return null + return GraphNodeDescriptor.new(descriptor_name, script_resource, metadata) + return null + + +static func _sort_descriptors(a, b) -> bool: + return a.display_name.naturalnocasecmp_to(b.display_name) < 0 diff --git a/common/nodes/node_bucket.gd.uid b/common/nodes/node_bucket.gd.uid new file mode 100644 index 00000000..ee32760d --- /dev/null +++ b/common/nodes/node_bucket.gd.uid @@ -0,0 +1 @@ +uid://clgkk52nqoxyj diff --git a/common/nodes/node_descriptor.gd b/common/nodes/node_descriptor.gd new file mode 100644 index 00000000..3ea2f993 --- /dev/null +++ b/common/nodes/node_descriptor.gd @@ -0,0 +1,58 @@ +class_name GraphNodeDescriptor extends RefCounted + +var name: String +var node_script: Script +var display_name: String +var category: String = "General" +var icon: Texture2D +var color: Color = Color.WHITE +var tags: Array[String] = [] +var description: String = "" + + +func _init(p_name: String = "", p_script: Script = null, metadata: Dictionary = {}) -> void: + name = p_name + node_script = p_script + display_name = metadata.get("display_name", Util.to_readable_name(name)) + category = metadata.get("category", category) + description = metadata.get("description", "") + + var raw_icon = metadata.get("icon") + if raw_icon is Texture2D: + icon = raw_icon + elif raw_icon is String and not raw_icon.is_empty(): + var loaded_icon = load(raw_icon) + if loaded_icon is Texture2D: + icon = loaded_icon + + var raw_color = metadata.get("color") + if raw_color is Color: + color = raw_color + elif raw_color is String and not raw_color.is_empty(): + color = Color(raw_color) + + if metadata.has("tags") and metadata["tags"] is Array: + tags = metadata["tags"].duplicate(true) + + +func instantiate_node(history: CommandManager) -> InspectableNode: + if node_script == null: + push_warning("Descriptor '%s' missing script for instantiation." % name) + return null + var instance = node_script.new(history) + if instance is InspectableNode: + return instance + push_error("Descriptor '%s' does not create an InspectableNode." % name) + return null + + +func to_metadata() -> Dictionary: + return { + "name": name, + "display_name": display_name, + "category": category, + "description": description, + "color": color, + "icon": icon, + "tags": tags.duplicate(true) + } diff --git a/common/nodes/node_descriptor.gd.uid b/common/nodes/node_descriptor.gd.uid new file mode 100644 index 00000000..13620592 --- /dev/null +++ b/common/nodes/node_descriptor.gd.uid @@ -0,0 +1 @@ +uid://c1fyc8bo63wvk diff --git a/common/schemas.gd b/common/schemas.gd new file mode 100644 index 00000000..9ef400bf --- /dev/null +++ b/common/schemas.gd @@ -0,0 +1,256 @@ +class_name Schemas + +static var VARIABLE: Dictionary = { + "title": "Variable", + "type": "object", + "properties": + { + "name": + { + "type": "text", + "default": "new variable", + "required": true, + "unique": true, + "validation": {"min_length": 1} + }, + "type": + { + "type": "dropdown", + "options": ["bool", "string", "int", "float"], + "default": "string", + "required": true + }, + "value": + { + "type": "dynamic", + "case_property": "type", + "cases": + { + "bool": {"type": "bool", "default": false}, + "string": {"type": "text", "default": "", "coerce": "string"}, + "int": {"type": "number", "default": 0, "coerce": "int"}, + "float": {"type": "number", "default": 0.0, "coerce": "float"} + } + }, + "description": + { + "type": "textarea", + "default": "", + "rows": 3, + } + }, + "layouts": + { + "default": + { + "fields": ["name", "type", "value", "description"], + }, + "list_item": + { + "fields": ["name", "type", "value", "description"], + "actions": ["duplicate", "delete"], + } + } +} + +static var CHARACTER: Dictionary = { + "title": "Character", + "type": "object", + "properties": + { + "id": + { + "type": "text", + "default": IDGen.generate, + "unique": true, + }, + "protected": + { + "type": "bool", + "default": false, + }, + "name": + { + "type": "text", + "default": NameGenerator.generate, + "required": true, + "unique": true, + "protect": true, + "validation": {"min_length": 1}, + }, + "display_name": + { + "type": "text", + "default": "", + }, + "nicknames": + { + "type": "text", + "default": "", + }, + "description": + { + "type": "textarea", + "default": "", + "rows": 4, + }, + "portraits": + { + "type": "list", + "default": [], + "minItems": 1, + "data_schema": PORTRAIT, + }, + "default_portrait": {"type": "string", "default": "", "validation": {}} + }, + "layouts": + { + "default": + { + "fields": ["name", "description"], + }, + "list_item": + { + "fields": ["name", "description"], + "actions": ["edit", "duplicate", "delete"], + } + } +} + +static var PORTRAIT: Dictionary = { + "title": "Portrait", + "type": "object", + "properties": + { + "name": + { + "type": "text", + "default": "new portrait", + "required": true, + "unique": true, + }, + "protected": + { + "type": "bool", + "default": false, + "tooltip": "Prevent deletion", + }, + "type": + { + "type": "dropdown", + "options": ["static", "animated"], + "default": "static", + "required": true, + }, + "mirror": + { + "type": "bool", + "default": false, + "tooltip": "Mirror the image horizontally", + }, + "offset": + { + "type": "vector2", + "default": Vector2.ZERO, + }, + "image_path": + { + "type": "path", + "default": "", + "filter": ["*.png", "*.jpg", "*.jpeg"], + "required": true, + "condition": {"property": "type", "equals": "static"} + }, + "timeline": + { + "type": "timeline", + "default": null, + "required": true, + "condition": {"property": "type", "equals": "animated"} + } + }, + "layouts": + { + "default": + { + "fields": ["name", "type", "image_path"], + }, + "compact": + { + "fields": ["name", "type", "image_path"], + } + } +} + +static var ITEM: Dictionary = { + "title": "Portrait", + "type": "object", + "properties": + { + "id": + { + "type": "text", + "default": IDGen.generate, + "unique": true, + }, + "name": + { + "type": "text", + "default": "new item", + "required": true, + "unique": true, + }, + "description": + { + "type": "textarea", + "default": "", + "rows": 4, + }, + }, + "layouts": + { + "default": + { + "fields": ["name", "description"], + }, + "list_item": + { + "fields": ["name", "description"], + "actions": ["edit", "duplicate", "delete"], + } + } +} + +# TODO: Location backgrounds with variants +static var LOCATION: Dictionary = { + "title": "Portrait", + "type": "object", + "properties": + { + "name": + { + "type": "text", + "default": "new location", + "required": true, + "unique": true, + }, + "description": + { + "type": "textarea", + "default": "", + "rows": 4, + }, + }, + "layouts": + { + "default": + { + "fields": ["name", "description"], + }, + "list_item": + { + "fields": ["name", "description"], + "actions": ["edit", "delete"], + } + } +} diff --git a/common/schemas.gd.uid b/common/schemas.gd.uid new file mode 100644 index 00000000..016a09fc --- /dev/null +++ b/common/schemas.gd.uid @@ -0,0 +1 @@ +uid://ctfwsw13u3127 diff --git a/common/storyline.gd b/common/storyline.gd new file mode 100644 index 00000000..9a9edf32 --- /dev/null +++ b/common/storyline.gd @@ -0,0 +1,180 @@ +class_name StorylineDocument extends InspectableStorylineObject + +signal node_added +signal node_removed +signal content_changed +signal undo_redo_changed + +var id: String = IDGen.generate() +var name: String = "" +var nodes: Array[InspectableNode] = [] +var file_path: String = "" +var is_dirty: bool = false + + +func _init(sname: String, sfile_path: String = "") -> void: + name = sname + file_path = sfile_path + + var command_manager = CommandManager.new() + command_manager.command_executed.connect(_on_command_executed) + command_manager.undone.connect(_on_undo) + command_manager.redone.connect(_on_redo) + + super._init(command_manager) + + _create_default_nodes() + + +func add_node(node: InspectableNode) -> void: + _register_node(node) + + +func remove_node(node: InspectableNode) -> void: + if not node in nodes: + push_warning("Can't remove node %s " % node.id) + return + + nodes.erase(node) + node_removed.emit() + + +func create_node(node_type: String) -> InspectableNode: + var node = NodeBucket.create_node(node_type, history) + _register_node(node) + return node + + +func get_node(node_id: String) -> InspectableNode: + for node: InspectableNode in nodes: + if node.get_property_value("id") == node_id: + return node + return null + + +func initialize_properties() -> void: + var default_narrator: Dictionary = ( + ListItemObject.new(Schemas.CHARACTER, {"name": "Narrator", "protected": true})._to_dict() + ) + + define_property( + "characters", + [default_narrator], + "list", + { + "visible_in_graph": false, + "visible_in_inspector": true, + "editable": true, + "data_schema": Schemas.CHARACTER, + "layout": "list_item" + }, + ) + + define_property( + "variables", + [], + "list", + { + "visible_in_graph": false, + "visible_in_inspector": true, + "editable": true, + "data_schema": Schemas.VARIABLE, + "layout": "list_item" + } + ) + + define_property( + "items", + [], + "list", + { + "visible_in_graph": false, + "visible_in_inspector": true, + "editable": true, + "data_schema": Schemas.ITEM, + "layout": "list_item" + } + ) + + define_property( + "locations", + [], + "list", + { + "visible_in_graph": false, + "visible_in_inspector": true, + "editable": true, + "data_schema": Schemas.LOCATION, + "layout": "list_item" + } + ) + + +func get_type() -> String: + return "storyline" + + +func get_settings() -> Dictionary: + return {} + + +func _on_property_changed(_pname: String, _old_value: Variant, _new_value: Variant) -> void: + is_dirty = true + content_changed.emit() + + +func build_graph_preview() -> Array[Control]: + return [] + + +func _on_command_executed(): + is_dirty = true + content_changed.emit() + undo_redo_changed.emit() + + +func _on_undo(): + content_changed.emit() + undo_redo_changed.emit() + + +func _on_redo(): + is_dirty = true + content_changed.emit() + undo_redo_changed.emit() + + +func _create_default_nodes() -> void: + var defaults := ["root", "sentence", "text"] + for node_type: String in defaults: + var node = NodeBucket.create_node(node_type, history) + _register_node(node) + + +func _register_node(node: InspectableNode) -> void: + if not node: + return + if not node in nodes: + nodes.append(node) + node.storyline_id = id + node.add_observer(_on_node_property_changed) + node_added.emit() + + +func _on_node_property_changed(_node: InspectableNode, _property: String) -> void: + # Maybe useless + is_dirty = true + + +func _to_dict() -> Dictionary: + var dict: Dictionary = super._to_dict() + dict["nodes"] = [] + var root_node_id: String = "" + for node: InspectableNode in nodes: + if node is RootNode: + root_node_id = node.get_property("id").get_value() + dict["nodes"].append(node._to_dict()) + + dict["root_node_id"] = root_node_id + + return dict diff --git a/common/storyline.gd.uid b/common/storyline.gd.uid new file mode 100644 index 00000000..33257a8d --- /dev/null +++ b/common/storyline.gd.uid @@ -0,0 +1 @@ +uid://cv5yppp8eqjja diff --git a/common/ui/buttons/close_button.tscn b/common/ui/buttons/close_button.tscn index cfbcc8d2..83938832 100644 --- a/common/ui/buttons/close_button.tscn +++ b/common/ui/buttons/close_button.tscn @@ -1,11 +1,15 @@ -[gd_scene load_steps=2 format=3 uid="uid://dspmmme0jspdx"] +[gd_scene load_steps=3 format=3 uid="uid://dspmmme0jspdx"] -[ext_resource type="Texture2D" uid="uid://c7vdr4e0mxst6" path="res://ui/assets/icons/close_icon.png" id="1_jkx7d"] +[ext_resource type="Texture2D" uid="uid://kk5em170gn2b" path="res://ui/assets/icons/ui_close.svg" id="1_ai8vd"] -[node name="CloseButton" type="TextureButton"] -offset_right = 16.0 -offset_bottom = 16.0 -size_flags_vertical = 3 -mouse_default_cursor_shape = 2 -texture_normal = ExtResource("1_jkx7d") -stretch_mode = 3 +[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_tlp5i"] + +[node name="Button" type="Button"] +anchors_preset = -1 +anchor_right = 0.017 +anchor_bottom = 0.03 +offset_right = 0.199999 +theme_override_constants/icon_max_width = 0 +theme_override_styles/normal = SubResource("StyleBoxEmpty_tlp5i") +icon = ExtResource("1_ai8vd") +flat = true diff --git a/common/ui/buttons/delete_button.tscn b/common/ui/buttons/delete_button.tscn index e2a40158..2b52e5bc 100644 --- a/common/ui/buttons/delete_button.tscn +++ b/common/ui/buttons/delete_button.tscn @@ -3,10 +3,11 @@ [ext_resource type="Texture2D" uid="uid://hmjhxdsk3pwj" path="res://ui/assets/icons/trash.svg" id="1_xsgmh"] [node name="DeleteButton" type="Button"] -custom_minimum_size = Vector2(34, 29) -offset_right = 34.0 +custom_minimum_size = Vector2(29, 29) +offset_right = 29.0 offset_bottom = 29.0 size_flags_vertical = 0 theme_type_variation = &"ButtonWarning" icon = ExtResource("1_xsgmh") +icon_alignment = 1 expand_icon = true diff --git a/common/ui/editor_properties/color/color.gd b/common/ui/editor_properties/color/color.gd new file mode 100644 index 00000000..88a1a79d --- /dev/null +++ b/common/ui/editor_properties/color/color.gd @@ -0,0 +1,71 @@ +extends Field + +# Sweetie 16 Palette by GrafxKid +const COLORS = [ + "#000000", + "#b13e53", + "#ef7d57", + "#ffcd75", + "#a7f070", + "#38b764", + "#257179", + "#3b5dc9", + "#41a6f6", + "#73eff7", + "#94b0c2", + "#566c86" +] + +@onready var color_preview: ColorRect = %ColorPreview +@onready var color_popup: PopupPanel = %ColorPopup +@onready var color_selector: GridContainer = %ColorSelector + +@onready var Swatch: PackedScene = preload("uid://psbrljdmbtg6") + +var color: Color = Color(COLORS[0]) + + +func _ready() -> void: + for color_string in COLORS: + var swatch: ColorSwatch = Swatch.instantiate() + swatch.color = color_string + color_selector.add_child(swatch) + swatch.pressed.connect(_on_color_swatch_pressed.bind(color_string)) + _update_preview() + + +func set_value(value: Variant) -> void: + color = Color(value) + _update_preview() + + +func get_value() -> Variant: + return color.to_html() + + +func _on_color_picker_button_pressed() -> void: + color_popup.position = global_position + Vector2(0, size.y) + color_popup.popup() + + +func _on_color_swatch_pressed(color_string: String) -> void: + color = Color(color_string) + color_popup.hide() + _update_preview() + + emit_value_changed(color_string) + emit_value_committed(color_string) + emit_preview_changed() + + +func _update_preview() -> void: + color_preview.color = color + + custom_minimum_size.x = size.y + + +func _on_resized() -> void: + if not is_node_ready(): + return + + _update_preview() diff --git a/common/ui/editor_properties/color/color.gd.uid b/common/ui/editor_properties/color/color.gd.uid new file mode 100644 index 00000000..4611c73b --- /dev/null +++ b/common/ui/editor_properties/color/color.gd.uid @@ -0,0 +1 @@ +uid://cwkwnc22br2nn diff --git a/common/ui/editor_properties/color/color.tscn b/common/ui/editor_properties/color/color.tscn new file mode 100644 index 00000000..a00ca7cd --- /dev/null +++ b/common/ui/editor_properties/color/color.tscn @@ -0,0 +1,58 @@ +[gd_scene load_steps=3 format=3 uid="uid://dywxnyncdf55t"] + +[ext_resource type="Script" uid="uid://cwkwnc22br2nn" path="res://common/ui/editor_properties/color/color.gd" id="1_fkepi"] + +[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_fkepi"] + +[node name="Color" type="VBoxContainer"] +anchors_preset = -1 +anchor_right = 0.011000001 +anchor_bottom = 0.010000001 +offset_right = 0.5999985 +size_flags_horizontal = 3 +size_flags_vertical = 3 +script = ExtResource("1_fkepi") + +[node name="HBox" type="HBoxContainer" parent="."] +layout_mode = 2 +size_flags_vertical = 3 + +[node name="ColorPickerButton" type="Button" parent="HBox"] +clip_contents = true +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="MarginContainer" type="MarginContainer" parent="HBox/ColorPickerButton"] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +theme_override_constants/margin_left = 5 +theme_override_constants/margin_top = 5 +theme_override_constants/margin_right = 5 +theme_override_constants/margin_bottom = 5 + +[node name="ColorPreview" type="ColorRect" parent="HBox/ColorPickerButton/MarginContainer"] +unique_name_in_owner = true +layout_mode = 2 +mouse_filter = 2 + +[node name="ColorPopup" type="PopupPanel" parent="HBox/ColorPickerButton"] +unique_name_in_owner = true +oversampling_override = 1.0 +size = Vector2i(8, 8) +theme_override_styles/panel = SubResource("StyleBoxEmpty_fkepi") + +[node name="PanelContainer" type="PanelContainer" parent="HBox/ColorPickerButton/ColorPopup"] +offset_right = 8.0 +offset_bottom = 8.0 + +[node name="ColorSelector" type="GridContainer" parent="HBox/ColorPickerButton/ColorPopup/PanelContainer"] +unique_name_in_owner = true +layout_mode = 2 +columns = 4 + +[connection signal="resized" from="." to="." method="_on_resized"] +[connection signal="pressed" from="HBox/ColorPickerButton" to="." method="_on_color_picker_button_pressed"] diff --git a/common/ui/editor_properties/color/color_swatch.gd b/common/ui/editor_properties/color/color_swatch.gd new file mode 100644 index 00000000..766e2792 --- /dev/null +++ b/common/ui/editor_properties/color/color_swatch.gd @@ -0,0 +1,19 @@ +@tool +extends Button +class_name ColorSwatch + +@onready var color_rect: ColorRect = %ColorRect + +@export var color: Color = Color("ffffff"): + set = _set_color + + +func _set_color(value: Color) -> void: + color = value + if not color_rect: + return + color_rect.color = value + + +func _ready() -> void: + self.color = color diff --git a/common/ui/editor_properties/color/color_swatch.gd.uid b/common/ui/editor_properties/color/color_swatch.gd.uid new file mode 100644 index 00000000..46c1e9f6 --- /dev/null +++ b/common/ui/editor_properties/color/color_swatch.gd.uid @@ -0,0 +1 @@ +uid://c5p813dybhgwt diff --git a/common/ui/editor_properties/color/color_swatch.tscn b/common/ui/editor_properties/color/color_swatch.tscn new file mode 100644 index 00000000..0af7b3ad --- /dev/null +++ b/common/ui/editor_properties/color/color_swatch.tscn @@ -0,0 +1,18 @@ +[gd_scene load_steps=2 format=3 uid="uid://psbrljdmbtg6"] + +[ext_resource type="Script" uid="uid://c5p813dybhgwt" path="res://common/ui/editor_properties/color/color_swatch.gd" id="1_x2h8f"] + +[node name="ColorSwatch" type="Button"] +clip_children = 1 +custom_minimum_size = Vector2(25, 25) +script = ExtResource("1_x2h8f") + +[node name="ColorRect" type="ColorRect" parent="."] +unique_name_in_owner = true +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 2 diff --git a/common/ui/editor_properties/color/index.gd b/common/ui/editor_properties/color/index.gd new file mode 100644 index 00000000..16e4905b --- /dev/null +++ b/common/ui/editor_properties/color/index.gd @@ -0,0 +1,9 @@ +extends MonologueIndexer + + +func get_scene() -> PackedScene: + return preload("uid://dywxnyncdf55t") + + +func get_metadata() -> Dictionary: + return {"name": "color", "type": ObjectType.FIELD, "color": Color("d1b37bff")} diff --git a/common/ui/editor_properties/color/index.gd.uid b/common/ui/editor_properties/color/index.gd.uid new file mode 100644 index 00000000..f214138a --- /dev/null +++ b/common/ui/editor_properties/color/index.gd.uid @@ -0,0 +1 @@ +uid://7bxfucw58wy0 diff --git a/common/ui/editor_properties/context/index.gd b/common/ui/editor_properties/context/index.gd new file mode 100644 index 00000000..c3d26b26 --- /dev/null +++ b/common/ui/editor_properties/context/index.gd @@ -0,0 +1,9 @@ +extends MonologueIndexer + + +func get_scene() -> PackedScene: + return PackedScene.new() + + +func get_metadata() -> Dictionary: + return {"name": "context", "type": ObjectType.FIELD, "color": Color("ffffff")} diff --git a/common/ui/editor_properties/context/index.gd.uid b/common/ui/editor_properties/context/index.gd.uid new file mode 100644 index 00000000..4e460bcb --- /dev/null +++ b/common/ui/editor_properties/context/index.gd.uid @@ -0,0 +1 @@ +uid://cg62bw4hys8fb diff --git a/common/ui/editor_properties/dropdown/dropdown_field.gd b/common/ui/editor_properties/dropdown/dropdown_field.gd new file mode 100644 index 00000000..d110bedc --- /dev/null +++ b/common/ui/editor_properties/dropdown/dropdown_field.gd @@ -0,0 +1,197 @@ +extends Field + +var _is_listening: bool = false +var _static_options: Array = [] + +@onready var option_button: OptionButton = %OptionButton + + +func _ready() -> void: + super._ready() + option_button.item_selected.connect(_on_item_selected) + + +func set_value(value: Variant) -> void: + if not is_node_ready(): + await ready + + # If value is a string, find it in the list + if value is String: + for i in range(option_button.item_count): + if option_button.get_item_text(i) == value: + option_button.selected = i + return + if option_button.item_count > 0: + option_button.selected = 0 + return + # If value is an int, use it as index + elif value is int and value >= 0 and value < option_button.item_count: + option_button.selected = value + + +func get_value() -> Variant: + var selected_idx = option_button.selected + if selected_idx >= 0: + return option_button.get_item_text(selected_idx) + return "" + + +func set_editable(is_editable: bool) -> void: + option_button.disabled = not is_editable + + +func _on_initialize() -> void: + super._on_initialize() + _populate_options() + _setup_source_listener() + + +func _setup_source_listener() -> void: + if not _binding or not _binding.property: + return + + var property: Property = _binding.property + var source: String = property.get_settings_value("source", "") + + if not source.is_empty(): + # Listen for changes to the source property + var storyline = _get_storyline() + if storyline: + storyline.add_observer(_on_source_changed) + if not _is_listening and storyline.history: + storyline.history.command_executed.connect(_on_storyline_command_executed) + storyline.history.redone.connect(_on_storyline_command_executed) + storyline.history.undone.connect(_on_storyline_command_executed) + _is_listening = true + + +func _on_source_changed(_obj: InspectableObject, property_name: String) -> void: + if not _binding or not _binding.property: + return + + var source: String = _binding.property.get_settings_value("source", "") + if property_name == source: + # Source data changed, repopulate options + _populate_options() + _set_value_to_existing() + + +func _on_storyline_command_executed() -> void: + _populate_options() + _set_value_to_existing() + + +func _populate_options() -> void: + option_button.clear() + + var options: Array = [] + var property: Property = _binding.property if _binding else null + if property: + var source: String = property.get_settings_value("source", "") + if not source.is_empty() and _binding.owner: + options = _get_options_from_source(source) + else: + options = _normalize_options_array(property.get_settings_value("options", [])) + + if options.is_empty(): + options = _static_options.duplicate() + + for option in options: + option_button.add_item(str(option)) + + _set_value_to_existing() + + +func _set_value_to_existing() -> void: + if not _binding or not _binding.property: + if _static_options.is_empty(): + return + var default_value: Variant = _static_options[0] if _static_options.size() > 0 else "" + set_value(default_value) + return + + var current_value: Variant = _binding.property.get_value() + if current_value == null: + return + set_value(current_value) + + +func set_static_options(options: Variant) -> void: + _static_options = _normalize_options_array(options) + if is_node_ready(): + _populate_options() + else: + call_deferred("_populate_options") + + +func _normalize_options_array(source: Variant) -> Array: + if source is Array: + return (source as Array).duplicate() + if source is PackedStringArray: + return Array(source) + if source is PackedInt32Array: + var arr: Array = [] + for value in source: + arr.append(value) + return arr + if source is String: + return [source] + if source == null: + return [] + return [str(source)] + + +func _get_options_from_source(source: String) -> Array: + var result: Array = [] + + # Get storyline from property owner + var storyline = _get_storyline() + if not storyline: + return result + + # Get the list property from storyline + var list_property: Property = storyline.get_property(source) + if not list_property: + return result + + var list_value = list_property.get_value() + if not list_value is Array: + return result + + # Extract names from list items + for item in list_value: + if item is Dictionary: + var entry_name: Variant = item.get("name", item.get("id", "")) + if entry_name is Dictionary: + entry_name = entry_name.get("value", "") + result.append(entry_name) + else: + result.append(str(item)) + + return result + + +func _get_storyline() -> InspectableObject: + if not _binding or not _binding.owner: + return null + + var story_owner = _binding.owner + + # If owner is a node, get its storyline + if story_owner is InspectableNode: + var node: InspectableNode = story_owner + var storyline_id = node.storyline_id + if storyline_id: + return StorylineManager.get_storyline(storyline_id) + + # If owner is already a storyline, return it + if story_owner is StorylineDocument: + return story_owner + + return null + + +func _on_item_selected(index: int) -> void: + var text = option_button.get_item_text(index) + emit_value_changed(text) + emit_value_committed(text) diff --git a/common/ui/editor_properties/dropdown/dropdown_field.gd.uid b/common/ui/editor_properties/dropdown/dropdown_field.gd.uid new file mode 100644 index 00000000..3793e12f --- /dev/null +++ b/common/ui/editor_properties/dropdown/dropdown_field.gd.uid @@ -0,0 +1 @@ +uid://c4n8o9p0q1r2t diff --git a/common/ui/editor_properties/dropdown/dropdown_field.tscn b/common/ui/editor_properties/dropdown/dropdown_field.tscn new file mode 100644 index 00000000..82617491 --- /dev/null +++ b/common/ui/editor_properties/dropdown/dropdown_field.tscn @@ -0,0 +1,14 @@ +[gd_scene load_steps=2 format=3 uid="uid://cqhk5p4a8jx0b"] + +[ext_resource type="Script" path="res://common/ui/editor_properties/dropdown/dropdown_field.gd" id="1_dropdown"] + +[node name="VBoxContainer" type="VBoxContainer"] +offset_right = 76.0 +offset_bottom = 29.0 +size_flags_horizontal = 3 +script = ExtResource("1_dropdown") + +[node name="OptionButton" type="OptionButton" parent="."] +unique_name_in_owner = true +layout_mode = 2 +size_flags_horizontal = 3 diff --git a/common/ui/editor_properties/dropdown/index.gd b/common/ui/editor_properties/dropdown/index.gd new file mode 100644 index 00000000..c3ffc2ff --- /dev/null +++ b/common/ui/editor_properties/dropdown/index.gd @@ -0,0 +1,9 @@ +extends MonologueIndexer + + +func get_scene() -> PackedScene: + return preload("uid://cqhk5p4a8jx0b") + + +func get_metadata() -> Dictionary: + return {"name": "dropdown", "type": ObjectType.FIELD, "color": Color("88c0d0ff")} diff --git a/common/ui/editor_properties/dropdown/index.gd.uid b/common/ui/editor_properties/dropdown/index.gd.uid new file mode 100644 index 00000000..f59e2aef --- /dev/null +++ b/common/ui/editor_properties/dropdown/index.gd.uid @@ -0,0 +1 @@ +uid://b3m7n8p9q0r1s diff --git a/common/ui/editor_properties/dynamic/dynamic_field.gd b/common/ui/editor_properties/dynamic/dynamic_field.gd new file mode 100644 index 00000000..0b7c8e2f --- /dev/null +++ b/common/ui/editor_properties/dynamic/dynamic_field.gd @@ -0,0 +1,82 @@ +extends Field + +var _case_property: String = "" +var _cases: Dictionary = {} + +@onready var field_container: HBoxContainer = %FieldContainer +var _field: Field + + +func _ready() -> void: + super._ready() + + +func set_value(value: Variant) -> void: + if not is_node_ready(): + await ready + + if _field: + _field.set_value(value) + + +func get_value() -> Variant: + if _field: + return _field.get_value() + return null + + +func set_editable(is_editable: bool) -> void: + if _field: + _field.set_editable(is_editable) + + +func _on_initialize() -> void: + super._on_initialize() + + _case_property = settings.get("case_property", "") + _cases = settings.get("cases", {}) + + _setup_property_case_listener() + _update_case_field() + + +func _setup_property_case_listener() -> void: + if not _binding or not _binding.property: + return + + var field_owner: InspectableObject = _binding.owner + var case_property: Property = field_owner.get_property(_case_property) + if case_property == null: + return + + case_property.value_changed.connect(_on_property_case_changed) + + +func _update_case_field() -> void: + for child in field_container.get_children(): + child.queue_free() + + var field_owner: InspectableObject = _binding.owner + var case_property: Property = field_owner.get_property(_case_property) + if case_property == null: + return + + var actual_case: String = case_property.get_value() + if not _cases.has(actual_case): + push_warning("Unknown case '%s' for dynamic field" % actual_case) + return + var case_data: Dictionary = _cases[actual_case] + var case_type: String = case_data.get("type") + var _case_default: Variant = case_data.get("default") # TODO: Support default value + var _case_coerce: Variant = case_data.get("coerce") # TODO: Coerce value + + var new_field: Control = FieldBucket.safe_create_field(case_type) + _field = null + if new_field is Field: + _field = new_field + _binding.property.call_deferred("bind_field", new_field, _binding.owner) + field_container.add_child(new_field) + + +func _on_property_case_changed(_old_value: Variant, _new_value: Variant) -> void: + _update_case_field() diff --git a/common/ui/editor_properties/dynamic/dynamic_field.gd.uid b/common/ui/editor_properties/dynamic/dynamic_field.gd.uid new file mode 100644 index 00000000..d7f16ac5 --- /dev/null +++ b/common/ui/editor_properties/dynamic/dynamic_field.gd.uid @@ -0,0 +1 @@ +uid://6vwlwawmd6qw diff --git a/common/ui/editor_properties/dynamic/dynamic_field.tscn b/common/ui/editor_properties/dynamic/dynamic_field.tscn new file mode 100644 index 00000000..092ba791 --- /dev/null +++ b/common/ui/editor_properties/dynamic/dynamic_field.tscn @@ -0,0 +1,12 @@ +[gd_scene load_steps=2 format=3 uid="uid://bmpb6yh0x0sup"] + +[ext_resource type="Script" uid="uid://6vwlwawmd6qw" path="res://common/ui/editor_properties/dynamic/dynamic_field.gd" id="1_g3o7u"] + +[node name="DynamicField" type="VBoxContainer"] +offset_right = 40.0 +offset_bottom = 40.0 +script = ExtResource("1_g3o7u") + +[node name="FieldContainer" type="HBoxContainer" parent="."] +unique_name_in_owner = true +layout_mode = 2 diff --git a/common/ui/editor_properties/dynamic/index.gd b/common/ui/editor_properties/dynamic/index.gd new file mode 100644 index 00000000..8307cdbe --- /dev/null +++ b/common/ui/editor_properties/dynamic/index.gd @@ -0,0 +1,9 @@ +extends MonologueIndexer + + +func get_scene() -> PackedScene: + return preload("uid://bmpb6yh0x0sup") + + +func get_metadata() -> Dictionary: + return {"name": "dynamic", "type": ObjectType.FIELD, "color": Color("d1929dff")} diff --git a/common/ui/editor_properties/dynamic/index.gd.uid b/common/ui/editor_properties/dynamic/index.gd.uid new file mode 100644 index 00000000..80131674 --- /dev/null +++ b/common/ui/editor_properties/dynamic/index.gd.uid @@ -0,0 +1 @@ +uid://b6rmavumgsbkj diff --git a/common/ui/editor_properties/field.gd b/common/ui/editor_properties/field.gd new file mode 100644 index 00000000..384caac9 --- /dev/null +++ b/common/ui/editor_properties/field.gd @@ -0,0 +1,78 @@ +@abstract +class_name Field extends VBoxContainer + +signal value_changed(new_value: Variant) +signal value_committed(new_value: Variant) +signal preview_changed + +var _binding: FieldBinding +var _default_modulate: Color = Color(1, 1, 1, 1) + +var settings: Dictionary = {} + + +func _ready() -> void: + _default_modulate = modulate + + +func initialize(binding: FieldBinding = null) -> void: + if binding: + _binding = binding + + if _binding and _binding.property: + var property: Property = _binding.property + settings = property.get_settings() + _on_initialize() + + +func _on_initialize() -> void: + pass + + +func emit_value_changed(value: Variant) -> void: + value_changed.emit(value) + + +func emit_preview_changed() -> void: + preview_changed.emit() + + +func emit_value_committed(value: Variant) -> void: + if settings.get("unique"): + var field_owner: InspectableObject = _binding.owner + var property_name: String = _binding.property.name + var property_value: Variant = _binding.property.get_value() + + if field_owner is ListItemObject: + var list_field: ListField = field_owner.list_field + + for item: ListItemObject in list_field._list_items: + var property: Property = item.get_property(property_name) + if property_value == property.get_value(): + continue + if property and property.get_value() == value: + set_value(property_value) + return + + value_committed.emit(value) + + +func set_editable(_is_editable: bool) -> void: + pass + + +func display_error(message: String) -> void: + tooltip_text = message + modulate = _default_modulate if message.is_empty() else Color(1, 0.85, 0.85, 1) + + +func clear_error() -> void: + display_error("") + + +func after_commit(_value: Variant) -> void: + pass + + +@abstract func set_value(value: Variant) -> void +@abstract func get_value() -> Variant diff --git a/common/ui/editor_properties/field.gd.uid b/common/ui/editor_properties/field.gd.uid new file mode 100644 index 00000000..85df71f3 --- /dev/null +++ b/common/ui/editor_properties/field.gd.uid @@ -0,0 +1 @@ +uid://7su6leuvyoaa diff --git a/common/ui/editor_properties/field_binding.gd b/common/ui/editor_properties/field_binding.gd new file mode 100644 index 00000000..4160ce51 --- /dev/null +++ b/common/ui/editor_properties/field_binding.gd @@ -0,0 +1,140 @@ +class_name FieldBinding extends RefCounted + +var property: Property +var field: Field +var descriptor: FieldDescriptor +var owner: InspectableObject + +var _is_syncing: bool = false +var _is_released: bool = false + + +func _init( + p_property: Property, + p_field: Field, + p_descriptor: FieldDescriptor, + p_owner: InspectableObject = null +) -> void: + property = p_property + field = p_field + descriptor = p_descriptor + owner = p_owner + + +func initialize() -> void: + if _is_released: + return + if not is_instance_valid(field): + push_warning("Attempted to initialize a binding with an invalid field instance.") + return + if descriptor == null: + push_warning("Field binding missing descriptor instance.") + return + field.initialize(self) + field.value_changed.connect(_on_field_value_changed) + if field.has_signal("value_committed"): + field.value_committed.connect(_on_field_value_committed) + if field.has_signal("preview_changed"): + field.preview_changed.connect(_on_field_preview_changed) + if property: + property.value_changed.connect(_on_property_value_changed) + field.tree_exiting.connect(_on_field_tree_exiting) + _sync_from_property() + _update_editable_state() + field.clear_error() + + +func release() -> void: + if _is_released: + return + _is_released = true + if is_instance_valid(field): + if field.value_changed.is_connected(_on_field_value_changed): + field.value_changed.disconnect(_on_field_value_changed) + if ( + field.has_signal("value_committed") + and field.value_committed.is_connected(_on_field_value_committed) + ): + field.value_committed.disconnect(_on_field_value_committed) + if field.tree_exiting.is_connected(_on_field_tree_exiting): + field.tree_exiting.disconnect(_on_field_tree_exiting) + if property and property.value_changed.is_connected(_on_property_value_changed): + property.value_changed.disconnect(_on_property_value_changed) + + +func refresh() -> void: + _sync_from_property() + _update_editable_state() + + +func is_active() -> bool: + return not _is_released + + +func _sync_from_property() -> void: + if not property or not is_instance_valid(field): + return + _is_syncing = true + field.set_value(property.get_value()) + field.clear_error() + _is_syncing = false + + +func _update_editable_state() -> void: + if not is_instance_valid(field) or not property: + return + var is_editable: bool = property.get_settings_value("editable", true) + if property.is_intput_connected(): + is_editable = false + field.set_editable(is_editable) + + +func _on_field_value_changed(value: Variant) -> void: + if _is_syncing: + return + _process_field_value(value, false) + + +func _on_field_value_committed(value: Variant) -> void: + if _is_syncing: + return + _process_field_value(value, true) + + +func _on_field_preview_changed() -> void: + owner.rebuild_preview() + + +func _process_field_value(value: Variant, is_commit: bool) -> void: + if not property or descriptor == null: + return + var validation_result = descriptor.validate(value) + if not validation_result.is_valid: + field.display_error(validation_result.message) + return + field.clear_error() + var formatted_value = descriptor.format(value) + if owner and not is_commit: + return + _is_syncing = true + if owner: + owner.set_property_value(property.name, formatted_value) + else: + property.set_value(formatted_value) + _is_syncing = false + _sync_from_property() + if is_commit: + field.after_commit(property.get_value()) + + +func _on_property_value_changed(_old_value: Variant, new_value: Variant) -> void: + if _is_released or _is_syncing or not field.is_node_ready(): + return + _is_syncing = true + field.set_value(new_value) + field.clear_error() + _is_syncing = false + + +func _on_field_tree_exiting() -> void: + release() diff --git a/common/ui/editor_properties/field_binding.gd.uid b/common/ui/editor_properties/field_binding.gd.uid new file mode 100644 index 00000000..4cfef785 --- /dev/null +++ b/common/ui/editor_properties/field_binding.gd.uid @@ -0,0 +1 @@ +uid://dkp1ix1cag4u5 diff --git a/common/ui/editor_properties/field_bucket.gd b/common/ui/editor_properties/field_bucket.gd new file mode 100644 index 00000000..d8262df5 --- /dev/null +++ b/common/ui/editor_properties/field_bucket.gd @@ -0,0 +1,132 @@ +# Autoload +extends Node + +const DEFAULT_FIELDS_LOCATION := "res://common/ui/editor_properties/" + +var _descriptors: Dictionary = {} +var _is_initialized: bool = false +var _next_type_id: int = 1 + + +func register_descriptor(descriptor: FieldDescriptor) -> void: + if descriptor == null: + push_warning("Attempted to register a null FieldDescriptor.") + return + if descriptor.name.is_empty(): + push_warning("FieldDescriptor missing name property.") + return + if _descriptors.has(descriptor.name): + push_warning("FieldDescriptor '%s' already registered." % descriptor.name) + return + if descriptor.default_settings == null: + descriptor.default_settings = {} + descriptor.type_id = _next_type_id + _next_type_id += 1 + _descriptors[descriptor.name] = descriptor + + +func bind( + property: Property, field: Field, property_owner: InspectableObject = null +) -> FieldBinding: + if not property or not is_instance_valid(field): + return null + var descriptor := get_descriptor(property.type) + if descriptor == null: + push_warning("No field descriptor found for type '%s'." % property.type) + return null + var binding: FieldBinding = FieldBinding.new(property, field, descriptor, property_owner) + binding.initialize() + return binding + + +func create_field(field_name: String) -> Field: + var descriptor := get_descriptor(field_name) + if descriptor: + return descriptor.instantiate_field() + return null + + +func safe_create_field(field_name: String) -> Control: + var new_field: Field = create_field(field_name) + if new_field: + return new_field + + var fb_field: Control = Label.new() + fb_field.theme_type_variation = "WarnLabel" + fb_field.text = "Unknown property type" + return fb_field + + +func get_scene(field_name: String) -> PackedScene: + var descriptor := get_descriptor(field_name) + if descriptor: + return descriptor.scene + return null + + +func get_metadata(field_name: String) -> Dictionary: + var descriptor := get_descriptor(field_name) + if descriptor: + return descriptor.to_metadata() + return {} + + +func get_type_id(field_name: String) -> int: + var descriptor := get_descriptor(field_name) + return descriptor.type_id if descriptor else -1 + + +func get_descriptor(field_name: String) -> FieldDescriptor: + _ensure_initialized() + return _descriptors.get(field_name) + + +func refresh_registry() -> void: + _is_initialized = false + _descriptors.clear() + _next_type_id = 1 + _ensure_initialized() + + +func _ensure_initialized() -> void: + if _is_initialized: + return + _search_fields() + _is_initialized = true + + +func _search_fields() -> void: + var directories: Array = DirAccess.get_directories_at(DEFAULT_FIELDS_LOCATION) + for dir: String in directories: + var script_path: String = DEFAULT_FIELDS_LOCATION.path_join(dir).path_join("index.gd") + if not FileAccess.file_exists(script_path): + continue + var script = load(script_path) + if script == null: + push_warning("Failed to load field indexer at %s" % script_path) + continue + var indexer = script.new() + var descriptor := _descriptor_from_indexer(indexer) + if descriptor: + descriptor.default_settings = ( + descriptor.default_settings.duplicate(true) if descriptor.default_settings else {} + ) + register_descriptor(descriptor) + + +func _descriptor_from_indexer(indexer) -> FieldDescriptor: + var descriptor + if indexer and indexer.has_method("get_descriptor"): + descriptor = indexer.call("get_descriptor") + if descriptor is FieldDescriptor: + return descriptor + var metadata: Dictionary = {} + if indexer and indexer.has_method("get_metadata"): + metadata = indexer.call("get_metadata") + var descriptor_name: String = metadata.get("name", "") + var scene: PackedScene + if indexer and indexer.has_method("get_scene"): + scene = indexer.call("get_scene") + if descriptor_name.is_empty(): + return null + return FieldDescriptor.new(descriptor_name, scene, metadata) diff --git a/common/ui/editor_properties/field_bucket.gd.uid b/common/ui/editor_properties/field_bucket.gd.uid new file mode 100644 index 00000000..070f8643 --- /dev/null +++ b/common/ui/editor_properties/field_bucket.gd.uid @@ -0,0 +1 @@ +uid://cmte2g7n7ogyd diff --git a/common/ui/editor_properties/field_descriptor.gd b/common/ui/editor_properties/field_descriptor.gd new file mode 100644 index 00000000..66330228 --- /dev/null +++ b/common/ui/editor_properties/field_descriptor.gd @@ -0,0 +1,76 @@ +class_name FieldDescriptor extends RefCounted + +const FIELD_OBJECT_TYPE := 1 + +var name: String +var scene: PackedScene +var color: Color = Color.WHITE +var default_settings: Dictionary = {} +var validators: Array[Callable] = [] +var formatter: Callable +var type_id: int = -1 + + +func _init(p_name: String = "", p_scene: PackedScene = null, metadata: Dictionary = {}) -> void: + name = p_name + scene = p_scene + var raw_color = metadata.get("color") + if raw_color is Color: + color = raw_color + elif raw_color is String and not raw_color.is_empty(): + color = Color(raw_color) + default_settings = metadata.get("default_settings", {}).duplicate(true) + var validator_list = metadata.get("validators") + if validator_list is Array: + for validator in validator_list: + register_validator(validator) + var raw_formatter = metadata.get("formatter") + if raw_formatter is Callable and raw_formatter.is_valid(): + formatter = raw_formatter + + +func instantiate_field() -> Field: + if not scene: + return null + var instance = scene.instantiate() + if instance is Field: + return instance + push_error("FieldDescriptor '%s' scene does not inherit Field." % name) + return null + + +func register_validator(validator: Callable) -> void: + if validator is Callable and validator.is_valid(): + validators.append(validator) + + +func validate(value: Variant): + for validator in validators: + var result = validator.call(value) + if result is FieldValidationResult: + if not result.is_valid: + return result + elif result is bool: + if not result: + return FieldValidationResult.failure("Validation failed.") + elif result is String: + var message := (result as String).strip_edges() + if not message.is_empty(): + return FieldValidationResult.failure(message) + return FieldValidationResult.success() + + +func format(value: Variant) -> Variant: + if formatter and formatter.is_valid(): + return formatter.call(value) + return value + + +func to_metadata() -> Dictionary: + return { + "name": name, + "type": FIELD_OBJECT_TYPE, + "color": color, + "type_id": type_id, + "default_settings": default_settings.duplicate(true), + } diff --git a/common/ui/editor_properties/field_descriptor.gd.uid b/common/ui/editor_properties/field_descriptor.gd.uid new file mode 100644 index 00000000..7cda8633 --- /dev/null +++ b/common/ui/editor_properties/field_descriptor.gd.uid @@ -0,0 +1 @@ +uid://c1vc0itqeuxic diff --git a/common/ui/editor_properties/field_validation_result.gd b/common/ui/editor_properties/field_validation_result.gd new file mode 100644 index 00000000..1b7e5184 --- /dev/null +++ b/common/ui/editor_properties/field_validation_result.gd @@ -0,0 +1,17 @@ +class_name FieldValidationResult extends RefCounted + +var is_valid: bool +var message: String + + +func _init(p_is_valid: bool = true, p_message: String = "") -> void: + is_valid = p_is_valid + message = p_message + + +static func success() -> FieldValidationResult: + return FieldValidationResult.new(true, "") + + +static func failure(error_message: String) -> FieldValidationResult: + return FieldValidationResult.new(false, error_message) diff --git a/common/ui/editor_properties/field_validation_result.gd.uid b/common/ui/editor_properties/field_validation_result.gd.uid new file mode 100644 index 00000000..c14f8393 --- /dev/null +++ b/common/ui/editor_properties/field_validation_result.gd.uid @@ -0,0 +1 @@ +uid://c6ue2ruq13my7 diff --git a/common/ui/editor_properties/list/index.gd b/common/ui/editor_properties/list/index.gd new file mode 100644 index 00000000..e62b459a --- /dev/null +++ b/common/ui/editor_properties/list/index.gd @@ -0,0 +1,9 @@ +extends MonologueIndexer + + +func get_scene() -> PackedScene: + return preload("uid://d2s4kv1234abc") + + +func get_metadata() -> Dictionary: + return {"name": "list", "type": ObjectType.FIELD, "color": Color("b48eadff")} diff --git a/common/ui/editor_properties/list/index.gd.uid b/common/ui/editor_properties/list/index.gd.uid new file mode 100644 index 00000000..b252ebed --- /dev/null +++ b/common/ui/editor_properties/list/index.gd.uid @@ -0,0 +1 @@ +uid://d5o9p0q1r2s3u diff --git a/common/ui/editor_properties/list/list_field.gd b/common/ui/editor_properties/list/list_field.gd new file mode 100644 index 00000000..f68cd47c --- /dev/null +++ b/common/ui/editor_properties/list/list_field.gd @@ -0,0 +1,216 @@ +class_name ListField extends Field + +var _list_items: Array[ListItemObject] = [] +var _hide_items: Array[int] = [] +var _data_schema: Dictionary = {} +var _layout: String = "default" +var _command_manager: CommandManager + +@onready var items_container: VBoxContainer = %ItemsContainer + + +func _ready() -> void: + super._ready() + _command_manager = CommandManager.new() + + +func hide_item(idx: int) -> void: + _hide_items.append(idx) + _rebuild_ui() + + +func show_all_items() -> void: + _hide_items.clear() + _rebuild_ui() + + +func set_value(value: Variant) -> void: + _list_items.clear() + for property_data: Dictionary in value: + var new_item: ListItemObject = ListItemObject.new(_data_schema, {}, _command_manager) + new_item.list_field = self + new_item._from_dict(property_data) + _connect_item_observer(new_item) + _list_items.append(new_item) + + _rebuild_ui() + + +func _connect_item_observer(item: ListItemObject) -> void: + item.add_observer(_on_item_changed) + + +func _on_item_changed(_item: ListItemObject, prop_name: String) -> void: + if _has_dependent_fields(prop_name): + call_deferred("_rebuild_ui") + + _emit_snapshot() + + +func get_value() -> Variant: + var result: Array = [] + for item: ListItemObject in _list_items: + result.append(item._to_dict()) + return result + + +func get_item_index(item: ListItemObject) -> int: + return _list_items.find(item) + + +func set_editable(is_editable: bool) -> void: + if not is_instance_valid(items_container): + return + + for child in items_container.get_children(): + if child.has_method("set_editable"): + child.set_editable(is_editable) + + +func _on_initialize() -> void: + if _binding and _binding.property: + _initialize_from_property(_binding.property) + + if not is_node_ready(): + await ready + + _rebuild_ui() + + +func _initialize_from_property(property: Property) -> void: + _data_schema = property.get_settings_value("data_schema", {}) + _layout = property.get_settings_value("layout", "default") + + +func _rebuild_ui() -> void: + if not is_instance_valid(items_container): + return + + _populate_items_container() + + +func _clear_items_container() -> void: + for child in items_container.get_children(): + items_container.remove_child(child) + child.queue_free() + + +func _populate_items_container() -> void: + _clear_items_container() + + for i in range(_list_items.size()): + if i in _hide_items: + continue + var item_ui = _create_item_ui(i) + if item_ui: + items_container.add_child(item_ui) + + +func _create_item_ui(index: int) -> Control: + var item = _list_items[index] + + var item_container = PanelContainer.new() + item_container.theme_type_variation = "ListItemContainer" + + var main_vbox = VBoxContainer.new() + item_container.add_child(main_vbox) + + var content = LayoutManager.create_layout(_data_schema, item, self, _layout) + if content: + main_vbox.add_child(content) + + return item_container + + +func _has_dependent_fields(field_name: String) -> bool: + var properties = _data_schema.get("properties", {}) + + for prop_name in properties: + var prop_config = properties[prop_name] + + if _has_condition_dependency(prop_config, field_name): + return true + + if _has_variant_dependency(prop_config, field_name): + return true + + return false + + +func _has_condition_dependency(prop_config: Dictionary, field_name: String) -> bool: + if not prop_config.has("condition"): + return false + + return prop_config["condition"].get("property") == field_name + + +func _has_variant_dependency(prop_config: Dictionary, field_name: String) -> bool: + if not prop_config.has("cases"): + return false + + var variants = prop_config["cases"] + return variants.get("property") == field_name + + +func _on_edit_item(index: int) -> void: + print("edit item %s" % index) + + +func _on_duplicate_item(index: int) -> void: + if not _is_valid_index(index): + return + var item_data: Dictionary = _list_items[index]._to_dict() + var new_item: ListItemObject = ListItemObject.new(_data_schema, {}, _command_manager, {}) + new_item.list_field = self + new_item._from_dict(item_data) + new_item.make_all_values_unique() + _connect_item_observer(new_item) + _list_items.insert(index + 1, new_item) + _rebuild_ui() + _emit_snapshot() + + +func _on_delete_item(index: int) -> void: + if not _is_valid_index(index): + return + + var item = _list_items[index] + + if item.is_protected(): + push_warning("Cannot delete protected item") + return + + if index >= 0 and index < _list_items.size(): + _list_items.remove_at(index) + _rebuild_ui() + _emit_snapshot() + + +func _is_valid_index(index: int) -> bool: + return index >= 0 and index < _list_items.size() + + +func _emit_snapshot() -> void: + # Emit a deep copy of the raw store as the authoritative value + emit_value_changed(get_value()) + emit_value_committed(get_value()) + + +func undo() -> void: + if _command_manager: + _command_manager.undo() + _rebuild_ui() + + +func redo() -> void: + if _command_manager: + _command_manager.redo() + _rebuild_ui() + + +func can_undo() -> bool: + return _command_manager and _command_manager.can_undo() + + +func can_redo() -> bool: + return _command_manager and _command_manager.can_redo() diff --git a/common/ui/editor_properties/list/list_field.gd.uid b/common/ui/editor_properties/list/list_field.gd.uid new file mode 100644 index 00000000..f74b59ec --- /dev/null +++ b/common/ui/editor_properties/list/list_field.gd.uid @@ -0,0 +1 @@ +uid://e6p0q1r2s3t4v diff --git a/common/ui/editor_properties/list/list_field.tscn b/common/ui/editor_properties/list/list_field.tscn new file mode 100644 index 00000000..6ff68a59 --- /dev/null +++ b/common/ui/editor_properties/list/list_field.tscn @@ -0,0 +1,14 @@ +[gd_scene load_steps=2 format=3 uid="uid://d2s4kv1234abc"] + +[ext_resource type="Script" uid="uid://bcb45yus8vyd4" path="res://common/ui/editor_properties/list/list_field.gd" id="1_list"] + +[node name="VBoxContainer" type="VBoxContainer"] +offset_right = 300.0 +offset_bottom = 100.0 +size_flags_horizontal = 3 +script = ExtResource("1_list") + +[node name="ItemsContainer" type="VBoxContainer" parent="."] +unique_name_in_owner = true +layout_mode = 2 +size_flags_horizontal = 3 diff --git a/common/ui/editor_properties/list/list_item_object.gd b/common/ui/editor_properties/list/list_item_object.gd new file mode 100644 index 00000000..dd6b6c9e --- /dev/null +++ b/common/ui/editor_properties/list/list_item_object.gd @@ -0,0 +1,177 @@ +class_name ListItemObject extends InspectableObject + +var _schema: Dictionary = {} +var _initial_data: Dictionary = {} + +var list_field: ListField + + +func _init( + schema: Dictionary, + initial_data: Dictionary = {}, + command_manager: CommandManager = null, + _settings: Dictionary = {} +) -> void: + _schema = schema + _initial_data = initial_data + settings = _settings + super._init(command_manager) + + +func initialize_properties() -> void: + var properties_config: Dictionary = _schema.get("properties", {}) + + for prop_name in properties_config: + var prop_config = properties_config[prop_name] + _define_property_from_config(prop_name, prop_config) + + +func _define_property_from_config(prop_name: String, prop_config: Dictionary) -> void: + var prop_value: Variant = _get_initial_value(prop_name, prop_config) + var prop_type = prop_config.get("type", "text") + var category = prop_config.get("category", "General") + + var prop_settings: Dictionary = prop_config.duplicate() + prop_settings.erase("type") + prop_settings.erase("default") + prop_settings.erase("category") + + define_property(prop_name, prop_value, prop_type, prop_settings, category) + + +func make_all_values_unique() -> void: + var properties_config: Dictionary = _schema.get("properties", {}) + for prop_name in properties_config: + var prop_config = properties_config[prop_name] + _make_property_unique(prop_name, prop_config) + + +func _make_property_unique(prop_name: String, prop_config: Dictionary) -> void: + var must_be_unique: bool = prop_config.get("unique", false) + if not must_be_unique or not list_field: + return + + var prop_value: Variant = get_property_value(prop_name) + var original_value: Variant = prop_value + var attempt: int = 0 + var max_attempts: int = 1000 + + while _value_exists_in_list(prop_name, prop_value) and attempt < max_attempts: + attempt += 1 + + if original_value is String: + var end_num: Variant = _get_end_number(original_value) + if end_num == null: + prop_value = "%s %d" % [original_value, attempt] + else: + var base_str: String = original_value.left(-str(end_num).length()).strip_edges() + prop_value = "%s %d" % [base_str, end_num + attempt] + elif original_value is int: + prop_value = original_value + attempt + elif original_value is bool: + break + + var property: Property = get_property(prop_name) + if property: + property.value = prop_value + + +func _value_exists_in_list(prop_name: String, value: Variant) -> bool: + if not list_field: + return false + + for item: ListItemObject in list_field._list_items: + if item == self: + continue + + var item_prop: Property = item.get_property(prop_name) + if not item_prop: + continue + + if item_prop.get_value() == value: + return true + + return false + + +func _get_end_number(value: String) -> Variant: + var regex = RegEx.new() + regex.compile("\\d+$") + var result: RegExMatch = regex.search(value) + if result: + return int(result.get_string()) + return null + + +func _get_initial_value(prop_name: String, prop_config: Dictionary) -> Variant: + if _initial_data.has(prop_name): + return _initial_data[prop_name] + + var default: Variant = prop_config.get("default") + + if default is Callable: + return default.call() + + if default != null: + return default + + return _get_default_for_type(prop_config.get("type", "text")) + + +func _get_default_for_type(type: String) -> Variant: + match type: + "bool": + return false + "number", "int", "float": + return 0 + "text", "textarea", "dropdown": + return "" + "list": + return [] + "vector2": + return Vector2.ZERO + "vector3": + return Vector3.ZERO + _: + return null + + +func get_schema() -> Dictionary: + return _schema + + +func is_protected() -> bool: + return get_property("protected") and get_property_value("protected") + + +func duplicate_item(command_manager: CommandManager = null) -> ListItemObject: + var duplicate_data = _to_dict() + duplicate_data.erase("$type") + + if duplicate_data.has("name"): + duplicate_data["name"] = str(duplicate_data["name"]) + " (Copy)" + + if ( + duplicate_data.has("id") + and _schema.get("properties", {}).get("id", {}).get("default") is Callable + ): + var id_generator = _schema["properties"]["id"]["default"] + duplicate_data["id"] = id_generator.call() + + var new_item: ListItemObject = ListItemObject.new( + _schema, duplicate_data, command_manager if command_manager else history + ) + new_item.make_all_values_unique() + return new_item + + +func get_type() -> String: + return _schema.get("title", "ListItem") + + +func _on_property_changed(_pname: String, _old_value: Variant, _new_value: Variant) -> void: + pass + + +func get_settings() -> Dictionary: + return {} diff --git a/common/ui/editor_properties/list/list_item_object.gd.uid b/common/ui/editor_properties/list/list_item_object.gd.uid new file mode 100644 index 00000000..8372d106 --- /dev/null +++ b/common/ui/editor_properties/list/list_item_object.gd.uid @@ -0,0 +1 @@ +uid://gn61ergh0wbq diff --git a/common/ui/editor_properties/text/index.gd b/common/ui/editor_properties/text/index.gd new file mode 100644 index 00000000..40379840 --- /dev/null +++ b/common/ui/editor_properties/text/index.gd @@ -0,0 +1,9 @@ +extends MonologueIndexer + + +func get_scene() -> PackedScene: + return preload("uid://be0xxn5gocqjo") + + +func get_metadata() -> Dictionary: + return {"name": "text", "type": ObjectType.FIELD, "color": Color("af85fdff")} diff --git a/common/ui/editor_properties/text/index.gd.uid b/common/ui/editor_properties/text/index.gd.uid new file mode 100644 index 00000000..c82c935b --- /dev/null +++ b/common/ui/editor_properties/text/index.gd.uid @@ -0,0 +1 @@ +uid://86csxw8qmvb4 diff --git a/common/ui/editor_properties/text/text_field.gd b/common/ui/editor_properties/text/text_field.gd new file mode 100644 index 00000000..cb27b8ca --- /dev/null +++ b/common/ui/editor_properties/text/text_field.gd @@ -0,0 +1,49 @@ +extends Field + +@onready var line_edit: LineEdit = %LineEdit + + +func _ready() -> void: + super._ready() + line_edit.text_changed.connect(_on_text_changed) + line_edit.text_submitted.connect(_on_text_submitted) + line_edit.focus_exited.connect(_on_focus_exited) + + +func _on_initialize() -> void: + line_edit.placeholder_text = settings.get("placeholder", "") + + +func set_value(value: Variant) -> void: + if not is_node_ready(): + await ready + + line_edit.text = str(value) + + +func get_value() -> Variant: + return line_edit.text + + +func set_editable(is_editable: bool) -> void: + line_edit.editable = is_editable + + +func display_error(message: String) -> void: + super.display_error(message) + if message.is_empty(): + line_edit.remove_theme_color_override("font_color") + else: + line_edit.add_theme_color_override("font_color", Color(0.8, 0.1, 0.1)) + + +func _on_text_changed(new_text: String) -> void: + emit_value_changed(new_text) + + +func _on_text_submitted(submitted_text: String) -> void: + emit_value_committed(submitted_text) + + +func _on_focus_exited() -> void: + emit_value_committed(line_edit.text) diff --git a/common/ui/editor_properties/text/text_field.gd.uid b/common/ui/editor_properties/text/text_field.gd.uid new file mode 100644 index 00000000..789d3ca6 --- /dev/null +++ b/common/ui/editor_properties/text/text_field.gd.uid @@ -0,0 +1 @@ +uid://ntsxdpbgyehu diff --git a/common/ui/editor_properties/text/text_field.tscn b/common/ui/editor_properties/text/text_field.tscn new file mode 100644 index 00000000..2b9c7f99 --- /dev/null +++ b/common/ui/editor_properties/text/text_field.tscn @@ -0,0 +1,13 @@ +[gd_scene load_steps=2 format=3 uid="uid://be0xxn5gocqjo"] + +[ext_resource type="Script" uid="uid://ntsxdpbgyehu" path="res://common/ui/editor_properties/text/text_field.gd" id="1_56141"] + +[node name="VBoxContainer" type="VBoxContainer"] +offset_right = 76.0 +offset_bottom = 29.0 +size_flags_horizontal = 3 +script = ExtResource("1_56141") + +[node name="LineEdit" type="LineEdit" parent="."] +unique_name_in_owner = true +layout_mode = 2 diff --git a/common/ui/editor_properties/textarea/index.gd b/common/ui/editor_properties/textarea/index.gd new file mode 100644 index 00000000..bb2819a1 --- /dev/null +++ b/common/ui/editor_properties/textarea/index.gd @@ -0,0 +1,9 @@ +extends MonologueIndexer + + +func get_scene() -> PackedScene: + return preload("uid://dmqvbcct7rbn4") + + +func get_metadata() -> Dictionary: + return {"name": "textarea", "type": ObjectType.FIELD, "color": Color("af85fdff")} diff --git a/common/ui/editor_properties/textarea/index.gd.uid b/common/ui/editor_properties/textarea/index.gd.uid new file mode 100644 index 00000000..82b0574f --- /dev/null +++ b/common/ui/editor_properties/textarea/index.gd.uid @@ -0,0 +1 @@ +uid://yocjhdu0idyk diff --git a/common/ui/editor_properties/textarea/textarea_field.gd b/common/ui/editor_properties/textarea/textarea_field.gd new file mode 100644 index 00000000..56b8f795 --- /dev/null +++ b/common/ui/editor_properties/textarea/textarea_field.gd @@ -0,0 +1,49 @@ +extends Field + +@onready var text_edit: TextEdit = %TextEdit + + +func _ready() -> void: + super._ready() + text_edit.text_changed.connect(_on_text_changed) + text_edit.focus_exited.connect(_on_focus_exited) + + +func _on_initialize() -> void: + text_edit.placeholder_text = settings.get("placeholder", "") + + var rows: int = settings.get("rows", 3) + var sb: StyleBox = get_theme_stylebox("normal") + var padding: int = int(sb.content_margin_bottom + sb.content_margin_top) + text_edit.custom_minimum_size.y = text_edit.get_line_height() * rows + padding + + +func set_value(value: Variant) -> void: + if not is_node_ready(): + await ready + + text_edit.text = str(value) + + +func get_value() -> Variant: + return text_edit.text + + +func set_editable(is_editable: bool) -> void: + text_edit.editable = is_editable + + +func display_error(message: String) -> void: + super.display_error(message) + if message.is_empty(): + text_edit.remove_theme_color_override("font_color") + else: + text_edit.add_theme_color_override("font_color", Color(0.8, 0.1, 0.1)) + + +func _on_text_changed() -> void: + emit_value_changed(text_edit.text) + + +func _on_focus_exited() -> void: + emit_value_committed(text_edit.text) diff --git a/common/ui/editor_properties/textarea/textarea_field.gd.uid b/common/ui/editor_properties/textarea/textarea_field.gd.uid new file mode 100644 index 00000000..a510ab6a --- /dev/null +++ b/common/ui/editor_properties/textarea/textarea_field.gd.uid @@ -0,0 +1 @@ +uid://dgob6i4vh3bel diff --git a/common/ui/editor_properties/textarea/textarea_field.tscn b/common/ui/editor_properties/textarea/textarea_field.tscn new file mode 100644 index 00000000..ca455798 --- /dev/null +++ b/common/ui/editor_properties/textarea/textarea_field.tscn @@ -0,0 +1,13 @@ +[gd_scene load_steps=2 format=3 uid="uid://dmqvbcct7rbn4"] + +[ext_resource type="Script" uid="uid://dgob6i4vh3bel" path="res://common/ui/editor_properties/textarea/textarea_field.gd" id="1_17mni"] + +[node name="VBoxContainer" type="VBoxContainer"] +offset_right = 76.0 +offset_bottom = 29.0 +size_flags_horizontal = 3 +script = ExtResource("1_17mni") + +[node name="TextEdit" type="TextEdit" parent="."] +unique_name_in_owner = true +layout_mode = 2 diff --git a/common/ui/fields/character_field/assets/portrait_placeholder.svg b/common/ui/fields/character_field/assets/portrait_placeholder.svg deleted file mode 100644 index 35f2b975..00000000 --- a/common/ui/fields/character_field/assets/portrait_placeholder.svg +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - diff --git a/common/ui/fields/character_field/monologue_character_field.gd b/common/ui/fields/character_field/monologue_character_field.gd deleted file mode 100644 index 8ad612df..00000000 --- a/common/ui/fields/character_field/monologue_character_field.gd +++ /dev/null @@ -1,26 +0,0 @@ -class_name MonologueCharacterField extends MonologueField - - -@onready var name_edit := %NameEdit -@onready var delete_button := $HBoxContainer/VBoxContainer/VBoxContainer/HBoxContainer/DeleteButton - -var character_index: int = -1 -var default_portrait: String = "" -var graph_edit: MonologueGraphEdit - - -func propagate(value: Variant) -> void: - super.propagate(value) - name_edit.text = value.get("Name", "") - - -func _on_name_edit_focus_exited() -> void: - _on_name_edit_text_submitted(name_edit.text) - - -func _on_name_edit_text_submitted(new_text: String) -> void: - field_updated.emit({"Name" = new_text}) - - -func _on_edit_button_pressed() -> void: - GlobalSignal.emit("open_character_edit", [graph_edit, character_index]) diff --git a/common/ui/fields/character_field/monologue_character_field.gd.uid b/common/ui/fields/character_field/monologue_character_field.gd.uid deleted file mode 100644 index a8c217d4..00000000 --- a/common/ui/fields/character_field/monologue_character_field.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://cmvo3t5bngju6 diff --git a/common/ui/fields/character_field/monologue_character_field.tscn b/common/ui/fields/character_field/monologue_character_field.tscn deleted file mode 100644 index e7cba915..00000000 --- a/common/ui/fields/character_field/monologue_character_field.tscn +++ /dev/null @@ -1,78 +0,0 @@ -[gd_scene load_steps=6 format=3 uid="uid://rmul5j0wm0l8"] - -[ext_resource type="PackedScene" uid="uid://dfwf55ovgwir3" path="res://common/ui/buttons/delete_button.tscn" id="1_eutnh"] -[ext_resource type="Script" uid="uid://cmvo3t5bngju6" path="res://common/ui/fields/character_field/monologue_character_field.gd" id="1_no1me"] -[ext_resource type="Texture2D" uid="uid://ddah0eo1qhki4" path="res://common/ui/fields/character_field/assets/portrait_placeholder.svg" id="2_jkh4y"] -[ext_resource type="Shader" uid="uid://bsso8dloc4bce" path="res://logic/shaders/texture_rect_clip.tres" id="2_nva25"] - -[sub_resource type="ShaderMaterial" id="ShaderMaterial_q7tom"] -shader = ExtResource("2_nva25") -shader_parameter/corner_scale = 0.1 - -[node name="VBoxContainer" type="VBoxContainer"] -offset_right = 40.0 -offset_bottom = 40.0 -size_flags_horizontal = 3 -theme_override_constants/separation = 0 -script = ExtResource("1_no1me") - -[node name="HBoxContainer" type="HBoxContainer" parent="."] -layout_mode = 2 - -[node name="CenterContainer" type="CenterContainer" parent="HBoxContainer"] -custom_minimum_size = Vector2(100, 100) -layout_mode = 2 - -[node name="TextureRect" type="TextureRect" parent="HBoxContainer/CenterContainer"] -material = SubResource("ShaderMaterial_q7tom") -clip_contents = true -custom_minimum_size = Vector2(100, 100) -layout_mode = 2 -texture = ExtResource("2_jkh4y") -expand_mode = 1 -stretch_mode = 6 - -[node name="VBoxContainer" type="VBoxContainer" parent="HBoxContainer"] -layout_mode = 2 -size_flags_horizontal = 3 - -[node name="NameContainer" type="HBoxContainer" parent="HBoxContainer/VBoxContainer"] -layout_mode = 2 -size_flags_vertical = 3 - -[node name="FieldLabel" type="Label" parent="HBoxContainer/VBoxContainer/NameContainer"] -custom_minimum_size = Vector2(100, 0) -layout_mode = 2 -size_flags_vertical = 0 -text = "Name" - -[node name="InnerVBox" type="VBoxContainer" parent="HBoxContainer/VBoxContainer/NameContainer"] -layout_mode = 2 -size_flags_horizontal = 3 - -[node name="NameEdit" type="LineEdit" parent="HBoxContainer/VBoxContainer/NameContainer/InnerVBox"] -unique_name_in_owner = true -custom_minimum_size = Vector2(100, 0) -layout_mode = 2 - -[node name="VBoxContainer" type="VBoxContainer" parent="HBoxContainer/VBoxContainer"] -layout_mode = 2 -size_flags_vertical = 3 -alignment = 2 - -[node name="HBoxContainer" type="HBoxContainer" parent="HBoxContainer/VBoxContainer/VBoxContainer"] -layout_mode = 2 -alignment = 1 - -[node name="EditButton" type="Button" parent="HBoxContainer/VBoxContainer/VBoxContainer/HBoxContainer"] -layout_mode = 2 -size_flags_horizontal = 3 -text = "Edit" - -[node name="DeleteButton" parent="HBoxContainer/VBoxContainer/VBoxContainer/HBoxContainer" instance=ExtResource("1_eutnh")] -layout_mode = 2 -size_flags_vertical = 4 - -[connection signal="focus_exited" from="HBoxContainer/VBoxContainer/NameContainer/InnerVBox/NameEdit" to="." method="_on_name_edit_focus_exited"] -[connection signal="text_submitted" from="HBoxContainer/VBoxContainer/NameContainer/InnerVBox/NameEdit" to="." method="_on_name_edit_text_submitted"] -[connection signal="pressed" from="HBoxContainer/VBoxContainer/VBoxContainer/HBoxContainer/EditButton" to="." method="_on_edit_button_pressed"] diff --git a/common/ui/fields/check_box/monologue_check_box.gd b/common/ui/fields/check_box/monologue_check_box.gd deleted file mode 100644 index d3d5c5f0..00000000 --- a/common/ui/fields/check_box/monologue_check_box.gd +++ /dev/null @@ -1,17 +0,0 @@ -class_name MonologueCheckBox extends MonologueField - -@onready var check_box = $VBox/CheckBox -@onready var label = $Label - - -func set_label_text(text: String) -> void: - label.text = text - - -func propagate(value: Variant) -> void: - super.propagate(value) - check_box.set_pressed_no_signal(value if (value is bool) else false) - - -func _on_check_box_toggled(toggled_on: bool) -> void: - field_updated.emit(toggled_on) diff --git a/common/ui/fields/check_box/monologue_check_box.gd.uid b/common/ui/fields/check_box/monologue_check_box.gd.uid deleted file mode 100644 index 688b968a..00000000 --- a/common/ui/fields/check_box/monologue_check_box.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://m2a68q1fce52 diff --git a/common/ui/fields/check_box/monologue_check_box.tscn b/common/ui/fields/check_box/monologue_check_box.tscn deleted file mode 100644 index 917031d9..00000000 --- a/common/ui/fields/check_box/monologue_check_box.tscn +++ /dev/null @@ -1,24 +0,0 @@ -[gd_scene load_steps=3 format=3 uid="uid://71sq1ohwv8cn"] - -[ext_resource type="Script" uid="uid://m2a68q1fce52" path="res://common/ui/fields/check_box/monologue_check_box.gd" id="1_awprp"] -[ext_resource type="PackedScene" uid="uid://x0daq5tsejey" path="res://common/ui/fields/field_label.tscn" id="2_8ij76"] - -[node name="MonologueCheckBox" type="HBoxContainer"] -custom_minimum_size = Vector2(0, 32) -offset_right = 81.0 -offset_bottom = 32.0 -theme_type_variation = &"HBoxContainer_Small" -script = ExtResource("1_awprp") - -[node name="VBox" type="VBoxContainer" parent="."] -layout_mode = 2 -alignment = 1 - -[node name="CheckBox" type="CheckBox" parent="VBox"] -layout_mode = 2 -expand_icon = true - -[node name="Label" parent="." instance=ExtResource("2_8ij76")] -layout_mode = 2 - -[connection signal="toggled" from="VBox/CheckBox" to="." method="_on_check_box_toggled"] diff --git a/common/ui/fields/collapsible_field/collapsible_field.gd b/common/ui/fields/collapsible_field/collapsible_field.gd deleted file mode 100644 index 355c820a..00000000 --- a/common/ui/fields/collapsible_field/collapsible_field.gd +++ /dev/null @@ -1,97 +0,0 @@ -class_name CollapsibleField extends VBoxContainer - -signal add_pressed - -@export var show_add_button: bool = false -@export var separate_items: bool = false -@export var expand: bool = false - -@onready var button := $Button -@onready var collapsible_container := $CollapsibleContainer -@onready var vbox := %FieldContainer -@onready var add_button := %AddButton - -@onready var icon_close := preload("res://ui/assets/icons/arrow_right.svg") -@onready var icon_open := preload("res://ui/assets/icons/arrow_down.svg") - - -func _ready() -> void: - button.icon = icon_close - add_button.visible = show_add_button - close() - _update() - - -func add_item(item: Control, force_readable_name: bool = false) -> void: - var existing_children = vbox.get_children().filter(_is_not_being_deleted) - if separate_items and existing_children.size() > 0: - var separator := HSeparator.new() - separator.theme_type_variation = "HDottedSeparator" - vbox.add_child(separator, true) - - item.visibility_changed.connect(_update) - - vbox.add_child(item, force_readable_name) - _update() - - -func _update(): - var can_see: bool = show_add_button - - for child in vbox.get_children(): - if not child.visible: - continue - can_see = true - - if visible != can_see: - visible = can_see - - if expand: - size_flags_vertical = SIZE_EXPAND_FILL - vbox.size_flags_vertical = SIZE_EXPAND_FILL - - -func set_title(text: String) -> void: - button.text = text - - -func get_items() -> Array[Node]: - return vbox.get_children().filter(func(c): return c is not HSeparator) - - -func is_open() -> bool: - return collapsible_container.visible - - -func clear() -> void: - for child in vbox.get_children(): - child.queue_free() - - _update() - - -func _on_button_pressed() -> void: - if is_open(): - close() - else: - open() - - -func open() -> void: - button.icon = icon_open - collapsible_container.show() - button.release_focus() - - -func close() -> void: - button.icon = icon_close - collapsible_container.hide() - button.release_focus() - - -func _on_add_button_pressed() -> void: - add_pressed.emit() - - -func _is_not_being_deleted(node: Node) -> bool: - return not node.is_queued_for_deletion() diff --git a/common/ui/fields/collapsible_field/collapsible_field.gd.uid b/common/ui/fields/collapsible_field/collapsible_field.gd.uid deleted file mode 100644 index 7f7e7dd8..00000000 --- a/common/ui/fields/collapsible_field/collapsible_field.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://bgy7bshgkocth diff --git a/common/ui/fields/collapsible_field/collapsible_field.tscn b/common/ui/fields/collapsible_field/collapsible_field.tscn deleted file mode 100644 index 7ee4ade7..00000000 --- a/common/ui/fields/collapsible_field/collapsible_field.tscn +++ /dev/null @@ -1,56 +0,0 @@ -[gd_scene load_steps=3 format=3 uid="uid://hvv74un17dp0"] - -[ext_resource type="Script" uid="uid://bgy7bshgkocth" path="res://common/ui/fields/collapsible_field/collapsible_field.gd" id="1_tmui1"] -[ext_resource type="Texture2D" uid="uid://cb6n6enqfvclw" path="res://ui/assets/icons/arrow_right.svg" id="2_357t1"] - -[node name="CollapsibleField" type="VBoxContainer"] -offset_right = 72.0 -offset_bottom = 89.0 -size_flags_horizontal = 3 -theme_override_constants/separation = 0 -script = ExtResource("1_tmui1") - -[node name="Button" type="Button" parent="."] -layout_mode = 2 -theme_type_variation = &"Button_Flat_NoCorner" -icon = ExtResource("2_357t1") -alignment = 0 -icon_alignment = 2 - -[node name="CollapsibleContainer" type="MarginContainer" parent="."] -layout_mode = 2 -size_flags_vertical = 3 -theme_type_variation = &"MarginContainer_Medium" -theme_override_constants/margin_left = 40 -theme_override_constants/margin_top = 0 -theme_override_constants/margin_right = 0 - -[node name="PanelContainer" type="PanelContainer" parent="CollapsibleContainer"] -layout_mode = 2 -theme_type_variation = &"CollapsibleFieldPanel" - -[node name="VBox" type="VBoxContainer" parent="CollapsibleContainer/PanelContainer"] -layout_mode = 2 -theme_override_constants/separation = 0 - -[node name="FieldContainer" type="VBoxContainer" parent="CollapsibleContainer/PanelContainer/VBox"] -unique_name_in_owner = true -layout_mode = 2 -size_flags_horizontal = 3 -size_flags_vertical = 3 -theme_type_variation = &"FieldContainer" - -[node name="MarginContainer" type="MarginContainer" parent="CollapsibleContainer/PanelContainer/VBox"] -layout_mode = 2 -theme_type_variation = &"MarginContainer_Medium" - -[node name="AddButton" type="Button" parent="CollapsibleContainer/PanelContainer/VBox/MarginContainer"] -unique_name_in_owner = true -visible = false -layout_mode = 2 -mouse_default_cursor_shape = 2 -theme_type_variation = &"Button_Outline" -text = "+" - -[connection signal="pressed" from="Button" to="." method="_on_button_pressed"] -[connection signal="pressed" from="CollapsibleContainer/PanelContainer/VBox/MarginContainer/AddButton" to="." method="_on_add_button_pressed"] diff --git a/common/ui/fields/dropdown/monolgue_dropdown.gd b/common/ui/fields/dropdown/monolgue_dropdown.gd deleted file mode 100644 index 151a1aca..00000000 --- a/common/ui/fields/dropdown/monolgue_dropdown.gd +++ /dev/null @@ -1,109 +0,0 @@ -class_name MonologueDropdown extends MonologueField - -@export var store_index: bool -## Usefull when items are set after the value is set. -@export var late_items: bool - -@onready var label: Label = $Label -@onready var option_button: OptionButton = $OptionButton - -var backup_value: Variant - - -func _ready() -> void: - option_button.get_popup().transparent_bg = true - - -func disable_items(index_list: PackedInt32Array): - for index in range(1, option_button.item_count): - var is_disabled = index_list.has(index) - option_button.set_item_disabled(index, is_disabled) - validate() - - -func get_items() -> Array[Dictionary]: - var result: Array[Dictionary] = [] - for idx in range(option_button.item_count): - result.append( - { - "id": option_button.get_item_id(idx), - "text": option_button.get_item_text(idx), - "metadata": option_button.get_item_metadata(idx) - } - ) - return result - - -func get_item_idx_from_text(text: String) -> int: - var items = get_items() - for item in items: - if item.text == text: - return items.find(item) - return -1 - - -func propagate(value: Variant) -> void: - super.propagate(value) - backup_value = value - var index = get_item_idx_from_text(value) if value is String else value - if index < 0 or index >= option_button.item_count: # avoid falsy check - option_button.selected = 0 - else: - option_button.selected = index - validate() - - -func set_icons(index_to_texture: Dictionary): - for index in index_to_texture.keys(): - option_button.set_item_icon(index, index_to_texture.get(index)) - - -# `key_text` can contain "/" to navigate inside `data`. -func set_items( - data: Array, - key_text: String = "text", - key_id: String = "EditorIndex", - key_meta: String = "metadata" -) -> void: - option_button.clear() - for idx in range(data.size()): - var item_id = data[idx].get(key_id, -1) - if item_id is String: - item_id = -1 - var item_name = data[idx] - var item_name_path = key_text.split("/") - - for path in item_name_path: - item_name = item_name.get(path) - if item_name == null: - item_name = "undefined" - break - - option_button.add_item(item_name, item_id) - option_button.set_item_metadata(idx, data[idx].get(key_meta, "")) - - if late_items: - propagate(backup_value) - - validate() - - -func set_label_text(text: String) -> void: - label.text = text - - -func validate(): - var is_out = option_button.selected >= option_button.item_count - var is_negative = option_button.selected < 0 - if is_negative or is_out or option_button.is_item_disabled(option_button.selected): - option_button.theme_type_variation = "OptionButton_Error" - else: - option_button.theme_type_variation = "" - - -func _on_item_selected(index: int) -> void: - var value = index - if not store_index: - value = option_button.get_item_text(index) - validate() - field_updated.emit(value) diff --git a/common/ui/fields/dropdown/monolgue_dropdown.gd.uid b/common/ui/fields/dropdown/monolgue_dropdown.gd.uid deleted file mode 100644 index e71d25b9..00000000 --- a/common/ui/fields/dropdown/monolgue_dropdown.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://ci7ipnx47b6fx diff --git a/common/ui/fields/dropdown/monologue_dropdown.tscn b/common/ui/fields/dropdown/monologue_dropdown.tscn deleted file mode 100644 index 39011579..00000000 --- a/common/ui/fields/dropdown/monologue_dropdown.tscn +++ /dev/null @@ -1,20 +0,0 @@ -[gd_scene load_steps=3 format=3 uid="uid://csunin0yg3ay0"] - -[ext_resource type="Script" uid="uid://ci7ipnx47b6fx" path="res://common/ui/fields/dropdown/monolgue_dropdown.gd" id="1_jtdjo"] -[ext_resource type="PackedScene" uid="uid://x0daq5tsejey" path="res://common/ui/fields/field_label.tscn" id="2_ahvj0"] - -[node name="MonologueDropdown" type="HBoxContainer"] -offset_right = 7.0 -offset_bottom = 29.0 -script = ExtResource("1_jtdjo") - -[node name="Label" parent="." instance=ExtResource("2_ahvj0")] -layout_mode = 2 - -[node name="OptionButton" type="OptionButton" parent="."] -layout_mode = 2 -size_flags_horizontal = 3 -clip_text = true -allow_reselect = true - -[connection signal="item_selected" from="OptionButton" to="." method="_on_item_selected"] diff --git a/common/ui/fields/field_label.tscn b/common/ui/fields/field_label.tscn deleted file mode 100644 index 31924d94..00000000 --- a/common/ui/fields/field_label.tscn +++ /dev/null @@ -1,7 +0,0 @@ -[gd_scene format=3 uid="uid://x0daq5tsejey"] - -[node name="FieldLabel" type="Label"] -custom_minimum_size = Vector2(100, 31) -size_flags_vertical = 0 -text = "Value" -vertical_alignment = 1 diff --git a/common/ui/fields/file_picker/file_picker.gd b/common/ui/fields/file_picker/file_picker.gd deleted file mode 100644 index 994993ec..00000000 --- a/common/ui/fields/file_picker/file_picker.gd +++ /dev/null @@ -1,78 +0,0 @@ -class_name FilePicker extends MonologueField - -const AUDIO = ["*.mp3,*.ogg,*.wav;Sound Files"] -const IMAGE = ["*.bmp,*.jpg,*.jpeg,*.png,*.svg,*.webp;Image Files"] - -@export var base_path: String -@export var filters: PackedStringArray - -@onready var label: Label = $Label -@onready var line_edit: LineEdit = $VBox/HBox/LineEdit -@onready var picker_button: Button = $VBox/HBox/FilePickerButton -@onready var warn_label: Label = $VBox/WarnLabel - - -func set_label_text(text: String) -> void: - label.text = text - - -func propagate(value: Variant) -> void: - super.propagate(value) - line_edit.text = value - validate(value) - - -func validate(path: String) -> bool: - warn_label.hide() - var is_valid = true - path = path.lstrip(" ") - path = path.rstrip(" ") - if path and filters: - var absolute_path = Path.relative_to_absolute(path, base_path) - if not FileAccess.file_exists(absolute_path): - warn_label.show() - warn_label.text = "File path not found!" - is_valid = false - else: - var correct_suffix: bool = false - var file_name: String = absolute_path.get_file() - for filter in filters: - var targets = _split_match(filter) - for target in targets: - if file_name.match(target): - correct_suffix = true - break - if not correct_suffix: - warn_label.show() - var formats = Array(filters).map(_split_match) - var text = ", ".join(formats.map(func(f): return ", ".join(f))) - warn_label.text = "File must match: %s" % text - is_valid = false - return is_valid - - -func _on_file_selected(path: String): - line_edit.text = Path.absolute_to_relative(path, base_path) - _on_focus_exited() - - -func _on_focus_exited() -> void: - _on_text_submitted(line_edit.text) - - -func _on_picker_button_pressed(): - GlobalSignal.emit("open_file_request", [_on_file_selected, filters, base_path.get_base_dir()]) - - -func _on_text_changed(new_text: String) -> void: - validate(new_text) - field_changed.emit(new_text) - - -func _on_text_submitted(file_path: String) -> void: - validate(file_path) - field_updated.emit(file_path) - - -func _split_match(filter: String) -> Array: - return filter.split(";")[0].split(",") diff --git a/common/ui/fields/file_picker/file_picker.gd.uid b/common/ui/fields/file_picker/file_picker.gd.uid deleted file mode 100644 index c3318124..00000000 --- a/common/ui/fields/file_picker/file_picker.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://bqlktpo5qx1ps diff --git a/common/ui/fields/file_picker/monologue_file_picker.tscn b/common/ui/fields/file_picker/monologue_file_picker.tscn deleted file mode 100644 index 5e7b6f0f..00000000 --- a/common/ui/fields/file_picker/monologue_file_picker.tscn +++ /dev/null @@ -1,50 +0,0 @@ -[gd_scene load_steps=5 format=3 uid="uid://o5dt5106rohh"] - -[ext_resource type="Script" uid="uid://bqlktpo5qx1ps" path="res://common/ui/fields/file_picker/file_picker.gd" id="1_siiu8"] -[ext_resource type="PackedScene" uid="uid://x0daq5tsejey" path="res://common/ui/fields/field_label.tscn" id="2_hph74"] -[ext_resource type="Texture2D" uid="uid://t1i3wy037vsu" path="res://ui/assets/icons/folder_icon.png" id="2_plad0"] - -[sub_resource type="LabelSettings" id="LabelSettings_nr3ee"] -font_color = Color(0.768627, 0.180392, 0.25098, 1) - -[node name="FilePickerLineEdit" type="HBoxContainer"] -offset_right = 300.0 -offset_bottom = 59.0 -script = ExtResource("1_siiu8") - -[node name="Label" parent="." instance=ExtResource("2_hph74")] -layout_mode = 2 - -[node name="VBox" type="VBoxContainer" parent="."] -layout_mode = 2 -size_flags_horizontal = 3 - -[node name="HBox" type="HBoxContainer" parent="VBox"] -layout_mode = 2 -theme_override_constants/separation = 0 -alignment = 2 - -[node name="LineEdit" type="LineEdit" parent="VBox/HBox"] -layout_mode = 2 -size_flags_horizontal = 3 -structured_text_bidi_override = 2 - -[node name="FilePickerButton" type="Button" parent="VBox/HBox"] -custom_minimum_size = Vector2(33, 25) -layout_mode = 2 -theme_type_variation = &"FlatButton" -icon = ExtResource("2_plad0") -icon_alignment = 1 -expand_icon = true - -[node name="WarnLabel" type="Label" parent="VBox"] -custom_minimum_size = Vector2(100, 0) -layout_mode = 2 -text = "File path not found!" -label_settings = SubResource("LabelSettings_nr3ee") -autowrap_mode = 2 - -[connection signal="focus_exited" from="VBox/HBox/LineEdit" to="." method="_on_focus_exited"] -[connection signal="text_changed" from="VBox/HBox/LineEdit" to="." method="_on_text_changed"] -[connection signal="text_submitted" from="VBox/HBox/LineEdit" to="." method="_on_text_submitted"] -[connection signal="pressed" from="VBox/HBox/FilePickerButton" to="." method="_on_picker_button_pressed"] diff --git a/common/ui/fields/line_edit/monologue_line_edit.gd b/common/ui/fields/line_edit/monologue_line_edit.gd deleted file mode 100644 index 4dcceceb..00000000 --- a/common/ui/fields/line_edit/monologue_line_edit.gd +++ /dev/null @@ -1,70 +0,0 @@ -class_name MonologueLine extends MonologueField - -@export var copyable: bool -@export var font_size: int = 16 -@export var is_sublabel: bool -@export var sublabel_prefix: String = "↳ " -@export var note_text: String - -var ribbon_scene = preload("res://common/ui/ribbon/ribbon.tscn") -var revert_text: String -var validator: Callable = func(_text): return true - -@onready var copy_button = $HBox/InnerVBox/LineEdit/HBoxContainer/CopyButton -@onready var label = $HBox/FieldLabel -@onready var line_edit = $HBox/InnerVBox/LineEdit -@onready var warning = $HBox/InnerVBox/WarnLabel -@onready var note = $NoteLabel - - -# Called when the node enters the scene tree for the first time. -func _ready() -> void: - copy_button.visible = copyable - label.add_theme_font_size_override("font_size", font_size) - line_edit.add_theme_font_size_override("font_size", font_size) - warning.add_theme_font_size_override("font_size", font_size) - warning.hide() - note.visible = !note_text.is_empty() - note.text = note_text - - -func set_label_text(text: String) -> void: - if is_sublabel: - label.custom_minimum_size.x = 140 - add_theme_constant_override("margin_left", 25) - label.add_theme_color_override("font_color", Color("858585")) - label.text = sublabel_prefix + text - else: - label.text = text - - -func set_label_visible(can_see: bool) -> void: - label.visible = can_see - - -func propagate(value: Variant) -> void: - super.propagate(value) - line_edit.text = str(value) - revert_text = line_edit.text - - -func _on_copy_button_pressed() -> void: - DisplayServer.clipboard_set(line_edit.text) - var ribbon = ribbon_scene.instantiate() - ribbon.position = get_viewport().get_mouse_position() - get_window().add_child(ribbon) - - -func _on_focus_exited() -> void: - _on_text_submitted(line_edit.text) - - -func _on_text_changed(new_text: String) -> void: - field_changed.emit(new_text) - - -func _on_text_submitted(new_text: String) -> void: - if validator.call(new_text): - field_updated.emit(new_text) - else: - line_edit.text = revert_text diff --git a/common/ui/fields/line_edit/monologue_line_edit.gd.uid b/common/ui/fields/line_edit/monologue_line_edit.gd.uid deleted file mode 100644 index 27ab279b..00000000 --- a/common/ui/fields/line_edit/monologue_line_edit.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://cdx8c5vk7f3jb diff --git a/common/ui/fields/line_edit/monologue_line_edit.tscn b/common/ui/fields/line_edit/monologue_line_edit.tscn deleted file mode 100644 index 8c82947a..00000000 --- a/common/ui/fields/line_edit/monologue_line_edit.tscn +++ /dev/null @@ -1,63 +0,0 @@ -[gd_scene load_steps=4 format=3 uid="uid://bw7thqdhujl41"] - -[ext_resource type="Script" uid="uid://cdx8c5vk7f3jb" path="res://common/ui/fields/line_edit/monologue_line_edit.gd" id="1_toqtt"] -[ext_resource type="Texture2D" uid="uid://dm2u0xqmmcorj" path="res://ui/assets/icons/copy.png" id="2_lbcco"] -[ext_resource type="PackedScene" uid="uid://x0daq5tsejey" path="res://common/ui/fields/field_label.tscn" id="2_v8fwd"] - -[node name="MonologueLineEdit" type="VBoxContainer"] -offset_right = 40.0 -offset_bottom = 40.0 -size_flags_horizontal = 3 -script = ExtResource("1_toqtt") -sublabel_prefix = "┗ " - -[node name="HBox" type="HBoxContainer" parent="."] -layout_mode = 2 - -[node name="FieldLabel" parent="HBox" instance=ExtResource("2_v8fwd")] -layout_mode = 2 - -[node name="InnerVBox" type="VBoxContainer" parent="HBox"] -layout_mode = 2 -size_flags_horizontal = 3 - -[node name="LineEdit" type="LineEdit" parent="HBox/InnerVBox"] -custom_minimum_size = Vector2(100, 0) -layout_mode = 2 - -[node name="HBoxContainer" type="HBoxContainer" parent="HBox/InnerVBox/LineEdit"] -layout_mode = 1 -anchors_preset = 11 -anchor_left = 1.0 -anchor_right = 1.0 -anchor_bottom = 1.0 -offset_left = -30.0 -grow_horizontal = 0 -grow_vertical = 2 -alignment = 2 - -[node name="CopyButton" type="Button" parent="HBox/InnerVBox/LineEdit/HBoxContainer"] -custom_minimum_size = Vector2(33, 25) -layout_mode = 2 -icon = ExtResource("2_lbcco") -flat = true -icon_alignment = 1 -expand_icon = true - -[node name="WarnLabel" type="Label" parent="HBox/InnerVBox"] -layout_mode = 2 -theme_type_variation = &"WarnLabel" -text = "Warning" - -[node name="NoteLabel" type="Label" parent="."] -custom_minimum_size = Vector2(100, 0) -layout_mode = 2 -theme_type_variation = &"NoteLabel" -theme_override_font_sizes/font_size = 12 -text = "Note: Description" -autowrap_mode = 3 - -[connection signal="focus_exited" from="HBox/InnerVBox/LineEdit" to="." method="_on_focus_exited"] -[connection signal="text_changed" from="HBox/InnerVBox/LineEdit" to="." method="_on_text_changed"] -[connection signal="text_submitted" from="HBox/InnerVBox/LineEdit" to="." method="_on_text_submitted"] -[connection signal="pressed" from="HBox/InnerVBox/LineEdit/HBoxContainer/CopyButton" to="." method="_on_copy_button_pressed"] diff --git a/common/ui/fields/list/monologue_list.gd b/common/ui/fields/list/monologue_list.gd deleted file mode 100644 index 7312cfc7..00000000 --- a/common/ui/fields/list/monologue_list.gd +++ /dev/null @@ -1,136 +0,0 @@ -## A list field that represents a [MonologueGraphEdit] data item. -class_name MonologueList extends MonologueField - -@onready var button := $CollapsibleField/Button -@onready var collapsible_container := $CollapsibleField/CollapsibleContainer -@onready var vbox := $CollapsibleField/CollapsibleContainer/PanelContainer/VBox -@onready -var field_container := $CollapsibleField/CollapsibleContainer/PanelContainer/VBox/FieldContainer - -var delete_scene = preload("res://common/ui/buttons/delete_button.tscn") - -var add_callback: Callable = Constants.empty_callback -var delete_callback: Callable = func(list): return list -var get_callback: Callable = Constants.empty_callback -var data_list: Array = [] -var flat: bool = false -var expand: bool = false - - -func _ready() -> void: - collapsible_field = $CollapsibleField - collapsible_field.add_pressed.connect(_on_add_button_pressed) - collapsible_field.expand = expand - post_ready.call_deferred() - - if flat: - collapsible_field.separate_items = false - button.hide() - collapsible_container.add_theme_constant_override("margin_left", 0) - field_container.add_theme_constant_override("margin_left", 0) - collapsible_field._update() - - -func post_ready() -> void: - if get_parent().get_child_count() <= 1: - collapsible_field.open() - - -## Add a new option node into the list and show its fields in the vbox. -func append_list_item(item) -> void: - var panel := create_flat_item_container() if flat else create_item_container() - var field_box = create_item_vbox(panel) - collapsible_field.add_item(panel, true) - for property_name in item.get_property_names(): - var property = item.get(property_name) - if not property.visible: - continue - var field = item.get(property_name).show(field_box, false) - field.set_label_text(Util.to_key_name(property_name, " ")) - var identifier = item.id.value if "id" in item else item.name.value - - if "custom_delete_button" in item and item.custom_delete_button: - item.custom_delete_button.connect("pressed", _on_delete_button_pressed.bind(identifier)) - return - create_delete_button(field_box, identifier) - - -func clear_list(): - collapsible_field.clear() - data_list = [] - - -func create_item_container() -> PanelContainer: - var item_container = PanelContainer.new() - item_container.theme_type_variation = "ItemContainer" - return item_container - - -func create_flat_item_container() -> PanelContainer: - var item_container = PanelContainer.new() - item_container.theme_type_variation = "ItemContainerFlat" - return item_container - - -func create_item_vbox(panel: PanelContainer) -> VBoxContainer: - var item_vbox = VBoxContainer.new() - panel.add_child(item_vbox, true) - return item_vbox - - -func create_delete_button(field_box: VBoxContainer, id: Variant) -> void: - var delete_button = delete_scene.instantiate() - delete_button.connect("pressed", _on_delete_button_pressed.bind(id)) - - var first_hbox = _find_first_hbox(field_box) - if first_hbox: - first_hbox.add_child(delete_button, true) - else: - delete_button.queue_free() - - -func set_label_text(text: String) -> void: - collapsible_field.set_title(text) - - -func set_label_visible(_can_see: bool) -> void: - pass - - -func propagate(data: Variant) -> void: - super.propagate(data) - clear_list() - data_list = get_callback.call() - for reference in data_list: - append_list_item(reference) - data_list = data_list.map(func(r): return r._to_dict()) - - -func _find_first_hbox(control: Control) -> HBoxContainer: - for child in control.get_children(): - if child is HBoxContainer and child.visible: - return child - else: - var recursive = _find_first_hbox(child) - if recursive: - return recursive - return null - - -func _on_add_button_pressed() -> void: - # the add_callback creates the actual instance in its source node - data_list = get_callback.call() - data_list = data_list.map(func(r): return r._to_dict()) - var new_item = add_callback.call() - data_list.append(new_item._to_dict.call()) - append_list_item(new_item) - field_updated.emit(data_list) - - -func _on_delete_button_pressed(id: Variant) -> void: - for reference in data_list: - if reference.get("ID") == id or reference.get("Name") == id: - data_list.erase(reference) - break - var modified_list = delete_callback.call(data_list) - field_updated.emit(modified_list) diff --git a/common/ui/fields/list/monologue_list.gd.uid b/common/ui/fields/list/monologue_list.gd.uid deleted file mode 100644 index 988801fc..00000000 --- a/common/ui/fields/list/monologue_list.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://u77m3oxit3r8 diff --git a/common/ui/fields/list/monologue_list.tscn b/common/ui/fields/list/monologue_list.tscn deleted file mode 100644 index 4fb5a8c0..00000000 --- a/common/ui/fields/list/monologue_list.tscn +++ /dev/null @@ -1,19 +0,0 @@ -[gd_scene load_steps=3 format=3 uid="uid://ddc27sbeek1p"] - -[ext_resource type="Script" uid="uid://u77m3oxit3r8" path="res://common/ui/fields/list/monologue_list.gd" id="1_8kx3n"] -[ext_resource type="PackedScene" uid="uid://hvv74un17dp0" path="res://common/ui/fields/collapsible_field/collapsible_field.tscn" id="2_jih45"] - -[node name="MonologueList" type="VBoxContainer"] -anchors_preset = -1 -anchor_right = 0.125 -anchor_bottom = 0.062 -offset_bottom = 0.479996 -theme_override_constants/separation = 5 -script = ExtResource("1_8kx3n") - -[node name="CollapsibleField" parent="." instance=ExtResource("2_jih45")] -layout_mode = 2 -show_add_button = true -separate_items = true - -[editable path="CollapsibleField"] diff --git a/common/ui/fields/localizable.gd b/common/ui/fields/localizable.gd deleted file mode 100644 index f692da31..00000000 --- a/common/ui/fields/localizable.gd +++ /dev/null @@ -1,65 +0,0 @@ -## Properties which can have language switching. -class_name Localizable extends Property - -## Stores the value in a locale dictionary. -var raw_data: Dictionary = {} -## The value to be initialized on a new locale. Empty string by default. -var initialized_value: Variant - - -func _init(ui_scene: PackedScene, ui_setters: Dictionary = {}, default: Variant = "") -> void: - super(ui_scene, ui_setters, default) - initialized_value = default - GlobalSignal.add_listener("language_deleted", store_data) - - -## Gets the current language from the language switcher. -func get_locale() -> LanguageOption: - if GlobalVariables.language_switcher: - return GlobalVariables.language_switcher.get_current_language() - else: - return null - - -func get_value() -> Variant: - if GlobalVariables.language_switcher: - return raw_data.get(get_locale().name, initialized_value) - return super.get_value() - - -func set_value(new_value: Variant) -> void: - if GlobalVariables.language_switcher: - var langs = GlobalVariables.language_switcher.get_languages().keys() - if new_value is Dictionary and Util.is_any_inside(new_value.keys(), langs): - raw_data = _from_raw_value(new_value) - else: - raw_data[get_locale().name] = new_value - super.set_value(new_value) - - -func store_data(node_name: String, restoration: Dictionary, _choices: Dictionary) -> void: - if raw_data.has(node_name): - restoration[self] = raw_data.duplicate(true) - - -## Export property value as localized dictionary. -func to_raw_value() -> Variant: - if GlobalVariables.language_switcher: - var new_dict = {} - for key in raw_data: - var option = GlobalVariables.language_switcher.get_by_node_name(key) - if option: - new_dict[str(option)] = raw_data.get(key, initialized_value) - return new_dict - return value - - -## Private method to load property value is a localized dictionary. -func _from_raw_value(string_dict: Dictionary) -> Dictionary: - var language_dict = GlobalVariables.language_switcher.get_languages() - var new_dict = {} - for key in string_dict: - var language_node_name = language_dict.get(key) - if language_node_name: - new_dict[language_node_name] = string_dict.get(key) - return new_dict diff --git a/common/ui/fields/localizable.gd.uid b/common/ui/fields/localizable.gd.uid deleted file mode 100644 index 22b5f7d7..00000000 --- a/common/ui/fields/localizable.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://bntwx0k2d3hqy diff --git a/common/ui/fields/monologue_argument.gd b/common/ui/fields/monologue_argument.gd deleted file mode 100644 index 4471f18d..00000000 --- a/common/ui/fields/monologue_argument.gd +++ /dev/null @@ -1,89 +0,0 @@ -## Similar to MonologueVariable but allows reference to existing variables. -class_name MonologueArgument extends MonologueVariable - -var last_boolean: bool -var last_number: float -var last_string: String - - -func _init(node: MonologueGraphNode): - super(node) - type.callers["set_items"][0].append({"id": 3, "text": "Variable"}) - #type.callers["set_icons"][0][3] = load("res://ui/assets/icons/bool_icon.png") - value.connect("preview", record_morph) - - -func change(_old_value: Variant, new_value: Variant, property: String) -> void: - var old_list = bound_node.arguments.value.duplicate(true) - var new_list = bound_node.arguments.value.duplicate(true) - new_list[index][property.capitalize()] = new_value - - # bound_node can be deleted, so we need to use PropertyChange here - graph.undo_redo.create_action("Arguments => %s" % new_value) - var pc = PropertyChange.new("arguments", old_list, new_list) - var ph = PropertyHistory.new(graph, graph.get_path_to(bound_node), [pc]) - graph.undo_redo.add_prepared_history(ph) - graph.undo_redo.commit_action() - - -## Creates a representation of the argument in an HBoxContainer. -func create_representation(parent: Control) -> HBoxContainer: - var representation = HBoxContainer.new() - parent.add_child(representation) - - var name_label = Label.new() - var name_text = name.value if name.value else "argument" - name_label.text = " #%d: %s" % [representation.get_index(), name_text] - representation.add_child(name_label) - - var type_label = Label.new() - type_label.text = "[%s]" % type.value if type.value else "type" - representation.add_child(type_label) - - var value_label = Label.new() - value_label.theme_type_variation = "NodeValue" - value_label.text = ( - str(value.value) if value.value is not String or value.value != "" else "value" - ) - representation.add_child(value_label) - - return representation - - -## Record the argument value so field morphing will populate correct value type. -func record_morph(new_value: Variant) -> void: - match typeof(new_value): - TYPE_BOOL: - last_boolean = new_value - TYPE_INT, TYPE_FLOAT: - last_number = new_value - TYPE_STRING: - last_string = new_value - - -## Reset the value if the argument value is not matching the type. -func reset_value(): - match type.value: - "Boolean": - if value.value is not bool: - value.value = last_boolean - "Integer": - if value.value is not float and value.value is not int: - value.value = last_number - _: - if value.value is not String: - value.value = last_string - - -func _type_morph(selected_type: String = type.value): - if selected_type == "Variable": - value.callers["set_items"] = [graph.variables, "Name", "ID", "Type"] - if graph.variables and value.value is not String: - value.value = graph.variables[0].get("Name") - value.morph(MonologueGraphNode.DROPDOWN) - else: - value.callers.erase("set_items") - super._type_morph(selected_type) - - reset_value() - value.propagate(value.value, false) diff --git a/common/ui/fields/monologue_argument.gd.uid b/common/ui/fields/monologue_argument.gd.uid deleted file mode 100644 index ea371999..00000000 --- a/common/ui/fields/monologue_argument.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://4omqhch6lxme diff --git a/common/ui/fields/monologue_field.gd b/common/ui/fields/monologue_field.gd deleted file mode 100644 index 8c24897b..00000000 --- a/common/ui/fields/monologue_field.gd +++ /dev/null @@ -1,35 +0,0 @@ -## UI control which allow the user to edit a graph node [MonologueProperty]. -class_name MonologueField extends Control - -## Emitted when the field's value is changed but not yet committed. -@warning_ignore("unused_signal") -signal field_changed(value: Variant) - -## Emitted when the field's value is updated/comitted by user input. -@warning_ignore("unused_signal") -signal field_updated(value: Variant) - -var collapsible_field: CollapsibleField: - set = set_collapsible_field - - -## Set the collapsible control that this MonologueField belongs to. -func set_collapsible_field(collapsible: CollapsibleField): - collapsible_field = collapsible - - -## Called by node panel to set field label text, if applicable. -func set_label_text(_text: String) -> void: - pass - - -## Set the field's label visibility. -func set_label_visible(_can_see: bool) -> void: - pass - - -## Meant to propagate the value set in [MonologueProperty] to this Field. -## This method does not emit [signal field_updated]. -func propagate(_value: Variant) -> void: - if collapsible_field: - collapsible_field.open() diff --git a/common/ui/fields/monologue_field.gd.uid b/common/ui/fields/monologue_field.gd.uid deleted file mode 100644 index 020c039d..00000000 --- a/common/ui/fields/monologue_field.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://bkhv4rjlyh64j diff --git a/common/ui/fields/monologue_variable.gd b/common/ui/fields/monologue_variable.gd deleted file mode 100644 index be7a9069..00000000 --- a/common/ui/fields/monologue_variable.gd +++ /dev/null @@ -1,75 +0,0 @@ -class_name MonologueVariable extends RefCounted - -var name := Property.new(MonologueGraphNode.LINE) -var type := Property.new(MonologueGraphNode.DROPDOWN, {}, "Boolean") -var value := Property.new(MonologueGraphNode.TOGGLE, {}, false) - -var index: int = -1 -var bound_node: MonologueGraphNode -var graph: MonologueGraphEdit - - -func _init(node: MonologueGraphNode) -> void: - bound_node = node - graph = node.get_graph_edit() - - type.callers["set_items"] = [ - [ - {"id": 0, "text": "Boolean"}, - {"id": 1, "text": "Integer"}, - {"id": 2, "text": "String"}, - ] - ] - type.callers["set_icons"] = [ - { - 0: load("res://ui/assets/icons/bool_icon.png"), - 1: load("res://ui/assets/icons/int_icon.png"), - 2: load("res://ui/assets/icons/str_icon.png"), - } - ] - - type.connect("shown", _type_morph) - type.connect("change", change.bind("type")) - type.connect("display", graph.set_selected.bind(bound_node)) - name.connect("change", change.bind("name")) - name.connect("display", graph.set_selected.bind(bound_node)) - value.connect("change", change.bind("value")) - value.connect("display", graph.set_selected.bind(bound_node)) - - -func change(_old_value: Variant, new_value: Variant, property: String) -> void: - var old_list = bound_node.variables.value.duplicate(true) - var new_list = bound_node.variables.value.duplicate(true) - new_list[index][property.capitalize()] = new_value - - graph.undo_redo.create_action("Variables => %s" % new_value) - graph.undo_redo.add_do_property(bound_node.variables, "value", new_list) - graph.undo_redo.add_do_method(bound_node.variables.propagate.bind(new_list)) - graph.undo_redo.add_undo_property(bound_node.variables, "value", old_list) - graph.undo_redo.add_undo_method(bound_node.variables.propagate.bind(old_list)) - graph.undo_redo.commit_action() - - -func get_property_names() -> PackedStringArray: - return ["name", "type", "value"] - - -func _from_dict(dict: Dictionary) -> void: - _type_morph() - name.value = dict.get("Name") - type.value = dict.get("Type") - value.value = dict.get("Value") - - -func _to_dict() -> Dictionary: - return {"Name": name.value, "Type": type.value, "Value": value.value} - - -func _type_morph(selected_type: String = type.value): - match selected_type: - "Boolean": - value.morph(MonologueGraphNode.TOGGLE) - "Integer": - value.morph(MonologueGraphNode.SPINBOX) - "String": - value.morph(MonologueGraphNode.LINE) diff --git a/common/ui/fields/monologue_variable.gd.uid b/common/ui/fields/monologue_variable.gd.uid deleted file mode 100644 index 47857bfa..00000000 --- a/common/ui/fields/monologue_variable.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://bo7lnuuv6ra7k diff --git a/common/ui/fields/portrait_option/abstract_portrait.gd b/common/ui/fields/portrait_option/abstract_portrait.gd deleted file mode 100644 index 6041f04a..00000000 --- a/common/ui/fields/portrait_option/abstract_portrait.gd +++ /dev/null @@ -1,70 +0,0 @@ -class_name AbstractPortraitOption extends RefCounted - -const PORTRAIT_FIELD := preload("res://common/ui/fields/portrait_option/portrait_option.tscn") - -var portrait_name := Property.new(MonologueGraphNode.LINE, {}, "") -var portrait := Property.new(PORTRAIT_FIELD, {}, {}) -var id := Property.new(MonologueGraphNode.LINE, {}, IDGen.generate(5)) -var idx := Property.new(MonologueGraphNode.SPINBOX, {}, 0) - -var custom_delete_button: Button = Button.new() - -var graph: MonologueGraphEdit -var root: PortraitListSection - - -func _init(node: PortraitListSection): - root = node - portrait.connect("change", update_portrait) - portrait_name.connect("change", update_portrait_name) - portrait.setters["graph_edit"] = graph - portrait_name.visible = false - - -func update_portrait(old_value: Variant, new_value: Variant): - var old_list = root.portraits.value.duplicate(true) - var new_list = root.portraits.value.duplicate(true) - - graph.undo_redo.create_action("Portrait %s => %s" % [str(old_value), str(new_value)]) - graph.undo_redo.add_do_property(root.portraits, "value", new_list) - graph.undo_redo.add_do_method(root.portraits.propagate.bind(new_list)) - graph.undo_redo.add_undo_property(root.portraits, "value", old_list) - graph.undo_redo.add_undo_method(root.portraits.propagate.bind(old_list)) - graph.undo_redo.commit_action() - - -func update_portrait_name(old_value: Variant, new_value: Variant): - var old_list = root.portraits.value.duplicate(true) - var new_list = root.portraits.value.duplicate(true) - - old_list[idx.value]["Name"] = old_value - new_list[idx.value]["Name"] = new_value - - graph.undo_redo.create_action("Portrait Name %s => %s" % [str(old_value), str(new_value)]) - graph.undo_redo.add_do_property(root.portraits, "value", new_list) - graph.undo_redo.add_do_method(root.portraits.propagate.bind(new_list)) - graph.undo_redo.add_undo_property(root.portraits, "value", old_list) - graph.undo_redo.add_undo_method(root.portraits.propagate.bind(old_list)) - graph.undo_redo.commit_action() - - -func get_property_names() -> PackedStringArray: - return ["portrait"] - - -func _from_dict(dict: Dictionary) -> void: - if dict.get("ID") is String: - id.value = dict.get("ID", IDGen.generate(5)) - portrait_name.value = dict.get("Name", "") - portrait.value = dict.get("Portrait", {}) - idx.value = dict.get("EditorIndex") - portrait.setters["portrait_index"] = idx.value - - -func _to_dict() -> Dictionary: - return { - "ID": id.value, - "Name": portrait_name.value, - "Portrait": portrait.value, - "EditorIndex": idx.value, - } diff --git a/common/ui/fields/portrait_option/abstract_portrait.gd.uid b/common/ui/fields/portrait_option/abstract_portrait.gd.uid deleted file mode 100644 index 95793685..00000000 --- a/common/ui/fields/portrait_option/abstract_portrait.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://cqf51jo7a4llv diff --git a/common/ui/fields/portrait_option/portrait_option.gd b/common/ui/fields/portrait_option/portrait_option.gd deleted file mode 100644 index 2fd14f54..00000000 --- a/common/ui/fields/portrait_option/portrait_option.gd +++ /dev/null @@ -1,98 +0,0 @@ -class_name PortraitOption extends MonologueField - -signal pressed(this_option: PortraitOption) -signal set_to_default(this_option: PortraitOption) -signal name_submitted(this_option: PortraitOption) - -@onready var line_edit: LineEdit = %LineEdit -@onready var btn_star := $MarginContainer/HBoxContainer/HBoxContainer/btnStar -@onready var button := %Button - -@onready var active_stylebox: StyleBoxFlat = StyleBoxFlat.new() -@onready var star_icon := preload("res://ui/assets/icons/star.svg") -@onready var star_full_icon := preload("res://ui/assets/icons/star_full.svg") - -@export var is_default: bool = false - -var is_active: bool = false -var line_edit_unfocus_stylebox := StyleBoxEmpty.new() -var custom_delete_button: Button = Button.new() - - -func _ready() -> void: - line_edit_unfocus() - - active_stylebox.bg_color = Color("d55160") - active_stylebox.set_corner_radius_all(5) - - -func propagate(value: Variant) -> void: - super.propagate(value) - - -func set_option_name(new_name: String) -> void: - line_edit.text = new_name - - -func line_edit_unfocus() -> void: - line_edit.editable = false - line_edit.selecting_enabled = false - line_edit.flat = true - line_edit.mouse_filter = Control.MOUSE_FILTER_PASS - - button.show() - add_theme_stylebox_override("focus", line_edit_unfocus_stylebox) - name_submitted.emit(self) - - -func _on_btn_edit_pressed() -> void: - line_edit.editable = true - line_edit.selecting_enabled = true - line_edit.flat = false - line_edit.mouse_filter = Control.MOUSE_FILTER_STOP - line_edit.grab_focus() - - button.hide() - - -func _on_line_edit_focus_exited() -> void: - line_edit_unfocus() - - -func _on_btn_star_pressed() -> void: - set_default() - - -func set_default() -> void: - is_default = true - btn_star.texture_normal = star_full_icon - set_to_default.emit(self) - - -func release_default() -> void: - is_default = false - btn_star.texture_normal = star_icon - - -func set_active() -> void: - is_active = true - add_theme_stylebox_override("panel", active_stylebox) - - -func release_active() -> void: - is_active = false - remove_theme_stylebox_override("panel") - line_edit_unfocus() - - -func _on_button_pressed() -> void: - pressed.emit(self) - - -func _on_button_gui_input(event: InputEvent) -> void: - if is_active and event is InputEventMouseButton and event.is_pressed() and event.double_click: - _on_btn_edit_pressed() - - -func _on_line_edit_text_submitted(_new_text: String) -> void: - line_edit_unfocus() diff --git a/common/ui/fields/portrait_option/portrait_option.gd.uid b/common/ui/fields/portrait_option/portrait_option.gd.uid deleted file mode 100644 index c2e25a2b..00000000 --- a/common/ui/fields/portrait_option/portrait_option.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://8i3yw0dywx4c diff --git a/common/ui/fields/portrait_option/portrait_option.tscn b/common/ui/fields/portrait_option/portrait_option.tscn deleted file mode 100644 index 7483cd82..00000000 --- a/common/ui/fields/portrait_option/portrait_option.tscn +++ /dev/null @@ -1,80 +0,0 @@ -[gd_scene load_steps=3 format=3 uid="uid://c3jo73wxyv6ux"] - -[ext_resource type="Script" uid="uid://8i3yw0dywx4c" path="res://common/ui/fields/portrait_option/portrait_option.gd" id="1_0c6eg"] -[ext_resource type="Texture2D" uid="uid://bogfuvhttgn1v" path="res://ui/assets/icons/star.svg" id="3_p62s6"] - -[node name="PortraitOption" type="Panel"] -custom_minimum_size = Vector2(0, 40) -anchors_preset = -1 -anchor_right = 0.096 -anchor_bottom = 0.05 -offset_right = -0.399994 -grow_horizontal = 2 -grow_vertical = 2 -size_flags_horizontal = 3 -script = ExtResource("1_0c6eg") - -[node name="MarginContainer" type="MarginContainer" parent="."] -layout_mode = 1 -anchors_preset = 15 -anchor_right = 1.0 -anchor_bottom = 1.0 -grow_horizontal = 2 -grow_vertical = 2 - -[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer"] -layout_mode = 2 - -[node name="Control" type="Control" parent="MarginContainer/HBoxContainer"] -layout_mode = 2 -size_flags_horizontal = 3 - -[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer/HBoxContainer/Control"] -layout_mode = 1 -anchors_preset = 15 -anchor_right = 1.0 -anchor_bottom = 1.0 -grow_horizontal = 2 -grow_vertical = 2 - -[node name="LineEdit" type="LineEdit" parent="MarginContainer/HBoxContainer/Control/HBoxContainer"] -unique_name_in_owner = true -layout_mode = 2 -size_flags_horizontal = 3 -size_flags_vertical = 4 -theme_type_variation = &"LineEditPortraitOption" -text = "default" -flat = true -caret_blink = true -text_direction = 1 - -[node name="Button" type="Button" parent="MarginContainer/HBoxContainer/Control"] -unique_name_in_owner = true -layout_mode = 1 -anchors_preset = -1 -anchor_left = -0.047 -anchor_top = -0.167 -anchor_right = 1.081 -anchor_bottom = 1.167 -offset_left = 0.0420003 -offset_top = 0.00800037 -offset_right = 0.033989 -offset_bottom = -0.00800133 -grow_horizontal = 2 -grow_vertical = 2 -mouse_filter = 1 -flat = true - -[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer/HBoxContainer"] -layout_mode = 2 - -[node name="btnStar" type="TextureButton" parent="MarginContainer/HBoxContainer/HBoxContainer"] -layout_mode = 2 -texture_normal = ExtResource("3_p62s6") -stretch_mode = 5 - -[connection signal="focus_exited" from="MarginContainer/HBoxContainer/Control/HBoxContainer/LineEdit" to="." method="_on_line_edit_focus_exited"] -[connection signal="text_submitted" from="MarginContainer/HBoxContainer/Control/HBoxContainer/LineEdit" to="." method="_on_line_edit_text_submitted"] -[connection signal="gui_input" from="MarginContainer/HBoxContainer/Control/Button" to="." method="_on_button_gui_input"] -[connection signal="pressed" from="MarginContainer/HBoxContainer/Control/Button" to="." method="_on_button_pressed"] -[connection signal="pressed" from="MarginContainer/HBoxContainer/HBoxContainer/btnStar" to="." method="_on_btn_star_pressed"] diff --git a/common/ui/fields/property.gd b/common/ui/fields/property.gd deleted file mode 100644 index 24c5b7ba..00000000 --- a/common/ui/fields/property.gd +++ /dev/null @@ -1,144 +0,0 @@ -## Represents a graph node property and its UI controls in Monologue. -class_name Property extends RefCounted - -## Emitted when property change is to be commited to undo/redo history. -signal change(old_value: Variant, new_value: Variant) -## Emitted if the graph node of this property should be displayed in panel. -signal display -## Emitted when the field's value is being changed and is requesting a preview. -signal preview(value: Variant) -## Emitted on show() and only if the field is visible to the user. -signal shown - -## Dictionary of field method names to argument list values. -var callers: Dictionary = {} -## Reference to UI instance. -var field: Control -## Reference to the field container. -var field_container: Control -## Scene used to instantiate the field's UI control. -var scene: PackedScene -## Dictionary of field property names to set values. -var setters: Dictionary -## Dictionary of callables to connect to field signals. -var connecters: Dictionary -## Temporary boolean to uncollapse the field when first shown if set to true. -var uncollapse: bool -## Initial value of the property. -var default_value: Variant -## Actual value of the property. -var value: Variant: - set = set_value, - get = get_value -## Toggles visibility of the field instance. -var visible: bool: - set = set_visible -## Overwrites the displayed property label -var custom_label: Variant - - -func _init( - ui_scene: PackedScene, - ui_setters: Dictionary = {}, - default: Variant = "", - ui_custom_label: Variant = null -) -> void: - scene = ui_scene - setters = ui_setters - value = default - default_value = default - custom_label = ui_custom_label - visible = true - - -func get_value() -> Variant: - return value - - -## Invokes a given method with the given arguments on the field if present. -func invoke(method_name: String, argument_list: Array) -> Variant: - if is_instance_valid(field): - return field.callv(method_name, argument_list) - return null - - -## Change the property's UI scene and replace the active field instance. -func morph(new_scene: PackedScene) -> void: - scene = new_scene - if is_instance_valid(field): - var panel = field.get_parent() - var child_index = field.get_index() - field_container.queue_free() - show(panel, child_index) - - -func propagate(new_value: Variant, can_display: bool = true) -> void: - preview.emit(new_value) - if is_instance_valid(field): - field.propagate(new_value) - elif can_display or not visible: - uncollapse = true - display.emit() - - -## Trigger a property value change only when valeus are different. -func save_value(new_value: Variant) -> void: - if new_value is Dictionary: - new_value = value.merged(new_value, true) - - if not Util.is_equal(value, new_value): - change.emit(value, new_value) - - -## Setter for value which does not trigger change signals. -func set_value(new_value: Variant) -> void: - value = new_value - - -func set_visible(can_see: bool) -> void: - visible = can_see - _check_visibility() - - -func show(panel: Control, child_index: int = -1, auto_margin: bool = true) -> MonologueField: - field = scene.instantiate() - - field_container = MarginContainer.new() - field_container.size_flags_horizontal = Control.SIZE_EXPAND_FILL - field_container.size_flags_vertical = field.size_flags_vertical - field_container.add_theme_constant_override("margin_right", 0) - field_container.add_theme_constant_override("margin_bottom", 0) - if field is CollapsibleField or field is MonologueList or not auto_margin: - field_container.add_theme_constant_override("margin_left", 0) - field_container.add_theme_constant_override("margin_top", 0) - - for property in setters.keys(): - field.set(property, setters.get(property)) - - field_container.add_child(field) - panel.add_child(field_container) - _check_visibility() - - if child_index >= 0: - panel.move_child(field_container, child_index) - - for method in callers.keys(): - field.callv(method, callers.get(method, [])) - - for callable in connecters.keys(): - var signal_name: String = connecters.get(callable, "") - if field.has_signal(signal_name): - field.connect(connecters.get(callable), callable) - - field.propagate(value) - field.connect("field_changed", preview.emit) - field.connect("field_updated", save_value) - _check_visibility() - if visible: - shown.emit() - return field - - -func _check_visibility(): - if is_instance_valid(field): - field_container.visible = visible diff --git a/common/ui/fields/property.gd.uid b/common/ui/fields/property.gd.uid deleted file mode 100644 index 44756639..00000000 --- a/common/ui/fields/property.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://chah3f6jf1tls diff --git a/common/ui/fields/slider/monologue_slider.gd b/common/ui/fields/slider/monologue_slider.gd deleted file mode 100644 index 72547fc3..00000000 --- a/common/ui/fields/slider/monologue_slider.gd +++ /dev/null @@ -1,59 +0,0 @@ -class_name MonologueSlider extends MonologueField - -@export var default: float -@export var minimum: float -@export var maximum: float -@export var step: float -@export var suffix: String - -@onready var control_label = $FieldLabel -@onready var spin_box = $HBoxContainer/SpinBox -@onready var reset_button = $HBoxContainer/ResetButton -@onready var slider = $HBoxContainer/HSlider - -var skip_spin_box_update: bool = false - - -func _ready(): - slider.min_value = minimum - slider.max_value = maximum - slider.step = step - - spin_box.min_value = minimum - spin_box.max_value = maximum - spin_box.step = step - spin_box.suffix = suffix - - -func set_label_text(text: String) -> void: - control_label.text = text - - -func propagate(value: Variant) -> void: - super.propagate(value) - slider.value = value if (value is float or value is int) else default - - -func _on_drag_ended(value_changed: bool) -> void: - if value_changed: - field_updated.emit(slider.value) - - -func _on_reset() -> void: - if slider.value != default: - slider.value = default - field_updated.emit(default) - - -func _on_value_changed(value: float) -> void: - skip_spin_box_update = true - spin_box.value = value - - -func _on_spin_box_value_changed(value: float) -> void: - if skip_spin_box_update: - skip_spin_box_update = false - return - - slider.value = value - field_updated.emit(slider.value) diff --git a/common/ui/fields/slider/monologue_slider.gd.uid b/common/ui/fields/slider/monologue_slider.gd.uid deleted file mode 100644 index 773fc609..00000000 --- a/common/ui/fields/slider/monologue_slider.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://bfviu4cmsm4jo diff --git a/common/ui/fields/slider/monologue_slider.tscn b/common/ui/fields/slider/monologue_slider.tscn deleted file mode 100644 index 5ab0d24e..00000000 --- a/common/ui/fields/slider/monologue_slider.tscn +++ /dev/null @@ -1,72 +0,0 @@ -[gd_scene load_steps=12 format=3 uid="uid://cndkr1vq6ab1o"] - -[ext_resource type="Script" uid="uid://bfviu4cmsm4jo" path="res://common/ui/fields/slider/monologue_slider.gd" id="1_waj5i"] -[ext_resource type="PackedScene" uid="uid://x0daq5tsejey" path="res://common/ui/fields/field_label.tscn" id="2_ntngi"] - -[sub_resource type="Texture2DRD" id="Texture2DRD_ipp53"] - -[sub_resource type="Texture2DRD" id="Texture2DRD_8e8dw"] - -[sub_resource type="Texture2DRD" id="Texture2DRD_cqv1s"] - -[sub_resource type="Texture2DRD" id="Texture2DRD_w48go"] - -[sub_resource type="Texture2DRD" id="Texture2DRD_peeyv"] - -[sub_resource type="Texture2DRD" id="Texture2DRD_delru"] - -[sub_resource type="Texture2DRD" id="Texture2DRD_8xcfa"] - -[sub_resource type="Texture2DRD" id="Texture2DRD_catv5"] - -[sub_resource type="Texture2DRD" id="Texture2DRD_d3004"] - -[node name="MonologueSlider" type="HBoxContainer"] -offset_right = 291.0 -offset_bottom = 29.0 -script = ExtResource("1_waj5i") - -[node name="FieldLabel" parent="." instance=ExtResource("2_ntngi")] -layout_mode = 2 - -[node name="HBoxContainer" type="HBoxContainer" parent="."] -layout_mode = 2 - -[node name="HSlider" type="HSlider" parent="HBoxContainer"] -custom_minimum_size = Vector2(100, 0) -layout_mode = 2 -size_flags_horizontal = 3 -size_flags_vertical = 4 -min_value = -100.0 - -[node name="SpinBox" type="SpinBox" parent="HBoxContainer"] -custom_minimum_size = Vector2(60, 0) -layout_mode = 2 -theme_override_constants/set_min_buttons_width_from_icons = 0 -theme_override_constants/buttons_width = 0 -theme_override_constants/field_and_buttons_separation = 0 -theme_override_constants/buttons_vertical_separation = 0 -theme_override_icons/up_disabled = SubResource("Texture2DRD_ipp53") -theme_override_icons/down = SubResource("Texture2DRD_8e8dw") -theme_override_icons/down_hover = SubResource("Texture2DRD_cqv1s") -theme_override_icons/down_pressed = SubResource("Texture2DRD_w48go") -theme_override_icons/down_disabled = SubResource("Texture2DRD_peeyv") -theme_override_icons/up_pressed = SubResource("Texture2DRD_delru") -theme_override_icons/up_hover = SubResource("Texture2DRD_8xcfa") -theme_override_icons/up = SubResource("Texture2DRD_catv5") -theme_override_icons/updown = SubResource("Texture2DRD_d3004") -alignment = 1 -update_on_text_changed = true -select_all_on_focus = true - -[node name="ResetButton" type="Button" parent="HBoxContainer"] -visible = false -layout_mode = 2 -size_flags_vertical = 4 -theme_type_variation = &"Button_Outline" -text = "reset" - -[connection signal="drag_ended" from="HBoxContainer/HSlider" to="." method="_on_drag_ended"] -[connection signal="value_changed" from="HBoxContainer/HSlider" to="." method="_on_value_changed"] -[connection signal="value_changed" from="HBoxContainer/SpinBox" to="." method="_on_spin_box_value_changed"] -[connection signal="pressed" from="HBoxContainer/ResetButton" to="." method="_on_reset"] diff --git a/common/ui/fields/spin_box/monologue_spin_box.gd b/common/ui/fields/spin_box/monologue_spin_box.gd deleted file mode 100644 index e58b97aa..00000000 --- a/common/ui/fields/spin_box/monologue_spin_box.gd +++ /dev/null @@ -1,31 +0,0 @@ -class_name MonologueSpinBox extends MonologueField - -@export var as_integer: bool = true -@export var minimum: float = -9999999999 -@export var maximum: float = 9999999999 -@export var step: float = 1 -@export var suffix: String - -@onready var label = $Label -@onready var spin_box = $CustomSpinBox - - -func _ready(): - spin_box.min_value = minimum - spin_box.max_value = maximum - spin_box.step = step - spin_box.suffix = suffix - spin_box._update_settings() - - -func set_label_text(text: String) -> void: - label.text = text - - -func propagate(value: Variant) -> void: - super.propagate(value) - spin_box.value = value if (value is float or value is int) else 0 - - -func _on_custom_spin_box_value_changed(value: Variant) -> void: - field_updated.emit(value) diff --git a/common/ui/fields/spin_box/monologue_spin_box.gd.uid b/common/ui/fields/spin_box/monologue_spin_box.gd.uid deleted file mode 100644 index 5502bee1..00000000 --- a/common/ui/fields/spin_box/monologue_spin_box.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://catei6iaaw77f diff --git a/common/ui/fields/spin_box/monologue_spin_box.tscn b/common/ui/fields/spin_box/monologue_spin_box.tscn deleted file mode 100644 index b0fb7313..00000000 --- a/common/ui/fields/spin_box/monologue_spin_box.tscn +++ /dev/null @@ -1,16 +0,0 @@ -[gd_scene load_steps=4 format=3 uid="uid://c0d8fac8so0p0"] - -[ext_resource type="Script" uid="uid://catei6iaaw77f" path="res://common/ui/fields/spin_box/monologue_spin_box.gd" id="1_wmtop"] -[ext_resource type="PackedScene" uid="uid://x0daq5tsejey" path="res://common/ui/fields/field_label.tscn" id="2_1ivi1"] -[ext_resource type="PackedScene" uid="uid://wiapsnoaoc44" path="res://common/ui/custom_spinbox/custom_spinbox.tscn" id="3_a42se"] - -[node name="MonologueSpinBox" type="HBoxContainer"] -script = ExtResource("1_wmtop") - -[node name="Label" parent="." instance=ExtResource("2_1ivi1")] -layout_mode = 2 - -[node name="CustomSpinBox" parent="." instance=ExtResource("3_a42se")] -layout_mode = 2 - -[connection signal="value_changed" from="CustomSpinBox" to="." method="_on_custom_spin_box_value_changed"] diff --git a/common/ui/fields/text/monologue_text.gd b/common/ui/fields/text/monologue_text.gd deleted file mode 100644 index d060898b..00000000 --- a/common/ui/fields/text/monologue_text.gd +++ /dev/null @@ -1,33 +0,0 @@ -class_name MonologueText extends MonologueField - -@export var minimum_size := Vector2(200, 200) - -@onready var label = $Label -@onready var text_edit = $HBoxContainer/TextEdit -@onready var expand_container = $HBoxContainer/TextEdit/Button -@onready var expand_button = $HBoxContainer/TextEdit/Button - - -func _ready(): - text_edit.custom_minimum_size = minimum_size - - -func set_label_text(text: String) -> void: - label.text = text - - -func propagate(value: Variant) -> void: - super.propagate(value) - text_edit.text = str(value) - - -func _on_focus_exited() -> void: - field_updated.emit(text_edit.text) - - -func _on_text_changed() -> void: - field_changed.emit(text_edit.text) - - -func _on_button_pressed() -> void: - GlobalSignal.emit("expand_text_edit", [text_edit]) diff --git a/common/ui/fields/text/monologue_text.gd.uid b/common/ui/fields/text/monologue_text.gd.uid deleted file mode 100644 index fd975a2c..00000000 --- a/common/ui/fields/text/monologue_text.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://laakj3xm565t diff --git a/common/ui/fields/text/monologue_text.tscn b/common/ui/fields/text/monologue_text.tscn deleted file mode 100644 index 1cd7bc50..00000000 --- a/common/ui/fields/text/monologue_text.tscn +++ /dev/null @@ -1,63 +0,0 @@ -[gd_scene load_steps=4 format=3 uid="uid://durq2yowmkr60"] - -[ext_resource type="Script" uid="uid://laakj3xm565t" path="res://common/ui/fields/text/monologue_text.gd" id="1_m7tlj"] -[ext_resource type="Texture2D" uid="uid://bu603ytypk2jb" path="res://ui/assets/icons/expand.svg" id="2_mkdom"] -[ext_resource type="PackedScene" uid="uid://x0daq5tsejey" path="res://common/ui/fields/field_label.tscn" id="2_nsrvi"] - -[node name="MonologueText" type="HBoxContainer"] -size_flags_horizontal = 3 -script = ExtResource("1_m7tlj") - -[node name="Label" parent="." instance=ExtResource("2_nsrvi")] -layout_mode = 2 - -[node name="HBoxContainer" type="HBoxContainer" parent="."] -layout_mode = 2 -size_flags_horizontal = 3 -theme_override_constants/separation = 0 - -[node name="TextEdit" type="TextEdit" parent="HBoxContainer"] -custom_minimum_size = Vector2(200, 200) -layout_mode = 2 -size_flags_horizontal = 3 -wrap_mode = 1 -caret_blink = true - -[node name="Button" type="Button" parent="HBoxContainer/TextEdit"] -custom_minimum_size = Vector2(22, 22) -layout_mode = 1 -anchors_preset = 1 -anchor_left = 1.0 -anchor_right = 1.0 -offset_left = -22.0 -offset_top = 2.0 -offset_right = -2.0 -offset_bottom = 22.0 -grow_horizontal = 0 - -[node name="CenterContainer" type="CenterContainer" parent="HBoxContainer/TextEdit/Button"] -layout_mode = 1 -anchors_preset = 8 -anchor_left = 0.5 -anchor_top = 0.5 -anchor_right = 0.5 -anchor_bottom = 0.5 -offset_left = -7.5 -offset_top = -7.5 -offset_right = 7.5 -offset_bottom = 7.5 -grow_horizontal = 2 -grow_vertical = 2 -mouse_filter = 2 - -[node name="TextureRect" type="TextureRect" parent="HBoxContainer/TextEdit/Button/CenterContainer"] -custom_minimum_size = Vector2(14, 14) -layout_mode = 2 -mouse_filter = 2 -texture = ExtResource("2_mkdom") -expand_mode = 4 -stretch_mode = 5 - -[connection signal="focus_exited" from="HBoxContainer/TextEdit" to="." method="_on_focus_exited"] -[connection signal="text_changed" from="HBoxContainer/TextEdit" to="." method="_on_text_changed"] -[connection signal="pressed" from="HBoxContainer/TextEdit/Button" to="." method="_on_button_pressed"] diff --git a/common/ui/fields/timeline/monologue_timeline.gd b/common/ui/fields/timeline/monologue_timeline.gd deleted file mode 100644 index a2b8b44e..00000000 --- a/common/ui/fields/timeline/monologue_timeline.gd +++ /dev/null @@ -1,327 +0,0 @@ -class_name MonologueAnimationTimeline extends MonologueField - -const IMAGE = ["*.bmp,*.jpg,*.jpeg,*.png,*.svg,*.webp;Image Files"] -const DEFAULT_LAYER_NAME: String = "Layer %s" - -var filters: Array = ["*.bmp", "*.jpg", "*.jpeg", "*.png", "*.svg", "*.webp"] - -@onready var layer_vbox := %LayerVBox -@onready var layer_timeline_vbox := %LayerTimelineVBox -@onready var cell_number_hbox := %CellNumberHBox -@onready var fps_spinbox := %FpsSpinBox -@onready var layer_container := %LayerContainer -@onready var import_frame_button := %ImportFrameButton - -@onready var layer := preload("res://common/ui/fields/timeline/timeline_layer.tscn") -@onready var layer_timeline := preload("res://common/ui/fields/timeline/timeline_cell_layer.tscn") -@onready var cell_number := preload("res://common/ui/fields/timeline/timeline_cell_number.tscn") -@onready var placement_indicator := preload("res://common/ui/horizontal_placement_indicator.tscn") - -var cell_count: int = 1 -var base_path: String -var selected_cell_idx: int = -1 -var selected_cell_layer_idx: int = -1 -var current_indicator: Control -var selected_layer: Layer -var preview_section - -var fps: float = 12.0 - - -func _process(_delta: float) -> void: - if current_indicator == null: - return - var indicator_dist: float = current_indicator.global_position.y - get_global_mouse_position().y - var layer_height: float = get_layer_height() - var layer_dist: float = ( - get_global_mouse_position().y - (selected_layer.global_position.y + layer_height / 2.0) - ) - var indicator_index: int = current_indicator.get_index() - - current_indicator.show() - if indicator_dist >= layer_height / 2.0: - layer_vbox.move_child(current_indicator, indicator_index - 1) - elif indicator_dist <= -layer_height / 2.0: - layer_vbox.move_child(current_indicator, indicator_index + 1) - elif abs(layer_dist) < layer_height: - current_indicator.hide() - - -func _clear() -> void: - cell_count = 1 - for child in layer_vbox.get_children(): - child.queue_free() - for child in layer_timeline_vbox.get_children(): - child.queue_free() - - -func propagate(value: Variant) -> void: - super.propagate(value) - _from_dict(value) - - -func _from_dict(dict: Dictionary) -> void: - _clear() - cell_count = dict.get("FrameCount", 1) - fps_spinbox.value = dict.get("Fps", 12) - selected_cell_idx = -1 - selected_cell_layer_idx = -1 - - var default_layer_data := [ - {"LayerName": DEFAULT_LAYER_NAME % 1, "Frames": {0: {"ImagePath": "", "Exposure": 1}}} - ] - - for layer_data in dict.get("Layers", default_layer_data): - var new_layer: Layer = add_timeline() - new_layer.timeline_label.text = layer_data.get("LayerName", "Layer") - layer_timeline_vbox.get_children().back()._from_dict(layer_data) - - _update_cell_number() - _update_preview.call_deferred() - - -func _to_dict() -> Dictionary: - var dict: Dictionary = {"Fps": fps, "FrameCount": cell_count, "Layers": []} - var layers: Array = get_all_layers() - - for l: Layer in layers: - var layer_idx: int = layers.find(l) - var l_timeline: LayerTimeline = layer_timeline_vbox.get_child(layer_idx) - dict["Layers"].append({"LayerName": l.timeline_label.text, "Frames": l_timeline._to_dict()}) - return dict - - -func get_all_layers() -> Array: - var layers: Array = [] - for child in layer_vbox.get_children(): - if child is not Layer or child.is_queued_for_deletion(): - continue - layers.append(child) - - return layers - - -func get_cell_width() -> int: - return layer_container.cell_width - - -func get_layer_height() -> int: - return get_all_layers()[0].size.y - - -func add_cell() -> void: - cell_count += 1 - _update_cell_number() - - -func add_timeline() -> Layer: - var new_layer: Layer = layer.instantiate() - var new_layer_timeline: LayerTimeline = layer_timeline.instantiate() - new_layer_timeline.timeline = self - - layer_vbox.add_child(new_layer) - layer_timeline_vbox.add_child(new_layer_timeline) - - new_layer.timeline_label.text = DEFAULT_LAYER_NAME % layer_vbox.get_child_count() - new_layer.hover_button.connect("button_down", _on_layer_button_down.bind(new_layer)) - new_layer.hover_button.connect("button_up", _on_layer_button_up.bind(new_layer)) - new_layer.delete_button_pressed.connect(_on_layer_delete_button_pressed.bind(new_layer)) - new_layer_timeline.connect("timeline_updated", _on_timeline_updated.bind(new_layer_timeline)) - - _update_preview() - - return new_layer - - -func _update_cell_number() -> void: - for cell in cell_number_hbox.get_children(): - cell.queue_free() - for i in range(cell_count): - var new_cell := cell_number.instantiate() - new_cell.cell_number = i + 1 - new_cell.custom_minimum_size.x = get_cell_width() - cell_number_hbox.add_child(new_cell) - - -func _update_preview() -> void: - if layer_timeline_vbox == null: - return - var sprites: Array = [] - var layers: Array[Node] = layer_timeline_vbox.get_children() - layers.reverse() - for child_timeline: LayerTimeline in layers: - sprites.append(child_timeline._to_sprite_frames()) - preview_section.update_animation(sprites) - - -func _on_timeline_updated(_layer_timeline: LayerTimeline) -> void: - _update_field.call_deferred() - - -func _update_field() -> void: - _update_preview() - field_updated.emit(_to_dict()) - - -func _on_btn_add_cell_pressed() -> void: - add_cell() - _update_field.call_deferred() - - -func _on_btn_add_layer_pressed() -> void: - add_timeline() - _update_field.call_deferred() - - -func _on_import_frame_button_pressed() -> void: - if selected_cell_idx <= -1 and selected_cell_layer_idx <= -1: - return - GlobalSignal.emit("open_files_request", [_on_files_selected, IMAGE, base_path.get_base_dir()]) - - -func get_selected_cell() -> Variant: - if selected_cell_idx <= -1 and selected_cell_layer_idx <= -1: - return null - - var s_layer_timeline: LayerTimeline = ( - layer_timeline_vbox.get_children()[selected_cell_layer_idx] - ) - return s_layer_timeline.get_all_cells()[selected_cell_idx] - - -func _on_files_selected(paths: Array) -> void: - if selected_cell_idx <= -1 and selected_cell_layer_idx <= -1: - return - - var first_path: String = paths.pop_front() - get_selected_cell().image_path = Path.absolute_to_relative(first_path, base_path) - get_selected_cell()._update() - - var selected_cell_layer: LayerTimeline = layer_timeline_vbox.get_child(selected_cell_layer_idx) - var first_frame_duration: int = int(selected_cell_layer.get_frame_duration(selected_cell_idx)) - var idx: int = 0 - for path in paths: - idx += 1 - var cell: TimelineCell = selected_cell_layer.add_cell( - Path.absolute_to_relative(path, base_path) - ) - selected_cell_layer.hbox.move_child(cell, selected_cell_idx + idx * first_frame_duration) - - for i in range(first_frame_duration - 1): - var exp_cell: TimelineCell = selected_cell_layer.add_cell() - exp_cell.is_exposure = true - selected_cell_layer.hbox.move_child( - exp_cell, selected_cell_idx + idx * first_frame_duration + i + 1 - ) - exp_cell._update() - - _update_field.call_deferred() - - -func cell_selected(s_cell: TimelineCell, s_timeline: LayerTimeline) -> void: - var cell_idx: int = s_timeline.get_all_cells().find(s_cell) - var timeline_idx: int = layer_timeline_vbox.get_children().find(s_timeline) - selected_cell_idx = cell_idx - selected_cell_layer_idx = timeline_idx - sub_select(cell_idx, timeline_idx) - if not s_cell.is_exposure: - import_frame_button.disabled = false - - -func cell_deselected() -> void: - var disable_func: Callable = func() -> void: - if import_frame_button.has_focus(): - return - import_frame_button.disabled = true - selected_cell_idx = -1 - selected_cell_layer_idx = -1 - sub_select(-1, -1) - disable_func.call_deferred() - - -func sub_select(col_idx: int, row_idx: int) -> void: - var deselect: bool = col_idx <= -1 and row_idx <= -1 - for cell in cell_number_hbox.get_children(): - cell.reset_style() - var timeline_idx: int = 0 - for t: LayerTimeline in layer_timeline_vbox.get_children(): - var cell_idx: int = 0 - for cell in t.get_all_cells(): - if cell_idx == col_idx and not deselect: - cell.sub_select() - if row_idx != timeline_idx: - cell.lose_focus() - else: - cell.reset_style() - cell.lose_focus() - cell_idx += 1 - timeline_idx += 1 - if not deselect: - cell_number_hbox.get_child(col_idx).sub_select() - - -func _on_layer_scroll_container_gui_input(_event: InputEvent) -> void: - %LayerTimelineScrollContainer.scroll_vertical = %LayerScrollContainer.scroll_vertical - - -func _on_layer_timeline_scroll_container_gui_input(_event: InputEvent) -> void: - %LayerScrollContainer.scroll_vertical = %LayerTimelineScrollContainer.scroll_vertical - - -func _on_layer_button_down(target_layer: Layer) -> void: - var layer_idx: int = get_all_layers().find(target_layer) - current_indicator = placement_indicator.instantiate() - layer_vbox.add_child(current_indicator) - layer_vbox.move_child(current_indicator, layer_idx + 1) - selected_layer = target_layer - - -func _on_layer_button_up(target_layer: Layer) -> void: - selected_layer = null - if not current_indicator.visible: - current_indicator.free() - current_indicator = null - return - - var new_placement_idx: int = current_indicator.get_index() - var layer_idx: int = get_all_layers().find(target_layer) - var t_layer_timeline: LayerTimeline = layer_timeline_vbox.get_child(layer_idx) - layer_vbox.move_child(target_layer, new_placement_idx) - current_indicator.free() - current_indicator = null - layer_timeline_vbox.move_child(t_layer_timeline, get_all_layers().find(target_layer)) - _update_field.call_deferred() - - -func _on_layer_delete_button_pressed(target_layer: Layer) -> void: - var layer_idx: int = get_all_layers().find(target_layer) - var t_layer_timeline: LayerTimeline = layer_timeline_vbox.get_child(layer_idx - 1) - t_layer_timeline.queue_free() - target_layer.queue_free() - _update_field.call_deferred() - - -func _on_fps_spin_box_value_changed(value: float) -> void: - if value != fps: - fps = value - _update_field.call_deferred() - - -func _on_play_backwards_button_pressed() -> void: - preview_section.play_backwards() - - -func _on_skip_backward_button_pressed() -> void: - pass # Replace with function body. - - -func _on_stop_button_pressed() -> void: - preview_section.stop() - - -func _on_skip_forward_button_pressed() -> void: - pass # Replace with function body. - - -func _on_play_button_pressed() -> void: - preview_section.play() diff --git a/common/ui/fields/timeline/monologue_timeline.gd.uid b/common/ui/fields/timeline/monologue_timeline.gd.uid deleted file mode 100644 index 96e5a4b6..00000000 --- a/common/ui/fields/timeline/monologue_timeline.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://bqqjre8f0yujm diff --git a/common/ui/fields/timeline/monologue_timeline.tscn b/common/ui/fields/timeline/monologue_timeline.tscn deleted file mode 100644 index 75b01fb9..00000000 --- a/common/ui/fields/timeline/monologue_timeline.tscn +++ /dev/null @@ -1,366 +0,0 @@ -[gd_scene load_steps=33 format=3 uid="uid://bqbr75kwcpu3i"] - -[ext_resource type="Script" uid="uid://bqqjre8f0yujm" path="res://common/ui/fields/timeline/monologue_timeline.gd" id="1_scldq"] -[ext_resource type="Texture2D" uid="uid://xiahr3jughjg" path="res://ui/assets/icons/plus_min.svg" id="2_qevyo"] -[ext_resource type="Texture2D" uid="uid://fcpb4fd7uma3" path="res://ui/assets/icons/trash_min.svg" id="3_i3rsl"] -[ext_resource type="PackedScene" uid="uid://wiapsnoaoc44" path="res://common/ui/custom_spinbox/custom_spinbox.tscn" id="4_i3rsl"] -[ext_resource type="Texture2D" uid="uid://08g8utdd2kai" path="res://ui/assets/icons/media_play_backward.svg" id="4_wgfvs"] -[ext_resource type="Texture2D" uid="uid://bowdhs0emx5i2" path="res://ui/assets/icons/media_skip_backward.svg" id="5_aaeml"] -[ext_resource type="Texture2D" uid="uid://ctm64x2sdw2y2" path="res://ui/assets/icons/media_stop.svg" id="6_kgr41"] -[ext_resource type="Texture2D" uid="uid://8cxo7ofybuix" path="res://ui/assets/icons/media_skip_forward.svg" id="7_gcvrj"] -[ext_resource type="Texture2D" uid="uid://bficqn5yhfmah" path="res://ui/assets/icons/media_play.svg" id="8_ga8ls"] -[ext_resource type="Texture2D" uid="uid://c07ekrem76mk3" path="res://ui/assets/icons/improt_cell.svg" id="9_vagt2"] -[ext_resource type="Script" uid="uid://csoamuetoupw0" path="res://common/ui/fields/timeline/timeline_layer_cell_container.gd" id="10_6qrpt"] -[ext_resource type="Texture2D" uid="uid://hlck6y4i3l5q" path="res://ui/assets/icons/plus.svg" id="11_u65pl"] -[ext_resource type="PackedScene" uid="uid://c3kq4oc8yxco7" path="res://common/ui/fields/timeline/timeline_cell_number.tscn" id="12_4mkmo"] - -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_wlqpu"] -draw_center = false -border_width_left = 2 -border_width_top = 2 -border_width_right = 2 -border_width_bottom = 2 -border_color = Color(0.835294, 0.317647, 0.376471, 1) -corner_radius_top_left = 2 -corner_radius_top_right = 2 -corner_radius_bottom_right = 2 -corner_radius_bottom_left = 2 - -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_v62g1"] -draw_center = false -border_width_left = 2 -border_width_top = 2 -border_width_right = 2 -border_width_bottom = 2 -border_color = Color(0.84, 0.3192, 0.37996, 0.498039) -corner_radius_top_left = 2 -corner_radius_top_right = 2 -corner_radius_bottom_right = 2 -corner_radius_bottom_left = 2 - -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_8ap2m"] -draw_center = false -border_width_left = 2 -border_width_top = 2 -border_width_right = 2 -border_width_bottom = 2 -border_color = Color(0.835294, 0.317647, 0.376471, 1) -corner_radius_top_left = 2 -corner_radius_top_right = 2 -corner_radius_bottom_right = 2 -corner_radius_bottom_left = 2 - -[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_4f5yu"] - -[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_xe0nk"] - -[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_arqpt"] - -[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_7j2ls"] - -[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_argys"] - -[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_aaeml"] - -[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_kgr41"] - -[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_gcvrj"] - -[sub_resource type="LabelSettings" id="LabelSettings_86o0e"] -line_spacing = 0.0 -font_size = 14 - -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_vknlb"] -bg_color = Color(0.117647, 0.117647, 0.129412, 1) - -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_xe0nk"] -bg_color = Color(0.117647, 0.117647, 0.129412, 1) - -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_arqpt"] -bg_color = Color(0.117647, 0.117647, 0.129412, 1) - -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_7j2ls"] -bg_color = Color(0.117647, 0.117647, 0.129412, 1) - -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_qevyo"] -draw_center = false -corner_radius_top_left = 4 -corner_radius_top_right = 4 - -[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_omduo"] - -[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_t1qxj"] - -[node name="Timeline" type="PanelContainer"] -offset_right = 528.0 -offset_bottom = 83.0 -size_flags_horizontal = 3 -size_flags_vertical = 3 -theme_type_variation = &"CollapsibleFieldPanel" -script = ExtResource("1_scldq") - -[node name="VBoxContainer" type="VBoxContainer" parent="."] -layout_mode = 2 -theme_override_constants/separation = 5 - -[node name="PanelContainer" type="PanelContainer" parent="VBoxContainer"] -layout_mode = 2 - -[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer/PanelContainer"] -custom_minimum_size = Vector2(0, 26) -layout_mode = 2 - -[node name="btnAddLayer" type="Button" parent="VBoxContainer/PanelContainer/HBoxContainer"] -visible = false -custom_minimum_size = Vector2(26, 26) -layout_mode = 2 -theme_override_styles/focus = SubResource("StyleBoxFlat_wlqpu") -theme_override_styles/hover = SubResource("StyleBoxFlat_v62g1") -theme_override_styles/pressed = SubResource("StyleBoxFlat_8ap2m") -theme_override_styles/normal = SubResource("StyleBoxEmpty_4f5yu") -icon = ExtResource("2_qevyo") -expand_icon = true - -[node name="btnDelete" type="Button" parent="VBoxContainer/PanelContainer/HBoxContainer"] -visible = false -custom_minimum_size = Vector2(26, 26) -layout_mode = 2 -theme_override_styles/focus = SubResource("StyleBoxFlat_wlqpu") -theme_override_styles/hover = SubResource("StyleBoxFlat_v62g1") -theme_override_styles/pressed = SubResource("StyleBoxFlat_8ap2m") -theme_override_styles/normal = SubResource("StyleBoxEmpty_4f5yu") -icon = ExtResource("3_i3rsl") -expand_icon = true - -[node name="VSeparator" type="VSeparator" parent="VBoxContainer/PanelContainer/HBoxContainer"] -visible = false -layout_mode = 2 - -[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer/PanelContainer/HBoxContainer"] -layout_mode = 2 -theme_override_constants/separation = 0 - -[node name="FpsSpinBox" parent="VBoxContainer/PanelContainer/HBoxContainer/HBoxContainer" instance=ExtResource("4_i3rsl")] -unique_name_in_owner = true -layout_mode = 2 -suffix = "fps" - -[node name="PlayBackwardsButton" type="Button" parent="VBoxContainer/PanelContainer/HBoxContainer"] -custom_minimum_size = Vector2(26, 26) -layout_mode = 2 -theme_override_styles/disabled = SubResource("StyleBoxEmpty_xe0nk") -theme_override_styles/hover_pressed = SubResource("StyleBoxEmpty_xe0nk") -theme_override_styles/hover = SubResource("StyleBoxEmpty_arqpt") -theme_override_styles/pressed = SubResource("StyleBoxEmpty_7j2ls") -theme_override_styles/normal = SubResource("StyleBoxEmpty_argys") -icon = ExtResource("4_wgfvs") -flat = true -icon_alignment = 1 -expand_icon = true - -[node name="SkipBackwardButton" type="Button" parent="VBoxContainer/PanelContainer/HBoxContainer"] -visible = false -custom_minimum_size = Vector2(26, 26) -layout_mode = 2 -theme_override_styles/disabled = SubResource("StyleBoxEmpty_xe0nk") -theme_override_styles/hover_pressed = SubResource("StyleBoxEmpty_xe0nk") -theme_override_styles/hover = SubResource("StyleBoxEmpty_arqpt") -theme_override_styles/pressed = SubResource("StyleBoxEmpty_7j2ls") -theme_override_styles/normal = SubResource("StyleBoxEmpty_argys") -icon = ExtResource("5_aaeml") -flat = true -icon_alignment = 1 -expand_icon = true - -[node name="StopButton" type="Button" parent="VBoxContainer/PanelContainer/HBoxContainer"] -custom_minimum_size = Vector2(26, 26) -layout_mode = 2 -theme_override_styles/disabled = SubResource("StyleBoxEmpty_xe0nk") -theme_override_styles/hover_pressed = SubResource("StyleBoxEmpty_xe0nk") -theme_override_styles/hover = SubResource("StyleBoxEmpty_arqpt") -theme_override_styles/pressed = SubResource("StyleBoxEmpty_7j2ls") -theme_override_styles/normal = SubResource("StyleBoxEmpty_argys") -icon = ExtResource("6_kgr41") -flat = true -icon_alignment = 1 -expand_icon = true - -[node name="SkipForwardButton" type="Button" parent="VBoxContainer/PanelContainer/HBoxContainer"] -visible = false -custom_minimum_size = Vector2(26, 26) -layout_mode = 2 -theme_override_styles/disabled = SubResource("StyleBoxEmpty_xe0nk") -theme_override_styles/hover_pressed = SubResource("StyleBoxEmpty_xe0nk") -theme_override_styles/hover = SubResource("StyleBoxEmpty_arqpt") -theme_override_styles/pressed = SubResource("StyleBoxEmpty_7j2ls") -theme_override_styles/normal = SubResource("StyleBoxEmpty_argys") -icon = ExtResource("7_gcvrj") -flat = true -icon_alignment = 1 -expand_icon = true - -[node name="PlayButton" type="Button" parent="VBoxContainer/PanelContainer/HBoxContainer"] -custom_minimum_size = Vector2(26, 26) -layout_mode = 2 -theme_override_styles/disabled = SubResource("StyleBoxEmpty_xe0nk") -theme_override_styles/hover_pressed = SubResource("StyleBoxEmpty_xe0nk") -theme_override_styles/hover = SubResource("StyleBoxEmpty_arqpt") -theme_override_styles/pressed = SubResource("StyleBoxEmpty_7j2ls") -theme_override_styles/normal = SubResource("StyleBoxEmpty_argys") -icon = ExtResource("8_ga8ls") -flat = true -icon_alignment = 1 -expand_icon = true - -[node name="VSeparator2" type="VSeparator" parent="VBoxContainer/PanelContainer/HBoxContainer"] -layout_mode = 2 - -[node name="ImportFrameButton" type="Button" parent="VBoxContainer/PanelContainer/HBoxContainer"] -unique_name_in_owner = true -custom_minimum_size = Vector2(26, 26) -layout_mode = 2 -theme_override_styles/disabled = SubResource("StyleBoxEmpty_xe0nk") -theme_override_styles/hover_pressed = SubResource("StyleBoxEmpty_xe0nk") -theme_override_styles/hover = SubResource("StyleBoxEmpty_arqpt") -theme_override_styles/pressed = SubResource("StyleBoxEmpty_7j2ls") -theme_override_styles/normal = SubResource("StyleBoxEmpty_argys") -disabled = true -icon = ExtResource("9_vagt2") -flat = true -icon_alignment = 1 -expand_icon = true - -[node name="LayerContainer" type="HSplitContainer" parent="VBoxContainer"] -unique_name_in_owner = true -layout_mode = 2 -size_flags_vertical = 3 -theme_override_constants/separation = 5 -script = ExtResource("10_6qrpt") - -[node name="LayerContainer" type="PanelContainer" parent="VBoxContainer/LayerContainer"] -custom_minimum_size = Vector2(150, 0) -layout_mode = 2 -theme_override_styles/panel = SubResource("StyleBoxEmpty_aaeml") - -[node name="MainLayerVBox" type="VBoxContainer" parent="VBoxContainer/LayerContainer/LayerContainer"] -layout_mode = 2 -size_flags_horizontal = 3 -size_flags_vertical = 3 - -[node name="PanelContainer" type="PanelContainer" parent="VBoxContainer/LayerContainer/LayerContainer/MainLayerVBox"] -custom_minimum_size = Vector2(0, 35) -layout_mode = 2 -theme_override_styles/panel = SubResource("StyleBoxEmpty_kgr41") - -[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer/LayerContainer/LayerContainer/MainLayerVBox/PanelContainer"] -layout_mode = 2 -size_flags_vertical = 3 -theme_override_constants/separation = 0 - -[node name="PanelContainer4" type="PanelContainer" parent="VBoxContainer/LayerContainer/LayerContainer/MainLayerVBox/PanelContainer/HBoxContainer"] -layout_mode = 2 -size_flags_horizontal = 3 -theme_override_styles/panel = SubResource("StyleBoxEmpty_gcvrj") - -[node name="Label" type="Label" parent="VBoxContainer/LayerContainer/LayerContainer/MainLayerVBox/PanelContainer/HBoxContainer/PanelContainer4"] -layout_mode = 2 -label_settings = SubResource("LabelSettings_86o0e") - -[node name="LayerScrollContainer" type="ScrollContainer" parent="VBoxContainer/LayerContainer/LayerContainer/MainLayerVBox"] -unique_name_in_owner = true -layout_mode = 2 -size_flags_vertical = 3 -vertical_scroll_mode = 3 - -[node name="VBoxContainer" type="VBoxContainer" parent="VBoxContainer/LayerContainer/LayerContainer/MainLayerVBox/LayerScrollContainer"] -layout_mode = 2 -size_flags_horizontal = 3 -theme_override_constants/separation = 0 - -[node name="LayerVBox" type="VBoxContainer" parent="VBoxContainer/LayerContainer/LayerContainer/MainLayerVBox/LayerScrollContainer/VBoxContainer"] -unique_name_in_owner = true -layout_mode = 2 -theme_override_constants/separation = 0 - -[node name="btnAddLayer" type="Button" parent="VBoxContainer/LayerContainer/LayerContainer/MainLayerVBox/LayerScrollContainer/VBoxContainer"] -custom_minimum_size = Vector2(24, 24) -layout_mode = 2 -theme_override_constants/icon_max_width = 10 -theme_override_styles/hover_pressed = SubResource("StyleBoxFlat_vknlb") -theme_override_styles/hover = SubResource("StyleBoxFlat_xe0nk") -theme_override_styles/pressed = SubResource("StyleBoxFlat_arqpt") -theme_override_styles/normal = SubResource("StyleBoxFlat_7j2ls") -icon = ExtResource("11_u65pl") -icon_alignment = 1 - -[node name="LayerTimelineContainer" type="ScrollContainer" parent="VBoxContainer/LayerContainer"] -layout_mode = 2 -vertical_scroll_mode = 0 - -[node name="LayerTimelineVBox" type="VBoxContainer" parent="VBoxContainer/LayerContainer/LayerTimelineContainer"] -layout_mode = 2 -size_flags_horizontal = 3 -size_flags_vertical = 3 - -[node name="FrameCountTimeline" type="PanelContainer" parent="VBoxContainer/LayerContainer/LayerTimelineContainer/LayerTimelineVBox"] -clip_contents = true -custom_minimum_size = Vector2(0, 25) -layout_mode = 2 -theme_override_styles/panel = SubResource("StyleBoxFlat_qevyo") - -[node name="HBox" type="HBoxContainer" parent="VBoxContainer/LayerContainer/LayerTimelineContainer/LayerTimelineVBox/FrameCountTimeline"] -layout_mode = 2 -size_flags_vertical = 3 -theme_override_constants/separation = 0 - -[node name="CellNumberHBox" type="HBoxContainer" parent="VBoxContainer/LayerContainer/LayerTimelineContainer/LayerTimelineVBox/FrameCountTimeline/HBox"] -unique_name_in_owner = true -layout_mode = 2 -theme_override_constants/separation = 0 - -[node name="CellNumber" parent="VBoxContainer/LayerContainer/LayerTimelineContainer/LayerTimelineVBox/FrameCountTimeline/HBox/CellNumberHBox" instance=ExtResource("12_4mkmo")] -custom_minimum_size = Vector2(27, 35) -layout_mode = 2 - -[node name="PanelContainer6" type="PanelContainer" parent="VBoxContainer/LayerContainer/LayerTimelineContainer/LayerTimelineVBox/FrameCountTimeline/HBox"] -custom_minimum_size = Vector2(27, 26) -layout_mode = 2 -theme_override_styles/panel = SubResource("StyleBoxEmpty_omduo") - -[node name="LayerTimelineScrollContainer" type="ScrollContainer" parent="VBoxContainer/LayerContainer/LayerTimelineContainer/LayerTimelineVBox"] -unique_name_in_owner = true -layout_mode = 2 -size_flags_horizontal = 3 -size_flags_vertical = 3 -follow_focus = true -horizontal_scroll_mode = 0 - -[node name="VBoxContainer" type="VBoxContainer" parent="VBoxContainer/LayerContainer/LayerTimelineContainer/LayerTimelineVBox/LayerTimelineScrollContainer"] -layout_mode = 2 -size_flags_horizontal = 3 -size_flags_vertical = 3 -theme_override_constants/separation = 0 - -[node name="LayerTimelineVBox" type="VBoxContainer" parent="VBoxContainer/LayerContainer/LayerTimelineContainer/LayerTimelineVBox/LayerTimelineScrollContainer/VBoxContainer"] -unique_name_in_owner = true -layout_mode = 2 -size_flags_horizontal = 3 -theme_override_constants/separation = 0 - -[node name="PanelContainer" type="PanelContainer" parent="VBoxContainer/LayerContainer/LayerTimelineContainer/LayerTimelineVBox/LayerTimelineScrollContainer/VBoxContainer"] -custom_minimum_size = Vector2(0, 24) -layout_mode = 2 -theme_override_styles/panel = SubResource("StyleBoxEmpty_t1qxj") - -[connection signal="value_changed" from="VBoxContainer/PanelContainer/HBoxContainer/HBoxContainer/FpsSpinBox" to="." method="_on_fps_spin_box_value_changed"] -[connection signal="pressed" from="VBoxContainer/PanelContainer/HBoxContainer/PlayBackwardsButton" to="." method="_on_play_backwards_button_pressed"] -[connection signal="pressed" from="VBoxContainer/PanelContainer/HBoxContainer/SkipBackwardButton" to="." method="_on_skip_backward_button_pressed"] -[connection signal="pressed" from="VBoxContainer/PanelContainer/HBoxContainer/StopButton" to="." method="_on_stop_button_pressed"] -[connection signal="pressed" from="VBoxContainer/PanelContainer/HBoxContainer/SkipForwardButton" to="." method="_on_skip_forward_button_pressed"] -[connection signal="pressed" from="VBoxContainer/PanelContainer/HBoxContainer/PlayButton" to="." method="_on_play_button_pressed"] -[connection signal="pressed" from="VBoxContainer/PanelContainer/HBoxContainer/ImportFrameButton" to="." method="_on_import_frame_button_pressed"] -[connection signal="mouse_entered" from="VBoxContainer/LayerContainer" to="VBoxContainer/LayerContainer" method="_on_mouse_entered"] -[connection signal="mouse_exited" from="VBoxContainer/LayerContainer" to="VBoxContainer/LayerContainer" method="_on_mouse_exited"] -[connection signal="gui_input" from="VBoxContainer/LayerContainer/LayerContainer/MainLayerVBox/LayerScrollContainer" to="." method="_on_layer_scroll_container_gui_input"] -[connection signal="pressed" from="VBoxContainer/LayerContainer/LayerContainer/MainLayerVBox/LayerScrollContainer/VBoxContainer/btnAddLayer" to="." method="_on_btn_add_layer_pressed"] -[connection signal="gui_input" from="VBoxContainer/LayerContainer/LayerTimelineContainer/LayerTimelineVBox/LayerTimelineScrollContainer" to="." method="_on_layer_timeline_scroll_container_gui_input"] diff --git a/common/ui/fields/timeline/timeline_cell.gd b/common/ui/fields/timeline/timeline_cell.gd deleted file mode 100644 index ef0a95ea..00000000 --- a/common/ui/fields/timeline/timeline_cell.gd +++ /dev/null @@ -1,105 +0,0 @@ -class_name TimelineCell extends PanelContainer - -signal button_down -signal button_up -signal button_focus_exited - -@onready var single_cell_texture := preload("res://ui/assets/icons/cell_single.svg") -@onready var empty_cell_texture := preload("res://ui/assets/icons/cell_empty.svg") -@onready var left_cell_texture := preload("res://ui/assets/icons/cell_left.svg") -@onready var right_cell_texture := preload("res://ui/assets/icons/cell_right.svg") -@onready var middle_cell_texture := preload("res://ui/assets/icons/cell_middle.svg") - -@onready var button := %Button -@onready var line_indicator := %LineIndicator -@onready var texture_rect := $TextureContainer/TextureRect -@onready var texture_container := $TextureContainer -@onready var hflow := %HFlow - -var image_path: String: - set = _set_image_path -var is_exposure: bool = false # If is the same frame as the previous one -var timeline: LayerTimeline - - -func _set_image_path(value: String) -> void: - image_path = value - _update() - - -func _ready() -> void: - GlobalSignal.add_listener("timeline_zoom_in", _on_timeline_zoom) - GlobalSignal.add_listener("timeline_zoom_out", _on_timeline_zoom) - _update() - - -func _update() -> void: - if not is_exposure and not image_path.is_empty(): - var root_dir = timeline.timeline.base_path.get_base_dir() + Path.get_separator() - texture_rect.texture = ImageLoader.load_thumbnail( - Path.relative_to_absolute(image_path, root_dir) - ) - - texture_container.visible = !is_exposure - line_indicator.visible = is_exposure - - -func lose_focus() -> void: - button.button_pressed = false - - -func get_base_sb() -> StyleBoxFlat: - # TODO: Use theme variation instead - var sb: StyleBox = StyleBoxFlat.new() - sb.bg_color = Color("d651613f") - sb.border_color = Color("1e1e21") - sb.border_width_right = 1 - return sb - - -func sub_select() -> void: - add_theme_stylebox_override("panel", get_base_sb()) - - -func reset_style() -> void: - var sb: StyleBox = get_base_sb() - sb.draw_center = false - add_theme_stylebox_override("panel", sb) - - -func _on_timeline_zoom(cell_width: int) -> void: - custom_minimum_size.x = cell_width - - -func _on_button_button_down() -> void: - button_down.emit() - - -func _on_button_button_up() -> void: - button_up.emit() - - -func _on_button_toggled(toggled_on: bool) -> void: - if toggled_on == false: - button_focus_exited.emit() - - -func _on_inc_exposure_button_pressed() -> void: - timeline.add_exposure(self) - - -func _on_mouse_entered() -> void: - if timeline.current_indicator == null: - hflow.show() - - -func _on_mouse_exited() -> void: - hflow.hide() - - -func _on_dec_exposure_button_pressed() -> void: - timeline.remove_cell(self) - - -func _on_button_focus_exited() -> void: - button_focus_exited.emit() diff --git a/common/ui/fields/timeline/timeline_cell.gd.uid b/common/ui/fields/timeline/timeline_cell.gd.uid deleted file mode 100644 index cb1930dd..00000000 --- a/common/ui/fields/timeline/timeline_cell.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://bstbijin8qrmw diff --git a/common/ui/fields/timeline/timeline_cell.tscn b/common/ui/fields/timeline/timeline_cell.tscn deleted file mode 100644 index 1ec2c598..00000000 --- a/common/ui/fields/timeline/timeline_cell.tscn +++ /dev/null @@ -1,152 +0,0 @@ -[gd_scene load_steps=11 format=3 uid="uid://cdpox07h3wlf3"] - -[ext_resource type="Script" uid="uid://bstbijin8qrmw" path="res://common/ui/fields/timeline/timeline_cell.gd" id="1_w2yvg"] -[ext_resource type="Script" uid="uid://dqhwi718vnyxk" path="res://common/layouts/character_edit/alpha_bg.gd" id="2_04ohn"] -[ext_resource type="Texture2D" uid="uid://2avo8aox8ls2" path="res://ui/assets/icons/minus_min.svg" id="3_tep1x"] -[ext_resource type="Texture2D" uid="uid://xiahr3jughjg" path="res://ui/assets/icons/plus_min.svg" id="4_ob7f1"] - -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_y3h2k"] -draw_center = false -border_width_right = 1 -border_width_bottom = 1 -border_color = Color(0.117647, 0.117647, 0.129412, 1) - -[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_xo2vn"] - -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_1614f"] -draw_center = false -border_width_left = 2 -border_width_top = 2 -border_width_right = 2 -border_width_bottom = 2 -border_color = Color(0.835294, 0.317647, 0.376471, 1) -corner_radius_top_left = 2 -corner_radius_top_right = 2 -corner_radius_bottom_right = 2 -corner_radius_bottom_left = 2 - -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_y37jy"] -draw_center = false -border_width_left = 2 -border_width_top = 2 -border_width_right = 2 -border_width_bottom = 2 -border_color = Color(0.84, 0.3192, 0.37996, 0.498039) -corner_radius_top_left = 2 -corner_radius_top_right = 2 -corner_radius_bottom_right = 2 -corner_radius_bottom_left = 2 - -[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_5et5j"] - -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_7wlkg"] -bg_color = Color(0.117647, 0.117647, 0.129412, 1) - -[node name="Cell" type="PanelContainer"] -custom_minimum_size = Vector2(27, 52) -offset_right = 27.0 -offset_bottom = 52.0 -theme_override_styles/panel = SubResource("StyleBoxFlat_y3h2k") -script = ExtResource("1_w2yvg") - -[node name="VBox" type="VBoxContainer" parent="."] -layout_mode = 2 -alignment = 1 - -[node name="LineIndicator" type="ColorRect" parent="VBox"] -unique_name_in_owner = true -visible = false -custom_minimum_size = Vector2(0, 2) -layout_mode = 2 - -[node name="TextureContainer" type="PanelContainer" parent="."] -clip_contents = true -layout_mode = 2 -theme_override_styles/panel = SubResource("StyleBoxEmpty_xo2vn") - -[node name="AlphaBG" type="ColorRect" parent="TextureContainer"] -layout_mode = 2 -script = ExtResource("2_04ohn") - -[node name="TextureRect" type="TextureRect" parent="TextureContainer"] -custom_minimum_size = Vector2(26, 26) -layout_mode = 2 -expand_mode = 1 -stretch_mode = 5 - -[node name="IncExposureContainer" type="Control" parent="."] -layout_mode = 2 -mouse_filter = 2 - -[node name="Button" type="Button" parent="IncExposureContainer"] -unique_name_in_owner = true -layout_mode = 1 -anchors_preset = 15 -anchor_right = 1.0 -anchor_bottom = 1.0 -grow_horizontal = 2 -grow_vertical = 2 -mouse_filter = 1 -theme_override_styles/focus = SubResource("StyleBoxFlat_1614f") -theme_override_styles/hover = SubResource("StyleBoxFlat_y37jy") -theme_override_styles/pressed = SubResource("StyleBoxFlat_1614f") -theme_override_styles/normal = SubResource("StyleBoxEmpty_5et5j") -keep_pressed_outside = true - -[node name="HFlow" type="HFlowContainer" parent="IncExposureContainer"] -unique_name_in_owner = true -visible = false -layout_mode = 1 -anchors_preset = 14 -anchor_top = 0.5 -anchor_right = 1.0 -anchor_bottom = 0.5 -offset_top = -12.0 -offset_bottom = 12.0 -grow_horizontal = 2 -grow_vertical = 2 -mouse_filter = 2 -alignment = 1 -last_wrap_alignment = 2 - -[node name="DecHBox" type="HBoxContainer" parent="IncExposureContainer/HFlow"] -layout_mode = 2 -size_flags_horizontal = 3 -mouse_filter = 2 - -[node name="DecExposureButton" type="Button" parent="IncExposureContainer/HFlow/DecHBox"] -custom_minimum_size = Vector2(24, 24) -layout_mode = 2 -mouse_filter = 1 -theme_override_styles/hover_pressed = SubResource("StyleBoxFlat_7wlkg") -theme_override_styles/hover = SubResource("StyleBoxFlat_7wlkg") -theme_override_styles/pressed = SubResource("StyleBoxFlat_7wlkg") -theme_override_styles/normal = SubResource("StyleBoxFlat_7wlkg") -icon = ExtResource("3_tep1x") -expand_icon = true - -[node name="IncHBox" type="HBoxContainer" parent="IncExposureContainer/HFlow"] -layout_mode = 2 -size_flags_horizontal = 3 -mouse_filter = 2 -alignment = 2 - -[node name="IncExposureButton" type="Button" parent="IncExposureContainer/HFlow/IncHBox"] -custom_minimum_size = Vector2(24, 24) -layout_mode = 2 -mouse_filter = 1 -theme_override_styles/hover_pressed = SubResource("StyleBoxFlat_7wlkg") -theme_override_styles/hover = SubResource("StyleBoxFlat_7wlkg") -theme_override_styles/pressed = SubResource("StyleBoxFlat_7wlkg") -theme_override_styles/normal = SubResource("StyleBoxFlat_7wlkg") -icon = ExtResource("4_ob7f1") -expand_icon = true - -[connection signal="mouse_entered" from="." to="." method="_on_mouse_entered"] -[connection signal="mouse_exited" from="." to="." method="_on_mouse_exited"] -[connection signal="button_down" from="IncExposureContainer/Button" to="." method="_on_button_button_down"] -[connection signal="button_up" from="IncExposureContainer/Button" to="." method="_on_button_button_up"] -[connection signal="focus_exited" from="IncExposureContainer/Button" to="." method="_on_button_focus_exited"] -[connection signal="toggled" from="IncExposureContainer/Button" to="." method="_on_button_toggled"] -[connection signal="pressed" from="IncExposureContainer/HFlow/DecHBox/DecExposureButton" to="." method="_on_dec_exposure_button_pressed"] -[connection signal="pressed" from="IncExposureContainer/HFlow/IncHBox/IncExposureButton" to="." method="_on_inc_exposure_button_pressed"] diff --git a/common/ui/fields/timeline/timeline_cell_layer.gd b/common/ui/fields/timeline/timeline_cell_layer.gd deleted file mode 100644 index eb117611..00000000 --- a/common/ui/fields/timeline/timeline_cell_layer.gd +++ /dev/null @@ -1,230 +0,0 @@ -class_name LayerTimeline extends PanelContainer - -signal timeline_updated - -@onready var hbox := %HBox - -var timeline: MonologueAnimationTimeline -var timeline_cell := preload("res://common/ui/fields/timeline/timeline_cell.tscn") -var placement_indicator := preload("res://common/ui/vertical_placement_indicator.tscn") - -var current_indicator: Control -var selected_cell: TimelineCell - - -func _ready() -> void: - add_cell() - - -func add_cell(image_path = "") -> TimelineCell: - var cells := get_all_cells() - var is_exposure: bool = false if image_path != null else cells.size() > 0 - - var new_cell := timeline_cell.instantiate() - new_cell.timeline = self - hbox.add_child(new_cell) - new_cell.is_exposure = is_exposure - new_cell.custom_minimum_size.x = timeline.get_cell_width() - new_cell.image_path = image_path - new_cell._update() - new_cell.connect("button_down", _on_cell_button_down.bind(new_cell)) - new_cell.connect("button_up", _on_cell_button_up.bind(new_cell)) - new_cell.connect("button_focus_exited", _on_cell_focus_exited) - - if get_all_cells().size() > timeline.cell_count: - timeline.add_cell() - - return new_cell - - -func _on_cell_button_down(cell: TimelineCell) -> void: - current_indicator = placement_indicator.instantiate() - hbox.add_child(current_indicator) - hbox.move_child(current_indicator, cell.get_index() + 1) - current_indicator.show() - selected_cell = cell - - -func _on_cell_button_up(cell: TimelineCell) -> void: - selected_cell = null - if not current_indicator.visible: - timeline.cell_selected(cell, self) - current_indicator.queue_free() - current_indicator = null - return - - var indicator_idx = current_indicator.get_index() - hbox.move_child(cell, indicator_idx) - - current_indicator.queue_free() - current_indicator = null - timeline.selected_cell_idx = get_all_cells().find(cell) - timeline.selected_cell_layer_idx = timeline.layer_timeline_vbox.get_children().find(self) - - var first_cell: TimelineCell = get_all_cells()[0] - if first_cell.is_exposure: - first_cell.is_exposure = false - first_cell._update() - - timeline_updated.emit() - - for child in get_all_cells(): - if child == cell: - continue - - child.lose_focus() - - -func _on_cell_focus_exited() -> void: - get_all_cells()[timeline.selected_cell_idx].reset_style() - timeline.cell_deselected() - - -func _process(_delta: float) -> void: - if current_indicator == null: - return - - var indicator_dist: float = current_indicator.global_position.x - get_global_mouse_position().x - var cell_width: float = timeline.get_cell_width() - var cell_dist: float = ( - get_global_mouse_position().x - (selected_cell.global_position.x + cell_width / 2.0) - ) - var indicator_index: int = current_indicator.get_index() - current_indicator.show() - if indicator_dist >= cell_width / 2.0: - hbox.move_child(current_indicator, indicator_index - 1) - elif indicator_dist <= -cell_width / 2.0: - hbox.move_child(current_indicator, indicator_index + 1) - elif abs(cell_dist) < cell_width: - current_indicator.hide() - - -func remove_cell(cell: TimelineCell) -> void: - var cells: Array = get_all_cells() - var index: int = cells.find(cell) - - if not cell.is_exposure and have_exposure_after(cell): - var c_after: TimelineCell = cells[index + 1] - c_after.is_exposure = false - c_after.image_path = cell.image_path - c_after._update() - - hbox.remove_child(cell) - cell.queue_free() - - timeline_updated.emit() - - -func fill() -> void: - _clear() - for _i in range(timeline.cell_count): - add_cell() - - -func _clear() -> void: - for cell in get_all_cells(): - cell.queue_free() - - -func _from_dict(dict: Dictionary) -> void: - _clear() - var frames: Dictionary = dict.get("Frames") - for frame_idx in frames.keys(): - for i in range(frames[frame_idx].get("Exposure", 1)): - var frame_data: Dictionary = frames[frame_idx] - var cell := add_cell() - cell.is_exposure = i > 0 - if i <= 0: - cell.image_path = frame_data.get("ImagePath", "") - cell._update() - - -func _to_dict() -> Dictionary: - var dict: Dictionary = {} - var cells: Array = get_all_cells() - for cell: TimelineCell in cells: - if cell.is_exposure: - continue - - var cell_idx: int = cells.find(cell) - dict[cell_idx] = {"ImagePath": cell.image_path, "Exposure": get_frame_duration(cell_idx)} - - return dict - - -func get_all_cells() -> Array: - var cells: Array = [] - for child in hbox.get_children(): - if child is not TimelineCell or child.is_queued_for_deletion(): - continue - cells.append(child) - - return cells - - -func _to_sprite_frames() -> SpriteFrames: - var sprite_frames := SpriteFrames.new() - sprite_frames.set_animation_speed("default", timeline.fps) - - var cells: Array = get_all_cells() - for i in range(timeline.cell_count): - var texture: Texture2D - var frame_duration: float = 1.0 - - if cells.size() > i: - var cell: TimelineCell = cells[i - 1] - if cell.is_exposure: - continue - - var idx = cells.find(cell) - frame_duration = get_frame_duration(idx) - - var root_dir = timeline.base_path.get_base_dir() + Path.get_separator() - var frame_path: String = Path.relative_to_absolute(cell.image_path, root_dir) - if FileAccess.file_exists(frame_path): - texture = ImageLoader.load_image(frame_path) - else: - texture = Texture2D.new() - - sprite_frames.add_frame("default", texture, frame_duration, i) - - return sprite_frames - - -func get_frame_duration(frame_idx: int) -> float: - var duration: float = 1.0 - - var cells: Array = get_all_cells().slice(frame_idx + 1) - for cell: TimelineCell in cells: - if cell.is_exposure: - duration += 1.0 - continue - break - - return duration - - -func add_exposure(of_cell: TimelineCell): - var index: int = get_all_cells().find(of_cell) - - var cell: TimelineCell = add_cell() - cell.is_exposure = true - hbox.move_child(cell, index + 1) - cell._on_mouse_exited() - timeline_updated.emit() - - -func _on_button_pressed() -> void: - var cell: TimelineCell = add_cell() - cell.is_exposure = false - cell._update() - timeline_updated.emit() - - -func have_exposure_after(cell: TimelineCell) -> bool: - var cells := get_all_cells() - var index: int = cells.find(cell) - if index == cells.size() - 1: - return false - - return cells[index + 1].is_exposure diff --git a/common/ui/fields/timeline/timeline_cell_layer.gd.uid b/common/ui/fields/timeline/timeline_cell_layer.gd.uid deleted file mode 100644 index 52d99c5c..00000000 --- a/common/ui/fields/timeline/timeline_cell_layer.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://dt0lru5kmkesc diff --git a/common/ui/fields/timeline/timeline_cell_layer.tscn b/common/ui/fields/timeline/timeline_cell_layer.tscn deleted file mode 100644 index 022b82ef..00000000 --- a/common/ui/fields/timeline/timeline_cell_layer.tscn +++ /dev/null @@ -1,44 +0,0 @@ -[gd_scene load_steps=7 format=3 uid="uid://hc8mgc7ndi5d"] - -[ext_resource type="Script" uid="uid://dt0lru5kmkesc" path="res://common/ui/fields/timeline/timeline_cell_layer.gd" id="1_uew4g"] -[ext_resource type="Texture2D" uid="uid://hlck6y4i3l5q" path="res://ui/assets/icons/plus.svg" id="2_68mbi"] - -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_0ynx3"] -bg_color = Color(0.117647, 0.117647, 0.129412, 1) - -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_jdrfe"] -bg_color = Color(0.117647, 0.117647, 0.129412, 1) - -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_wroo4"] -bg_color = Color(0.117647, 0.117647, 0.129412, 1) - -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_abmyl"] -bg_color = Color(0.117647, 0.117647, 0.129412, 1) - -[node name="LayerTimeline" type="PanelContainer"] -custom_minimum_size = Vector2(0, 52) -size_flags_horizontal = 3 -theme_type_variation = &"ItemContainerFlat" -script = ExtResource("1_uew4g") - -[node name="BaseContainer" type="HBoxContainer" parent="."] -layout_mode = 2 -theme_override_constants/separation = 0 - -[node name="HBox" type="HBoxContainer" parent="BaseContainer"] -unique_name_in_owner = true -layout_mode = 2 -theme_override_constants/separation = 0 - -[node name="Button" type="Button" parent="BaseContainer"] -custom_minimum_size = Vector2(24, 0) -layout_mode = 2 -theme_override_constants/icon_max_width = 10 -theme_override_styles/hover_pressed = SubResource("StyleBoxFlat_0ynx3") -theme_override_styles/hover = SubResource("StyleBoxFlat_jdrfe") -theme_override_styles/pressed = SubResource("StyleBoxFlat_wroo4") -theme_override_styles/normal = SubResource("StyleBoxFlat_abmyl") -icon = ExtResource("2_68mbi") -icon_alignment = 1 - -[connection signal="pressed" from="BaseContainer/Button" to="." method="_on_button_pressed"] diff --git a/common/ui/fields/timeline/timeline_cell_number.tscn b/common/ui/fields/timeline/timeline_cell_number.tscn deleted file mode 100644 index 40e27468..00000000 --- a/common/ui/fields/timeline/timeline_cell_number.tscn +++ /dev/null @@ -1,100 +0,0 @@ -[gd_scene load_steps=6 format=3 uid="uid://c3kq4oc8yxco7"] - -[sub_resource type="GDScript" id="GDScript_aiax2"] -script/source = "extends PanelContainer - -signal selected(cell_number: int) - -@onready var label: Label = $Label - -@export var cell_number: int = 1 - - -func _ready() -> void: - label.text = str(cell_number) - GlobalSignal.add_listener(\"timeline_zoom_in\", _on_timeline_zoom) - GlobalSignal.add_listener(\"timeline_zoom_out\", _on_timeline_zoom) - - -func get_base_sb() -> StyleBoxFlat: - # TODO: Use theme variation instead - var sb: StyleBox = StyleBoxFlat.new() - sb.bg_color = Color(\"d651613f\") - sb.border_color = Color(\"1e1e21\") - sb.border_width_right = 1 - return sb - - -func sub_select() -> void: - add_theme_stylebox_override(\"panel\", get_base_sb()) - -func reset_style() -> void: - var sb: StyleBox = get_base_sb() - sb.draw_center = false - add_theme_stylebox_override(\"panel\", sb) - - -func _on_button_pressed() -> void: - selected.emit(cell_number) - - -func _on_timeline_zoom(cell_width: int) -> void: - custom_minimum_size.x = cell_width - - -func _on_minimum_size_changed() -> void: - custom_minimum_size.x = max(custom_minimum_size.x, 27.0) -" - -[sub_resource type="LabelSettings" id="LabelSettings_jbxed"] -line_spacing = 0.0 -font_size = 14 - -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_fi15l"] -draw_center = false -border_width_left = 2 -border_width_top = 2 -border_width_right = 2 -border_width_bottom = 2 -border_color = Color(0.835294, 0.317647, 0.376471, 1) -corner_radius_top_left = 2 -corner_radius_top_right = 2 -corner_radius_bottom_right = 2 -corner_radius_bottom_left = 2 - -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_vog8c"] -draw_center = false -border_width_left = 2 -border_width_top = 2 -border_width_right = 2 -border_width_bottom = 2 -border_color = Color(0.84, 0.3192, 0.37996, 0.498039) -corner_radius_top_left = 2 -corner_radius_top_right = 2 -corner_radius_bottom_right = 2 -corner_radius_bottom_left = 2 - -[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_x14x4"] - -[node name="CellNumber" type="PanelContainer"] -custom_minimum_size = Vector2(27, 26) -theme_type_variation = &"TimelineCellNumber" -script = SubResource("GDScript_aiax2") - -[node name="Label" type="Label" parent="."] -layout_mode = 2 -text = "1" -label_settings = SubResource("LabelSettings_jbxed") -horizontal_alignment = 1 -vertical_alignment = 1 - -[node name="Button" type="Button" parent="."] -visible = false -layout_mode = 2 -theme_override_styles/focus = SubResource("StyleBoxFlat_fi15l") -theme_override_styles/hover = SubResource("StyleBoxFlat_vog8c") -theme_override_styles/pressed = SubResource("StyleBoxFlat_fi15l") -theme_override_styles/normal = SubResource("StyleBoxEmpty_x14x4") - -[connection signal="minimum_size_changed" from="." to="." method="_on_minimum_size_changed"] -[connection signal="pressed" from="Button" to="." method="_on_button_pressed"] diff --git a/common/ui/fields/timeline/timeline_layer.gd b/common/ui/fields/timeline/timeline_layer.gd deleted file mode 100644 index 72a293ce..00000000 --- a/common/ui/fields/timeline/timeline_layer.gd +++ /dev/null @@ -1,10 +0,0 @@ -class_name Layer extends PanelContainer - -signal delete_button_pressed - -@onready var timeline_label := %Label -@onready var hover_button := %HoverButton - - -func _on_delete_button_pressed() -> void: - delete_button_pressed.emit() diff --git a/common/ui/fields/timeline/timeline_layer.gd.uid b/common/ui/fields/timeline/timeline_layer.gd.uid deleted file mode 100644 index 8d065b20..00000000 --- a/common/ui/fields/timeline/timeline_layer.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://bodradtjajfd7 diff --git a/common/ui/fields/timeline/timeline_layer.tscn b/common/ui/fields/timeline/timeline_layer.tscn deleted file mode 100644 index 6db97d30..00000000 --- a/common/ui/fields/timeline/timeline_layer.tscn +++ /dev/null @@ -1,88 +0,0 @@ -[gd_scene load_steps=7 format=3 uid="uid://d2ekvpgbp07fe"] - -[ext_resource type="Script" uid="uid://bodradtjajfd7" path="res://common/ui/fields/timeline/timeline_layer.gd" id="1_teuw3"] -[ext_resource type="PackedScene" uid="uid://dfwf55ovgwir3" path="res://common/ui/buttons/delete_button.tscn" id="2_ta0kq"] - -[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_cpp16"] - -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_6c6x0"] -draw_center = false -border_width_left = 2 -border_width_top = 2 -border_width_right = 2 -border_width_bottom = 2 -border_color = Color(0.84, 0.3192, 0.37996, 0.498039) -corner_radius_top_left = 4 -corner_radius_top_right = 4 -corner_radius_bottom_right = 4 -corner_radius_bottom_left = 4 - -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_j41u5"] -draw_center = false -border_width_left = 2 -border_width_top = 2 -border_width_right = 2 -border_width_bottom = 2 -border_color = Color(0.835294, 0.317647, 0.376471, 1) -corner_radius_top_left = 2 -corner_radius_top_right = 2 -corner_radius_bottom_right = 2 -corner_radius_bottom_left = 2 - -[sub_resource type="LabelSettings" id="LabelSettings_86o0e"] -line_spacing = 0.0 -font_size = 14 - -[node name="Layer" type="PanelContainer"] -custom_minimum_size = Vector2(0, 52) -theme_type_variation = &"TimelineLayerPanel" -script = ExtResource("1_teuw3") - -[node name="Control" type="Control" parent="."] -layout_mode = 2 -mouse_filter = 2 - -[node name="HoverButton" type="Button" parent="Control"] -unique_name_in_owner = true -layout_mode = 1 -anchors_preset = 15 -anchor_right = 1.0 -anchor_bottom = 1.0 -offset_left = -8.0 -offset_top = -8.0 -offset_right = 8.0 -offset_bottom = 8.0 -grow_horizontal = 2 -grow_vertical = 2 -theme_override_styles/focus = SubResource("StyleBoxEmpty_cpp16") -theme_override_styles/hover = SubResource("StyleBoxFlat_6c6x0") -theme_override_styles/pressed = SubResource("StyleBoxFlat_j41u5") -theme_override_styles/normal = SubResource("StyleBoxEmpty_cpp16") -keep_pressed_outside = true - -[node name="HBoxContainer" type="HBoxContainer" parent="."] -layout_mode = 2 -size_flags_vertical = 3 -mouse_filter = 2 - -[node name="HBoxContainer" type="HBoxContainer" parent="HBoxContainer"] -layout_mode = 2 -size_flags_horizontal = 3 -mouse_filter = 2 - -[node name="Label" type="Label" parent="HBoxContainer/HBoxContainer"] -unique_name_in_owner = true -layout_mode = 2 -size_flags_horizontal = 3 -text = "Layer 1" -label_settings = SubResource("LabelSettings_86o0e") - -[node name="VBoxContainer" type="VBoxContainer" parent="HBoxContainer"] -layout_mode = 2 -mouse_filter = 2 -alignment = 1 - -[node name="DeleteButton" parent="HBoxContainer/VBoxContainer" instance=ExtResource("2_ta0kq")] -layout_mode = 2 - -[connection signal="pressed" from="HBoxContainer/VBoxContainer/DeleteButton" to="." method="_on_delete_button_pressed"] diff --git a/common/ui/fields/timeline/timeline_layer_cell_container.gd b/common/ui/fields/timeline/timeline_layer_cell_container.gd deleted file mode 100644 index 217915b6..00000000 --- a/common/ui/fields/timeline/timeline_layer_cell_container.gd +++ /dev/null @@ -1,38 +0,0 @@ -extends HSplitContainer - -const MAX_CELL_WIDTH: int = 150 -const MIN_CELL_WIDTH: int = 26 - -@onready var layer_timeline_scroll_container := %LayerTimelineScrollContainer - -var mouse_hover: bool = false -var cell_width: int = 75 - - -func _input(_event: InputEvent) -> void: - # Disable scroll container if Ctrl is pressed - if Input.is_action_just_pressed("Ctrl"): - layer_timeline_scroll_container.mouse_filter = MOUSE_FILTER_IGNORE - elif Input.is_action_just_released("Ctrl"): - layer_timeline_scroll_container.mouse_filter = MOUSE_FILTER_PASS - - -func _gui_input(event: InputEvent) -> void: - if event is InputEventMouseButton and event.is_pressed() and Input.is_action_pressed("Ctrl"): - var t: float = remap(cell_width, MIN_CELL_WIDTH, MAX_CELL_WIDTH, 0.0, 1.0) - # zoom in - if event.button_index == MOUSE_BUTTON_WHEEL_UP: - cell_width = min(cell_width + lerp(2.0, 12.0, pow(t, 2)), MAX_CELL_WIDTH) - GlobalSignal.emit("timeline_zoom_in", [cell_width]) - # zoom out - if event.button_index == MOUSE_BUTTON_WHEEL_DOWN: - cell_width = max(cell_width - lerp(2.0, 12.0, pow(t, 2)), MIN_CELL_WIDTH) - GlobalSignal.emit("timeline_zoom_out", [cell_width]) - - -func _on_mouse_entered() -> void: - mouse_hover = true - - -func _on_mouse_exited() -> void: - mouse_hover = false diff --git a/common/ui/fields/timeline/timeline_layer_cell_container.gd.uid b/common/ui/fields/timeline/timeline_layer_cell_container.gd.uid deleted file mode 100644 index bb8612df..00000000 --- a/common/ui/fields/timeline/timeline_layer_cell_container.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://csoamuetoupw0 diff --git a/common/ui/fields/toggle/monologue_toggle.gd b/common/ui/fields/toggle/monologue_toggle.gd deleted file mode 100644 index 0146dca8..00000000 --- a/common/ui/fields/toggle/monologue_toggle.gd +++ /dev/null @@ -1,17 +0,0 @@ -class_name MonologueToggle extends MonologueField - -@onready var label = $Label -@onready var check_button = %CheckButton - - -func set_label_text(text: String) -> void: - label.text = text - - -func propagate(value: Variant) -> void: - super.propagate(value) - check_button.set_pressed_no_signal(value if value is bool else false) - - -func _on_check_button_toggled(toggled_on: bool) -> void: - field_updated.emit(toggled_on) diff --git a/common/ui/fields/toggle/monologue_toggle.gd.uid b/common/ui/fields/toggle/monologue_toggle.gd.uid deleted file mode 100644 index 1bd63073..00000000 --- a/common/ui/fields/toggle/monologue_toggle.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://ctumcy1k8si7o diff --git a/common/ui/fields/toggle/monologue_toggle.tscn b/common/ui/fields/toggle/monologue_toggle.tscn deleted file mode 100644 index 76a379ce..00000000 --- a/common/ui/fields/toggle/monologue_toggle.tscn +++ /dev/null @@ -1,22 +0,0 @@ -[gd_scene load_steps=3 format=3 uid="uid://dh7yuosc0hhpp"] - -[ext_resource type="Script" uid="uid://ctumcy1k8si7o" path="res://common/ui/fields/toggle/monologue_toggle.gd" id="1_0u5l0"] -[ext_resource type="PackedScene" uid="uid://x0daq5tsejey" path="res://common/ui/fields/field_label.tscn" id="2_tj6ps"] - -[node name="MonologueCheckButton" type="HBoxContainer"] -offset_right = 43.0 -offset_bottom = 29.0 -script = ExtResource("1_0u5l0") - -[node name="Label" parent="." instance=ExtResource("2_tj6ps")] -layout_mode = 2 - -[node name="VBoxContainer" type="VBoxContainer" parent="."] -layout_mode = 2 -alignment = 1 - -[node name="CheckButton" type="CheckButton" parent="VBoxContainer"] -unique_name_in_owner = true -layout_mode = 2 - -[connection signal="toggled" from="VBoxContainer/CheckButton" to="." method="_on_check_button_toggled"] diff --git a/common/ui/fields/vector/monologue_vector.gd b/common/ui/fields/vector/monologue_vector.gd deleted file mode 100644 index 98096304..00000000 --- a/common/ui/fields/vector/monologue_vector.gd +++ /dev/null @@ -1,38 +0,0 @@ -class_name MonologueVector extends MonologueField - -@export var minimum: float = -9999999999 -@export var maximum: float = 9999999999 -@export var step: float = 1 - -@onready var label = $FieldLabel -@onready var x_spin_box := %XSpinBox -@onready var y_spin_box := %YSpinBox - -var ribbon_scene = preload("res://common/ui/ribbon/ribbon.tscn") - - -func _ready() -> void: - x_spin_box.min_value = minimum - y_spin_box.min_value = minimum - x_spin_box.max_value = maximum - y_spin_box.max_value = maximum - x_spin_box.step = step - y_spin_box.step = step - - -func set_label_text(text: String) -> void: - label.text = text - - -func propagate(value: Variant) -> void: - super.propagate(value) - x_spin_box.value = value[0] if (value[0] is float or value[0] is int) else 0 - y_spin_box.value = value[1] if (value[1] is float or value[1] is int) else 0 - - -func _on_focus_exited() -> void: - _on_spin_box_value_changed() - - -func _on_spin_box_value_changed(_value: float = 0.0) -> void: - field_updated.emit([x_spin_box.value, y_spin_box.value]) diff --git a/common/ui/fields/vector/monologue_vector.gd.uid b/common/ui/fields/vector/monologue_vector.gd.uid deleted file mode 100644 index 8d95749d..00000000 --- a/common/ui/fields/vector/monologue_vector.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://37empx7gweoa diff --git a/common/ui/fields/vector/monologue_vector.tscn b/common/ui/fields/vector/monologue_vector.tscn deleted file mode 100644 index b7f17d93..00000000 --- a/common/ui/fields/vector/monologue_vector.tscn +++ /dev/null @@ -1,47 +0,0 @@ -[gd_scene load_steps=4 format=3 uid="uid://5ciquxsl5tw5"] - -[ext_resource type="Script" uid="uid://37empx7gweoa" path="res://common/ui/fields/vector/monologue_vector.gd" id="1_qpl0j"] -[ext_resource type="PackedScene" uid="uid://x0daq5tsejey" path="res://common/ui/fields/field_label.tscn" id="2_8olwg"] -[ext_resource type="PackedScene" uid="uid://wiapsnoaoc44" path="res://common/ui/custom_spinbox/custom_spinbox.tscn" id="2_034ks"] - -[node name="MonologueVector" type="HBoxContainer"] -offset_right = 282.0 -offset_bottom = 29.0 -script = ExtResource("1_qpl0j") - -[node name="FieldLabel" parent="." instance=ExtResource("2_8olwg")] -layout_mode = 2 - -[node name="HBoxContainer" type="HBoxContainer" parent="."] -layout_mode = 2 -size_flags_horizontal = 3 - -[node name="HBoxContainer" type="HBoxContainer" parent="HBoxContainer"] -layout_mode = 2 - -[node name="Label" type="Label" parent="HBoxContainer/HBoxContainer"] -layout_mode = 2 -text = "x" - -[node name="XSpinBox" parent="HBoxContainer/HBoxContainer" instance=ExtResource("2_034ks")] -unique_name_in_owner = true -layout_mode = 2 -suffix = "px" - -[node name="VSeparator" type="VSeparator" parent="HBoxContainer"] -layout_mode = 2 - -[node name="HBoxContainer2" type="HBoxContainer" parent="HBoxContainer"] -layout_mode = 2 - -[node name="Label" type="Label" parent="HBoxContainer/HBoxContainer2"] -layout_mode = 2 -text = "y" - -[node name="YSpinBox" parent="HBoxContainer/HBoxContainer2" instance=ExtResource("2_034ks")] -unique_name_in_owner = true -layout_mode = 2 -suffix = "px" - -[connection signal="value_changed" from="HBoxContainer/HBoxContainer/XSpinBox" to="." method="_on_spin_box_value_changed"] -[connection signal="value_changed" from="HBoxContainer/HBoxContainer2/YSpinBox" to="." method="_on_spin_box_value_changed"] diff --git a/common/windows/file_dialog/file_dialog.gd b/common/windows/file_dialog/file_dialog.gd index 6de2b963..26b4ba31 100644 --- a/common/windows/file_dialog/file_dialog.gd +++ b/common/windows/file_dialog/file_dialog.gd @@ -9,6 +9,12 @@ func _ready(): GlobalSignal.add_listener("open_files_request", _on_open_files_request) +func save_file( + callback: Callable, filter_list: PackedStringArray = [], root_subdir: String = "" +) -> void: + _on_save_file_request(callback, filter_list, root_subdir) + + func _on_save_file_request( callable: Callable, filter_list: PackedStringArray = [], root_subdir: String = "" ) -> void: @@ -40,11 +46,12 @@ func _on_open_files_request( _core_request(callable, filter_list, root_subdir) -func _core_request(callable: Callable, filter_list: PackedStringArray = [], - root_subdir: String = "") -> void: +func _core_request( + callable: Callable, filter_list: PackedStringArray = [], root_subdir: String = "" +) -> void: if not root_subdir.ends_with(Path.get_separator()): root_subdir += Path.get_separator() - + _callback = callable filters = filter_list current_path = root_subdir diff --git a/common/windows/graph_node_picker/graph_node_picker.gd b/common/windows/graph_node_picker/graph_node_picker.gd index f54a5215..326115de 100644 --- a/common/windows/graph_node_picker/graph_node_picker.gd +++ b/common/windows/graph_node_picker/graph_node_picker.gd @@ -1,9 +1,6 @@ class_name GraphNodePicker extends Window -## Reference to the tab switcher so that the picker knows which tab it is in. -@export var switcher: GraphEditSwitcher - -@onready var dimmer := $"../Dimmer" +@onready var node_tree := %Tree ## The node in which the picker was spawned/dragged from. var from_node: String @@ -24,25 +21,27 @@ func _ready(): func _on_enable_picker_mode( - node: String = "", port: int = -1, mouse_pos = null, graph_release_pos = null, center_pos = null, center_window: bool = false + node: String = "", + port: int = -1, + mouse_pos = null, + graph_release_pos = null, + center_pos = null, + center_window: bool = false ): - if switcher.current.file_path and (not dimmer or not dimmer.visible): - from_node = node - from_port = port - release = mouse_pos - graph_release = graph_release_pos - center = center_pos - - if from_node != "": - position = Vector2i(release) + get_tree().get_root().position - else: - var mouse_position = Vector2i(get_parent().get_global_mouse_position()) - position = get_tree().get_root().position + mouse_position - current_screen = get_tree().get_root().current_screen - show() - - if center_window: - move_to_center() + open_for_node(node, port, mouse_pos, graph_release_pos, center_pos, center_window) + + +# +#if from_node != "": +#position = Vector2i(release) + get_tree().get_root().position +#else: +#var mouse_position = Vector2i(get_parent().get_global_mouse_position()) +#position = get_tree().get_root().position + mouse_position +#current_screen = get_tree().get_root().current_screen +#show() +# +#if center_window: +#move_to_center() func close() -> void: @@ -57,6 +56,35 @@ func flush() -> void: center = null +func open_for_node( + node: String = "", + port: int = -1, + mouse_pos = null, + graph_release_pos = null, + center_pos = null, + _center_window: bool = false +) -> void: + flush() + from_node = node + from_port = port + release = mouse_pos + graph_release = graph_release_pos + center = center_pos + + if node_tree: + node_tree.reload_tree() + node_tree.grab_focus() + + popup() + move_to_center() + + var root_window := get_tree().get_root() + if root_window: + current_screen = root_window.current_screen + + grab_focus() + + func _on_close_requested() -> void: close() @@ -66,7 +94,8 @@ func _on_cancel_button_pressed() -> void: func _on_create_button_pressed() -> void: - close() + if node_tree.create_selected_descriptor(): + close() func _on_visibility_changed() -> void: diff --git a/common/windows/graph_node_picker/graph_node_picker.tscn b/common/windows/graph_node_picker/graph_node_picker.tscn index 1e3d505d..8657d003 100644 --- a/common/windows/graph_node_picker/graph_node_picker.tscn +++ b/common/windows/graph_node_picker/graph_node_picker.tscn @@ -5,6 +5,7 @@ [node name="GraphNodePicker" type="Window"] auto_translate_mode = 1 +oversampling_override = 1.0 title = "Create Graph Node" position = Vector2i(0, 36) size = Vector2i(345, 425) @@ -36,6 +37,7 @@ layout_mode = 2 placeholder_text = "Search" [node name="Tree" type="Tree" parent="PanelContainer/VBoxContainer"] +unique_name_in_owner = true layout_mode = 2 size_flags_vertical = 3 hide_root = true diff --git a/common/windows/graph_node_picker/graph_node_tree.gd b/common/windows/graph_node_picker/graph_node_tree.gd index 7544a5a9..6743b8bf 100644 --- a/common/windows/graph_node_picker/graph_node_tree.gd +++ b/common/windows/graph_node_picker/graph_node_tree.gd @@ -1,99 +1,86 @@ +class_name GraphNodeTree extends Tree @onready var create_btn: Button = %CreateButton @onready var window: GraphNodePicker = $"../../.." -## The data to build the tree -## An oject can contain keys with name "text", "value", icon" and "children". -var _data = [ - { - "text": "Narration", - "children": - [ - {"text": "Sentence", "icon": "text.svg"}, - {"text": "Choice", "icon": "choice.svg"}, - ] - }, - { - "text": "Logic", - "children": - [ - {"text": "Action", "icon": "action.svg"}, - {"text": "Condition", "icon": "condition.svg"}, - {"text": "Random", "icon": "dice.svg"}, - {"text": "Setter", "icon": "toggle.svg"}, - ] - }, - { - "text": "Flow", - "children": - [ - {"text": "Event", "icon": "calendar.svg"}, - {"text": "Bridge", "icon": "link.svg"}, - {"text": "EndPath", "icon": "exit.svg"}, - {"text": "Wait", "icon": "time.svg"}, - ] - }, - { - "text": "Audio and Visuals", - "children": - [ - {"text": "Audio", "icon": "recording.svg"}, - {"text": "Background", "icon": "picture.svg"}, - {"text": "Character", "icon": "character.svg"}, - ] - }, - { - "text": "Helpers", - "children": - [ - {"text": "Comment", "icon": "comment.svg"}, - {"text": "Reroute", "icon": "path.svg"}, - ] - } -] - var _first_item_found: bool = false -# Called when the node enters the scene tree for the first time. func _ready() -> void: - var root = create_item() - _recusive_load_data(_data, root) + reload_tree() + + +func reload_tree() -> void: + clear() + _first_item_found = false + var root := create_item() + create_btn.disabled = true + + var categories: PackedStringArray = NodeBucket.get_categories() + if categories.is_empty(): + _add_placeholder(root, "No nodes available") + return + + for category in categories: + var category_item := create_item(root) + category_item.set_text(0, category) + category_item.collapsed = true + category_item.set_selectable(0, false) + var descriptors: Array = NodeBucket.get_descriptors_by_category(category) + for descriptor in descriptors: + _create_descriptor_item(category_item, descriptor) + deselect_all() -func _recusive_load_data(items: Array, tree_parent: TreeItem) -> void: - for obj: Dictionary in items: - var tree_item = create_item(tree_parent) - tree_item.collapsed = true +func _add_placeholder(parent: TreeItem, text: String) -> void: + var placeholder := create_item(parent) + placeholder.set_text(0, text) + placeholder.set_selectable(0, false) - if obj.has("text"): - tree_item.set_text(0, obj.get("text")) - if obj.has("icon"): - var icon_texture = load("res://ui/assets/icons/" + obj.get("icon")) - tree_item.set_icon(0, icon_texture) - if obj.has("children"): - _recusive_load_data(obj.get("children"), tree_item) +func _create_descriptor_item(parent: TreeItem, descriptor) -> void: + var item := create_item(parent) + item.set_text(0, descriptor.display_name) + if descriptor.icon: + item.set_icon(0, descriptor.icon) + item.set_metadata(0, descriptor.name) -func _create() -> void: - var node_type = get_selected().get_text(0) - GlobalSignal.emit("add_graph_node", [node_type, window]) + +func _create() -> bool: + var selected := get_selected() + if selected == null: + return false + var descriptor_name = selected.get_metadata(0) + if descriptor_name == null: + return false + GlobalSignal.emit("add_graph_node", [String(descriptor_name), window]) + deselect_all() + return true + + +func create_selected_descriptor() -> bool: + return _create() func _on_item_activated() -> void: var item: TreeItem = get_selected() + if item == null: + return if item.get_child_count() > 0: item.collapsed = !item.collapsed - else: - _create() + return + if _create(): window.close() func _on_item_selected() -> void: var item: TreeItem = get_selected() - create_btn.disabled = item.get_child_count() > 0 + if item == null: + create_btn.disabled = true + return + create_btn.disabled = item.get_metadata(0) == null func _on_search_bar_text_changed(new_text: String) -> void: diff --git a/common/windows/prompt_window/prompt_window.tscn b/common/windows/prompt_window/prompt_window.tscn index b0e7177b..2e27a423 100644 --- a/common/windows/prompt_window/prompt_window.tscn +++ b/common/windows/prompt_window/prompt_window.tscn @@ -6,7 +6,7 @@ [node name="PromptWindow" type="Window"] transparent_bg = true initial_position = 2 -size = Vector2i(650, 206) +size = Vector2i(798, 226) wrap_controls = true unresizable = true borderless = true @@ -16,38 +16,50 @@ popup_window = true script = ExtResource("1_u0ucq") [node name="PanelContainer" type="PanelContainer" parent="."] -anchors_preset = -1 -anchor_right = 1.0 -anchor_bottom = 0.903 -offset_bottom = -0.0180054 +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -331.5 +offset_top = -73.0 +offset_right = 331.5 +offset_bottom = 73.0 grow_horizontal = 2 grow_vertical = 2 size_flags_horizontal = 3 size_flags_vertical = 3 theme_type_variation = &"OuterPanel" -[node name="HBox" type="HBoxContainer" parent="PanelContainer"] +[node name="MarginContainer" type="MarginContainer" parent="PanelContainer"] layout_mode = 2 -theme_type_variation = &"HBoxContainer_Big" +theme_override_constants/margin_left = 25 +theme_override_constants/margin_top = 25 +theme_override_constants/margin_right = 25 +theme_override_constants/margin_bottom = 25 + +[node name="HBox" type="HBoxContainer" parent="PanelContainer/MarginContainer"] +layout_mode = 2 +theme_override_constants/separation = 25 -[node name="TextureRect" type="TextureRect" parent="PanelContainer/HBox"] +[node name="TextureRect" type="TextureRect" parent="PanelContainer/MarginContainer/HBox"] custom_minimum_size = Vector2(80, 0) layout_mode = 2 texture = ExtResource("2_kx1ym") expand_mode = 1 stretch_mode = 5 -[node name="VBox" type="VBoxContainer" parent="PanelContainer/HBox"] +[node name="VBox" type="VBoxContainer" parent="PanelContainer/MarginContainer/HBox"] layout_mode = 2 size_flags_horizontal = 3 size_flags_vertical = 4 theme_type_variation = &"VBoxContainer_Big" -[node name="LabelHBox" type="VBoxContainer" parent="PanelContainer/HBox/VBox"] +[node name="LabelHBox" type="VBoxContainer" parent="PanelContainer/MarginContainer/HBox/VBox"] layout_mode = 2 theme_type_variation = &"VBoxContainer_Medium" -[node name="TitleLabel" type="Label" parent="PanelContainer/HBox/VBox/LabelHBox"] +[node name="TitleLabel" type="Label" parent="PanelContainer/MarginContainer/HBox/VBox/LabelHBox"] unique_name_in_owner = true layout_mode = 2 theme_type_variation = &"HeaderSmall" @@ -55,37 +67,37 @@ text = "Save changes?" clip_text = true text_overrun_behavior = 2 -[node name="DescriptionLabel" type="Label" parent="PanelContainer/HBox/VBox/LabelHBox"] +[node name="DescriptionLabel" type="Label" parent="PanelContainer/MarginContainer/HBox/VBox/LabelHBox"] unique_name_in_owner = true custom_minimum_size = Vector2(500, 75) layout_mode = 2 -theme_type_variation = &"Label_Secondary" +theme_type_variation = &"NoteLabel" text = "The document you have opened will be closed. Do you want to save the changes?" autowrap_mode = 3 -[node name="HBox" type="HBoxContainer" parent="PanelContainer/HBox/VBox"] +[node name="HBox" type="HBoxContainer" parent="PanelContainer/MarginContainer/HBox/VBox"] layout_mode = 2 theme_type_variation = &"HBoxContainer_Big" -[node name="ConfirmButton" type="Button" parent="PanelContainer/HBox/VBox/HBox"] +[node name="ConfirmButton" type="Button" parent="PanelContainer/MarginContainer/HBox/VBox/HBox"] unique_name_in_owner = true custom_minimum_size = Vector2(125, 0) layout_mode = 2 text = "Yes" -[node name="DenyButton" type="Button" parent="PanelContainer/HBox/VBox/HBox"] +[node name="DenyButton" type="Button" parent="PanelContainer/MarginContainer/HBox/VBox/HBox"] unique_name_in_owner = true custom_minimum_size = Vector2(125, 0) layout_mode = 2 text = "No" -[node name="CancelButton" type="Button" parent="PanelContainer/HBox/VBox/HBox"] +[node name="CancelButton" type="Button" parent="PanelContainer/MarginContainer/HBox/VBox/HBox"] unique_name_in_owner = true custom_minimum_size = Vector2(125, 0) layout_mode = 2 text = "Cancel" [connection signal="tree_exited" from="." to="." method="_on_tree_exited"] -[connection signal="pressed" from="PanelContainer/HBox/VBox/HBox/ConfirmButton" to="." method="_on_confirm_button_pressed"] -[connection signal="pressed" from="PanelContainer/HBox/VBox/HBox/DenyButton" to="." method="_on_deny_button_pressed"] -[connection signal="pressed" from="PanelContainer/HBox/VBox/HBox/CancelButton" to="." method="_on_cancel_button_pressed"] +[connection signal="pressed" from="PanelContainer/MarginContainer/HBox/VBox/HBox/ConfirmButton" to="." method="_on_confirm_button_pressed"] +[connection signal="pressed" from="PanelContainer/MarginContainer/HBox/VBox/HBox/DenyButton" to="." method="_on_deny_button_pressed"] +[connection signal="pressed" from="PanelContainer/MarginContainer/HBox/VBox/HBox/CancelButton" to="." method="_on_cancel_button_pressed"] diff --git a/common/windows/welcome_window/welcome_window.tscn b/common/windows/welcome_window/welcome_window.tscn index 7a4bc96d..d6798cad 100644 --- a/common/windows/welcome_window/welcome_window.tscn +++ b/common/windows/welcome_window/welcome_window.tscn @@ -11,7 +11,7 @@ auto_translate_mode = 1 transparent_bg = true initial_position = 2 -size = Vector2i(450, 297) +size = Vector2i(1000, 300) wrap_controls = true transient = true transient_to_focused = true @@ -26,13 +26,12 @@ script = ExtResource("1_hscvo") [node name="PanelContainer" type="PanelContainer" parent="."] clip_children = 2 -anchors_preset = 15 -anchor_right = 1.0 +custom_minimum_size = Vector2(400, 300) +anchors_preset = -1 +anchor_right = 0.4 anchor_bottom = 1.0 -grow_horizontal = 2 -grow_vertical = 2 -size_flags_horizontal = 3 -size_flags_vertical = 3 +size_flags_horizontal = 4 +size_flags_vertical = 0 theme_type_variation = &"OuterPanel" [node name="MarginContainer" type="MarginContainer" parent="PanelContainer"] @@ -42,8 +41,14 @@ layout_mode = 2 layout_mode = 2 theme_type_variation = &"VBoxContainer_Medium" -[node name="TextureRect" type="TextureRect" parent="PanelContainer/MarginContainer/VBoxContainer"] -custom_minimum_size = Vector2(0, 100) +[node name="MarginContainer" type="MarginContainer" parent="PanelContainer/MarginContainer/VBoxContainer"] +layout_mode = 2 +theme_override_constants/margin_left = 20 +theme_override_constants/margin_top = 20 +theme_override_constants/margin_right = 20 +theme_override_constants/margin_bottom = 20 + +[node name="TextureRect" type="TextureRect" parent="PanelContainer/MarginContainer/VBoxContainer/MarginContainer"] layout_mode = 2 texture = ExtResource("2_ked33") expand_mode = 5 diff --git a/icon.png b/icon.png index d4d10e60..09575b08 100644 Binary files a/icon.png and b/icon.png differ diff --git a/icon.png.import b/icon.png.import index 72ba513e..c61637da 100644 --- a/icon.png.import +++ b/icon.png.import @@ -2,7 +2,7 @@ importer="texture" type="CompressedTexture2D" -uid="uid://c1tt7cwyc3s5u" +uid="uid://b2ebpoey21tpc" path="res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.ctex" metadata={ "vram_texture": false @@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.cte compress/mode=0 compress/high_quality=false compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 compress/hdr_compression=1 compress/normal_map=0 compress/channel_pack=0 @@ -25,6 +27,10 @@ mipmaps/generate=false mipmaps/limit=-1 roughness/mode=0 roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 process/fix_alpha_border=true process/premult_alpha=false process/normal_map_invert_y=false diff --git a/icon_min.png.import b/icon_min.png.import index 105d800f..cd6665c2 100644 --- a/icon_min.png.import +++ b/icon_min.png.import @@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/icon_min.png-d31382ea5491ba6cb1c00baeef6393a0 compress/mode=0 compress/high_quality=false compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 compress/hdr_compression=1 compress/normal_map=0 compress/channel_pack=0 @@ -25,6 +27,10 @@ mipmaps/generate=false mipmaps/limit=-1 roughness/mode=0 roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 process/fix_alpha_border=true process/premult_alpha=false process/normal_map_invert_y=false diff --git a/icon_transparent.png b/icon_transparent.png new file mode 100644 index 00000000..0545feba Binary files /dev/null and b/icon_transparent.png differ diff --git a/addons/gdUnit4/src/reporters/html/template/css/logo.png.import b/icon_transparent.png.import similarity index 55% rename from addons/gdUnit4/src/reporters/html/template/css/logo.png.import rename to icon_transparent.png.import index 95c30a28..42981b8c 100644 --- a/addons/gdUnit4/src/reporters/html/template/css/logo.png.import +++ b/icon_transparent.png.import @@ -2,22 +2,24 @@ importer="texture" type="CompressedTexture2D" -uid="uid://2n0cbwv2t23g" -path="res://.godot/imported/logo.png-d555ca92b260de08658ae2e1d4572e8c.ctex" +uid="uid://bou7qelcr5dwn" +path="res://.godot/imported/icon_transparent.png-574b1e7a19305c536c473b5d16827b4d.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://addons/gdUnit4/src/reporters/html/template/css/logo.png" -dest_files=["res://.godot/imported/logo.png-d555ca92b260de08658ae2e1d4572e8c.ctex"] +source_file="res://icon_transparent.png" +dest_files=["res://.godot/imported/icon_transparent.png-574b1e7a19305c536c473b5d16827b4d.ctex"] [params] compress/mode=0 compress/high_quality=false compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 compress/hdr_compression=1 compress/normal_map=0 compress/channel_pack=0 @@ -25,6 +27,10 @@ mipmaps/generate=false mipmaps/limit=-1 roughness/mode=0 roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 process/fix_alpha_border=true process/premult_alpha=false process/normal_map_invert_y=false diff --git a/logic/history/add_nodes_command.gd b/logic/history/add_nodes_command.gd new file mode 100644 index 00000000..0ed13bb2 --- /dev/null +++ b/logic/history/add_nodes_command.gd @@ -0,0 +1,34 @@ +class_name AddNodesCommand extends Command + +var storyline_id: String +var nodes: Array = [] + + +func _init( + p_storyline_id: String, + p_nodes: Array, +) -> void: + storyline_id = p_storyline_id + nodes = p_nodes + + +func execute() -> void: + var storyline: StorylineDocument = StorylineManager.get_storyline(storyline_id) + if not storyline: + return + + for node in nodes: + storyline.add_node(node) + + +func undo() -> void: + var storyline: StorylineDocument = StorylineManager.get_storyline(storyline_id) + if not storyline: + return + + for node in nodes: + storyline.remove_node(node) + + +func get_description() -> String: + return "Add %s nodes" % nodes.size() diff --git a/logic/history/add_nodes_command.gd.uid b/logic/history/add_nodes_command.gd.uid new file mode 100644 index 00000000..b6349ff5 --- /dev/null +++ b/logic/history/add_nodes_command.gd.uid @@ -0,0 +1 @@ +uid://1br7o001ta7f diff --git a/logic/history/command.gd b/logic/history/command.gd new file mode 100644 index 00000000..7746633d --- /dev/null +++ b/logic/history/command.gd @@ -0,0 +1,6 @@ +@abstract +class_name Command extends RefCounted + +@abstract func execute() +@abstract func undo() +@abstract func get_description() -> String diff --git a/logic/history/command.gd.uid b/logic/history/command.gd.uid new file mode 100644 index 00000000..00111e41 --- /dev/null +++ b/logic/history/command.gd.uid @@ -0,0 +1 @@ +uid://dxrwkktseecun diff --git a/logic/history/command_manager.gd b/logic/history/command_manager.gd new file mode 100644 index 00000000..e1489dfd --- /dev/null +++ b/logic/history/command_manager.gd @@ -0,0 +1,102 @@ +class_name CommandManager extends RefCounted + +var undo_redo: UndoRedo + +signal command_executed +signal undone +signal redone +signal history_changed + + +func _init(max_history: int = 200) -> void: + undo_redo = UndoRedo.new() + undo_redo.max_steps = max_history + undo_redo.version_changed.connect(_on_version_changed) + + +func execute(command: Command, merge_mode: UndoRedo.MergeMode = UndoRedo.MERGE_ENDS) -> void: + var description = command.get_description() + undo_redo.create_action(description, merge_mode) + undo_redo.add_do_method(command.execute.bind()) + undo_redo.add_undo_method(command.undo.bind()) + undo_redo.add_do_reference(command) + undo_redo.add_undo_reference(command) + + undo_redo.commit_action() + + command_executed.emit() + history_changed.emit() + + +func undo() -> bool: + if not can_undo(): + return false + + undo_redo.undo() + undone.emit() + history_changed.emit() + return true + + +func redo() -> bool: + if not can_redo(): + return false + + undo_redo.redo() + redone.emit() + history_changed.emit() + return true + + +func can_undo() -> bool: + return undo_redo.has_undo() + + +func can_redo() -> bool: + return undo_redo.has_redo() + + +func get_undo_description() -> String: + if not can_undo(): + return "" + return undo_redo.get_action_name(undo_redo.get_version() - 1) + + +func get_redo_description() -> String: + if not can_redo(): + return "" + return undo_redo.get_action_name(undo_redo.get_version()) + + +func clear(): + undo_redo.clear_history() + history_changed.emit() + + +func get_version() -> int: + return undo_redo.get_version() + + +func get_history_count() -> int: + return undo_redo.get_history_count() + + +func _on_version_changed(): + history_changed.emit() + + +func begin_group(description: String = "Group"): + undo_redo.create_action(description, UndoRedo.MERGE_DISABLE) + + +func add_to_group(command: Command): + undo_redo.add_do_method(command.execute.bind()) + undo_redo.add_undo_method(command.undo.bind()) + undo_redo.add_do_reference(command) + undo_redo.add_undo_reference(command) + + +func end_group(): + undo_redo.commit_action() + command_executed.emit() + history_changed.emit() diff --git a/logic/history/command_manager.gd.uid b/logic/history/command_manager.gd.uid new file mode 100644 index 00000000..948b9434 --- /dev/null +++ b/logic/history/command_manager.gd.uid @@ -0,0 +1 @@ +uid://dwxg4gbtegie1 diff --git a/logic/history/delete_nodes_command.gd b/logic/history/delete_nodes_command.gd new file mode 100644 index 00000000..90b5886f --- /dev/null +++ b/logic/history/delete_nodes_command.gd @@ -0,0 +1,13 @@ +class_name DeleteNodesCommand extends AddNodesCommand + + +func execute() -> void: + super.undo() + + +func undo() -> void: + super.execute() + + +func get_description() -> String: + return "Delete %s nodes" % nodes.size() diff --git a/logic/history/delete_nodes_command.gd.uid b/logic/history/delete_nodes_command.gd.uid new file mode 100644 index 00000000..2b244e3a --- /dev/null +++ b/logic/history/delete_nodes_command.gd.uid @@ -0,0 +1 @@ +uid://bi0nf2bllnil5 diff --git a/logic/history/node_connection_command.gd b/logic/history/node_connection_command.gd new file mode 100644 index 00000000..0be3bda8 --- /dev/null +++ b/logic/history/node_connection_command.gd @@ -0,0 +1,98 @@ +class_name NodeConnectionCommand extends Command + +var graph_view: MonologueGraphEdit +var from_node_id: String +var to_node_id: String +var from_property_name: String +var to_property_name: String +var disconnect_node: bool + + +func _init( + n_graph_view: MonologueGraphEdit, + n_from_node_id: String, + n_to_node_id: String, + n_from_property_name: String, + n_to_property_name: String, + n_disconnect: bool = false +) -> void: + graph_view = n_graph_view + from_node_id = n_from_node_id + to_node_id = n_to_node_id + from_property_name = n_from_property_name + to_property_name = n_to_property_name + disconnect_node = n_disconnect + + +func execute() -> void: + # Recalculate port indices in case they changed + var from_port = graph_view.get_port_index_for_property(from_node_id, from_property_name) + var to_port = graph_view.get_port_index_for_property(to_node_id, to_property_name) + + if disconnect_node: + if graph_view.connection_manager: + graph_view.connection_manager.unregister_connection( + from_node_id, from_port, to_node_id, to_port + ) + + if from_port >= 0 and to_port >= 0: + graph_view.disconnect_node(from_node_id, from_port, to_node_id, to_port) + else: + if graph_view.connection_manager: + graph_view.connection_manager.register_connection_by_property( + from_node_id, from_property_name, to_node_id, to_property_name + ) + + if from_port >= 0 and to_port >= 0: + graph_view.connect_node(from_node_id, from_port, to_node_id, to_port) + + _notify_node_changes() + + +func undo() -> void: + # Recalculate port indices in case they changed + var from_port = graph_view.get_port_index_for_property(from_node_id, from_property_name) + var to_port = graph_view.get_port_index_for_property(to_node_id, to_property_name) + + if not disconnect_node: + if graph_view.connection_manager: + graph_view.connection_manager.unregister_connection( + from_node_id, from_port, to_node_id, to_port + ) + + if from_port >= 0 and to_port >= 0: + graph_view.disconnect_node(from_node_id, from_port, to_node_id, to_port) + else: + if graph_view.connection_manager: + graph_view.connection_manager.register_connection_by_property( + from_node_id, from_property_name, to_node_id, to_property_name + ) + + if from_port >= 0 and to_port >= 0: + graph_view.connect_node(from_node_id, from_port, to_node_id, to_port) + + _notify_node_changes() + + +func _notify_node_changes() -> void: + var storyline: StorylineDocument = StorylineManager.get_storyline(graph_view.storyline_id) + var from_nodes: Array = storyline.nodes.filter( + func(n: InspectableNode) -> bool: return n.get_property_value("id") == from_node_id + ) + var to_nodes: Array = storyline.nodes.filter( + func(n: InspectableNode) -> bool: return n.get_property_value("id") == to_node_id + ) + + if not from_nodes.is_empty(): + var from_node: InspectableNode = from_nodes[0] + from_node._notify_change(from_node_id) + + if not to_nodes.is_empty(): + var to_node: InspectableNode = to_nodes[0] + to_node._notify_change(to_property_name) + + +func get_description() -> String: + return ( + "Connect %s.%s to %s.%s" % [from_node_id, from_property_name, to_node_id, to_property_name] + ) diff --git a/logic/history/node_connection_command.gd.uid b/logic/history/node_connection_command.gd.uid new file mode 100644 index 00000000..6e475902 --- /dev/null +++ b/logic/history/node_connection_command.gd.uid @@ -0,0 +1 @@ +uid://7kht5ybdplta diff --git a/logic/history/node_selection_command.gd b/logic/history/node_selection_command.gd new file mode 100644 index 00000000..b51f9394 --- /dev/null +++ b/logic/history/node_selection_command.gd @@ -0,0 +1,44 @@ +class_name NodeSelectionCommand extends Command + +var storyline_id: String +var previous_node: InspectableNode +var next_node: InspectableNode +var apply_callable: Callable + + +func _init( + p_storyline_id: String, + p_previous_node: InspectableNode, + p_next_node: InspectableNode, + p_apply_callable: Callable +) -> void: + storyline_id = p_storyline_id + previous_node = p_previous_node + next_node = p_next_node + apply_callable = p_apply_callable + + +func execute() -> void: + _apply_selection(next_node) + + +func undo() -> void: + _apply_selection(previous_node) + + +func get_description() -> String: + var target_id := "" + if next_node: + var id_property := next_node.get_property("id") + if id_property: + target_id = String(id_property.get_value()) + if target_id.is_empty(): + return "Change selection" + return "Select node %s" % target_id + + +func _apply_selection(target: InspectableNode) -> void: + if not apply_callable.is_valid(): + return + + apply_callable.call(target, storyline_id) diff --git a/logic/history/node_selection_command.gd.uid b/logic/history/node_selection_command.gd.uid new file mode 100644 index 00000000..87551d7f --- /dev/null +++ b/logic/history/node_selection_command.gd.uid @@ -0,0 +1 @@ +uid://eghqtautsvc2 diff --git a/logic/history/property_command.gd b/logic/history/property_command.gd new file mode 100644 index 00000000..b4a73c6f --- /dev/null +++ b/logic/history/property_command.gd @@ -0,0 +1,49 @@ +class_name PropertyChangeCommand extends Command + +var target: InspectableObject +var property_name: String +var old_value: Variant +var new_value: Variant + + +func _init(p_target: InspectableObject, p_property: String, p_old: Variant, p_new: Variant) -> void: + target = p_target + property_name = p_property + old_value = p_old + new_value = p_new + + +func execute() -> void: + var property: Property = target.get_property(property_name) + property.set_value(new_value) + target._notify_change(property_name) + _broadcast_change() + + +func undo() -> void: + var property: Property = target.get_property(property_name) + property.set_value(old_value) + target._notify_change(property_name) + _broadcast_change(true) + + +func get_description() -> String: + return "Change value of `%s` property" % property_name + + +func _broadcast_change(is_undo: bool = false) -> void: + if not (target is InspectableNode): + return + + var node := target as InspectableNode + var property: Property = node.get_property(property_name) + if not property: + return + + if target is InspectableNode and property_name == "position": + GlobalSignal.emit("request_node_inspection", [node, node.storyline_id, true]) + + if not property.get_settings_value("visible_in_inspector", true): + return + + GlobalSignal.emit("inspector_property_changed", [node, property_name, is_undo]) diff --git a/logic/history/property_command.gd.uid b/logic/history/property_command.gd.uid new file mode 100644 index 00000000..57f949eb --- /dev/null +++ b/logic/history/property_command.gd.uid @@ -0,0 +1 @@ +uid://dmv35lufxhghw diff --git a/logic/history/property_settings_command.gd b/logic/history/property_settings_command.gd new file mode 100644 index 00000000..d80f1021 --- /dev/null +++ b/logic/history/property_settings_command.gd @@ -0,0 +1,80 @@ +class_name PropertySettingsChangeCommand extends Command + +var target: InspectableObject +var property_name: String +var settings_name: String +var old_value: Variant +var new_value: Variant + + +func _init( + p_target: InspectableObject, + p_property: String, + p_settings_name: String, + p_old: Variant, + p_new: Variant, +) -> void: + target = p_target + property_name = p_property + settings_name = p_settings_name + old_value = p_old + new_value = p_new + + +func execute() -> void: + var property: Property = target.get_property(property_name) + property.settings[settings_name] = new_value + _handle_connection_visibility(new_value) + target._notify_change(property_name) + property.refresh_bindings() + #target._notify_property_settings_change(property_name, settings_name, old_value, new_value) + + +func undo() -> void: + var property: Property = target.get_property(property_name) + if old_value: + property.settings[settings_name] = old_value + else: + property.settings.erase(settings_name) + _handle_connection_visibility(old_value) + target._notify_change(property_name) + property.refresh_bindings() + #target._notify_property_settings_change(property_name, settings_name, new_value, old_value) + + +func get_description() -> String: + return "Change settings of `%s` property" % property_name + + +func _handle_connection_visibility(setting_value: Variant) -> void: + if settings_name not in ["exposed", "export"]: + return + var node = _get_target_node() + if not node: + return + var graph_view = node.graph_view + if not graph_view: + return + var graph_edit = graph_view.get_parent() + if not (graph_edit is MonologueGraphEdit): + return + var manager: ConnectionManager = graph_edit.connection_manager + if not manager: + return + var node_name: String = graph_view.name + if settings_name == "exposed": + if setting_value: + manager.restore_incoming_property_connections(node_name, property_name) + return + manager.suspend_incoming_property_connections(node_name, property_name) + else: + if setting_value: + manager.restore_outgoing_property_connections(node_name, property_name) + return + manager.suspend_outgoing_property_connections(node_name, property_name) + + +func _get_target_node(): + if target is InspectableNode: + return target + return null diff --git a/logic/history/property_settings_command.gd.uid b/logic/history/property_settings_command.gd.uid new file mode 100644 index 00000000..4201c437 --- /dev/null +++ b/logic/history/property_settings_command.gd.uid @@ -0,0 +1 @@ +uid://dabyel4cj64ff diff --git a/logic/history/add_language_history.gd b/logic/old_history/add_language_history.gd similarity index 100% rename from logic/history/add_language_history.gd rename to logic/old_history/add_language_history.gd diff --git a/logic/history/add_language_history.gd.uid b/logic/old_history/add_language_history.gd.uid similarity index 100% rename from logic/history/add_language_history.gd.uid rename to logic/old_history/add_language_history.gd.uid diff --git a/logic/history/add_node_history.gd b/logic/old_history/add_node_history.gd similarity index 100% rename from logic/history/add_node_history.gd rename to logic/old_history/add_node_history.gd diff --git a/logic/history/add_node_history.gd.uid b/logic/old_history/add_node_history.gd.uid similarity index 100% rename from logic/history/add_node_history.gd.uid rename to logic/old_history/add_node_history.gd.uid diff --git a/logic/history/character_history.gd b/logic/old_history/character_history.gd similarity index 94% rename from logic/history/character_history.gd rename to logic/old_history/character_history.gd index e35bf3d6..bffbe480 100644 --- a/logic/history/character_history.gd +++ b/logic/old_history/character_history.gd @@ -42,4 +42,4 @@ func _hide_unrelated_windows() -> void: func _update_character(property: String, value: Variant) -> void: var key = Util.to_key_name(property) - graph_edit.characters[character_index]["Character"][key] = value + graph_edit.characters.value[character_index]["Character"][key] = value diff --git a/logic/history/character_history.gd.uid b/logic/old_history/character_history.gd.uid similarity index 100% rename from logic/history/character_history.gd.uid rename to logic/old_history/character_history.gd.uid diff --git a/logic/history/delete_language_history.gd b/logic/old_history/delete_language_history.gd similarity index 100% rename from logic/history/delete_language_history.gd rename to logic/old_history/delete_language_history.gd diff --git a/logic/history/delete_language_history.gd.uid b/logic/old_history/delete_language_history.gd.uid similarity index 100% rename from logic/history/delete_language_history.gd.uid rename to logic/old_history/delete_language_history.gd.uid diff --git a/logic/history/delete_node_history.gd b/logic/old_history/delete_node_history.gd similarity index 100% rename from logic/history/delete_node_history.gd rename to logic/old_history/delete_node_history.gd diff --git a/logic/history/delete_node_history.gd.uid b/logic/old_history/delete_node_history.gd.uid similarity index 100% rename from logic/history/delete_node_history.gd.uid rename to logic/old_history/delete_node_history.gd.uid diff --git a/logic/history/history_handle.gd b/logic/old_history/history_handle.gd similarity index 100% rename from logic/history/history_handle.gd rename to logic/old_history/history_handle.gd diff --git a/logic/history/history_handle.gd.uid b/logic/old_history/history_handle.gd.uid similarity index 100% rename from logic/history/history_handle.gd.uid rename to logic/old_history/history_handle.gd.uid diff --git a/logic/history/language_history.gd b/logic/old_history/language_history.gd similarity index 100% rename from logic/history/language_history.gd rename to logic/old_history/language_history.gd diff --git a/logic/history/language_history.gd.uid b/logic/old_history/language_history.gd.uid similarity index 100% rename from logic/history/language_history.gd.uid rename to logic/old_history/language_history.gd.uid diff --git a/logic/history/modify_language_history.gd b/logic/old_history/modify_language_history.gd similarity index 100% rename from logic/history/modify_language_history.gd rename to logic/old_history/modify_language_history.gd diff --git a/logic/history/modify_language_history.gd.uid b/logic/old_history/modify_language_history.gd.uid similarity index 100% rename from logic/history/modify_language_history.gd.uid rename to logic/old_history/modify_language_history.gd.uid diff --git a/logic/history/monologue_history.gd b/logic/old_history/monologue_history.gd similarity index 100% rename from logic/history/monologue_history.gd rename to logic/old_history/monologue_history.gd diff --git a/logic/history/monologue_history.gd.uid b/logic/old_history/monologue_history.gd.uid similarity index 100% rename from logic/history/monologue_history.gd.uid rename to logic/old_history/monologue_history.gd.uid diff --git a/logic/history/portrait_history.gd b/logic/old_history/portrait_history.gd similarity index 92% rename from logic/history/portrait_history.gd rename to logic/old_history/portrait_history.gd index 65203ae7..8cb572e6 100644 --- a/logic/history/portrait_history.gd +++ b/logic/old_history/portrait_history.gd @@ -27,7 +27,7 @@ func revert_properties() -> void: func set_property(node: Variant, property: String, value: Variant) -> void: super.set_property(node, property, value) - var character_dict = graph_edit.characters[character_index]["Character"] + var character_dict = graph_edit.characters.value[character_index]["Character"] var key = Util.to_key_name(property) character_dict["Portraits"][portrait_index]["Portrait"][key] = value diff --git a/logic/history/portrait_history.gd.uid b/logic/old_history/portrait_history.gd.uid similarity index 100% rename from logic/history/portrait_history.gd.uid rename to logic/old_history/portrait_history.gd.uid diff --git a/logic/history/property_change.gd b/logic/old_history/property_change.gd similarity index 100% rename from logic/history/property_change.gd rename to logic/old_history/property_change.gd diff --git a/logic/history/property_change.gd.uid b/logic/old_history/property_change.gd.uid similarity index 100% rename from logic/history/property_change.gd.uid rename to logic/old_history/property_change.gd.uid diff --git a/logic/history/property_history.gd b/logic/old_history/property_history.gd similarity index 77% rename from logic/history/property_history.gd rename to logic/old_history/property_history.gd index 55e0d293..4d9984f6 100644 --- a/logic/history/property_history.gd +++ b/logic/old_history/property_history.gd @@ -54,16 +54,17 @@ func set_property(node: Variant, property: String, value: Variant) -> void: node[property].value = value -func refresh_properties(node: Variant, language: String) -> void: - var properties: PackedStringArray = [] - if node is MonologueGraphNode: - # if language is the same, we can do partial refresh with given properties - # otherwise, full refresh so other controls can reflect the language change - if locale == language: - properties = changes.map(func(c): return c.property) - else: - properties = changes.map(func(c): return c.property) - GlobalSignal.emit.call_deferred("refresh", [node, properties]) +func refresh_properties(_node: Variant, _language: String) -> void: + pass + #var properties: PackedStringArray = [] + #if node is MonologueGraphNode: + ## if language is the same, we can do partial refresh with given properties + ## otherwise, full refresh so other controls can reflect the language change + #if locale == language: + #properties = changes.map(func(c): return c.property) + #else: + #properties = changes.map(func(c): return c.property) + #GlobalSignal.emit.call_deferred("refresh", [node, properties]) func _hide_unrelated_windows() -> void: diff --git a/logic/history/property_history.gd.uid b/logic/old_history/property_history.gd.uid similarity index 100% rename from logic/history/property_history.gd.uid rename to logic/old_history/property_history.gd.uid diff --git a/nodes/abstract_character/abstract_character.gd b/nodes/abstract_character/abstract_character.gd deleted file mode 100644 index 3f42d28f..00000000 --- a/nodes/abstract_character/abstract_character.gd +++ /dev/null @@ -1,71 +0,0 @@ -## Character data builder. -class_name MonologueCharacter extends RefCounted - -const CHARACTER_FIELD := preload( - "res://common/ui/fields/character_field/monologue_character_field.tscn" -) - -var character := Property.new(CHARACTER_FIELD, {}, {}) -var id := Property.new(MonologueGraphNode.LINE, {}, IDGen.generate()) -var idx := Property.new(MonologueGraphNode.SPINBOX, {}, 0) -var protected := Property.new(MonologueGraphNode.TOGGLE, {}, false) - -var custom_delete_button: - get: - return character.field.delete_button - -var graph: MonologueGraphEdit -var root: RootNode - - -func _init(node: RootNode): - root = node - graph = node.get_parent() - character.connect("change", update_character) - character.connect("display", graph.set_selected.bind(root)) - character.connect("shown", _on_character_field_shown) - character.setters["graph_edit"] = graph - - -func _on_character_field_shown() -> void: - character.field.delete_button.visible = !protected.value - character.field.name_edit.editable = !protected.value - - -func update_character(old_value: Variant, new_value: Variant): - var old_list = root.characters.value.duplicate(true) - var new_list = root.characters.value.duplicate(true) - new_list[idx.value]["Character"] = new_value - - graph.undo_redo.create_action("Character %s => %s" % [str(old_value), str(new_value)]) - graph.undo_redo.add_do_property(root.characters, "value", new_list) - graph.undo_redo.add_do_method(root.characters.propagate.bind(new_list)) - graph.undo_redo.add_do_method(graph.set_selected.bind(root)) - graph.undo_redo.add_do_method(GlobalSignal.emit.bind("close_character_edit")) - graph.undo_redo.add_undo_property(root.characters, "value", old_list) - graph.undo_redo.add_undo_method(root.characters.propagate.bind(old_list)) - graph.undo_redo.add_undo_method(graph.set_selected.bind(root)) - graph.undo_redo.add_undo_method(GlobalSignal.emit.bind("close_character_edit")) - graph.undo_redo.commit_action() - - -func get_property_names() -> PackedStringArray: - return ["character"] - - -func _from_dict(dict: Dictionary) -> void: - if dict.get("ID") is String: - id.value = dict.get("ID") - character.value = dict.get("Character") - protected.value = dict.get("Protected") - idx.value = dict.get("EditorIndex") - character.setters["character_index"] = idx.value - - -func _to_dict(): - return { - "ID": id.value, - "Protected": protected.value, - "Character": character.value, - "EditorIndex": idx.value - } diff --git a/nodes/abstract_character/abstract_character.gd.uid b/nodes/abstract_character/abstract_character.gd.uid deleted file mode 100644 index 3a5330ce..00000000 --- a/nodes/abstract_character/abstract_character.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://bwg2j62ue4e3v diff --git a/nodes/abstract_character/asbtract_character.gd.uid b/nodes/abstract_character/asbtract_character.gd.uid deleted file mode 100644 index 31adf8f8..00000000 --- a/nodes/abstract_character/asbtract_character.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://bhg4nsmhomi15 diff --git a/nodes/abstract_variable/abstract_variable.gd b/nodes/abstract_variable/abstract_variable.gd deleted file mode 100644 index 90142122..00000000 --- a/nodes/abstract_variable/abstract_variable.gd +++ /dev/null @@ -1,119 +0,0 @@ -## Common abstract class for nodes that deal with variables. -class_name AbstractVariableNode extends MonologueGraphNode - -var variable := Property.new(DROPDOWN) -var operator := Property.new(DROPDOWN, {}, "=") -var value := Property.new(LINE) - -var last_boolean: bool -var last_number: float -var last_string: String - - -func _ready(): - variable.connect("preview", get_variable_label().set_text) - operator.callers["set_items"] = [get_operator_options()] - operator.connect("preview", get_operator_label().set_text) - operator.connect("shown", value_morph) - value.connect("preview", record_morph) - super._ready() - - -func get_default_text(new_value: Variant, default: String) -> String: - var is_not_string = new_value is not String - return str(new_value) if is_not_string or new_value != "" else default - - -func get_variable_label() -> Label: - return null - - -## Returns the variable's typestring from the graph edit. -func get_variable_type(variable_name: String) -> String: - for data in get_graph_edit().variables: - if data.get("Name") == variable_name: - return data.get("Type") - return "" - - -func get_operator_label() -> Label: - return null - - -func get_operator_options() -> Array[Dictionary]: - return [ - {"id": 0, "text": "="}, - {"id": 1, "text": "+="}, - {"id": 2, "text": "-="}, - {"id": 3, "text": "*="}, - {"id": 4, "text": "/="}, - ] - - -func get_operator_disabler() -> PackedInt32Array: - return [1, 2, 3, 4] - - -func get_value_label() -> Label: - return null - - -## Reset the variable dropdown to the first value and return its type. -func reset_variable() -> String: - if get_graph_edit().variables: - variable.value = get_graph_edit().variables[0].get("Name") - return get_graph_edit().variables[0].get("Type") - else: - variable.value = "" - return "" - - -func record_morph(new_value: Variant): - match typeof(new_value): - TYPE_BOOL: - last_boolean = new_value - TYPE_INT, TYPE_FLOAT: - last_number = new_value - TYPE_STRING: - last_string = new_value - - # display integer without decimals - match get_variable_type(variable.value): - "Integer": - new_value = int(new_value) if new_value else 0 - get_value_label().text = str(new_value) - - -func value_morph(selected_name: Variant = variable.value) -> void: - var selected_type = get_variable_type(selected_name) - if not selected_type: - selected_type = reset_variable() - - match selected_type: - "Boolean": - operator.invoke("disable_items", [get_operator_disabler()]) - value.morph(TOGGLE) - value.value = last_boolean - value.propagate(last_boolean, false) - get_value_label().text = str(last_boolean) - "Integer": - operator.invoke("disable_items", [[]]) - value.morph(SPINBOX) - value.value = int(last_number) - value.propagate(int(last_number), false) - get_value_label().text = str(int(last_number)) - "String": - operator.invoke("disable_items", [get_operator_disabler()]) - value.morph(LINE) - value.value = last_string - value.propagate(last_string, false) - get_value_label().text = get_default_text(last_string, "value") - - -func _update() -> void: - variable.callers["set_items"] = [get_graph_edit().variables, "Name", "ID", "Type"] - value_morph(variable.value) - get_variable_label().text = get_default_text(variable.value, "variable") - get_operator_label().text = get_default_text(operator.value, "operator") - get_value_label().text = get_default_text(value.value, "value") - super._update() diff --git a/nodes/abstract_variable/abstract_variable.gd.uid b/nodes/abstract_variable/abstract_variable.gd.uid deleted file mode 100644 index aa967836..00000000 --- a/nodes/abstract_variable/abstract_variable.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://bh8bqa4yv070b diff --git a/nodes/action_node/action_node.gd b/nodes/action_node/action_node.gd deleted file mode 100644 index af062956..00000000 --- a/nodes/action_node/action_node.gd +++ /dev/null @@ -1,68 +0,0 @@ -@icon("res://ui/assets/icons/action.svg") -class_name ActionNode extends MonologueGraphNode - -@export var arg_box: VBoxContainer -@export var action_label: Label -@export var no_args_label: Label - -var action := Property.new(LINE) -var arguments := Property.new(LIST, {}, []) -var _argument_references = [] - - -func _ready(): - node_type = "NodeAction" - super._ready() - - action.connect("preview", _set_action_text) - arguments.setters["add_callback"] = add_argument - arguments.setters["get_callback"] = get_arguments - arguments.connect("preview", load_arguments) - - -func add_argument(data: Dictionary = {}) -> MonologueArgument: - var argument = MonologueArgument.new(self) - if data: - argument._from_dict(data) - argument.index = _argument_references.size() - _argument_references.append(argument) - return argument - - -func get_arguments(): - return _argument_references - - -func load_arguments(new_argument_list: Array): - _argument_references.clear() - for argument in new_argument_list: - add_argument(argument) - arguments.value = new_argument_list - _update.call_deferred() - - -func _from_dict(dict: Dictionary) -> void: - for key in dict.keys(): - var property = get(key.to_snake_case()) - if property is Property: - property.value = dict.get(key) - - _load_position(dict) - load_arguments(arguments.value) - - -func _set_action_text(new_text: String = action.value) -> void: - action_label.text = new_text if new_text else "custom action" - - -func _update() -> void: - _set_action_text() - no_args_label.visible = _argument_references.is_empty() - for child in arg_box.get_children(): - arg_box.remove_child(child) - child.queue_free() - - for i in range(_argument_references.size()): - arguments.value[i]["Value"] = _argument_references[i].value.value - _argument_references[i].create_representation(arg_box) - super._update() diff --git a/nodes/action_node/action_node.gd.uid b/nodes/action_node/action_node.gd.uid deleted file mode 100644 index 052632f4..00000000 --- a/nodes/action_node/action_node.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://cq8g0jelhsidq diff --git a/nodes/action_node/action_node.tscn b/nodes/action_node/action_node.tscn deleted file mode 100644 index 0db0ee52..00000000 --- a/nodes/action_node/action_node.tscn +++ /dev/null @@ -1,62 +0,0 @@ -[gd_scene load_steps=2 format=3 uid="uid://dg1if067aop0p"] - -[ext_resource type="Script" uid="uid://cq8g0jelhsidq" path="res://nodes/action_node/action_node.gd" id="3_s1gpj"] - -[node name="ActionNode" type="GraphNode" node_paths=PackedStringArray("arg_box", "action_label", "no_args_label") groups=["graph_nodes"]] -custom_minimum_size = Vector2(360, 0) -offset_right = 343.0 -offset_bottom = 87.0 -size_flags_horizontal = 0 -size_flags_vertical = 0 -title = "ActionNode" -slot/0/left_enabled = true -slot/0/left_type = 0 -slot/0/left_color = Color(1, 1, 1, 1) -slot/0/left_icon = null -slot/0/right_enabled = true -slot/0/right_type = 0 -slot/0/right_color = Color(1, 1, 1, 1) -slot/0/right_icon = null -slot/0/draw_stylebox = false -slot/1/left_enabled = false -slot/1/left_type = 0 -slot/1/left_color = Color(1, 1, 1, 1) -slot/1/left_icon = null -slot/1/right_enabled = false -slot/1/right_type = 0 -slot/1/right_color = Color(1, 1, 1, 1) -slot/1/right_icon = null -slot/1/draw_stylebox = true -script = ExtResource("3_s1gpj") -arg_box = NodePath("ArgBox") -action_label = NodePath("CallBox/ActionLabel") -no_args_label = NodePath("CallBox/NoArgsLabel") -titlebar_color = Color(0.733333, 0.392157, 0.188235, 1) - -[node name="CallBox" type="HBoxContainer" parent="."] -layout_mode = 2 -mouse_filter = 2 -theme_type_variation = &"HBoxContainer_Small" - -[node name="CallLabel" type="Label" parent="CallBox"] -layout_mode = 2 -text = "Call" - -[node name="ActionLabel" type="Label" parent="CallBox"] -layout_mode = 2 -theme_type_variation = &"NodeValue" -text = "custom action" - -[node name="WithLabel" type="Label" parent="CallBox"] -layout_mode = 2 -text = "with" - -[node name="NoArgsLabel" type="Label" parent="CallBox"] -layout_mode = 2 -theme_type_variation = &"NodeValue" -text = "no arguments" - -[node name="ArgBox" type="VBoxContainer" parent="."] -layout_mode = 2 -mouse_filter = 2 -theme_type_variation = &"VBoxContainer_Small" diff --git a/nodes/audio_node/audio_node.gd b/nodes/audio_node/audio_node.gd deleted file mode 100644 index 9ac2aa88..00000000 --- a/nodes/audio_node/audio_node.gd +++ /dev/null @@ -1,32 +0,0 @@ -class_name AudioNode extends MonologueGraphNode - -var loop := Property.new(TOGGLE, {}, false) -var volume := Property.new(SLIDER, {"suffix": "db", "minimum": -80, "maximum": 24, "step": 0.25}) -var pitch := Property.new(SLIDER, {"default": 1, "minimum": 0, "maximum": 4, "step": 0.1}) -var audio := Property.new(FILE, {"filters": FilePicker.AUDIO}) - -@onready var _audio_label = $HBox/AudioLabel -@onready var _loop_label = $HBox/LoopLabel - - -func _ready(): - node_type = "NodeAudio" - super._ready() - audio.connect("preview", _on_audio_preview) - audio.setters["base_path"] = get_parent().file_path - loop.connect("preview", _on_loop_preview) - _update() - - -func _on_audio_preview(audio_path: Variant): - _audio_label.text = str(audio_path).get_file() if audio_path else "nothing" - - -func _on_loop_preview(is_loop: Variant): - _loop_label.visible = bool(is_loop) - - -func _update(): - _on_audio_preview(audio.value) - _loop_label.visible = loop.value - super._update() diff --git a/nodes/audio_node/audio_node.gd.uid b/nodes/audio_node/audio_node.gd.uid deleted file mode 100644 index 57d91551..00000000 --- a/nodes/audio_node/audio_node.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://bkh2tynw3hgl4 diff --git a/nodes/audio_node/audio_node.tscn b/nodes/audio_node/audio_node.tscn deleted file mode 100644 index 43fe7352..00000000 --- a/nodes/audio_node/audio_node.tscn +++ /dev/null @@ -1,48 +0,0 @@ -[gd_scene load_steps=4 format=3 uid="uid://cu4kxjolgtrml"] - -[ext_resource type="Script" uid="uid://bkh2tynw3hgl4" path="res://nodes/audio_node/audio_node.gd" id="3_su5mj"] - -[sub_resource type="Theme" id="Theme_llmqa"] - -[sub_resource type="LabelSettings" id="LabelSettings_v4ya3"] -font_color = Color(0.572549, 0.572549, 0.572549, 1) - -[node name="AudioNode" type="GraphNode" groups=["graph_nodes"]] -offset_right = 214.0 -offset_bottom = 82.0 -size_flags_horizontal = 0 -size_flags_vertical = 0 -theme = SubResource("Theme_llmqa") -title = "AudioNode" -slot/0/left_enabled = true -slot/0/left_type = 0 -slot/0/left_color = Color(1, 1, 1, 1) -slot/0/left_icon = null -slot/0/right_enabled = true -slot/0/right_type = 0 -slot/0/right_color = Color(1, 1, 1, 1) -slot/0/right_icon = null -slot/0/draw_stylebox = false -script = ExtResource("3_su5mj") -titlebar_color = Color(0, 0.505882, 0.501961, 1) - -[node name="HBox" type="HBoxContainer" parent="."] -layout_mode = 2 -mouse_filter = 2 -theme_type_variation = &"HBoxContainer_Small" - -[node name="Label" type="Label" parent="HBox"] -layout_mode = 2 -text = "Play" - -[node name="AudioLabel" type="Label" parent="HBox"] -layout_mode = 2 -theme_type_variation = &"NodeValue" -text = "nothing" - - -[node name="LoopLabel" type="Label" parent="HBox"] -layout_mode = 2 -theme_type_variation = &"NodeValue" -text = "and loop" - diff --git a/nodes/background_node/background_node.gd b/nodes/background_node/background_node.gd deleted file mode 100644 index 34441d6a..00000000 --- a/nodes/background_node/background_node.gd +++ /dev/null @@ -1,58 +0,0 @@ -class_name BackgroundNode extends MonologueGraphNode - -var image := Property.new(FILE, {"filters": FilePicker.IMAGE}) -var transition := Property.new(DROPDOWN, {}, "No Transition") -var duration := Property.new(SPINBOX, {"step": 0.1, "minimum": 0.0}, 0.0) - -@onready var _path_label = $VBox/HBox/PathLabel -@onready var _preview_rect = $VBox/PreviewRect - - -func _ready(): - node_type = "NodeBackground" - transition.callers["set_items"] = [ - [ - {"id": 0, "text": "No Transition"}, - {"id": 1, "text": "Push Down"}, - {"id": 1, "text": "Push Left"}, - {"id": 1, "text": "Push Right"}, - {"id": 1, "text": "Push Up"}, - {"id": 1, "text": "Simple Fade"}, - ] - ] - transition.connect("preview", _update) - super._ready() - image.setters["base_path"] = get_parent().file_path - image.connect("preview", _on_path_preview) - _update() - - -func _load_image(): - _path_label.text = image.value if image.value else "nothing" - _preview_rect.hide() - size.y = 0 - var base = image.setters.get("base_path") - var path = Path.relative_to_absolute(image.value, base) - if FileAccess.file_exists(path): - var img = ImageLoader.load_image(path) - if img: - _preview_rect.show() - _preview_rect.texture = img - _path_label.text = image.value.get_file() - else: - _preview_rect.hide() - - -func _on_path_preview(path: Variant): - _path_label.text = str(path).get_file() - _load_image.call_deferred() - - -func _update(_value: Variant = null): - _path_label.text = image.value - _load_image() - super._update() - - -func _get_field_groups() -> Array: - return ["image", {"Transition": ["transition", "duration"]}] diff --git a/nodes/background_node/background_node.gd.uid b/nodes/background_node/background_node.gd.uid deleted file mode 100644 index 97d62a11..00000000 --- a/nodes/background_node/background_node.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://dx6dikjrdfg5f diff --git a/nodes/background_node/background_node.tscn b/nodes/background_node/background_node.tscn deleted file mode 100644 index a4913ca7..00000000 --- a/nodes/background_node/background_node.tscn +++ /dev/null @@ -1,53 +0,0 @@ -[gd_scene load_steps=4 format=3 uid="uid://cwpq37000kaqi"] - -[ext_resource type="Script" uid="uid://dx6dikjrdfg5f" path="res://nodes/background_node/background_node.gd" id="3_oaxk1"] - -[sub_resource type="Theme" id="Theme_llmqa"] - -[sub_resource type="LabelSettings" id="LabelSettings_ae3bv"] -font_color = Color(0.572549, 0.572549, 0.572549, 1) - -[node name="Background" type="GraphNode" groups=["graph_nodes"]] -custom_minimum_size = Vector2(300, 0) -offset_right = 308.0 -offset_bottom = 72.0 -size_flags_horizontal = 0 -size_flags_vertical = 0 -theme = SubResource("Theme_llmqa") -title = "SetterNode" -slot/0/left_enabled = true -slot/0/left_type = 0 -slot/0/left_color = Color(1, 1, 1, 1) -slot/0/left_icon = null -slot/0/right_enabled = true -slot/0/right_type = 0 -slot/0/right_color = Color(1, 1, 1, 1) -slot/0/right_icon = null -slot/0/draw_stylebox = false -script = ExtResource("3_oaxk1") -titlebar_color = Color(0, 0.505882, 0.501961, 1) - -[node name="VBox" type="VBoxContainer" parent="."] -layout_mode = 2 -theme_type_variation = &"VBoxContainer_Big" - -[node name="HBox" type="HBoxContainer" parent="VBox"] -layout_mode = 2 -mouse_filter = 2 -theme_type_variation = &"HBoxContainer_Small" - -[node name="BgLabel" type="Label" parent="VBox/HBox"] -layout_mode = 2 -text = "Set Background to Image" - -[node name="PathLabel" type="Label" parent="VBox/HBox"] -layout_mode = 2 -theme_type_variation = &"NodeValue" -text = "No Image" - -[node name="PreviewRect" type="TextureRect" parent="VBox"] -visible = false -custom_minimum_size = Vector2(0, 200) -layout_mode = 2 -expand_mode = 1 -stretch_mode = 6 diff --git a/nodes/bridge_in_node/bridge_in_node.gd b/nodes/bridge_in_node/bridge_in_node.gd deleted file mode 100644 index 4110101c..00000000 --- a/nodes/bridge_in_node/bridge_in_node.gd +++ /dev/null @@ -1,46 +0,0 @@ -## Continues the dialogue from BridgeIn node to its counterpart BridgeOut node. -@icon("res://ui/assets/icons/link.svg") -class_name BridgeInNode extends MonologueGraphNode - -var bridge_out_scene = preload("res://nodes/bridge_out_node/bridge_out_node.tscn") - -## Spinner control which selects what number to bridge to. -@onready var number_selector := $HBoxContainer/LinkNumber - - -func _ready(): - node_type = "NodeBridgeIn" - title = node_type - super._ready() - - -func add_to(graph): - var created = super.add_to(graph) - var number = graph.get_free_bridge_number() - number_selector.value = number - - var bridge_out = bridge_out_scene.instantiate() - bridge_out.add_to(graph) - bridge_out.number_selector.value = number - created.append(bridge_out) - - return created - - -func _from_dict(dict): - number_selector.value = dict.get("NumberSelector") - super._from_dict(dict) - - -func _load_connections(_data: Dictionary, _key: String = "") -> void: - return # BridgeIn uses NextID covertly, not as a graph connection - - -func _to_fields(dict: Dictionary) -> void: - super._to_fields(dict) - dict["NumberSelector"] = number_selector.value - - -func _to_next(dict: Dictionary, key: String = "NextID") -> void: - var next_node = get_parent().get_linked_bridge_node(number_selector.value) - dict[key] = next_node.id.value if next_node else -1 diff --git a/nodes/bridge_in_node/bridge_in_node.gd.uid b/nodes/bridge_in_node/bridge_in_node.gd.uid deleted file mode 100644 index a9ef5ac4..00000000 --- a/nodes/bridge_in_node/bridge_in_node.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://bqxf6ixm3hcsj diff --git a/nodes/bridge_in_node/bridge_in_node.tscn b/nodes/bridge_in_node/bridge_in_node.tscn deleted file mode 100644 index ebe04d8d..00000000 --- a/nodes/bridge_in_node/bridge_in_node.tscn +++ /dev/null @@ -1,34 +0,0 @@ -[gd_scene load_steps=3 format=3 uid="uid://b0eo5lvnrwidu"] - -[ext_resource type="Script" uid="uid://bqxf6ixm3hcsj" path="res://nodes/bridge_in_node/bridge_in_node.gd" id="1_8y1eo"] -[ext_resource type="PackedScene" uid="uid://wiapsnoaoc44" path="res://common/ui/custom_spinbox/custom_spinbox.tscn" id="2_81r38"] - -[node name="BridgeInNode" type="GraphNode"] -offset_right = 240.0 -offset_bottom = 82.0 -scale = Vector2(0.6, 0.6) -mouse_filter = 1 -title = "BridgeIn" -slot/0/left_enabled = true -slot/0/left_type = 0 -slot/0/left_color = Color(1, 1, 1, 1) -slot/0/left_icon = null -slot/0/right_enabled = false -slot/0/right_type = 0 -slot/0/right_color = Color(1, 1, 1, 1) -slot/0/right_icon = null -slot/0/draw_stylebox = false -script = ExtResource("1_8y1eo") -titlebar_color = Color(0.360784, 0.501961, 0.184314, 1) - -[node name="HBoxContainer" type="HBoxContainer" parent="."] -layout_mode = 2 -theme_override_constants/separation = 10 -alignment = 1 - -[node name="Label" type="Label" parent="HBoxContainer"] -layout_mode = 2 -text = "Link to" - -[node name="LinkNumber" parent="HBoxContainer" instance=ExtResource("2_81r38")] -layout_mode = 2 diff --git a/nodes/bridge_out_node/bridge_out_node.gd b/nodes/bridge_out_node/bridge_out_node.gd deleted file mode 100644 index 64fa3e17..00000000 --- a/nodes/bridge_out_node/bridge_out_node.gd +++ /dev/null @@ -1,19 +0,0 @@ -@icon("res://ui/assets/icons/link.svg") -class_name BridgeOutNode extends MonologueGraphNode - -@onready var number_selector := $HBoxContainer/LinkNumber - - -func _ready(): - node_type = "NodeBridgeOut" - super._ready() - - -func _from_dict(dict): - number_selector.value = dict.get("NumberSelector") - super._from_dict(dict) - - -func _to_fields(dict: Dictionary) -> void: - super._to_fields(dict) - dict["NumberSelector"] = number_selector.value diff --git a/nodes/bridge_out_node/bridge_out_node.gd.uid b/nodes/bridge_out_node/bridge_out_node.gd.uid deleted file mode 100644 index 6d817527..00000000 --- a/nodes/bridge_out_node/bridge_out_node.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://bimgycdfh52xb diff --git a/nodes/bridge_out_node/bridge_out_node.tscn b/nodes/bridge_out_node/bridge_out_node.tscn deleted file mode 100644 index 64a7c712..00000000 --- a/nodes/bridge_out_node/bridge_out_node.tscn +++ /dev/null @@ -1,35 +0,0 @@ -[gd_scene load_steps=3 format=3 uid="uid://c75iblt2kuvr2"] - -[ext_resource type="Script" uid="uid://bimgycdfh52xb" path="res://nodes/bridge_out_node/bridge_out_node.gd" id="1_6kxjr"] -[ext_resource type="PackedScene" uid="uid://wiapsnoaoc44" path="res://common/ui/custom_spinbox/custom_spinbox.tscn" id="2_qrxgf"] - -[node name="BridgeOutNode" type="GraphNode"] -offset_right = 185.0 -offset_bottom = 72.0 -scale = Vector2(0.6, 0.6) -mouse_filter = 1 -title = "BridgeOut" -slot/0/left_enabled = false -slot/0/left_type = 0 -slot/0/left_color = Color(1, 1, 1, 1) -slot/0/left_icon = null -slot/0/right_enabled = true -slot/0/right_type = 0 -slot/0/right_color = Color(1, 1, 1, 1) -slot/0/right_icon = null -slot/0/draw_stylebox = false -script = ExtResource("1_6kxjr") -titlebar_color = Color(0.360784, 0.501961, 0.184314, 1) - -[node name="HBoxContainer" type="HBoxContainer" parent="."] -layout_mode = 2 -theme_override_constants/separation = 10 -alignment = 1 - -[node name="Label" type="Label" parent="HBoxContainer"] -layout_mode = 2 -text = "Link to" -justification_flags = 195 - -[node name="LinkNumber" parent="HBoxContainer" instance=ExtResource("2_qrxgf")] -layout_mode = 2 diff --git a/nodes/bughiuhb.tscn b/nodes/bughiuhb.tscn new file mode 100644 index 00000000..93d9a14d --- /dev/null +++ b/nodes/bughiuhb.tscn @@ -0,0 +1,36 @@ +[gd_scene format=3 uid="uid://crdsjpypmul7c"] + +[node name="Bughiuhb" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 + +[node name="GraphEdit" type="GraphEdit" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +scroll_offset = Vector2(-40, -40) + +[node name="GraphNode" type="GraphNode" parent="GraphEdit"] +layout_mode = 0 +offset_left = 100.0 +offset_top = 184.0 +offset_right = 218.0 +offset_bottom = 265.0 +mouse_filter = 1 +position_offset = Vector2(60, 144) + +[node name="GraphNode2" type="GraphNode" parent="GraphEdit"] +layout_mode = 0 +offset_left = 345.0 +offset_top = 173.0 +offset_right = 475.0 +offset_bottom = 257.0 +mouse_filter = 1 +position_offset = Vector2(305, 133) diff --git a/nodes/character_node/character_node.gd b/nodes/character_node/character_node.gd deleted file mode 100644 index 0e8a12ea..00000000 --- a/nodes/character_node/character_node.gd +++ /dev/null @@ -1,152 +0,0 @@ -class_name CharacterNode extends MonologueGraphNode - -var character := Property.new(DROPDOWN, {"store_index": true}, 0) -var action_type := Property.new(DROPDOWN, {}, "Join") - -var _position := Property.new(DROPDOWN, {}, "Left") -var join_animation := Property.new(DROPDOWN, {}, "Default", "Animation Type") -var leave_animation := Property.new(DROPDOWN, {}, "Default", "Animation Type") -var update_animation := Property.new(DROPDOWN, {}, "Default", "Animation Type") -var portrait := Property.new(DROPDOWN, {"late_items": true}) -var duration := Property.new(SPINBOX, {"step": 0.1, "minimum": 0.0}, 0.5) -var _z_index := Property.new(SPINBOX, {"step": 1}, 0) -var mirrored := Property.new(TOGGLE, {}, false) - -var _control_groups = { - "Join": [portrait, _z_index, join_animation, _position, mirrored], - "Leave": [leave_animation], - "Update": [portrait, _z_index, update_animation, _position, mirrored], -} - -@onready var character_name_label := %CharacterNameLabel -@onready var action_type_label := %ActionTypeLabel -@onready var display_container := %DisplayContainer -@onready var position_label := %PositionLabel -@onready var portrait_name_label := %PortraitNameLabel - - -func _ready(): - node_type = "NodeCharacter" - - var characters: Array = get_graph_edit().characters - character.callers["set_items"] = [characters, "Character/Name", "EditorIndex"] - character.connect("preview", _update) - - portrait.connect("preview", _update) - - action_type.callers["set_items"] = [ - [ - {"id": 0, "text": "Join"}, - {"id": 1, "text": "Leave"}, - {"id": 2, "text": "Update"}, - ] - ] - action_type.connect("preview", _show_group) - action_type.connect("preview", _update) - - _position.callers["set_items"] = [ - [ - {"id": 0, "text": "Left"}, - {"id": 1, "text": "Center"}, - {"id": 2, "text": "Right"}, - ] - ] - _position.connect("preview", _update) - - join_animation.callers["set_items"] = [ - [ - {"id": 0, "text": "Default"}, - {"id": 1, "text": "None"}, - {"id": 2, "text": "Fade In"}, - {"id": 3, "text": "Slide In Auto"}, - {"id": 4, "text": "Slide In Down"}, - {"id": 5, "text": "Slide In Left"}, - {"id": 6, "text": "Slide In Right"}, - {"id": 7, "text": "Slide In Up"}, - ] - ] - join_animation.connect("preview", _update) - - leave_animation.callers["set_items"] = [ - [ - {"id": 0, "text": "Default"}, - {"id": 1, "text": "None"}, - {"id": 2, "text": "Fade Out"}, - {"id": 3, "text": "Slide Out Auto"}, - {"id": 4, "text": "Slide Out Down"}, - {"id": 5, "text": "Slide Out Left"}, - {"id": 6, "text": "Slide Out Right"}, - {"id": 7, "text": "Slide Out Up"}, - ] - ] - leave_animation.connect("preview", _update) - - update_animation.callers["set_items"] = [ - [ - {"id": 0, "text": "Default"}, - {"id": 1, "text": "None"}, - {"id": 2, "text": "Bounce"}, - {"id": 3, "text": "Shake"}, - ] - ] - update_animation.connect("preview", _update) - - super._ready() - _show_group() - _update() - - -func _update(_value: Variant = null) -> void: - await get_tree().process_frame - super._update() - - var action: Variant = action_type.value - var characters: Array = get_graph_edit().characters - character.callers["set_items"] = [characters, "Character/Name", "EditorIndex"] - if characters[character.value] and characters[character.value]["Character"].has("Portraits"): - if portrait.field: - portrait.field.set_items(characters[character.value]["Character"]["Portraits"], "Name") - else: - portrait.setters["set_items"] = [ - characters[character.value]["Character"]["Portraits"], "Name" - ] - - display_container.visible = action != "Leave" - character_name_label.text = characters[character.value].get("Character", {}).get( - "Name", "Unknown" - ) - action_type_label.text = action - position_label.text = _position.value - portrait_name_label.text = portrait.value if portrait.value else "Unknown" - - -func _show_group(act_type: Variant = action_type.value) -> void: - for key in _control_groups.keys(): - for property in _control_groups.get(key): - property.visible = false - - for key in _control_groups.keys(): - for property in _control_groups.get(key): - if key == act_type: - property.visible = true - title = node_type - - -func _get_field_groups() -> Array: - return [ - "character", - "action_type", - { - "Display Settings": - [ - "portrait", - "_z_index", - { - "Animation": - ["join_animation", "leave_animation", "update_animation", "duration"] - }, - "_position", - "mirrored" - ] - } - ] diff --git a/nodes/character_node/character_node.gd.uid b/nodes/character_node/character_node.gd.uid deleted file mode 100644 index 5c3db070..00000000 --- a/nodes/character_node/character_node.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://c7bmubh3y8hfx diff --git a/nodes/character_node/character_node.tscn b/nodes/character_node/character_node.tscn deleted file mode 100644 index 07e2dd49..00000000 --- a/nodes/character_node/character_node.tscn +++ /dev/null @@ -1,83 +0,0 @@ -[gd_scene load_steps=3 format=3 uid="uid://gn7806oog6qo"] - -[ext_resource type="Script" uid="uid://c7bmubh3y8hfx" path="res://nodes/character_node/character_node.gd" id="3_3dcof"] - -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_ryo67"] -content_margin_left = 10.0 -content_margin_top = 2.0 -content_margin_right = 10.0 -content_margin_bottom = 2.0 -corner_radius_top_left = 2 -corner_radius_top_right = 2 -corner_radius_bottom_right = 2 -corner_radius_bottom_left = 2 - -[node name="CharacterNode" type="GraphNode" groups=["graph_nodes"]] -offset_right = 245.0 -offset_bottom = 136.0 -size_flags_vertical = 0 -theme_override_styles/titlebar = SubResource("StyleBoxFlat_ryo67") -title = "NodeCharacter" -slot/0/left_enabled = true -slot/0/left_type = 0 -slot/0/left_color = Color(1, 1, 1, 1) -slot/0/left_icon = null -slot/0/right_enabled = true -slot/0/right_type = 0 -slot/0/right_color = Color(1, 1, 1, 1) -slot/0/right_icon = null -slot/0/draw_stylebox = false -script = ExtResource("3_3dcof") -titlebar_color = Color(0, 0.505882, 0.501961, 1) - -[node name="VBoxContainer" type="VBoxContainer" parent="."] -layout_mode = 2 -theme_type_variation = &"FieldContainer" - -[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer"] -layout_mode = 2 - -[node name="CharacterLabel" type="Label" parent="VBoxContainer/HBoxContainer"] -layout_mode = 2 -text = "Character" - -[node name="CharacterNameLabel" type="Label" parent="VBoxContainer/HBoxContainer"] -unique_name_in_owner = true -layout_mode = 2 -theme_type_variation = &"NodeValue" -text = "Unknown" - -[node name="ActionTypeLabel" type="Label" parent="VBoxContainer/HBoxContainer"] -unique_name_in_owner = true -layout_mode = 2 -theme_type_variation = &"NodeValue" -text = "Join" - -[node name="DisplayContainer" type="HBoxContainer" parent="VBoxContainer"] -unique_name_in_owner = true -layout_mode = 2 - -[node name="AtLabel" type="Label" parent="VBoxContainer/DisplayContainer"] -layout_mode = 2 -text = "at" - -[node name="PositionLabel" type="Label" parent="VBoxContainer/DisplayContainer"] -unique_name_in_owner = true -layout_mode = 2 -theme_type_variation = &"NodeValue" -text = "Left" - -[node name="HBoxContainer2" type="HBoxContainer" parent="VBoxContainer"] -layout_mode = 2 - -[node name="PortraitLabel" type="Label" parent="VBoxContainer/HBoxContainer2"] -layout_mode = 2 -text = "with portrait" - -[node name="PortraitNameLabel" type="Label" parent="VBoxContainer/HBoxContainer2"] -unique_name_in_owner = true -layout_mode = 2 -theme_type_variation = &"NodeValue" -text = "Unknown" - -[connection signal="resize_request" from="." to="." method="_on_GraphNode_resize_request"] diff --git a/nodes/choice_node/choice_node.gd b/nodes/choice_node/choice_node.gd deleted file mode 100644 index 21c6e801..00000000 --- a/nodes/choice_node/choice_node.gd +++ /dev/null @@ -1,142 +0,0 @@ -@icon("res://ui/assets/icons/choice.svg") -class_name ChoiceNode extends MonologueGraphNode - -var option_scene = preload("res://nodes/option_node/option_node.tscn") -var options := Property.new(LIST, {}, []) - -## Temporary ID storage for first-time loading of base options in project load. -var _base_id_list: Array = [] - - -func _ready(): - node_type = "NodeChoice" - super._ready() - options.setters["add_callback"] = add_option - options.setters["get_callback"] = get_children - options.callers["set_label_visible"] = [false] - options.connect("preview", _refresh) - editor_position.set_visible(false) - GlobalSignal.add_listener("language_deleted", store_options) - - if get_child_count() <= 0: - options.value.append(add_option()._to_dict()) - options.value.append(add_option()._to_dict()) - - -func add_option(reference: Dictionary = {}) -> OptionNode: - var new_option = option_scene.instantiate() - add_child(new_option, true) - new_option.set_count(new_option.get_index() + 1) - - if reference: - new_option._from_dict(reference) - var value = reference.get("Option", reference.get("Sentence", "")) - if value is Dictionary: - var switcher = GlobalVariables.language_switcher - var locale = str(switcher.get_current_language()) - value = value.get(locale, "") - new_option.preview_label.text = value - link_option(new_option) - - var is_first = get_child_count() <= 1 - set_slot( - get_child_count() - 1, - is_first, - 0, - Color("ffffff"), - true, - 0, - Color("ffffff"), - LEFT_SLOT, - RIGHT_SLOT, - false - ) - return new_option - - -func clear_children(): - for child in get_children(): - remove_child(child) - child.queue_free() - - -func get_option_by_id(option_id: String) -> OptionNode: - for node in get_children(): - if node.id.value == option_id: - return node - return null - - -func link_option(option: OptionNode, link: bool = true): - var index = option.get_index() - if option.next_id.value is String: # non-connections are -1 (int) - var next_node = get_parent().get_node_by_id(option.next_id.value) - if next_node: - if link: - get_parent().connect_node(name, index, next_node.name, 0) - else: - get_parent().disconnect_node(name, index, next_node.name, 0) - - -func store_options(_name, _rest: Dictionary, choices: Dictionary) -> void: - var nodes = get_children().map(func(o): return o._to_dict()) - choices[self] = nodes - - -func reload_preview() -> void: - var nodes = get_children() - for node in nodes: - node.reload_preview() - - -## Update the NextID of this choice node on the given port. -func update_next_id(from_port: int, next_node: MonologueGraphNode): - var option_node = get_child(from_port) - var next_value = -1 - if next_node: - next_value = next_node.id.value - option_node.next_id.value = next_value - options.value[from_port] = option_node._to_dict() - options.propagate(options.value, false) - - -func _from_dict(dict: Dictionary) -> void: - _base_id_list = dict.get("OptionsID", []) - if _base_id_list.size() > 0: - options.value = [] - clear_children() - _load_position(dict) - super._from_dict(dict) - # overridden to prevent _update() from happening too early here - - -func _load_connections(_data: Dictionary, _key: String = "") -> void: - # called after _load_nodes() in MonologueControl, this is used to - # load embedded OptionNodes which automatically forms the connections - for option_id in _base_id_list: - var reference = get_parent().base_options[option_id] - var loaded_option = add_option(reference) - options.value.append(loaded_option._to_dict()) - - -func _refresh(new_options_list: Array): - # disconnect all outbound connections - for connection in get_parent().get_all_outbound_connections(name): - var from_port = connection.get("from_port") - var to_node = connection.get("to_node") - get_parent().disconnect_node(name, from_port, to_node, 0) - clear_children() - - for new_option_data in new_options_list: - add_option(new_option_data) - _update() - - -func restore_options(options_value: Array) -> void: - options.value = options_value - _refresh(options_value) - - -func _to_fields(dict: Dictionary) -> void: - var child_options = get_children().filter(func(c): return c is OptionNode) - dict["OptionsID"] = child_options.map(func(o): return o.id.value) diff --git a/nodes/choice_node/choice_node.gd.uid b/nodes/choice_node/choice_node.gd.uid deleted file mode 100644 index 979d87f2..00000000 --- a/nodes/choice_node/choice_node.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://hoywtrxb87tk diff --git a/nodes/choice_node/choice_node.tscn b/nodes/choice_node/choice_node.tscn deleted file mode 100644 index 10d58c9d..00000000 --- a/nodes/choice_node/choice_node.tscn +++ /dev/null @@ -1,12 +0,0 @@ -[gd_scene load_steps=2 format=3 uid="uid://coq74c18uq3d3"] - -[ext_resource type="Script" uid="uid://hoywtrxb87tk" path="res://nodes/choice_node/choice_node.gd" id="1_nn3v2"] - -[node name="ChoiceNode" type="GraphNode" groups=["graph_nodes"]] -custom_minimum_size = Vector2(400, 60) -offset_right = 400.0 -offset_bottom = 60.0 -size_flags_vertical = 0 -title = "ChoiceNode" -script = ExtResource("1_nn3v2") -titlebar_color = Color(0.835294, 0.317647, 0.376471, 1) diff --git a/nodes/comment_node/comment_node.gd b/nodes/comment_node/comment_node.gd deleted file mode 100644 index 245987c3..00000000 --- a/nodes/comment_node/comment_node.gd +++ /dev/null @@ -1,19 +0,0 @@ -@icon("res://ui/assets/icons/comment.svg") -class_name CommentNode extends MonologueGraphNode - -@onready var comment_edit = $CommentEdit - - -func _ready() -> void: - node_type = "NodeComment" - super._ready() - - -func _from_dict(dict: Dictionary) -> void: - comment_edit.text = dict.get("Comment") - super._from_dict(dict) - - -func _to_fields(dict: Dictionary) -> void: - super._to_fields(dict) - dict["Comment"] = comment_edit.text diff --git a/nodes/comment_node/comment_node.gd.uid b/nodes/comment_node/comment_node.gd.uid deleted file mode 100644 index 80524383..00000000 --- a/nodes/comment_node/comment_node.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://b60bh6vkocfn0 diff --git a/nodes/comment_node/comment_node.tscn b/nodes/comment_node/comment_node.tscn deleted file mode 100644 index ad65a005..00000000 --- a/nodes/comment_node/comment_node.tscn +++ /dev/null @@ -1,31 +0,0 @@ -[gd_scene load_steps=3 format=3 uid="uid://b4ptsysoq7mgm"] - -[ext_resource type="Script" uid="uid://b60bh6vkocfn0" path="res://nodes/comment_node/comment_node.gd" id="3_vd25i"] - -[sub_resource type="Theme" id="Theme_llmqa"] - -[node name="CommentNode" type="GraphNode" groups=["graph_nodes"]] -custom_minimum_size = Vector2(400, 100) -offset_right = 400.0 -offset_bottom = 100.0 -theme = SubResource("Theme_llmqa") -title = "NodeComment" -slot/0/left_enabled = false -slot/0/left_type = 0 -slot/0/left_color = Color(1, 1, 1, 1) -slot/0/left_icon = null -slot/0/right_enabled = false -slot/0/right_type = 0 -slot/0/right_color = Color(1, 1, 1, 1) -slot/0/right_icon = null -slot/0/draw_stylebox = true -script = ExtResource("3_vd25i") -titlebar_color = Color(1, 1, 1, 1) - -[node name="CommentEdit" type="TextEdit" parent="."] -layout_mode = 2 -size_flags_vertical = 3 -wrap_mode = 1 -scroll_fit_content_height = true - -[connection signal="resize_request" from="." to="." method="_on_GraphNode_resize_request"] diff --git a/nodes/condition_node/condition_node.gd b/nodes/condition_node/condition_node.gd deleted file mode 100644 index 94f62594..00000000 --- a/nodes/condition_node/condition_node.gd +++ /dev/null @@ -1,25 +0,0 @@ -@icon("res://ui/assets/icons/Condition.svg") -class_name ConditionNode extends EventNode - - -func _ready(): - super._ready() - node_type = "NodeCondition" - title = node_type - - -func _load_connections(data: Dictionary, key: String = "IfNextID") -> void: - super._load_connections(data, key) - var else_next_id = data.get("ElseNextID") - if else_next_id is String: - var else_next_node = get_graph_edit().get_node_by_id(else_next_id) - if else_next_node: - get_graph_edit().connect_node(name, 1, else_next_node.name, 0) - - -func _to_next(dict: Dictionary, key: String = "IfNextID") -> void: - var next_id_node = get_graph_edit().get_all_connections_from_slot(name, 0) - dict[key] = next_id_node[0].id.value if next_id_node else -1 - - var else_id_node = get_graph_edit().get_all_connections_from_slot(name, 1) - dict["ElseNextID"] = else_id_node[0].id.value if else_id_node else -1 diff --git a/nodes/condition_node/condition_node.gd.uid b/nodes/condition_node/condition_node.gd.uid deleted file mode 100644 index e55a1c79..00000000 --- a/nodes/condition_node/condition_node.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://bt5pl4c11vfxd diff --git a/nodes/condition_node/condition_node.tscn b/nodes/condition_node/condition_node.tscn deleted file mode 100644 index a029f8c2..00000000 --- a/nodes/condition_node/condition_node.tscn +++ /dev/null @@ -1,73 +0,0 @@ -[gd_scene load_steps=4 format=3 uid="uid://dsv566w4evo8b"] - -[ext_resource type="Script" uid="uid://bt5pl4c11vfxd" path="res://nodes/condition_node/condition_node.gd" id="3_vhhwe"] - -[sub_resource type="Theme" id="Theme_llmqa"] - -[sub_resource type="LabelSettings" id="LabelSettings_v4ya3"] -font_color = Color(0.572549, 0.572549, 0.572549, 1) - -[node name="ConditionNode" type="GraphNode" groups=["graph_nodes"]] -offset_right = 314.0 -offset_bottom = 128.0 -size_flags_horizontal = 0 -size_flags_vertical = 0 -theme = SubResource("Theme_llmqa") -title = "ConditionNode" -slot/0/left_enabled = true -slot/0/left_type = 0 -slot/0/left_color = Color(1, 1, 1, 1) -slot/0/left_icon = null -slot/0/right_enabled = true -slot/0/right_type = 0 -slot/0/right_color = Color(1, 1, 1, 1) -slot/0/right_icon = null -slot/0/draw_stylebox = false -slot/1/left_enabled = false -slot/1/left_type = 0 -slot/1/left_color = Color(1, 1, 1, 1) -slot/1/left_icon = null -slot/1/right_enabled = true -slot/1/right_type = 0 -slot/1/right_color = Color(1, 1, 1, 1) -slot/1/right_icon = null -slot/1/draw_stylebox = false -script = ExtResource("3_vhhwe") -titlebar_color = Color(0.733333, 0.392157, 0.188235, 1) - -[node name="HBox" type="HBoxContainer" parent="."] -layout_mode = 2 -theme_type_variation = &"HBoxContainer_Small" - -[node name="IfLabel" type="Label" parent="HBox"] -layout_mode = 2 -text = "If" - -[node name="VariableLabel" type="Label" parent="HBox"] -layout_mode = 2 -theme_type_variation = &"NodeValue" -text = "variable" - - -[node name="OperatorLabel" type="Label" parent="HBox"] -layout_mode = 2 -theme_type_variation = &"NodeValue" -text = "condition" - - -[node name="ValueLabel" type="Label" parent="HBox"] -layout_mode = 2 -theme_type_variation = &"NodeValue" -text = "value" - - -[node name="ThenLabel" type="Label" parent="HBox"] -layout_mode = 2 -text = "then" - -[node name="ElseHBox" type="HBoxContainer" parent="."] -layout_mode = 2 - -[node name="ElseLabel" type="Label" parent="ElseHBox"] -layout_mode = 2 -text = "Else" diff --git a/nodes/end_path_node/end_path_node.gd b/nodes/end_path_node/end_path_node.gd deleted file mode 100644 index d73cdfd2..00000000 --- a/nodes/end_path_node/end_path_node.gd +++ /dev/null @@ -1,20 +0,0 @@ -@icon("res://ui/assets/icons/exit.svg") -class_name EndPathNode extends MonologueGraphNode - -var next_story := Property.new(FILE, {"filters": ["*.json;Monologue File"]}) - - -func _ready(): - node_type = "NodeEndPath" - super._ready() - next_story.setters["base_path"] = get_parent().file_path - - -func _from_dict(dict: Dictionary): - next_story.value = dict.get("NextStoryName", "") # backwards compatibility - super._from_dict(dict) - - -func _on_close_request(): - queue_free() - get_parent().clear_all_empty_connections() diff --git a/nodes/end_path_node/end_path_node.gd.uid b/nodes/end_path_node/end_path_node.gd.uid deleted file mode 100644 index 142c5d16..00000000 --- a/nodes/end_path_node/end_path_node.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://cnoxaqxh33sue diff --git a/nodes/end_path_node/end_path_node.tscn b/nodes/end_path_node/end_path_node.tscn deleted file mode 100644 index 8d5d4a80..00000000 --- a/nodes/end_path_node/end_path_node.tscn +++ /dev/null @@ -1,30 +0,0 @@ -[gd_scene load_steps=3 format=3 uid="uid://c3t0igg4s2pne"] - -[ext_resource type="Script" uid="uid://cnoxaqxh33sue" path="res://nodes/end_path_node/end_path_node.gd" id="1_vdup8"] -[ext_resource type="Texture2D" uid="uid://dccbv4x7joj8a" path="res://ui/assets/icons/exit.png" id="3_w7usk"] - -[node name="EndPathNode" type="GraphNode"] -offset_right = 240.0 -offset_bottom = 91.0 -scale = Vector2(0.6, 0.6) -mouse_filter = 1 -title = "EndPath" -slot/0/left_enabled = true -slot/0/left_type = 0 -slot/0/left_color = Color(1, 1, 1, 1) -slot/0/left_icon = null -slot/0/right_enabled = false -slot/0/right_type = 0 -slot/0/right_color = Color(1, 1, 1, 1) -slot/0/right_icon = null -slot/0/draw_stylebox = false -script = ExtResource("1_vdup8") -titlebar_color = Color(0.0196078, 0.513726, 0.341176, 1) - -[node name="TextureRect" type="TextureRect" parent="."] -custom_minimum_size = Vector2(48, 48) -layout_mode = 2 -size_flags_vertical = 3 -texture = ExtResource("3_w7usk") -expand_mode = 2 -stretch_mode = 5 diff --git a/nodes/event_node/event_node.gd b/nodes/event_node/event_node.gd deleted file mode 100644 index 13f32b85..00000000 --- a/nodes/event_node/event_node.gd +++ /dev/null @@ -1,48 +0,0 @@ -@icon("res://ui/assets/icons/calendar.svg") -class_name EventNode extends AbstractVariableNode - - -func _ready(): - node_type = "NodeEvent" - super._ready() - - -func get_variable_label() -> Label: - return $HBox/VariableLabel - - -func get_operator_label() -> Label: - return $HBox/OperatorLabel - - -func get_value_label() -> Label: - return $HBox/ValueLabel - - -func get_operator_options(): - return [ - {"id": 0, "text": "=="}, - {"id": 1, "text": ">="}, - {"id": 2, "text": "<="}, - {"id": 3, "text": "!="}, - ] - - -func get_operator_disabler(): - return [1, 2] - - -func _from_dict(dict: Dictionary): - var condition = dict.get("Condition", {}) - var morphing_value = dict.get("Value", "") - if condition: - for v in get_graph_edit().variables: - if v.get("Name") == condition.get("Variable"): - variable.value = condition.get("Variable") - break - operator.value = condition.get("Operator", "==") - morphing_value = condition.get("Value", "") - value.value = morphing_value - - record_morph(morphing_value) - super._from_dict(dict) diff --git a/nodes/event_node/event_node.gd.uid b/nodes/event_node/event_node.gd.uid deleted file mode 100644 index b4e092a8..00000000 --- a/nodes/event_node/event_node.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://dytqpwd0qegbw diff --git a/nodes/event_node/event_node.tscn b/nodes/event_node/event_node.tscn deleted file mode 100644 index 6a1baad5..00000000 --- a/nodes/event_node/event_node.tscn +++ /dev/null @@ -1,57 +0,0 @@ -[gd_scene load_steps=4 format=3 uid="uid://bwfykyaajuu4i"] - -[ext_resource type="Script" uid="uid://dytqpwd0qegbw" path="res://nodes/event_node/event_node.gd" id="3_c6hyr"] - -[sub_resource type="Theme" id="Theme_llmqa"] - -[sub_resource type="LabelSettings" id="LabelSettings_v4ya3"] -font_color = Color(0.572549, 0.572549, 0.572549, 1) - -[node name="EventNode" type="GraphNode" groups=["graph_nodes"]] -offset_right = 324.0 -offset_bottom = 72.0 -size_flags_horizontal = 0 -size_flags_vertical = 0 -theme = SubResource("Theme_llmqa") -title = "EventNode" -slot/0/left_enabled = false -slot/0/left_type = 0 -slot/0/left_color = Color(1, 1, 1, 1) -slot/0/left_icon = null -slot/0/right_enabled = true -slot/0/right_type = 0 -slot/0/right_color = Color(1, 1, 1, 1) -slot/0/right_icon = null -slot/0/draw_stylebox = false -script = ExtResource("3_c6hyr") -titlebar_color = Color(0.0196078, 0.513726, 0.341176, 1) - -[node name="HBox" type="HBoxContainer" parent="."] -layout_mode = 2 -theme_type_variation = &"HBoxContainer_Small" - -[node name="WhenLabel" type="Label" parent="HBox"] -layout_mode = 2 -text = "When" - -[node name="VariableLabel" type="Label" parent="HBox"] -layout_mode = 2 -theme_type_variation = &"NodeValue" -text = "variable" - - -[node name="OperatorLabel" type="Label" parent="HBox"] -layout_mode = 2 -theme_type_variation = &"NodeValue" -text = "condition" - - -[node name="ValueLabel" type="Label" parent="HBox"] -layout_mode = 2 -theme_type_variation = &"NodeValue" -text = "value" - - -[node name="DoLabel" type="Label" parent="HBox"] -layout_mode = 2 -text = "do" \ No newline at end of file diff --git a/nodes/option_node/option_node.gd b/nodes/option_node/option_node.gd deleted file mode 100644 index 0f1aa2c0..00000000 --- a/nodes/option_node/option_node.gd +++ /dev/null @@ -1,72 +0,0 @@ -class_name OptionNode extends MonologueGraphNode - -var option := Localizable.new(TEXT, {"minimum_size": Vector2(200, 100)}) -var enable_by_default := Property.new(CHECKBOX, {}, true) -var one_shot := Property.new(CHECKBOX, {}, false) -var next_id := Property.new(LINE, {}, -1) - -@onready var choice_node = get_parent() -@onready var count_label = %CountLabel -@onready var preview_label = $VBox/PreviewLabel -@onready var ebd_label = %EbDLabel -@onready var one_shot_label = %OneShotLabel - - -func _ready() -> void: - node_type = "NodeOption" - super._ready() - option.connect("change", update_parent) - option.connect("preview", _on_text_preview) - one_shot.connect("change", update_parent) - one_shot.connect("preview", _update) - enable_by_default.connect("change", update_parent) - enable_by_default.connect("preview", _update) - next_id.visible = false - get_titlebar_hbox().get_child(0).hide() - _update() - - -func display() -> void: - get_graph_edit().set_selected(get_parent()) - - -func get_graph_edit() -> MonologueGraphEdit: - return choice_node.get_graph_edit() - - -func reload_preview() -> void: - preview_label.text = option.value - - -func set_count(number: int) -> void: - count_label.text = "Option %d" % number - - -func _update(_value: Variant = null) -> void: - if ebd_label and one_shot_label: - ebd_label.visible = enable_by_default.value - one_shot_label.visible = one_shot.value - - -func update_parent(_old_value = "", _new_value = "") -> void: - var old_option = choice_node.options.value[get_index()] - var new_options = choice_node.options.value.duplicate(true) - new_options[get_index()] = old_option.merged(_to_dict(), true) - choice_node.options.value = new_options - - _update() - - -func _from_dict(dict: Dictionary) -> void: - option.value = dict.get("Sentence", "") - enable_by_default.value = dict.get("Enable", false) - dict.erase("EditorPosition") - super._from_dict(dict) - - -func _on_text_preview(text: Variant) -> void: - preview_label.text = str(text) - - -func _to_next(dict: Dictionary, key: String = "NextID") -> void: - dict[key] = next_id.value diff --git a/nodes/option_node/option_node.gd.uid b/nodes/option_node/option_node.gd.uid deleted file mode 100644 index 5334a03a..00000000 --- a/nodes/option_node/option_node.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://b3sgq1spd1cf8 diff --git a/nodes/option_node/option_node.tscn b/nodes/option_node/option_node.tscn deleted file mode 100644 index 5accde55..00000000 --- a/nodes/option_node/option_node.tscn +++ /dev/null @@ -1,80 +0,0 @@ -[gd_scene load_steps=5 format=3 uid="uid://ccuhx5vr7t50a"] - -[ext_resource type="Script" uid="uid://b3sgq1spd1cf8" path="res://nodes/option_node/option_node.gd" id="1_67u8k"] - -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_5mv5j"] -content_margin_left = 10.0 -content_margin_top = 10.0 -content_margin_right = 10.0 -content_margin_bottom = 10.0 -bg_color = Color(0.192157, 0.192157, 0.211765, 1) -border_width_left = 1 -border_width_top = 1 -border_width_right = 1 -border_width_bottom = 1 -border_color = Color(0.301961, 0.301961, 0.301961, 1) -corner_radius_top_left = 3 -corner_radius_top_right = 3 -corner_radius_bottom_right = 3 -corner_radius_bottom_left = 3 -corner_detail = 12 - -[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_32su8"] - -[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_vd2tk"] - -[node name="OptionNode" type="GraphNode"] -custom_minimum_size = Vector2(0, 70) -offset_right = 412.0 -offset_bottom = 94.0 -size_flags_horizontal = 3 -mouse_filter = 2 -theme_override_styles/panel = SubResource("StyleBoxFlat_5mv5j") -theme_override_styles/titlebar = SubResource("StyleBoxEmpty_32su8") -theme_override_styles/slot = SubResource("StyleBoxEmpty_vd2tk") -draggable = false -selectable = false -slot/0/left_enabled = false -slot/0/left_type = 0 -slot/0/left_color = Color(1, 1, 1, 1) -slot/0/left_icon = null -slot/0/right_enabled = false -slot/0/right_type = 0 -slot/0/right_color = Color(1, 1, 1, 1) -slot/0/right_icon = null -slot/0/draw_stylebox = true -script = ExtResource("1_67u8k") -titlebar_color = Color(0.835294, 0.317647, 0.376471, 1) -show_titlebar = false - -[node name="VBox" type="VBoxContainer" parent="."] -layout_mode = 2 -mouse_filter = 2 -theme_type_variation = &"VBoxContainer_Small" - -[node name="HBoxContainer" type="HBoxContainer" parent="VBox"] -custom_minimum_size = Vector2(0, 29) -layout_mode = 2 - -[node name="CountLabel" type="Label" parent="VBox/HBoxContainer"] -unique_name_in_owner = true -layout_mode = 2 -theme_type_variation = &"NoteLabel" -text = "Option 1" - -[node name="EbDLabel" type="Label" parent="VBox/HBoxContainer"] -unique_name_in_owner = true -layout_mode = 2 -theme_type_variation = &"NodeValue" -text = "Enable by default" - -[node name="OneShotLabel" type="Label" parent="VBox/HBoxContainer"] -unique_name_in_owner = true -layout_mode = 2 -theme_type_variation = &"NodeValue" -text = "One-shot" - -[node name="PreviewLabel" type="Label" parent="VBox"] -layout_mode = 2 -clip_text = true -text_overrun_behavior = 3 diff --git a/nodes/random_node/output_line.tscn b/nodes/random_node/output_line.tscn deleted file mode 100644 index fa55ab68..00000000 --- a/nodes/random_node/output_line.tscn +++ /dev/null @@ -1,17 +0,0 @@ -[gd_scene load_steps=2 format=3 uid="uid://pa33y1sg05tb"] - -[sub_resource type="GDScript" id="GDScript_ojesf"] -script/source = "extends HBoxContainer - - -func update_label(new_value: String): - $Label.text = new_value -" - -[node name="OutputLine" type="HBoxContainer"] -alignment = 2 -script = SubResource("GDScript_ojesf") - -[node name="Label" type="Label" parent="."] -layout_mode = 2 -text = "100%" diff --git a/nodes/random_node/random_node.gd b/nodes/random_node/random_node.gd deleted file mode 100644 index 7524ca54..00000000 --- a/nodes/random_node/random_node.gd +++ /dev/null @@ -1,150 +0,0 @@ -@icon("res://ui/assets/icons/dice.svg") -class_name RandomNode extends MonologueGraphNode - -@onready var output_line := preload("res://nodes/random_node/output_line.tscn") - -var outputs := Property.new(LIST, {}, []) - -var _output_references: Array = [] - - -func _ready(): - node_type = "NodeRandom" - super._ready() - - outputs.setters["add_callback"] = add_output - outputs.setters["delete_callback"] = modify_on_delete - outputs.setters["get_callback"] = get_outputs - outputs.connect("preview", _refresh) - - if outputs.value.size() <= 0: - load_outputs([]) - _refresh(outputs.value) - - -func _from_dict(dict: Dictionary) -> void: - # check for backwards compatibility v2.x - if dict.has("Target"): - var converter = NodeConverter.new() - dict = converter.convert_dice_roll(dict) - - load_outputs(dict.get("Outputs", [])) - _load_position(dict) - _update() - - -func _load_connections(data: Dictionary, _key: String = "NextID") -> void: - for output in data.get("Outputs"): - link_output(output, output.get("ID")) - - -func _to_next(_dict: Dictionary, _key: String = "NextID") -> void: - pass - - -func add_output(data: Dictionary = {}) -> MonologueRandomOutput: - var output = MonologueRandomOutput.new(self) - output.id.value = _output_references.size() - if data: - output._from_dict(data) - link_output(data, output.id.value) - - _output_references.append(output) - var line_instance := output_line.instantiate() - add_child(line_instance) - line_instance.update_label(str(int(output.weight.value)) + "%") - - # if output was added from scratch, redistribute all equally - if not data: - var share = 100.0 / _output_references.size() - for idx in range(_output_references.size()): - var weight = ceil(share) if idx == 0 else floor(share) - _output_references[idx].weight.value = weight - - var refs = _output_references.slice(0, _output_references.size() - 1) - var dicts = refs.map(func(r): return r._to_dict()) - outputs.propagate(dicts) - - return output - - -func clear_children() -> void: - for child in get_children(): - child.free() - _output_references.clear() - - -func get_outputs() -> Array: - return _output_references - - -func link_output(data: Dictionary, from_port: int): - var next_id = data.get("NextID", -1) - if next_id is String: - var next_node = get_parent().get_node_by_id(next_id) - if next_node: - get_parent().connect_node(name, from_port, next_node.name, 0) - - -func load_outputs(new_output_list: Array): - clear_children() - var ascending = func(a, b): return a.get("ID") < b.get("ID") - new_output_list.sort_custom(ascending) - for output_data in new_output_list: - add_output(output_data) - - if _output_references.is_empty(): - var first = add_output() - var second = add_output() - first.weight.value = 50 - second.weight.value = 50 - new_output_list.append(first._to_dict()) - new_output_list.append(second._to_dict()) - outputs.value = new_output_list - - -func modify_on_delete(data_list: Array): - if data_list: - # reassign IDs on delete - for i in range(data_list.size()): - data_list[i]["ID"] = i - - # rebalance weights if the sum is not equal to 100 - var weights = data_list.map(func(d): return d.get("Weight")) - var sum = weights.reduce(func(total, w): return total + w) - if sum != 100: - var share = 100.0 / data_list.size() - for idx in range(data_list.size()): - var weight = ceil(share) if idx == 0 else floor(share) - data_list[idx]["Weight"] = weight - return data_list - - -## Update the NextID of the output on the given port. -func update_next_id(from_port: int, next_node: MonologueGraphNode): - var output = _output_references[from_port] - var next_value = -1 - if next_node: - next_value = next_node.id.value - output.next_id.value = next_value - outputs.value[from_port] = output._to_dict() - outputs.propagate(outputs.value, false) - - -func _refresh(new_outputs_list: Array): - # disconnect all outbound connections - for connection in get_parent().get_all_outbound_connections(name): - var from_port = connection.get("from_port") - var to_node = connection.get("to_node") - get_parent().disconnect_node(name, from_port, to_node, 0) - clear_children() - - for new_output_data in new_outputs_list: - add_output(new_output_data) - _update() - - -func _update(_new_value: Variant = null) -> void: - for idx in get_child_count(): - set_slot(idx, idx == 0, 0, Color.WHITE, true, 0, Color.WHITE, LEFT_SLOT, RIGHT_SLOT) - super._update() diff --git a/nodes/random_node/random_node.gd.uid b/nodes/random_node/random_node.gd.uid deleted file mode 100644 index bc1d050e..00000000 --- a/nodes/random_node/random_node.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://cx8uppic5c27l diff --git a/nodes/random_node/random_node.tscn b/nodes/random_node/random_node.tscn deleted file mode 100644 index 26f6942e..00000000 --- a/nodes/random_node/random_node.tscn +++ /dev/null @@ -1,10 +0,0 @@ -[gd_scene load_steps=2 format=3 uid="uid://b6mcmodpmsacw"] - -[ext_resource type="Script" uid="uid://cx8uppic5c27l" path="res://nodes/random_node/random_node.gd" id="1_qeufj"] - -[node name="RandomNode" type="GraphNode" groups=["graph_nodes"]] -offset_right = 127.0 -offset_bottom = 53.0 -title = "RandomNode" -script = ExtResource("1_qeufj") -titlebar_color = Color(0.560784, 0.462745, 0.0980392, 1) diff --git a/nodes/random_node/random_output.gd b/nodes/random_node/random_output.gd deleted file mode 100644 index 668dc768..00000000 --- a/nodes/random_node/random_output.gd +++ /dev/null @@ -1,61 +0,0 @@ -## Random output data builder. -class_name MonologueRandomOutput extends RefCounted - -var weight := Property.new(MonologueGraphNode.SPINBOX, {"minimum": 0, "maximum": 100}) -var id := Property.new(MonologueGraphNode.SPINBOX, {}, 0) -var next_id := Property.new(MonologueGraphNode.LINE, {}, -1) - -var graph: MonologueGraphEdit -var graph_node: RandomNode - - -func _init(node: RandomNode): - graph_node = node - graph = node.get_parent() - weight.connect("change", change_output_weight) - id.visible = false - - -func change_output_weight(old_value: Variant, new_value: Variant): - var old_list = graph_node.outputs.value.duplicate(true) - var new_list = graph_node.outputs.value.duplicate(true) - - # new value cannot push total weight to exceed 100 - var clamped = clampi(new_value, 1, 100 - new_list.size() + 1) - new_list[id.value]["Weight"] = clamped - - # make up for missing weight by balancing from next - var weight_sum = new_list.reduce(func(total, n): return total + n.get("Weight"), 0) - var balance = 100 - weight_sum - var count = 1 - while count < new_list.size() and balance != 0: - var i = int(id.value + count) % new_list.size() - var new_weight = new_list[i].get("Weight") + balance - if new_weight < 1: - balance -= new_list[i].get("Weight") - 1 - new_weight = 1 - else: - balance = 0 - new_list[i]["Weight"] = new_weight - count += 1 - - graph.undo_redo.create_action("RandomOutput %s => %s" % [old_value, new_value]) - graph.undo_redo.add_do_property(graph_node.outputs, "value", new_list) - graph.undo_redo.add_do_method(graph_node.outputs.propagate.bind(new_list)) - graph.undo_redo.add_undo_property(graph_node.outputs, "value", old_list) - graph.undo_redo.add_undo_method(graph_node.outputs.propagate.bind(old_list)) - graph.undo_redo.commit_action() - - -func get_property_names() -> PackedStringArray: - return ["weight"] - - -func _from_dict(dict: Dictionary) -> void: - #id.value = dict.get("ID") - weight.value = dict.get("Weight") - next_id.value = dict.get("NextID") - - -func _to_dict(): - return {"ID": id.value, "Weight": weight.value, "NextID": next_id.value} diff --git a/nodes/random_node/random_output.gd.uid b/nodes/random_node/random_output.gd.uid deleted file mode 100644 index abc14ac5..00000000 --- a/nodes/random_node/random_output.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://deywhjcajo6if diff --git a/nodes/reroute_node/reroute_node.gd b/nodes/reroute_node/reroute_node.gd deleted file mode 100644 index fd4fc1c5..00000000 --- a/nodes/reroute_node/reroute_node.gd +++ /dev/null @@ -1,20 +0,0 @@ -class_name RerouteNode extends MonologueGraphNode - -@onready var drag_panel: PanelContainer = $Control/CenterContainer/DragPanel - - -func _ready() -> void: - drag_panel.modulate.a = 0 - node_type = "NodeReroute" - super._ready() - title = "" - - -func _on_mouse_entered() -> void: - var tween: Tween = create_tween() - tween.tween_property(drag_panel, "modulate:a", 1, 0.1) - - -func _on_mouse_exited() -> void: - var tween: Tween = create_tween() - tween.tween_property(drag_panel, "modulate:a", 0, 0.1) diff --git a/nodes/reroute_node/reroute_node.gd.uid b/nodes/reroute_node/reroute_node.gd.uid deleted file mode 100644 index af5cff43..00000000 --- a/nodes/reroute_node/reroute_node.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://dar0qh0amas7f diff --git a/nodes/reroute_node/reroute_node.tscn b/nodes/reroute_node/reroute_node.tscn deleted file mode 100644 index 90f18eb6..00000000 --- a/nodes/reroute_node/reroute_node.tscn +++ /dev/null @@ -1,87 +0,0 @@ -[gd_scene load_steps=9 format=3 uid="uid://b4n4q43gfk82"] - -[ext_resource type="Script" uid="uid://dar0qh0amas7f" path="res://nodes/reroute_node/reroute_node.gd" id="1_2xjs7"] -[ext_resource type="Texture2D" uid="uid://blumv8ks5udd0" path="res://ui/assets/icons/move.svg" id="2_qvw7q"] - -[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_f11gq"] - -[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_0vsom"] - -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_eb0dt"] -content_margin_left = 16.0 -content_margin_top = 16.0 -content_margin_right = 16.0 -content_margin_bottom = 16.0 -bg_color = Color(0.952941, 0.352941, 0.572549, 0) - -[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_pfaoj"] -content_margin_left = 16.0 -content_margin_top = 16.0 -content_margin_right = 16.0 -content_margin_bottom = 16.0 - -[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_m1v7b"] - -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_03oiu"] -bg_color = Color(0.192157, 0.192157, 0.211765, 1) -corner_radius_top_left = 20 -corner_radius_top_right = 20 -corner_radius_bottom_right = 20 -corner_radius_bottom_left = 20 -corner_detail = 20 - -[node name="RerouteNode" type="GraphNode"] -custom_minimum_size = Vector2(60, 0) -anchors_preset = -1 -anchor_right = 0.04 -anchor_bottom = 0.094 -offset_right = -20.0 -offset_bottom = -0.199997 -mouse_filter = 1 -theme_override_constants/port_h_offset = 30 -theme_override_styles/panel = SubResource("StyleBoxEmpty_f11gq") -theme_override_styles/panel_selected = SubResource("StyleBoxEmpty_0vsom") -theme_override_styles/titlebar = SubResource("StyleBoxFlat_eb0dt") -theme_override_styles/titlebar_selected = SubResource("StyleBoxEmpty_pfaoj") -theme_override_styles/slot = SubResource("StyleBoxEmpty_m1v7b") -slot/0/left_enabled = true -slot/0/left_type = 0 -slot/0/left_color = Color(1, 1, 1, 1) -slot/0/left_icon = null -slot/0/right_enabled = true -slot/0/right_type = 0 -slot/0/right_color = Color(1, 1, 1, 1) -slot/0/right_icon = null -slot/0/draw_stylebox = false -script = ExtResource("1_2xjs7") -show_close_button = false -show_titlebar = false - -[node name="Control" type="Control" parent="."] -layout_mode = 2 -mouse_filter = 1 - -[node name="CenterContainer" type="CenterContainer" parent="Control"] -layout_mode = 1 -anchors_preset = 10 -anchor_right = 1.0 -offset_top = -53.0 -offset_bottom = -13.0 -grow_horizontal = 2 - -[node name="DragPanel" type="PanelContainer" parent="Control/CenterContainer"] -custom_minimum_size = Vector2(40, 40) -layout_mode = 2 -mouse_filter = 1 -theme_override_styles/panel = SubResource("StyleBoxFlat_03oiu") - -[node name="CenterContainer" type="CenterContainer" parent="Control/CenterContainer/DragPanel"] -layout_mode = 2 - -[node name="TextureRect" type="TextureRect" parent="Control/CenterContainer/DragPanel/CenterContainer"] -layout_mode = 2 -texture = ExtResource("2_qvw7q") -stretch_mode = 3 - -[connection signal="mouse_entered" from="Control/CenterContainer" to="." method="_on_mouse_entered"] -[connection signal="mouse_exited" from="Control/CenterContainer" to="." method="_on_mouse_exited"] diff --git a/nodes/root_node/index.gd b/nodes/root_node/index.gd new file mode 100644 index 00000000..792b067c --- /dev/null +++ b/nodes/root_node/index.gd @@ -0,0 +1,24 @@ +extends MonologueIndexer + +const NODE_SCRIPT := preload("res://nodes/root_node/root_node.gd") +const ICON_PATH := "res://ui/assets/icons/root.svg" + + +func get_scene() -> PackedScene: + return null + + +func get_metadata() -> Dictionary: + return { + "name": "root", + "type": ObjectType.NODE, + "display_name": "Root", + "category": "Flow", + "script": NODE_SCRIPT, + "icon": ICON_PATH, + "color": Color("ffffff") + } + + +func get_node_script() -> Script: + return NODE_SCRIPT diff --git a/nodes/root_node/index.gd.uid b/nodes/root_node/index.gd.uid new file mode 100644 index 00000000..a6d662ca --- /dev/null +++ b/nodes/root_node/index.gd.uid @@ -0,0 +1 @@ +uid://c5djdhldg6qbu diff --git a/nodes/root_node/root_node.gd b/nodes/root_node/root_node.gd index 12ad5d29..48db27d1 100644 --- a/nodes/root_node/root_node.gd +++ b/nodes/root_node/root_node.gd @@ -1,80 +1,26 @@ @icon("res://ui/assets/icons/root.svg") -class_name RootNode extends MonologueGraphNode +class_name RootNode extends InspectableNode -var characters := Property.new(LIST, {}, []) -var variables := Property.new(LIST, {}, []) -var _character_references = [] -var _variable_references = [] +func initialize_properties() -> void: + define_main_property("root", "context", false, null, {"exposed": false}) -func _ready(): - node_type = "NodeRoot" - super._ready() +func get_type() -> String: + return "root" - load_character(get_parent().characters) - characters.setters["add_callback"] = add_character - characters.setters["get_callback"] = get_speakers - characters.connect("preview", load_character) - load_variables(get_parent().variables) - variables.setters["add_callback"] = add_variable - variables.setters["get_callback"] = get_variables - variables.connect("preview", load_variables) +func get_settings() -> Dictionary: + return {} -func add_character(data: Dictionary = {}) -> MonologueCharacter: - var character = MonologueCharacter.new(self) - if data: - character._from_dict(data) - character.idx.value = _character_references.size() - character.character.setters["character_index"] = character.idx.value - _character_references.append(character) - return character +func get_icon() -> Texture2D: + return Texture2D.new() -func add_variable(data: Dictionary = {}) -> MonologueVariable: - var variable = MonologueVariable.new(self) - if data: - variable._from_dict(data) - variable.index = _variable_references.size() - _variable_references.append(variable) - return variable +func get_color() -> Color: + return Color.WHITE -func get_speakers(): - return _character_references - - -func get_variables(): - return _variable_references - - -## Perform initial loading of speakers and set indexes correctly. -func load_character(new_character_list: Array): - _character_references.clear() - var ascending = func(a, b): return a.get("EditorIndex") < b.get("EditorIndex") - new_character_list.sort_custom(ascending) - for speaker_data in new_character_list: - add_character(speaker_data) - - if _character_references.is_empty(): - var narrator = add_character() - narrator.character.value["Name"] = "_NARRATOR" - narrator.protected.value = true - new_character_list.append(narrator._to_dict()) - - characters.value = new_character_list - get_graph_edit().characters = new_character_list - - -func load_variables(new_variable_list: Array): - _variable_references.clear() - for variable in new_variable_list: - add_variable(variable) - variables.value = new_variable_list - get_graph_edit().variables = new_variable_list - - -func _to_fields(_dict: Dictionary) -> void: - pass # speakers and variables are stored outside of root node +func _on_property_changed(_pname: String, _old_value: Variant, _new_value: Variant) -> void: + pass diff --git a/nodes/root_node/root_node.tscn b/nodes/root_node/root_node.tscn deleted file mode 100644 index 58106c43..00000000 --- a/nodes/root_node/root_node.tscn +++ /dev/null @@ -1,31 +0,0 @@ -[gd_scene load_steps=2 format=3 uid="uid://dqsnkyn3r76m4"] - -[ext_resource type="Script" uid="uid://csx2ec4ra5m8k" path="res://nodes/root_node/root_node.gd" id="1_e8g7i"] - -[node name="RootNode" type="GraphNode" groups=["graph_nodes"]] -offset_right = 282.0 -offset_bottom = 78.0 -size_flags_vertical = 0 -title = "RootNode" -slot/0/left_enabled = false -slot/0/left_type = 0 -slot/0/left_color = Color(1, 1, 1, 1) -slot/0/left_icon = null -slot/0/right_enabled = true -slot/0/right_type = 0 -slot/0/right_color = Color(1, 1, 1, 1) -slot/0/right_icon = null -slot/0/draw_stylebox = false -script = ExtResource("1_e8g7i") -titlebar_color = Color(0, 0, 0, 1) -show_close_button = false - -[node name="VBoxContainer" type="VBoxContainer" parent="."] -layout_mode = 2 -size_flags_vertical = 3 -alignment = 1 - -[node name="Label" type="Label" parent="VBoxContainer"] -layout_mode = 2 -theme_type_variation = &"NoteLabel" -text = "Select this node to edit settings" diff --git a/nodes/sentence_node/index.gd b/nodes/sentence_node/index.gd new file mode 100644 index 00000000..ae82eeb5 --- /dev/null +++ b/nodes/sentence_node/index.gd @@ -0,0 +1,24 @@ +extends MonologueIndexer + +const NODE_SCRIPT := preload("res://nodes/sentence_node/sentence_node.gd") +const ICON_PATH := "res://ui/assets/icons/text.svg" + + +func get_scene() -> PackedScene: + return null + + +func get_metadata() -> Dictionary: + return { + "name": "sentence", + "type": ObjectType.NODE, + "display_name": "Sentence", + "category": "Narration", + "script": NODE_SCRIPT, + "icon": ICON_PATH, + "color": Color("af85fdff") + } + + +func get_node_script() -> Script: + return NODE_SCRIPT diff --git a/nodes/sentence_node/index.gd.uid b/nodes/sentence_node/index.gd.uid new file mode 100644 index 00000000..7b83af61 --- /dev/null +++ b/nodes/sentence_node/index.gd.uid @@ -0,0 +1 @@ +uid://b165nmgmvcms diff --git a/nodes/sentence_node/sentence_node.gd b/nodes/sentence_node/sentence_node.gd index 81b29dbf..c13848c9 100644 --- a/nodes/sentence_node/sentence_node.gd +++ b/nodes/sentence_node/sentence_node.gd @@ -1,47 +1,30 @@ @icon("res://ui/assets/icons/text.svg") -class_name SentenceNode extends MonologueGraphNode +class_name SentenceNode extends InspectableNode -var speaker := Property.new(DROPDOWN, {"store_index": true}, 0) -var display_name := Property.new(LINE) -var sentence := Localizable.new(TEXT) -var voiceline := Localizable.new(FILE, {"filters": FilePicker.AUDIO}) -@onready var _preview = $TextLabelPreview +func initialize_properties() -> void: + define_main_property("sentence", "context", false, null, {"export": true}) + define_property("speaker", "", "dropdown", {"source": "characters"}) + define_property("display_name", "", "text") + define_property("line", "", "text") + define_property("voiceline", "", "file", {"visible_in_graph": false}) -func _ready(): - node_type = "NodeSentence" - sentence.connect("preview", _on_text_preview) - voiceline.setters["base_path"] = get_graph_edit().file_path - super._ready() - _update() +func get_type() -> String: + return "sentence" -func reload_preview() -> void: - _preview.text = sentence.value +func get_settings() -> Dictionary: + return {} -func _from_dict(dict: Dictionary): - # special handling for backwards compatibility v2.x - speaker.value = dict.get("SpeakerID", 0) - display_name.value = dict.get("DisplaySpeakerName", "") - voiceline.value = dict.get("VoicelinePath", "") - super._from_dict(dict) +func get_icon() -> Texture2D: + return Texture2D.new() -func _on_text_preview(text: Variant): - _preview.text = str(text) +func get_color() -> Color: + return Color.WHITE -func _update(): - super._update() - - var characters: Array = get_graph_edit().characters - speaker.callers["set_items"] = [characters, "Character/Name", "EditorIndex"] - if speaker.value is String: - speaker.value = 0 - reload_preview() - - -func _get_field_groups() -> Array: - return [{"Speaker": ["speaker", "display_name"]}] +func _on_property_changed(_pname: String, _old_value: Variant, _new_value: Variant) -> void: + pass diff --git a/nodes/sentence_node/sentence_node.tscn b/nodes/sentence_node/sentence_node.tscn deleted file mode 100644 index bb0b5e36..00000000 --- a/nodes/sentence_node/sentence_node.tscn +++ /dev/null @@ -1,32 +0,0 @@ -[gd_scene load_steps=2 format=3 uid="uid://cifg2nritn8t6"] - -[ext_resource type="Script" uid="uid://bm2we18ivulms" path="res://nodes/sentence_node/sentence_node.gd" id="1_at5jy"] - -[node name="SentenceNode" type="GraphNode" groups=["graph_nodes"]] -custom_minimum_size = Vector2(400, 100) -offset_right = 400.0 -offset_bottom = 100.0 -size_flags_vertical = 0 -title = "NodeSentence" -slot/0/left_enabled = true -slot/0/left_type = 0 -slot/0/left_color = Color(1, 1, 1, 1) -slot/0/left_icon = null -slot/0/right_enabled = true -slot/0/right_type = 0 -slot/0/right_color = Color(1, 1, 1, 1) -slot/0/right_icon = null -slot/0/draw_stylebox = false -script = ExtResource("1_at5jy") -titlebar_color = Color(0.835294, 0.317647, 0.376471, 1) - -[node name="TextLabelPreview" type="RichTextLabel" parent="."] -layout_mode = 2 -size_flags_vertical = 3 -mouse_filter = 2 -theme_override_colors/default_color = Color(0.72549, 0.72549, 0.72549, 1) -bbcode_enabled = true -fit_content = true -scroll_following = true - -[connection signal="resize_request" from="." to="." method="_on_GraphNode_resize_request"] diff --git a/nodes/setter_node/setter_node.gd b/nodes/setter_node/setter_node.gd deleted file mode 100644 index eecf1a2a..00000000 --- a/nodes/setter_node/setter_node.gd +++ /dev/null @@ -1,63 +0,0 @@ -class_name SetterNode extends AbstractVariableNode - -var set_type := Property.new(DROPDOWN, {}, "Option") -var option_id := Property.new(LINE) -var enable := Property.new(TOGGLE) - -var _control_groups = {"Option": [option_id, enable], "Variable": [variable, operator, value]} - -@onready var _option_container = $OptionContainer -@onready var _option_id_label = $OptionContainer/OptionIdLabel -@onready var _bool_label = $OptionContainer/BoolLabel -@onready var _variable_container = $VariableContainer - - -func _ready() -> void: - node_type = "NodeSetter" - set_type.callers["set_items"] = [ - [ - {"id": 0, "text": "Option"}, - {"id": 1, "text": "Variable"}, - ] - ] - set_type.connect("preview", _show_group) - set_type.connect("preview", _update) - option_id.connect("preview", _option_id_label.set_text) - enable.connect("preview", func(e): _bool_label.text = str(e)) - - super._ready() - _show_group(set_type.value) - _update(set_type.value) - - -func get_variable_label() -> Label: - return $VariableContainer/VariableLabel - - -func get_operator_label() -> Label: - return $VariableContainer/OperatorLabel - - -func get_value_label() -> Label: - return $VariableContainer/ValueLabel - - -func _from_dict(dict: Dictionary) -> void: - record_morph(dict.get("Value")) - super._from_dict(dict) - _show_group(set_type.value) - - -func _show_group(setter_type: Variant) -> void: - for key in _control_groups.keys(): - for property in _control_groups.get(key): - property.visible = key == setter_type - - -func _update(setter_type: Variant = set_type.value) -> void: - _option_container.visible = setter_type == "Option" - _option_id_label.text = get_default_text(option_id.value, "option id") - _bool_label.text = get_default_text(enable.value, "false") - - _variable_container.visible = setter_type == "Variable" - super._update() diff --git a/nodes/setter_node/setter_node.gd.uid b/nodes/setter_node/setter_node.gd.uid deleted file mode 100644 index 461dc7a4..00000000 --- a/nodes/setter_node/setter_node.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://c8qi7r33gmf1i diff --git a/nodes/setter_node/setter_node.tscn b/nodes/setter_node/setter_node.tscn deleted file mode 100644 index da26c1f4..00000000 --- a/nodes/setter_node/setter_node.tscn +++ /dev/null @@ -1,81 +0,0 @@ -[gd_scene load_steps=3 format=3 uid="uid://qd3nbp87ls3r"] - -[ext_resource type="Script" uid="uid://c8qi7r33gmf1i" path="res://nodes/setter_node/setter_node.gd" id="3_3ny3s"] - -[sub_resource type="Theme" id="Theme_llmqa"] - -[node name="SetterNode" type="GraphNode" groups=["graph_nodes"]] -offset_right = 300.0 -offset_bottom = 132.0 -size_flags_horizontal = 0 -size_flags_vertical = 0 -theme = SubResource("Theme_llmqa") -title = "SetterNode" -slot/0/left_enabled = true -slot/0/left_type = 0 -slot/0/left_color = Color(1, 1, 1, 1) -slot/0/left_icon = null -slot/0/right_enabled = true -slot/0/right_type = 0 -slot/0/right_color = Color(1, 1, 1, 1) -slot/0/right_icon = null -slot/0/draw_stylebox = false -slot/1/left_enabled = false -slot/1/left_type = 0 -slot/1/left_color = Color(1, 1, 1, 1) -slot/1/left_icon = null -slot/1/right_enabled = false -slot/1/right_type = 0 -slot/1/right_color = Color(1, 1, 1, 1) -slot/1/right_icon = null -slot/1/draw_stylebox = true -script = ExtResource("3_3ny3s") -titlebar_color = Color(0.733333, 0.392157, 0.188235, 1) - -[node name="OptionContainer" type="HBoxContainer" parent="."] -layout_mode = 2 -mouse_filter = 2 -theme_type_variation = &"HBoxContainer_Small" - -[node name="DescriptorLabel" type="Label" parent="OptionContainer"] -layout_mode = 2 -text = "Enable option" - -[node name="OptionIdLabel" type="Label" parent="OptionContainer"] -layout_mode = 2 -theme_type_variation = &"NodeValue" -text = "option id" - -[node name="QuestionLabel" type="Label" parent="OptionContainer"] -layout_mode = 2 -text = "?" - -[node name="BoolLabel" type="Label" parent="OptionContainer"] -layout_mode = 2 -theme_type_variation = &"NodeValue" -text = "value" - -[node name="VariableContainer" type="HBoxContainer" parent="."] -layout_mode = 2 -mouse_filter = 2 -theme_type_variation = &"HBoxContainer_Small" - -[node name="DescriptorLabel" type="Label" parent="VariableContainer"] -layout_mode = 2 -text = "Set" - -[node name="VariableLabel" type="Label" parent="VariableContainer"] -layout_mode = 2 -theme_type_variation = &"NodeValue" -text = "variable" - -[node name="OperatorLabel" type="Label" parent="VariableContainer"] -layout_mode = 2 -theme_type_variation = &"NodeValue" -text = "operator" - -[node name="ValueLabel" type="Label" parent="VariableContainer"] -layout_mode = 2 -size_flags_horizontal = 4 -theme_type_variation = &"NodeValue" -text = "value" diff --git a/nodes/text_node/index.gd b/nodes/text_node/index.gd new file mode 100644 index 00000000..dfff9c8e --- /dev/null +++ b/nodes/text_node/index.gd @@ -0,0 +1,24 @@ +extends MonologueIndexer + +const NODE_SCRIPT := preload("res://nodes/text_node/text_node.gd") +const ICON_PATH := "res://ui/assets/icons/text.svg" + + +func get_scene() -> PackedScene: + return null + + +func get_metadata() -> Dictionary: + return { + "name": "text", + "type": ObjectType.NODE, + "display_name": "Text", + "category": "Narration", + "script": NODE_SCRIPT, + "icon": ICON_PATH, + "color": Color("af85fdff") + } + + +func get_node_script() -> Script: + return NODE_SCRIPT diff --git a/nodes/text_node/index.gd.uid b/nodes/text_node/index.gd.uid new file mode 100644 index 00000000..97e0fbb6 --- /dev/null +++ b/nodes/text_node/index.gd.uid @@ -0,0 +1 @@ +uid://b67i013h21w4e diff --git a/nodes/text_node/text_node.gd b/nodes/text_node/text_node.gd new file mode 100644 index 00000000..5bb7583a --- /dev/null +++ b/nodes/text_node/text_node.gd @@ -0,0 +1,26 @@ +@icon("res://ui/assets/icons/text.svg") +class_name TextNode extends InspectableNode + + +func initialize_properties() -> void: + define_main_property("text", "text", true, "", {"exposed": false}) + + +func get_type() -> String: + return "text" + + +func get_settings() -> Dictionary: + return {} + + +func get_icon() -> Texture2D: + return Texture2D.new() + + +func get_color() -> Color: + return Color.WHITE + + +func _on_property_changed(_pname: String, _old_value: Variant, _new_value: Variant) -> void: + pass diff --git a/nodes/text_node/text_node.gd.uid b/nodes/text_node/text_node.gd.uid new file mode 100644 index 00000000..f33d766f --- /dev/null +++ b/nodes/text_node/text_node.gd.uid @@ -0,0 +1 @@ +uid://8hoiik6d0qim diff --git a/nodes/wait_node/wait_node.gd b/nodes/wait_node/wait_node.gd deleted file mode 100644 index f54034cc..00000000 --- a/nodes/wait_node/wait_node.gd +++ /dev/null @@ -1,20 +0,0 @@ -class_name WaitNode extends MonologueGraphNode - -var time := Property.new(SPINBOX, {"minimum": 0, "maximum": 120}) - -@onready var wait_label := $HBox/WaitLabel - - -func _ready() -> void: - node_type = "NodeWait" - super._ready() - time.connect("preview", _on_wait_preview) - - -func _on_wait_preview(value: Variant): - wait_label.text = str(int(value)) - - -func _update(): - wait_label.text = str(int(time.value)) - super._update() diff --git a/nodes/wait_node/wait_node.gd.uid b/nodes/wait_node/wait_node.gd.uid deleted file mode 100644 index 7ffcd60a..00000000 --- a/nodes/wait_node/wait_node.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://b804pp3yjytjr diff --git a/nodes/wait_node/wait_node.tscn b/nodes/wait_node/wait_node.tscn deleted file mode 100644 index 8ee49b91..00000000 --- a/nodes/wait_node/wait_node.tscn +++ /dev/null @@ -1,44 +0,0 @@ -[gd_scene load_steps=3 format=3 uid="uid://bxu71eq40qoq6"] - -[ext_resource type="Script" uid="uid://b804pp3yjytjr" path="res://nodes/wait_node/wait_node.gd" id="3_n44rg"] - -[sub_resource type="LabelSettings" id="LabelSettings_82fue"] -font_color = Color(0.572549, 0.572549, 0.572549, 1) - -[node name="WaitNode" type="GraphNode" groups=["graph_nodes"]] -custom_minimum_size = Vector2(200, 0) -offset_right = 200.0 -offset_bottom = 82.0 -size_flags_vertical = 0 -title = "NodeWait" -slot/0/left_enabled = true -slot/0/left_type = 0 -slot/0/left_color = Color(1, 1, 1, 1) -slot/0/left_icon = null -slot/0/right_enabled = true -slot/0/right_type = 0 -slot/0/right_color = Color(1, 1, 1, 1) -slot/0/right_icon = null -slot/0/draw_stylebox = false -script = ExtResource("3_n44rg") -titlebar_color = Color(0.360784, 0.501961, 0.184314, 1) - -[node name="HBox" type="HBoxContainer" parent="."] -layout_mode = 2 -mouse_filter = 2 -theme_type_variation = &"HBoxContainer_Small" - -[node name="Label" type="Label" parent="HBox"] -layout_mode = 2 -text = "Wait" - -[node name="WaitLabel" type="Label" parent="HBox"] -layout_mode = 2 -theme_type_variation = &"NodeValue" -text = "0" - -[node name="Label2" type="Label" parent="HBox"] -layout_mode = 2 -text = "seconds" - -[connection signal="resize_request" from="." to="." method="_on_GraphNode_resize_request"] \ No newline at end of file diff --git a/project.godot b/project.godot index 3cb34d31..11ce2601 100644 --- a/project.godot +++ b/project.godot @@ -20,23 +20,28 @@ config/tags=PackedStringArray("monologue") run/main_scene="res://scenes/splash/splash.tscn" run/print_header=false run/enable_alt_space_menu=true -config/features=PackedStringArray("4.4") +config/features=PackedStringArray("4.5") boot_splash/bg_color=Color(0.117647, 0.117647, 0.129412, 1) boot_splash/show_image=false -config/icon="res://icon.png" +config/icon="uid://b2ebpoey21tpc" [autoload] Constants="*res://autoloads/constants.gd" +IDGen="*res://autoloads/id_gen.gd" App="*res://autoloads/app.gd" +ThemeManager="*res://autoloads/theme_manager.gd" GlobalVariables="*res://autoloads/global_variables.gd" GlobalSignal="*res://autoloads/global_signal.gd" Util="*res://autoloads/util.gd" SfxLoader="*res://autoloads/sfx_loader.gd" Path="*res://autoloads/path.gd" -IDGen="*res://autoloads/id_gen.gd" Cursor="*res://autoloads/cursor.gd" ImageLoader="*res://autoloads/image_loader.gd" +UndoRedoService="*res://autoloads/undo_redo_service.gd" +FieldBucket="*res://common/ui/editor_properties/field_bucket.gd" +NodeBucket="*res://common/nodes/node_bucket.gd" +StorylineManager="*res://autoloads/storyline_manager.gd" [debug] @@ -46,7 +51,6 @@ gdscript/warnings/integer_division=0 window/size/viewport_width=1400 window/size/viewport_height=800 -window/size/resizable=false window/size/transparent=true window/size/extend_to_title=true window/energy_saving/keep_screen_on=false @@ -55,7 +59,7 @@ window/size/fullscreen=true [editor_plugins] -enabled=PackedStringArray("res://addons/Todo_Manager/plugin.cfg", "res://addons/gdUnit4/plugin.cfg", "res://addons/monologue/plugin.cfg") +enabled=PackedStringArray("res://addons/Todo_Manager/plugin.cfg", "res://addons/beautify_code_on_save/plugin.cfg", "res://addons/dockable_container/plugin.cfg", "res://addons/gdUnit4/plugin.cfg") [file_customization] @@ -75,10 +79,44 @@ ui/inspector/tree_view_mode=1 [gui] -theme/custom="uid://budfhk1hudcfj" -theme/custom_font="uid://xxjublydw27h" theme/default_font_hinting=2 +theme/default_font_multichannel_signed_distance_field=true theme/lcd_subpixel_layout=0 +theme/custom="uid://budfhk1hudcfj" +theme/custom_font="uid://xxjublydw27h" + +[importer_defaults] + +font_data_dynamic={ +"Compress": null, +"Fallbacks": null, +"Rendering": null, +"allow_system_fallback": true, +"antialiasing": 1, +"compress": true, +"disable_embedded_bitmaps": true, +"fallbacks": [], +"force_autohinter": false, +"generate_mipmaps": false, +"hinting": 1, +"keep_rounding_remainders": true, +"language_support": {}, +"modulate_color_glyphs": false, +"msdf_pixel_range": 8, +"msdf_size": 48, +"multichannel_signed_distance_field": false, +"opentype_features": {}, +"oversampling": 2.0, +"preload": [{ +"chars": [], +"glyphs": [], +"name": "Nouvelle configuration", +"size": Vector2i(16, 0), +&"variation_embolden": 0.0 +}], +"script_support": {}, +"subpixel_positioning": 4 +} [input] diff --git a/scenes/main/app.tscn b/scenes/main/app.tscn index 4263e148..a66684b2 100644 --- a/scenes/main/app.tscn +++ b/scenes/main/app.tscn @@ -1,14 +1,10 @@ -[gd_scene load_steps=14 format=3 uid="uid://bim51g1aibuw0"] +[gd_scene load_steps=10 format=3 uid="uid://bim51g1aibuw0"] -[ext_resource type="Texture2D" uid="uid://dd8v3hpxxk33d" path="res://ui/assets/icons/logo_white.svg" id="1_1u5fg"] -[ext_resource type="PackedScene" uid="uid://bqjfdabrxujp7" path="res://scenes/main/graph.tscn" id="1_kiov6"] -[ext_resource type="Texture2D" uid="uid://hlck6y4i3l5q" path="res://ui/assets/icons/plus.svg" id="3_gcdaj"] -[ext_resource type="Script" uid="uid://m1wxne1g6kju" path="res://scenes/main/main_menu.gd" id="4_f1t0i"] +[ext_resource type="PackedScene" uid="uid://bqjfdabrxujp7" path="res://scenes/main/editor.tscn" id="1_kiov6"] [ext_resource type="Shader" uid="uid://de1ql8ahad2ts" path="res://common/blur.gdshader" id="5_1u5fg"] [ext_resource type="PackedScene" uid="uid://bcs6s2yuf374j" path="res://common/layouts/expanded_text_edit/expanded_text_edit_container.tscn" id="6_cqyrh"] -[ext_resource type="Script" uid="uid://d0xgy6gflipxs" path="res://common/layouts/dimmer/dimmer.gd" id="6_nw038"] +[ext_resource type="Script" uid="uid://d0xgy6gflipxs" path="res://common/layouts/editor/editor_dimmer.gd" id="6_nw038"] [ext_resource type="PackedScene" uid="uid://c7cf7rfwnhf77" path="res://common/layouts/character_edit/character_edit.tscn" id="7_7qdje"] -[ext_resource type="PackedScene" uid="uid://cmpsaafag7cwl" path="res://common/windows/graph_node_picker/graph_node_picker.tscn" id="7_nw038"] [ext_resource type="PackedScene" uid="uid://d3f7d4bb40iht" path="res://common/windows/preview_window/preview_window.tscn" id="8_7qdje"] [ext_resource type="PackedScene" uid="uid://bqqcww601rcx5" path="res://common/windows/welcome_window/welcome_window.tscn" id="9_fp7qq"] [ext_resource type="Script" uid="uid://b2l7hjfyrnr3x" path="res://common/windows/file_dialog/file_dialog.gd" id="10_r77hi"] @@ -44,45 +40,14 @@ theme_type_variation = &"EditorBackground" layout_mode = 2 theme_override_constants/separation = 0 -[node name="CustomTitleBar" type="HBoxContainer" parent="Frame/VBoxContainer"] -custom_minimum_size = Vector2(0, 40) -layout_mode = 2 -theme_override_constants/separation = 0 - -[node name="MainPopupMenu" type="MenuButton" parent="Frame/VBoxContainer/CustomTitleBar"] -custom_minimum_size = Vector2(43, 0) -layout_mode = 2 -icon = ExtResource("1_1u5fg") -icon_alignment = 1 -expand_icon = true -script = ExtResource("4_f1t0i") - -[node name="VSeparator" type="VSeparator" parent="Frame/VBoxContainer/CustomTitleBar"] -layout_mode = 2 - -[node name="HBoxContainer2" type="HBoxContainer" parent="Frame/VBoxContainer/CustomTitleBar"] -layout_mode = 2 -size_flags_horizontal = 3 -theme_override_constants/separation = 0 - -[node name="TabBar" type="TabBar" parent="Frame/VBoxContainer/CustomTitleBar/HBoxContainer2"] -layout_mode = 2 -current_tab = 0 -clip_tabs = false -tab_count = 1 -tab_0/icon = ExtResource("3_gcdaj") - -[node name="HSeparator" type="HSeparator" parent="Frame/VBoxContainer"] -layout_mode = 2 -theme_override_constants/separation = 1 - -[node name="MonologueControl" parent="Frame/VBoxContainer" node_paths=PackedStringArray("welcome_window", "graph_node_picker") instance=ExtResource("1_kiov6")] +[node name="MonologueEditor" parent="Frame/VBoxContainer" node_paths=PackedStringArray("welcome_window", "graph_container", "file_dialog") instance=ExtResource("1_kiov6")] layout_mode = 2 welcome_window = NodePath("../../../WelcomeWindow") -graph_node_picker = NodePath("../../../GraphNodePicker") +graph_container = NodePath("DockableContainer/Graph/GraphContainer") +file_dialog = NodePath("../../../FileDialog") -[node name="GraphEditSwitcher" parent="Frame/VBoxContainer/MonologueControl/MainContainer/GraphEditsArea" index="0" node_paths=PackedStringArray("tab_bar")] -tab_bar = NodePath("../../../../CustomTitleBar/HBoxContainer2/TabBar") +[node name="GraphContainer" parent="Frame/VBoxContainer/MonologueEditor/DockableContainer/Graph" index="0" node_paths=PackedStringArray("inspector_panel")] +inspector_panel = NodePath("../../Inspector") [node name="Dimmer" type="ColorRect" parent="."] visible = false @@ -106,13 +71,6 @@ visible = false z_index = 2 layout_mode = 1 -[node name="GraphNodePicker" parent="." node_paths=PackedStringArray("switcher") instance=ExtResource("7_nw038")] -visible = false -keep_title_visible = false -content_scale_mode = 2 -content_scale_aspect = 1 -switcher = NodePath("../Frame/VBoxContainer/MonologueControl/MainContainer/GraphEditsArea/GraphEditSwitcher") - [node name="PreviewWindow" parent="." instance=ExtResource("8_7qdje")] visible = false @@ -127,7 +85,10 @@ access = 2 use_native_dialog = true script = ExtResource("10_r77hi") +[connection signal="gui_input" from="Dimmer" to="Dimmer" method="_on_gui_input"] [connection signal="visibility_changed" from="CharacterEditContainer" to="CharacterEditContainer" method="_on_visibility_changed"] [connection signal="file_selected" from="FileDialog" to="FileDialog" method="_on_file_selected"] -[editable path="Frame/VBoxContainer/MonologueControl"] +[editable path="Frame/VBoxContainer/MonologueEditor"] +[editable path="Frame/VBoxContainer/MonologueEditor/DockableContainer/Graph"] +[editable path="Frame/VBoxContainer/MonologueEditor/DockableContainer/Inspector"] diff --git a/scenes/main/editor.tscn b/scenes/main/editor.tscn new file mode 100644 index 00000000..65b9af98 --- /dev/null +++ b/scenes/main/editor.tscn @@ -0,0 +1,186 @@ +[gd_scene load_steps=24 format=3 uid="uid://bqjfdabrxujp7"] + +[ext_resource type="Script" uid="uid://q6eg6rid6xqd" path="res://scenes/main/monologue_editor.gd" id="1_ovo1o"] +[ext_resource type="Script" uid="uid://k2o7qui1lr6l" path="res://addons/dockable_container/dockable_container.gd" id="2_xxwqg"] +[ext_resource type="Texture2D" uid="uid://dd8v3hpxxk33d" path="res://ui/assets/icons/logo_white.svg" id="3_mei7o"] +[ext_resource type="Script" uid="uid://bh202gagkdkar" path="res://addons/dockable_container/layout_panel.gd" id="3_uvwqm"] +[ext_resource type="Script" uid="uid://dos02hjhrf1ws" path="res://addons/dockable_container/layout_split.gd" id="4_kkjrq"] +[ext_resource type="Script" uid="uid://m1wxne1g6kju" path="res://scenes/main/main_menu.gd" id="4_pwbil"] +[ext_resource type="Script" uid="uid://cylirj261q6ru" path="res://addons/dockable_container/layout.gd" id="5_svwnc"] +[ext_resource type="Script" uid="uid://cpi3ixjp3ye17" path="res://scenes/main/tab_bar.gd" id="6_2cy6n"] +[ext_resource type="PackedScene" uid="uid://mfdu320oy6ex" path="res://common/layouts/editor/editor_list_section.tscn" id="6_mei7o"] +[ext_resource type="PackedScene" uid="uid://c8525nhvwt1y0" path="res://common/layouts/editor/graph.tscn" id="9_qd5yd"] +[ext_resource type="PackedScene" uid="uid://dgvhvxdrd58qp" path="res://common/layouts/editor/inspector/inspector_panel.tscn" id="14_craj7"] +[ext_resource type="Script" uid="uid://q0oqx6butjwn" path="res://scenes/main/search_bar_container.gd" id="15_35jwg"] +[ext_resource type="PackedScene" uid="uid://cmpsaafag7cwl" path="res://common/windows/graph_node_picker/graph_node_picker.tscn" id="15_q62vd"] +[ext_resource type="PackedScene" uid="uid://cvum3eaenloix" path="res://common/layouts/search_bar/search_bar.tscn" id="16_n4eqx"] + +[sub_resource type="Resource" id="Resource_g5pcf"] +resource_name = "Tabs" +script = ExtResource("3_uvwqm") +names = PackedStringArray("_Tabs") + +[sub_resource type="Resource" id="Resource_xxwqg"] +resource_name = "Tabs" +script = ExtResource("3_uvwqm") +names = PackedStringArray("Characters", "Variables", "Items", "Locations") + +[sub_resource type="Resource" id="Resource_uvwqm"] +resource_name = "Tabs" +script = ExtResource("3_uvwqm") +names = PackedStringArray("Graph") + +[sub_resource type="Resource" id="Resource_kkjrq"] +resource_name = "Split" +script = ExtResource("4_kkjrq") +percent = 0.0 +first = SubResource("Resource_xxwqg") +second = SubResource("Resource_uvwqm") + +[sub_resource type="Resource" id="Resource_svwnc"] +resource_name = "Tabs" +script = ExtResource("3_uvwqm") +names = PackedStringArray("Inspector") + +[sub_resource type="Resource" id="Resource_mvfhp"] +resource_name = "Split" +script = ExtResource("4_kkjrq") +percent = 1.0 +first = SubResource("Resource_kkjrq") +second = SubResource("Resource_svwnc") + +[sub_resource type="Resource" id="Resource_e6y6g"] +resource_name = "Split" +script = ExtResource("4_kkjrq") +direction = 1 +percent = 0.0 +first = SubResource("Resource_g5pcf") +second = SubResource("Resource_mvfhp") + +[sub_resource type="Resource" id="Resource_jojum"] +resource_name = "Layout" +script = ExtResource("5_svwnc") +root = SubResource("Resource_e6y6g") + +[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_sr1k3"] + +[node name="MonologueEditor" type="Control"] +clip_contents = true +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +size_flags_horizontal = 3 +size_flags_vertical = 3 +script = ExtResource("1_ovo1o") + +[node name="DockableContainer" type="Container" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +script = ExtResource("2_xxwqg") +tab_alignment = 0 +use_hidden_tabs_for_min_size = true +layout = SubResource("Resource_jojum") +metadata/_custom_type_script = "uid://k2o7qui1lr6l" + +[node name="_Tabs" type="PanelContainer" parent="DockableContainer"] +unique_name_in_owner = true +layout_mode = 2 +size_flags_horizontal = 0 +size_flags_vertical = 0 +theme_override_styles/panel = SubResource("StyleBoxEmpty_sr1k3") +script = ExtResource("6_2cy6n") + +[node name="TabBar" type="HBoxContainer" parent="DockableContainer/_Tabs"] +custom_minimum_size = Vector2(0, 30) +layout_mode = 2 +theme_override_constants/separation = 0 + +[node name="MainPopupMenu" type="MenuButton" parent="DockableContainer/_Tabs/TabBar"] +custom_minimum_size = Vector2(30, 0) +layout_mode = 2 +icon = ExtResource("3_mei7o") +icon_alignment = 1 +expand_icon = true +script = ExtResource("4_pwbil") + +[node name="VSeparator" type="VSeparator" parent="DockableContainer/_Tabs/TabBar"] +visible = false +layout_mode = 2 +theme_type_variation = &"VSeparatorGrow" + +[node name="TabBar" type="TabBar" parent="DockableContainer/_Tabs/TabBar"] +unique_name_in_owner = true +layout_mode = 2 +size_flags_horizontal = 3 +theme_override_constants/h_separation = 4 + +[node name="Graph" parent="DockableContainer" instance=ExtResource("9_qd5yd")] +layout_mode = 2 + +[node name="Inspector" parent="DockableContainer" instance=ExtResource("14_craj7")] +unique_name_in_owner = true +custom_minimum_size = Vector2(330, 0) +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="Characters" parent="DockableContainer" instance=ExtResource("6_mei7o")] +unique_name_in_owner = true +layout_mode = 2 + +[node name="Variables" parent="DockableContainer" instance=ExtResource("6_mei7o")] +unique_name_in_owner = true +visible = false +layout_mode = 2 + +[node name="Items" parent="DockableContainer" instance=ExtResource("6_mei7o")] +unique_name_in_owner = true +visible = false +layout_mode = 2 + +[node name="Locations" parent="DockableContainer" instance=ExtResource("6_mei7o")] +unique_name_in_owner = true +visible = false +layout_mode = 2 + +[node name="GraphNodePicker" parent="." instance=ExtResource("15_q62vd")] +unique_name_in_owner = true +visible = false +keep_title_visible = false +content_scale_mode = 2 +content_scale_aspect = 1 + +[node name="SearchBarContainer" type="CenterContainer" parent="."] +layout_mode = 1 +anchors_preset = -1 +anchor_right = 1.0 +anchor_bottom = 0.5 +offset_left = 4.0 +offset_top = 4.0 +offset_right = 4.0 +offset_bottom = 4.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 2 +script = ExtResource("15_35jwg") + +[node name="SearchBar" parent="SearchBarContainer" instance=ExtResource("16_n4eqx")] +visible = false +layout_mode = 2 + +[node name="SplitContainer" type="SplitContainer" parent="."] +layout_mode = 0 +offset_right = 40.0 +offset_bottom = 40.0 + +[connection signal="add_document" from="DockableContainer/_Tabs" to="." method="_on__tabs_add_document"] +[connection signal="tab_changed" from="DockableContainer/_Tabs/TabBar/TabBar" to="DockableContainer/_Tabs" method="_on_tab_bar_tab_changed"] + +[editable path="DockableContainer/Graph"] +[editable path="DockableContainer/Inspector"] diff --git a/scenes/main/graph.tscn b/scenes/main/graph.tscn deleted file mode 100644 index 9f74833e..00000000 --- a/scenes/main/graph.tscn +++ /dev/null @@ -1,229 +0,0 @@ -[gd_scene load_steps=14 format=3 uid="uid://bqjfdabrxujp7"] - -[ext_resource type="Script" uid="uid://q6eg6rid6xqd" path="res://scenes/main/monologue_control.gd" id="1_r00lk"] -[ext_resource type="Texture2D" uid="uid://bfmsxfn26cvfn" path="res://ui/assets/icons/character.svg" id="5_1pnba"] -[ext_resource type="PackedScene" uid="uid://dgvhvxdrd58qp" path="res://common/layouts/side_panel/side_panel.tscn" id="6_3jc6d"] -[ext_resource type="Texture2D" uid="uid://b46sqb5g0spae" path="res://ui/assets/icons/variables.svg" id="6_bfi1l"] -[ext_resource type="Texture2D" uid="uid://dd6wdpndndufl" path="res://ui/assets/icons/sparkles.svg" id="6_l6ili"] -[ext_resource type="PackedScene" uid="uid://cb3se7h7akt47" path="res://common/layouts/language_switcher/language_switcher.tscn" id="6_nqv8k"] -[ext_resource type="Script" uid="uid://bmku341x5gaoe" path="res://scenes/main/add_node_button.gd" id="6_tdvn8"] -[ext_resource type="Script" uid="uid://q0oqx6butjwn" path="res://scenes/main/search_bar_container.gd" id="7_eu0e0"] -[ext_resource type="PackedScene" uid="uid://cvum3eaenloix" path="res://common/layouts/search_bar/search_bar.tscn" id="8_tvorm"] -[ext_resource type="Texture2D" uid="uid://d4fesqfd2v8fd" path="res://ui/assets/icons/settings.svg" id="8_yubrq"] -[ext_resource type="Script" uid="uid://nxistnt1yhxc" path="res://scenes/main/graph_edit_switcher.gd" id="11_k843q"] -[ext_resource type="Texture2D" uid="uid://b272tbdmvxj20" path="res://ui/assets/icons/play.svg" id="15_hn16p"] - -[sub_resource type="GDScript" id="GDScript_lenro"] -script/source = "extends Button - - -func _on_pressed() -> void: - GlobalSignal.emit(\"test_trigger\") -" - -[node name="MonologueControl" type="Control"] -clip_contents = true -layout_mode = 3 -anchors_preset = 15 -anchor_right = 1.0 -anchor_bottom = 1.0 -grow_horizontal = 2 -grow_vertical = 2 -size_flags_horizontal = 3 -size_flags_vertical = 3 -script = ExtResource("1_r00lk") - -[node name="MainContainer" type="VBoxContainer" parent="."] -layout_mode = 1 -anchors_preset = 15 -anchor_right = 1.0 -anchor_bottom = 1.0 -grow_horizontal = 2 -grow_vertical = 2 -theme_override_constants/separation = 15 - -[node name="GraphEditsArea" type="Control" parent="MainContainer"] -layout_mode = 2 -size_flags_vertical = 3 -mouse_filter = 2 - -[node name="GraphEditSwitcher" type="VBoxContainer" parent="MainContainer/GraphEditsArea" node_paths=PackedStringArray("side_panel")] -unique_name_in_owner = true -layout_mode = 1 -anchors_preset = 15 -anchor_right = 1.0 -anchor_bottom = 1.0 -grow_horizontal = 2 -grow_vertical = 2 -mouse_filter = 2 -theme_override_constants/separation = 0 -script = ExtResource("11_k843q") -side_panel = NodePath("../MarginContainer/HSplitContainer/SidePanel") - -[node name="GraphEditZone" type="Control" parent="MainContainer/GraphEditsArea/GraphEditSwitcher"] -layout_mode = 2 -size_flags_vertical = 3 - -[node name="GraphEdits" type="Control" parent="MainContainer/GraphEditsArea/GraphEditSwitcher/GraphEditZone"] -layout_mode = 1 -anchors_preset = 15 -anchor_right = 1.0 -anchor_bottom = 1.0 -grow_horizontal = 2 -grow_vertical = 2 -size_flags_vertical = 3 - -[node name="MarginContainer" type="MarginContainer" parent="MainContainer/GraphEditsArea"] -layout_mode = 1 -anchors_preset = -1 -anchor_left = 0.5 -anchor_right = 1.0 -anchor_bottom = 1.0 -grow_horizontal = 0 -grow_vertical = 2 -mouse_filter = 2 -theme_override_constants/margin_left = 0 -theme_override_constants/margin_top = 0 -theme_override_constants/margin_right = 0 -theme_override_constants/margin_bottom = 0 - -[node name="HSplitContainer" type="HSplitContainer" parent="MainContainer/GraphEditsArea/MarginContainer"] -layout_mode = 2 -mouse_filter = 2 - -[node name="Container" type="Container" parent="MainContainer/GraphEditsArea/MarginContainer/HSplitContainer"] -layout_mode = 2 -size_flags_horizontal = 3 -mouse_filter = 2 - -[node name="SidePanel" parent="MainContainer/GraphEditsArea/MarginContainer/HSplitContainer" instance=ExtResource("6_3jc6d")] -unique_name_in_owner = true -custom_minimum_size = Vector2(450, 0) -layout_mode = 2 -size_flags_horizontal = 3 - -[node name="ToolBarContainer" type="MarginContainer" parent="MainContainer/GraphEditsArea"] -layout_mode = 1 -anchors_preset = 12 -anchor_top = 1.0 -anchor_right = 1.0 -anchor_bottom = 1.0 -offset_top = -80.0 -grow_horizontal = 2 -grow_vertical = 0 -mouse_filter = 2 -theme_type_variation = &"MarginContainer_Medium" - -[node name="VBoxContainer" type="VBoxContainer" parent="MainContainer/GraphEditsArea/ToolBarContainer"] -layout_mode = 2 -mouse_filter = 2 -alignment = 2 - -[node name="CenterContainer" type="CenterContainer" parent="MainContainer/GraphEditsArea/ToolBarContainer/VBoxContainer"] -layout_mode = 2 -mouse_filter = 2 - -[node name="ToolBar" type="HBoxContainer" parent="MainContainer/GraphEditsArea/ToolBarContainer/VBoxContainer/CenterContainer"] -layout_mode = 2 -theme_type_variation = &"HBoxContainer_Medium" - -[node name="Left" type="PanelContainer" parent="MainContainer/GraphEditsArea/ToolBarContainer/VBoxContainer/CenterContainer/ToolBar"] -layout_mode = 2 -mouse_filter = 1 -theme_type_variation = &"OuterPanel" - -[node name="HBoxContainer" type="HBoxContainer" parent="MainContainer/GraphEditsArea/ToolBarContainer/VBoxContainer/CenterContainer/ToolBar/Left"] -layout_mode = 2 -theme_type_variation = &"HBoxContainer_Medium" -alignment = 1 - -[node name="AddNodeBtn" type="Button" parent="MainContainer/GraphEditsArea/ToolBarContainer/VBoxContainer/CenterContainer/ToolBar/Left/HBoxContainer"] -layout_mode = 2 -theme_type_variation = &"Button_Flat" -text = "Add a node..." -script = ExtResource("6_tdvn8") - -[node name="ButtonCharacters" type="Button" parent="MainContainer/GraphEditsArea/ToolBarContainer/VBoxContainer/CenterContainer/ToolBar/Left/HBoxContainer"] -visible = false -layout_mode = 2 -theme_type_variation = &"Button_Flat" -icon = ExtResource("5_1pnba") -icon_alignment = 1 - -[node name="ButtonVariables" type="Button" parent="MainContainer/GraphEditsArea/ToolBarContainer/VBoxContainer/CenterContainer/ToolBar/Left/HBoxContainer"] -visible = false -layout_mode = 2 -theme_type_variation = &"Button_Flat" -icon = ExtResource("6_bfi1l") -icon_alignment = 1 - -[node name="LanguageSwitcher" parent="MainContainer/GraphEditsArea/ToolBarContainer/VBoxContainer/CenterContainer/ToolBar/Left/HBoxContainer" instance=ExtResource("6_nqv8k")] -unique_name_in_owner = true -layout_mode = 2 -theme_type_variation = &"Button_Flat" -disabled = true - -[node name="ButtonSettings" type="Button" parent="MainContainer/GraphEditsArea/ToolBarContainer/VBoxContainer/CenterContainer/ToolBar/Left/HBoxContainer"] -layout_mode = 2 -theme_type_variation = &"Button_Flat" -icon = ExtResource("8_yubrq") -icon_alignment = 1 - -[node name="ButtonSparkle" type="Button" parent="MainContainer/GraphEditsArea/ToolBarContainer/VBoxContainer/CenterContainer/ToolBar/Left/HBoxContainer"] -visible = false -layout_mode = 2 -theme_type_variation = &"Button_Flat" -icon = ExtResource("6_l6ili") - -[node name="Right" type="PanelContainer" parent="MainContainer/GraphEditsArea/ToolBarContainer/VBoxContainer/CenterContainer/ToolBar"] -layout_mode = 2 -mouse_filter = 1 -theme_type_variation = &"OuterPanel" - -[node name="HBoxContainer" type="HBoxContainer" parent="MainContainer/GraphEditsArea/ToolBarContainer/VBoxContainer/CenterContainer/ToolBar/Right"] -layout_mode = 2 -theme_override_constants/separation = 0 -alignment = 1 - -[node name="RunButton" type="Button" parent="MainContainer/GraphEditsArea/ToolBarContainer/VBoxContainer/CenterContainer/ToolBar/Right/HBoxContainer"] -custom_minimum_size = Vector2(34, 34) -layout_mode = 2 -theme_type_variation = &"Button_Flat" -script = SubResource("GDScript_lenro") - -[node name="CenterContainer" type="CenterContainer" parent="MainContainer/GraphEditsArea/ToolBarContainer/VBoxContainer/CenterContainer/ToolBar/Right/HBoxContainer/RunButton"] -layout_mode = 1 -anchors_preset = 15 -anchor_right = 1.0 -anchor_bottom = 1.0 -grow_horizontal = 2 -grow_vertical = 2 -rotation = -0.00318988 - -[node name="TextureRect" type="TextureRect" parent="MainContainer/GraphEditsArea/ToolBarContainer/VBoxContainer/CenterContainer/ToolBar/Right/HBoxContainer/RunButton/CenterContainer"] -custom_minimum_size = Vector2(24, 24) -layout_mode = 2 -tooltip_text = "Run the project from the RootNode." -texture = ExtResource("15_hn16p") -expand_mode = 3 -stretch_mode = 5 - -[node name="SearchBarContainer" type="CenterContainer" parent="MainContainer/GraphEditsArea"] -layout_mode = 1 -anchors_preset = -1 -anchor_right = 1.0 -anchor_bottom = 0.5 -grow_horizontal = 2 -grow_vertical = 2 -mouse_filter = 2 -script = ExtResource("7_eu0e0") - -[node name="SearchBar" parent="MainContainer/GraphEditsArea/SearchBarContainer" node_paths=PackedStringArray("graph_edit_switcher") instance=ExtResource("8_tvorm")] -visible = false -layout_mode = 2 -graph_edit_switcher = NodePath("../../GraphEditSwitcher") - -[connection signal="pressed" from="MainContainer/GraphEditsArea/ToolBarContainer/VBoxContainer/CenterContainer/ToolBar/Left/HBoxContainer/AddNodeBtn" to="MainContainer/GraphEditsArea/ToolBarContainer/VBoxContainer/CenterContainer/ToolBar/Left/HBoxContainer/AddNodeBtn" method="_on_pressed"] -[connection signal="pressed" from="MainContainer/GraphEditsArea/ToolBarContainer/VBoxContainer/CenterContainer/ToolBar/Left/HBoxContainer/ButtonSettings" to="." method="_on_button_settings_pressed"] -[connection signal="pressed" from="MainContainer/GraphEditsArea/ToolBarContainer/VBoxContainer/CenterContainer/ToolBar/Left/HBoxContainer/ButtonSparkle" to="." method="_on_button_sparkle_pressed"] -[connection signal="pressed" from="MainContainer/GraphEditsArea/ToolBarContainer/VBoxContainer/CenterContainer/ToolBar/Right/HBoxContainer/RunButton" to="MainContainer/GraphEditsArea/ToolBarContainer/VBoxContainer/CenterContainer/ToolBar/Right/HBoxContainer/RunButton" method="_on_pressed"] diff --git a/scenes/main/graph_container.gd b/scenes/main/graph_container.gd new file mode 100644 index 00000000..6c3cca82 --- /dev/null +++ b/scenes/main/graph_container.gd @@ -0,0 +1,89 @@ +## Consists of a TabBar which allows the user to switch between GraphEdits. +## Saving and loading of GraphEdit data is handled by MonologueEditor. +class_name GraphContainer extends VBoxContainer + +var prompt_scene = preload("res://common/windows/prompt_window/prompt_window.tscn") + +@export var inspector_panel: InspectorPanel +@onready var graph: MonologueGraphEdit = %GraphEdit + +var _selected_nodes: Dictionary = {} # storyline_id -> InspectableNode +var _is_applying_selection: bool = false + + +func _ready() -> void: + GlobalSignal.add_listener("request_node_inspection", _on_request_node_inspection) + StorylineManager.storyline_changed.connect(refresh) + StorylineManager.storyline_switched.connect(_on_storyline_switched) + + +func refresh() -> void: + pass + + +func _on_storyline_switched() -> void: + var storyline: StorylineDocument = StorylineManager.get_active_storyline() + graph.storyline_id = storyline.id + graph.refresh() + + +func _on_graph_edit_node_view_selected(node: InspectableNode) -> void: + request_node_selection(node) + + +func _on_request_node_inspection( + node: InspectableNode, storyline_id: String = "", skip_history: bool = false +) -> void: + var target_storyline_id := storyline_id + if target_storyline_id.is_empty() and node: + target_storyline_id = node.storyline_id + if target_storyline_id.is_empty(): + return + request_node_selection(node, skip_history) + + +func request_node_selection(node: InspectableNode, skip_history: bool = false) -> void: + if _is_applying_selection: + return + + var storyline: StorylineDocument = StorylineManager.get_active_storyline() + var current_node: InspectableNode = _selected_nodes.get(storyline.id) + var needs_selection_update := current_node != node + if not needs_selection_update: + if graph and node and is_instance_valid(node.graph_view): + needs_selection_update = not node.graph_view.selected + + if not needs_selection_update and inspector_panel.current_object == node: + return + + if skip_history: + _apply_selection(node, storyline.id) + return + + var history: CommandManager = storyline.history if storyline else null + if not history: + _apply_selection(node, storyline.id) + return + + var command := NodeSelectionCommand.new( + storyline.id, current_node, node, Callable(self, "_apply_selection") + ) + + history.execute(command, UndoRedo.MERGE_ENDS) + + +func _apply_selection(node: InspectableNode, storyline_id: String) -> void: + _is_applying_selection = true + + if node: + _selected_nodes[storyline_id] = node + else: + _selected_nodes.erase(storyline_id) + + if node and is_instance_valid(node.graph_view): + graph.set_selected(node.graph_view) + + if inspector_panel.current_object != node: + inspector_panel.inspect(node) + + _is_applying_selection = false diff --git a/scenes/main/graph_edit_switcher.gd.uid b/scenes/main/graph_container.gd.uid similarity index 100% rename from scenes/main/graph_edit_switcher.gd.uid rename to scenes/main/graph_container.gd.uid diff --git a/scenes/main/graph_edit_switcher.tscn b/scenes/main/graph_container.tscn similarity index 71% rename from scenes/main/graph_edit_switcher.tscn rename to scenes/main/graph_container.tscn index 8e1a8cdb..84baacf4 100644 --- a/scenes/main/graph_edit_switcher.tscn +++ b/scenes/main/graph_container.tscn @@ -1,24 +1,24 @@ -[gd_scene load_steps=4 format=3 uid="uid://cvjfcgqktlyc2"] +[gd_scene load_steps=4 format=3 uid="uid://51mo3wv8gb1o"] -[ext_resource type="Script" uid="uid://nxistnt1yhxc" path="res://scenes/main/graph_edit_switcher.gd" id="1_fvn0a"] -[ext_resource type="Texture2D" uid="uid://c7vdr4e0mxst6" path="res://ui/assets/icons/close_icon.png" id="2_k726l"] -[ext_resource type="PackedScene" uid="uid://qdgl8co6qy6" path="res://common/layouts/graph_edit/monologue_graph_edit.tscn" id="3_o6be6"] +[ext_resource type="Script" uid="uid://nxistnt1yhxc" path="res://scenes/main/graph_container.gd" id="1_5dl3l"] +[ext_resource type="Texture2D" uid="uid://c7vdr4e0mxst6" path="res://ui/assets/icons/close_icon.png" id="2_5pcvw"] +[ext_resource type="PackedScene" uid="uid://qdgl8co6qy6" path="res://common/layouts/graph_edit/monologue_graph_edit.tscn" id="3_jrlr1"] -[node name="GraphEditSwitcher" type="VBoxContainer"] +[node name="GraphEditContainer" type="VBoxContainer"] anchors_preset = 15 anchor_right = 1.0 anchor_bottom = 1.0 grow_horizontal = 2 grow_vertical = 2 mouse_filter = 2 -script = ExtResource("1_fvn0a") +script = ExtResource("1_5dl3l") [node name="TabBar" type="TabBar" parent="."] custom_minimum_size = Vector2(0, 30) layout_mode = 2 size_flags_horizontal = 0 mouse_default_cursor_shape = 2 -theme_override_icons/close = ExtResource("2_k726l") +theme_override_icons/close = ExtResource("2_5pcvw") current_tab = 0 clip_tabs = false tab_close_display_policy = 1 @@ -30,8 +30,11 @@ layout_mode = 2 size_flags_vertical = 3 mouse_filter = 2 -[node name="Default" parent="GraphEdits" instance=ExtResource("3_o6be6")] +[node name="Default" parent="GraphEdits" instance=ExtResource("3_jrlr1")] layout_mode = 1 +[node name="TabContainer" type="TabContainer" parent="."] +layout_mode = 2 + [connection signal="tab_changed" from="TabBar" to="." method="_on_tab_changed"] [connection signal="tab_close_pressed" from="TabBar" to="." method="on_tab_close_pressed"] diff --git a/scenes/main/graph_edit_switcher.gd b/scenes/main/graph_edit_switcher.gd deleted file mode 100644 index ac523fc3..00000000 --- a/scenes/main/graph_edit_switcher.gd +++ /dev/null @@ -1,179 +0,0 @@ -## Consists of a TabBar which allows the user to switch between GraphEdits. -## Saving and loading of GraphEdit data is handled by MonologueControl. -class_name GraphEditSwitcher extends VBoxContainer - - -## Reference to the side panel control to connect graph edits to. -@export var side_panel: SidePanel -## Reference to the tab bar for switching graph edits. -@export var tab_bar: TabBar - -var current: MonologueGraphEdit: get = get_current_graph_edit -var graph_edit_scene = preload("res://common/layouts/graph_edit/monologue_graph_edit.tscn") -var is_closing_all_tabs: bool -var pending_new_graph: MonologueGraphEdit -var prompt_scene = preload("res://common/windows/prompt_window/prompt_window.tscn") -var root_scene = Constants.NODE_SCENES.get("Root") -var last_selected_tab: int = 0 -var prevent_switching: bool = false - -@onready var graph_edits: Control = $GraphEditZone/GraphEdits - - -func _ready() -> void: - tab_bar.connect("tab_changed", _on_tab_changed) - tab_bar.connect("tab_close_pressed", _on_tab_close_pressed) - new_graph_edit() - GlobalSignal.add_listener("previous_tab", previous_tab) - GlobalSignal.add_listener("last_tab", last_tab) - GlobalSignal.add_listener("show_current_config", show_current_config) - - -func _input(event: InputEvent) -> void: - # IMPORTANT: order matters, redo must come first, undo second - if event.is_action_pressed("Redo"): - current.trigger_redo() - elif event.is_action_pressed("Undo"): - current.trigger_undo() - elif event.is_action_pressed("Delete") and not side_panel.visible: - current.trigger_delete() - - -## Adds a root node to the current graph edit if given root ID doesn't exist. -func add_root(save: bool = true) -> void: - if not current.get_root_node(): - var root_node = root_scene.instantiate() - current.add_child(root_node) - if save: GlobalSignal.emit("save", [true]) - - -## Adds a new tab with the given JSON filename as the tab title. -func add_tab(filename: String) -> void: - tab_bar.add_tab(Util.truncate_filename(filename)) - tab_bar.move_tab(tab_bar.tab_count - 2, tab_bar.tab_count - 1) - tab_bar.current_tab = tab_bar.tab_count - 2 - - -func connect_side_panel(graph_edit: MonologueGraphEdit) -> void: - graph_edit.connect("node_selected", side_panel.on_graph_node_selected) - graph_edit.connect("node_deselected", side_panel.on_graph_node_deselected) - graph_edit.undo_redo.connect("version_changed", update_save_state) - - -func commit_side_panel(node: MonologueGraphNode) -> void: - side_panel.refocus(node) - - -func get_current_graph_edit() -> MonologueGraphEdit: - return graph_edits.get_child(tab_bar.current_tab) - - -## Check if a graph edit representing the given filepath is opened or not. -func is_file_opened(filepath: String) -> bool: - for node in graph_edits.get_children(): - if node is MonologueGraphEdit and node.file_path == filepath: - return true - return false - - -func new_graph_edit() -> MonologueGraphEdit: - var graph_edit = graph_edit_scene.instantiate() - var root_node = root_scene.instantiate() - - graph_edit.add_child(root_node) - connect_side_panel(graph_edit) - graph_edits.add_child(graph_edit) - - for ge in graph_edits.get_children(): - ge.visible = ge == graph_edit - - return graph_edit - - -func _on_tab_close_pressed(tab: int) -> void: - if prevent_switching: - return - - var ge = graph_edits.get_child(tab) - if ge.is_unsaved(): # prompt user if there are unsaved changes - GlobalSignal.emit("disable_picker_mode") - tab_bar.current_tab = tab - var save_prompt = prompt_scene.instantiate() - save_prompt.connect("confirmed", _close_tab.bind(ge, tab, true)) - save_prompt.connect("cancelled", set.bind("is_closing_all_tabs", false)) - save_prompt.connect("denied", _close_tab.bind(ge, tab)) - add_child(save_prompt) - save_prompt.prompt_save(ge.file_path) - else: - _close_tab(ge, tab) - - -func previous_tab(): - if tab_bar.tab_count > 1: - tab_bar.select_previous_available() - - -func last_tab(): - tab_bar.current_tab = last_selected_tab - tab_bar.tab_changed.emit(last_selected_tab) - - -## Select the RootNode of the current graph edit, which opens the side panel. -func show_current_config() -> void: - var root_node = current.get_root_node() - current.set_selected(root_node) - - -## Update tab title with a suffix based on the current graph_edit's save state. -func update_save_state() -> void: - var index = current.get_index() - var trim = tab_bar.get_tab_title(index).trim_suffix(Constants.UNSAVED_FILE_SUFFIX) - var title = trim + Constants.UNSAVED_FILE_SUFFIX if current.is_unsaved() else trim - tab_bar.set_tab_title(index, title) - - -func _close_tab(graph_edit, tab_index, save_first = false) -> void: - if save_first: - GlobalSignal.emit("save", [true]) - GlobalSignal.emit("close_character_edit") - graph_edit.queue_free() - await graph_edit.tree_exited # buggy if we switch tabs without waiting - tab_bar.remove_tab(tab_index) - - if tab_bar.tab_count == 0: - get_tree().quit() - elif is_closing_all_tabs: - _on_tab_close_pressed(0) - - -func _on_tab_changed(tab: int) -> void: - if prevent_switching: - tab_bar.current_tab = last_selected_tab - return - - if tab < tab_bar.tab_count - 1: - # this allows user to switch out of the new tab (welcome window) - tab_bar.tab_close_display_policy = TabBar.CLOSE_BUTTON_SHOW_ACTIVE_ONLY - if pending_new_graph and not pending_new_graph.file_path: - pending_new_graph.queue_free() - pending_new_graph = null - GlobalSignal.emit("hide_welcome") - GlobalSignal.emit("enable_language_switcher") - - for ge in graph_edits.get_children(): - if graph_edits.get_child(tab) == ge: - ge.visible = true - GlobalSignal.emit("load_languages", [ge.languages, ge]) - if ge.active_graphnode: - side_panel.on_graph_node_selected(ge.active_graphnode, true) - else: - side_panel.hide() - else: - ge.visible = false - last_selected_tab = tab - else: - tab_bar.tab_close_display_policy = TabBar.CLOSE_BUTTON_SHOW_NEVER - pending_new_graph = new_graph_edit() - GlobalSignal.emit("show_welcome") - GlobalSignal.emit("disable_language_switcher") - side_panel.hide() diff --git a/scenes/main/monologue_control.gd b/scenes/main/monologue_control.gd deleted file mode 100644 index 27f5a4b2..00000000 --- a/scenes/main/monologue_control.gd +++ /dev/null @@ -1,211 +0,0 @@ -class_name MonologueControl extends Control - -@export var welcome_window: WelcomeWindow -@export var graph_node_picker: GraphNodePicker - -@onready var graph_switcher: GraphEditSwitcher = %GraphEditSwitcher -@onready var side_panel_node: SidePanel = %SidePanel -@onready var run_window := preload("res://scenes/run/run_window.tscn") -@onready var dimmer := $"../../../Dimmer" - - -func _ready(): - get_tree().auto_accept_quit = false # quit handled by _close_tab() - welcome_window.show() - - GlobalSignal.add_listener("add_graph_node", add_node_from_global) - GlobalSignal.add_listener("select_new_node", _select_new_node) - GlobalSignal.add_listener("refresh", refresh) - GlobalSignal.add_listener("load_project", load_project) - GlobalSignal.add_listener("test_trigger", test_project) - GlobalSignal.add_listener("save", save) - - -func _select_new_node() -> void: - graph_node_picker.show() - - -func _input(event): - if event.is_action_pressed("Save"): - save() - - -func _to_dict() -> Dictionary: - var list_nodes: Array[Dictionary] = [] - - # compile all node data of the current graph edit - for node in graph_switcher.current.get_nodes(): - if node.is_queued_for_deletion(): - continue - - # if side panel is still open, release the focus so that some - # text controls trigger the focus_exited() signal to update - if side_panel_node.visible and side_panel_node.selected_node == node: - var refocus = get_viewport().gui_get_focus_owner() - if refocus: - refocus.release_focus() - refocus.grab_focus() - - list_nodes.append(node._to_dict()) - if node.node_type == "NodeChoice": - for child in node.get_children(): - list_nodes.append(child._to_dict()) - - # build data for dialogue characters - var characters = graph_switcher.current.characters - if characters.size() <= 0: - characters.append( - { - "ID": IDGen.generate(5), - "Protected": true, - "Character": {"Name": "_NARRATOR"}, - "EditorIndex": 0 - } - ) - - return { - "EditorVersion": ProjectSettings.get_setting("application/config/version", "unknown"), - "RootNodeID": get_root_dict(list_nodes).get("ID"), - "ListNodes": list_nodes, - "Characters": characters, - "Variables": graph_switcher.current.variables, - "Languages": GlobalVariables.language_switcher.get_languages().keys() - } - - -## Function callback for when the user wants to add a node from global context. -## Used by header menu and graph node selector (picker). -func add_node_from_global(node_type: String, picker: GraphNodePicker = null): - var nodes: Array[MonologueGraphNode] = graph_switcher.current.add_node(node_type, true, picker) - graph_switcher.current.pick_and_center(nodes, picker) - - -func get_root_dict(node_list: Array) -> Dictionary: - for node in node_list: - if node.get("$type") == "NodeRoot": - return node - return {} - - -func load_project(path: String, new_graph: bool = false) -> void: - var file = FileAccess.open(path, FileAccess.READ) - if file and not graph_switcher.is_file_opened(path): - if new_graph: - graph_switcher.new_graph_edit() - graph_switcher.current.file_path = path # set path first before tab creation - - var data = {} - var text = file.get_as_text() - if text: - data = JSON.parse_string(text) - if not data: - data = _to_dict() - save() - - var converter := NodeConverter.new() - graph_switcher.current.languages = data.get("Languages", []) # load language before tab - graph_switcher.add_tab(path.get_file()) - graph_switcher.current.clear() - graph_switcher.current.name = path.get_file().trim_suffix(".json") - graph_switcher.current.characters = converter.convert_characters(data.get("Characters")) - graph_switcher.current.variables = data.get("Variables") - graph_switcher.current.data = data - - var node_list = data.get("ListNodes") - _load_nodes(node_list) - _connect_nodes(node_list) - graph_switcher.add_root() - graph_switcher.current.update_node_positions() - graph_switcher.current.grab_focus() - GlobalSignal.emit("load_successful", [path]) - - -## Reload the current graph edit and side panel values. -func refresh(node: MonologueGraphNode = null, affected_properties: PackedStringArray = []) -> void: - # if there is a given node, refresh only the parts that were specified - if node: - node.reload_preview() - if node is not OptionNode: - node._update.call_deferred() - if side_panel_node.visible: - # actual property value updates are handled by PropertyHistory - for property_name in affected_properties: - var field = side_panel_node.collapsibles.get(property_name) - if is_instance_valid(field): - field.open() - else: - var choice = node.choice_node if node is OptionNode else node - node.get_graph_edit().set_selected(choice) - # otherwise, remake the entire panel and refresh all node previews - else: - for each_node in graph_switcher.current.get_nodes(): - each_node.reload_preview() - #each_node._update.call_deferred() - if side_panel_node.visible: - var current_node = side_panel_node.selected_node - side_panel_node.on_graph_node_selected(current_node, true) - - -func save(): - var data = JSON.stringify(_to_dict(), "\t", false, true) - if data: - var path = graph_switcher.current.file_path - var file = FileAccess.open(path, FileAccess.WRITE) - file.store_string(data) - file.close() - graph_switcher.current.update_version() - graph_switcher.update_save_state() - - -func test_project(from_node: Variant = null): - if graph_switcher.current.file_path: - await save() - var window: RunWindow = run_window.instantiate() - window.file_path = graph_switcher.current.file_path - window.from_node = from_node - window.tree_exited.connect(dimmer.hide) - get_tree().root.add_child(window) - dimmer.show() - - -func _connect_nodes(node_list: Array) -> void: - for node in node_list: - var current_node = graph_switcher.current.get_node_by_id(node.get("ID", "")) - if current_node: - current_node._load_connections(node) - - -func _load_nodes(node_list: Array) -> void: - var converter = NodeConverter.new() - for node in node_list: - var data = converter.convert_node(node) - var node_type = data.get("$type").trim_prefix("Node") - if node_type == "Option": - # option data gets sent to the base_options dictionary - graph_switcher.current.base_options[data.get("ID")] = data - else: - var node_scene = Constants.NODE_SCENES.get(node_type) - if node_scene: - var node_instance = node_scene.instantiate() - node_instance.id.value = data.get("ID") - graph_switcher.current.add_child(node_instance, true) - node_instance._from_dict(data) - - -func _notification(what: int) -> void: - if what == NOTIFICATION_WM_CLOSE_REQUEST: - get_viewport().gui_release_focus() - graph_switcher.is_closing_all_tabs = true - graph_switcher._on_tab_close_pressed(0) - - -func _on_button_sparkle_pressed() -> void: - # TODO: Create an undo/redo action for every nodes. Need to pack undo/redo action into one action. - pass - #graph_switcher.current.set_block_signals(true) - #graph_switcher.current.arrange_nodes() - #graph_switcher.current.set_block_signals.bind(false).call_deferred() - - -func _on_button_settings_pressed() -> void: - GlobalSignal.emit("show_current_config") diff --git a/scenes/main/monologue_editor.gd b/scenes/main/monologue_editor.gd new file mode 100644 index 00000000..15a6400f --- /dev/null +++ b/scenes/main/monologue_editor.gd @@ -0,0 +1,177 @@ +class_name MonologueEditor extends Control + +const STORYLINE_EXTENSIONS: Array = ["*.mnlg,*.json;Storyline Document"] + +@export var welcome_window: WelcomeWindow +@export var graph_container: GraphContainer +@export var file_dialog: GlobalFileDialog + +@onready var graph_node_picker: GraphNodePicker = %GraphNodePicker +@onready var inspector_panel_node: InspectorPanel = %Inspector +@onready var run_window := preload("res://scenes/run/run_window.tscn") +@onready var dimmer := $"../../../Dimmer" +@onready var document_tab_manager: DocumentTabManager = %_Tabs + +@onready var characters_section := %Characters +@onready var variables_section := %Variables +@onready var items_section := %Items +@onready var locations_section := %Locations + + +func _ready(): + get_tree().auto_accept_quit = false # quit handled by _close_tab() + #welcome_window.show() + + GlobalSignal.add_listener("add_graph_node", add_node_from_global) + GlobalSignal.add_listener("select_new_node", _select_new_node) + GlobalSignal.add_listener("load_project", load_project) + GlobalSignal.add_listener("test_trigger", test_project) + GlobalSignal.add_listener("save", save) + + StorylineManager.create_storyline() + + # Load the editor sections after creating the storyline + await get_tree().process_frame + load_editor_sections() + + +func _select_new_node() -> void: + graph_node_picker.open_for_node("", -1, null, null, null, true) + + +func _input(event): + if event.is_action_pressed("Save"): + save() + + if event.is_action_pressed("ui_undo"): + var focus_owner: Control = get_viewport().gui_get_focus_owner() + if focus_owner: + focus_owner.release_focus() + StorylineManager.get_active_storyline().history.undo() + + if event.is_action_pressed("ui_redo"): + StorylineManager.get_active_storyline().history.redo() + + +## Function callback for when the user wants to add a node from global context. +## Used by header menu and graph node selector (picker). +func add_node_from_global(node_type: String, picker: GraphNodePicker = null): + var storyline := StorylineManager.get_active_storyline() + if storyline == null: + push_warning("No active storyline available to add node.") + return + + var node := storyline.create_node(node_type) + if node == null: + push_warning("Unable to create node of type '%s'." % node_type) + return + + var graph_edit: MonologueGraphEdit = graph_container.graph + var target_position := Vector2.ZERO + if picker and picker.graph_release is Vector2: + target_position = picker.graph_release + else: + target_position = graph_edit.scroll_offset / graph_edit.zoom + + var position_property := node.get_property("position") + if position_property: + position_property.set_value(target_position) + + var command: AddNodesCommand = AddNodesCommand.new(storyline.id, [node]) + storyline.history.execute(command) + + +func get_root_dict(node_list: Array) -> Dictionary: + for node in node_list: + if node.get("$type") == "NodeRoot": + return node + return {} + + +func load_project(path: String, new_graph: bool = false) -> void: + var file = FileAccess.open(path, FileAccess.READ) + if not file or graph_container.is_file_opened(path): + return + + var data = {} + var text = file.get_as_text() + if text: + data = JSON.parse_string(text) + if not data: + save() + + var converter := NodeConverter.new() + var storyline = StorylineManager.get_active_storyline() + + load_editor_sections() + + +func load_editor_sections() -> void: + var storyline := StorylineManager.get_active_storyline() + if storyline: + characters_section.load_items(storyline.get_property("characters"), storyline) + variables_section.load_items(storyline.get_property("variables"), storyline) + items_section.load_items(storyline.get_property("items"), storyline) + locations_section.load_items(storyline.get_property("locations"), storyline) + + +func save(): + var storyline = StorylineManager.get_active_storyline() + if storyline.file_path.is_empty(): + file_dialog.save_file(save_file_logic, STORYLINE_EXTENSIONS) + return + save_file_logic(storyline.file_path) + + +func save_file_logic(path: String) -> void: + var storyline = StorylineManager.get_active_storyline() + var dict: Dictionary = storyline._to_dict() + dict["editor_version"] = ProjectSettings.get_setting("application/config/version") + var storyline_data: String = JSON.stringify(dict, "\t", false, true) + + if path.get_extension().is_empty(): + path = path.trim_suffix(".") + path = "%s.mnlg" % path + + var access: FileAccess = FileAccess.open(path, FileAccess.WRITE_READ) + access.store_string(storyline_data) + + storyline.file_path = path + storyline.name = path.get_file() + storyline.is_dirty = false + storyline.content_changed.emit() + + +func test_project(_from_node: Variant = null): + return + #if graph_switcher.current.file_path: + #await save() + #var window: RunWindow = run_window.instantiate() + #window.file_path = graph_switcher.current.file_path + #window.from_node = from_node + #window.tree_exited.connect(dimmer.hide) + #get_tree().root.add_child(window) + #dimmer.show() + + +func _notification(what: int) -> void: + if what == NOTIFICATION_WM_CLOSE_REQUEST: + get_viewport().gui_release_focus() + #graph_switcher.is_closing_all_tabs = true + #graph_switcher._on_tab_close_pressed(0) + + +func _on_button_sparkle_pressed() -> void: + # TODO: Create an undo/redo action for every nodes. Need to pack undo/redo action into one action. + pass + #graph_switcher.current.set_block_signals(true) + #graph_switcher.current.arrange_nodes() + #graph_switcher.current.set_block_signals.bind(false).call_deferred() + + +func _on_button_settings_pressed() -> void: + GlobalSignal.emit("show_current_config") + + +func _on__tabs_add_document() -> void: + welcome_window.show() diff --git a/scenes/main/monologue_control.gd.uid b/scenes/main/monologue_editor.gd.uid similarity index 100% rename from scenes/main/monologue_control.gd.uid rename to scenes/main/monologue_editor.gd.uid diff --git a/scenes/main/search_bar_container.gd b/scenes/main/search_bar_container.gd index 4f1978af..08e0d568 100644 --- a/scenes/main/search_bar_container.gd +++ b/scenes/main/search_bar_container.gd @@ -1,16 +1,17 @@ extends CenterContainer -@onready var searchbar = $SearchBar -@onready var graph_edit_switcher = %GraphEditSwitcher +#@onready var searchbar = $SearchBar +#@export var graph_edit_switcher = %GraphEditSwitcher func _input(_event: InputEvent) -> void: - if Input.is_action_just_pressed("Show searchbar"): - searchbar.visible = !searchbar.visible - if searchbar.visible: - searchbar.focus() - graph_edit_switcher.prevent_switching = true - - if Input.is_key_pressed(KEY_ESCAPE): - searchbar.hide() - graph_edit_switcher.prevent_switching = false + pass + #if Input.is_action_just_pressed("Show searchbar"): + #searchbar.visible = !searchbar.visible + #if searchbar.visible: + #searchbar.focus() + #graph_edit_switcher.prevent_switching = true +# +#if Input.is_key_pressed(KEY_ESCAPE): +#searchbar.hide() +#graph_edit_switcher.prevent_switching = false diff --git a/scenes/main/tab_bar.gd b/scenes/main/tab_bar.gd new file mode 100644 index 00000000..1783b084 --- /dev/null +++ b/scenes/main/tab_bar.gd @@ -0,0 +1,59 @@ +class_name DocumentTabManager extends PanelContainer + +signal add_document + +@warning_ignore("unused_private_class_variable") +var _static_container: bool = true + +@onready var tab_bar: TabBar = %TabBar + +var _last_opened_tab: int = 0 +var _reloading_ui: bool = false + + +func _ready() -> void: + StorylineManager.storyline_changed.connect(_on_storyline_changed) + StorylineManager.storyline_created.connect(_on_storyline_created) + + +func _reload_ui() -> void: + _reloading_ui = true + tab_bar.clear_tabs() + for document_id: String in StorylineManager.get_storyline_ids(): + var document: StorylineDocument = StorylineManager.get_storyline(document_id) + + var tab_title: String = document.name + if document.file_path.is_empty(): + tab_title = "<%s>" % tab_title + if document.is_dirty: + tab_title += "*" + + tab_bar.add_tab(tab_title) + tab_bar.set_tab_metadata(tab_bar.tab_count - 1, document_id) + + tab_bar.current_tab = _last_opened_tab + + tab_bar.add_tab("", preload("res://ui/assets/icons/plus.svg")) + _reloading_ui = false + + +func _on_storyline_created() -> void: + _reload_ui() + + +func _on_storyline_changed() -> void: + _reload_ui() + + +func _on_tab_bar_tab_changed(tab: int) -> void: + if tab >= tab_bar.tab_count - 1: + tab_bar.current_tab = _last_opened_tab + if _reloading_ui: + return + add_document.emit() + return + + if tab_bar.current_tab != _last_opened_tab: + StorylineManager.storyline_switched.emit() + + _last_opened_tab = tab_bar.current_tab diff --git a/scenes/main/tab_bar.gd.uid b/scenes/main/tab_bar.gd.uid new file mode 100644 index 00000000..a980195e --- /dev/null +++ b/scenes/main/tab_bar.gd.uid @@ -0,0 +1 @@ +uid://cpi3ixjp3ye17 diff --git a/scenes/run/assets/background.png.import b/scenes/run/assets/background.png.import index f19e0e97..841b3fb4 100644 --- a/scenes/run/assets/background.png.import +++ b/scenes/run/assets/background.png.import @@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/background.png-3276b190ef914a8e7e153690f9d0db compress/mode=0 compress/high_quality=false compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 compress/hdr_compression=1 compress/normal_map=0 compress/channel_pack=0 @@ -25,6 +27,10 @@ mipmaps/generate=false mipmaps/limit=-1 roughness/mode=0 roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 process/fix_alpha_border=true process/premult_alpha=false process/normal_map_invert_y=false diff --git a/scenes/splash/dino/Render0001.png b/scenes/splash/dino/Render0001.png new file mode 100644 index 00000000..31c619e3 Binary files /dev/null and b/scenes/splash/dino/Render0001.png differ diff --git a/scenes/splash/dino/Render0001.png.import b/scenes/splash/dino/Render0001.png.import new file mode 100644 index 00000000..8f9fb708 --- /dev/null +++ b/scenes/splash/dino/Render0001.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://c41kgi20w10ks" +path="res://.godot/imported/Render0001.png-878138baf4c902f226fe7b0c83336c52.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://scenes/splash/dino/Render0001.png" +dest_files=["res://.godot/imported/Render0001.png-878138baf4c902f226fe7b0c83336c52.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/scenes/splash/dino/Render0002.png b/scenes/splash/dino/Render0002.png new file mode 100644 index 00000000..31c619e3 Binary files /dev/null and b/scenes/splash/dino/Render0002.png differ diff --git a/scenes/splash/dino/Render0002.png.import b/scenes/splash/dino/Render0002.png.import new file mode 100644 index 00000000..7bc725ff --- /dev/null +++ b/scenes/splash/dino/Render0002.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bb8loih7rtsm7" +path="res://.godot/imported/Render0002.png-9a390ff5f6d680afcd1eb67ae5535da5.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://scenes/splash/dino/Render0002.png" +dest_files=["res://.godot/imported/Render0002.png-9a390ff5f6d680afcd1eb67ae5535da5.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/scenes/splash/dino/Render0003.png b/scenes/splash/dino/Render0003.png new file mode 100644 index 00000000..31c619e3 Binary files /dev/null and b/scenes/splash/dino/Render0003.png differ diff --git a/scenes/splash/dino/Render0003.png.import b/scenes/splash/dino/Render0003.png.import new file mode 100644 index 00000000..c0a470a7 --- /dev/null +++ b/scenes/splash/dino/Render0003.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bkcu31j26iae2" +path="res://.godot/imported/Render0003.png-eb552878929270253e56e0c9c04ff6bd.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://scenes/splash/dino/Render0003.png" +dest_files=["res://.godot/imported/Render0003.png-eb552878929270253e56e0c9c04ff6bd.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/scenes/splash/dino/Render0004.png b/scenes/splash/dino/Render0004.png new file mode 100644 index 00000000..31c619e3 Binary files /dev/null and b/scenes/splash/dino/Render0004.png differ diff --git a/scenes/splash/dino/Render0004.png.import b/scenes/splash/dino/Render0004.png.import new file mode 100644 index 00000000..6e280b40 --- /dev/null +++ b/scenes/splash/dino/Render0004.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://drdnk23jjdwhh" +path="res://.godot/imported/Render0004.png-de477e7a80e712cad5cdbd2b322ede87.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://scenes/splash/dino/Render0004.png" +dest_files=["res://.godot/imported/Render0004.png-de477e7a80e712cad5cdbd2b322ede87.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/scenes/splash/dino/Render0005.png b/scenes/splash/dino/Render0005.png new file mode 100644 index 00000000..31c619e3 Binary files /dev/null and b/scenes/splash/dino/Render0005.png differ diff --git a/scenes/splash/dino/Render0005.png.import b/scenes/splash/dino/Render0005.png.import new file mode 100644 index 00000000..9defebc8 --- /dev/null +++ b/scenes/splash/dino/Render0005.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dt4bk5bfbm3yy" +path="res://.godot/imported/Render0005.png-a82f70bf84972ea535a92f9550b4052e.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://scenes/splash/dino/Render0005.png" +dest_files=["res://.godot/imported/Render0005.png-a82f70bf84972ea535a92f9550b4052e.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/scenes/splash/dino/Render0006.png b/scenes/splash/dino/Render0006.png new file mode 100644 index 00000000..31c619e3 Binary files /dev/null and b/scenes/splash/dino/Render0006.png differ diff --git a/scenes/splash/dino/Render0006.png.import b/scenes/splash/dino/Render0006.png.import new file mode 100644 index 00000000..998204a9 --- /dev/null +++ b/scenes/splash/dino/Render0006.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cbf4cp1cctyy4" +path="res://.godot/imported/Render0006.png-c4f43d7df9a331d291ab55e01054ef6c.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://scenes/splash/dino/Render0006.png" +dest_files=["res://.godot/imported/Render0006.png-c4f43d7df9a331d291ab55e01054ef6c.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/scenes/splash/dino/Render0007.png b/scenes/splash/dino/Render0007.png new file mode 100644 index 00000000..31c619e3 Binary files /dev/null and b/scenes/splash/dino/Render0007.png differ diff --git a/ui/assets/icons/slot_left.svg.import b/scenes/splash/dino/Render0007.png.import similarity index 55% rename from ui/assets/icons/slot_left.svg.import rename to scenes/splash/dino/Render0007.png.import index 04ad2a9d..68935292 100644 --- a/ui/assets/icons/slot_left.svg.import +++ b/scenes/splash/dino/Render0007.png.import @@ -2,22 +2,24 @@ importer="texture" type="CompressedTexture2D" -uid="uid://px17kflnvnd7" -path="res://.godot/imported/slot_left.svg-95dad6ec06003ae7e5766bd98efb6690.ctex" +uid="uid://yw1qkpxfsphn" +path="res://.godot/imported/Render0007.png-ec7643933ec76239816b200808a7dbfd.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://ui/assets/icons/slot_left.svg" -dest_files=["res://.godot/imported/slot_left.svg-95dad6ec06003ae7e5766bd98efb6690.ctex"] +source_file="res://scenes/splash/dino/Render0007.png" +dest_files=["res://.godot/imported/Render0007.png-ec7643933ec76239816b200808a7dbfd.ctex"] [params] compress/mode=0 compress/high_quality=false compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 compress/hdr_compression=1 compress/normal_map=0 compress/channel_pack=0 @@ -25,6 +27,10 @@ mipmaps/generate=false mipmaps/limit=-1 roughness/mode=0 roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 process/fix_alpha_border=true process/premult_alpha=false process/normal_map_invert_y=false @@ -32,6 +38,3 @@ process/hdr_as_srgb=false process/hdr_clamp_exposure=false process/size_limit=0 detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false diff --git a/scenes/splash/dino/Render0008.png b/scenes/splash/dino/Render0008.png new file mode 100644 index 00000000..31c619e3 Binary files /dev/null and b/scenes/splash/dino/Render0008.png differ diff --git a/scenes/splash/dino/Render0008.png.import b/scenes/splash/dino/Render0008.png.import new file mode 100644 index 00000000..e54912d1 --- /dev/null +++ b/scenes/splash/dino/Render0008.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b14o2y1e6e3hx" +path="res://.godot/imported/Render0008.png-9aa714af1264bee7db30393a7e6f1e63.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://scenes/splash/dino/Render0008.png" +dest_files=["res://.godot/imported/Render0008.png-9aa714af1264bee7db30393a7e6f1e63.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/scenes/splash/dino/Render0009.png b/scenes/splash/dino/Render0009.png new file mode 100644 index 00000000..31c619e3 Binary files /dev/null and b/scenes/splash/dino/Render0009.png differ diff --git a/scenes/splash/dino/Render0009.png.import b/scenes/splash/dino/Render0009.png.import new file mode 100644 index 00000000..6771a042 --- /dev/null +++ b/scenes/splash/dino/Render0009.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dxwyfggk3n36h" +path="res://.godot/imported/Render0009.png-4a068f759d97606655293ba637b5faaa.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://scenes/splash/dino/Render0009.png" +dest_files=["res://.godot/imported/Render0009.png-4a068f759d97606655293ba637b5faaa.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/scenes/splash/dino/Render0010.png b/scenes/splash/dino/Render0010.png new file mode 100644 index 00000000..31c619e3 Binary files /dev/null and b/scenes/splash/dino/Render0010.png differ diff --git a/scenes/splash/dino/Render0010.png.import b/scenes/splash/dino/Render0010.png.import new file mode 100644 index 00000000..506dd8a2 --- /dev/null +++ b/scenes/splash/dino/Render0010.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bnnm4e1auy3jf" +path="res://.godot/imported/Render0010.png-ea4d3b22bd994ed02c59c0b1791de636.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://scenes/splash/dino/Render0010.png" +dest_files=["res://.godot/imported/Render0010.png-ea4d3b22bd994ed02c59c0b1791de636.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/scenes/splash/dino/Render0011.png b/scenes/splash/dino/Render0011.png new file mode 100644 index 00000000..31c619e3 Binary files /dev/null and b/scenes/splash/dino/Render0011.png differ diff --git a/scenes/splash/dino/Render0011.png.import b/scenes/splash/dino/Render0011.png.import new file mode 100644 index 00000000..eeb43800 --- /dev/null +++ b/scenes/splash/dino/Render0011.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://capb5oodtr03d" +path="res://.godot/imported/Render0011.png-ec6d8d4260b8748cab3228f805407507.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://scenes/splash/dino/Render0011.png" +dest_files=["res://.godot/imported/Render0011.png-ec6d8d4260b8748cab3228f805407507.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/scenes/splash/dino/Render0012.png b/scenes/splash/dino/Render0012.png new file mode 100644 index 00000000..31c619e3 Binary files /dev/null and b/scenes/splash/dino/Render0012.png differ diff --git a/scenes/splash/dino/Render0012.png.import b/scenes/splash/dino/Render0012.png.import new file mode 100644 index 00000000..f81c19b6 --- /dev/null +++ b/scenes/splash/dino/Render0012.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://d3xd0b7slaext" +path="res://.godot/imported/Render0012.png-39c71147fe0d295ce172f0aac06bbf3a.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://scenes/splash/dino/Render0012.png" +dest_files=["res://.godot/imported/Render0012.png-39c71147fe0d295ce172f0aac06bbf3a.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/scenes/splash/dino/Render0013.png b/scenes/splash/dino/Render0013.png new file mode 100644 index 00000000..31c619e3 Binary files /dev/null and b/scenes/splash/dino/Render0013.png differ diff --git a/scenes/splash/dino/Render0013.png.import b/scenes/splash/dino/Render0013.png.import new file mode 100644 index 00000000..0d7f87b0 --- /dev/null +++ b/scenes/splash/dino/Render0013.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cm2jva4mjfmbd" +path="res://.godot/imported/Render0013.png-f8af2bb72c0a35026575aa271c5b7a65.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://scenes/splash/dino/Render0013.png" +dest_files=["res://.godot/imported/Render0013.png-f8af2bb72c0a35026575aa271c5b7a65.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/scenes/splash/dino/Render0014.png b/scenes/splash/dino/Render0014.png new file mode 100644 index 00000000..67228ae7 Binary files /dev/null and b/scenes/splash/dino/Render0014.png differ diff --git a/scenes/splash/dino/Render0014.png.import b/scenes/splash/dino/Render0014.png.import new file mode 100644 index 00000000..0c5e6995 --- /dev/null +++ b/scenes/splash/dino/Render0014.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bp1pq3d3nohvw" +path="res://.godot/imported/Render0014.png-d4f915ee72d9ada6e6a9f5a7ac881bed.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://scenes/splash/dino/Render0014.png" +dest_files=["res://.godot/imported/Render0014.png-d4f915ee72d9ada6e6a9f5a7ac881bed.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/scenes/splash/dino/Render0015.png b/scenes/splash/dino/Render0015.png new file mode 100644 index 00000000..af8bfb48 Binary files /dev/null and b/scenes/splash/dino/Render0015.png differ diff --git a/scenes/splash/dino/Render0015.png.import b/scenes/splash/dino/Render0015.png.import new file mode 100644 index 00000000..1c2998de --- /dev/null +++ b/scenes/splash/dino/Render0015.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://ba87aujsth7cl" +path="res://.godot/imported/Render0015.png-412c1f4270e75c735cb355e623ebee20.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://scenes/splash/dino/Render0015.png" +dest_files=["res://.godot/imported/Render0015.png-412c1f4270e75c735cb355e623ebee20.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/scenes/splash/dino/Render0016.png b/scenes/splash/dino/Render0016.png new file mode 100644 index 00000000..af8bfb48 Binary files /dev/null and b/scenes/splash/dino/Render0016.png differ diff --git a/scenes/splash/dino/Render0016.png.import b/scenes/splash/dino/Render0016.png.import new file mode 100644 index 00000000..8c56130b --- /dev/null +++ b/scenes/splash/dino/Render0016.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b0ealo6tadsem" +path="res://.godot/imported/Render0016.png-1ee48f8fefcfcc497eed980f0f02f81a.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://scenes/splash/dino/Render0016.png" +dest_files=["res://.godot/imported/Render0016.png-1ee48f8fefcfcc497eed980f0f02f81a.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/scenes/splash/dino/Render0017.png b/scenes/splash/dino/Render0017.png new file mode 100644 index 00000000..67228ae7 Binary files /dev/null and b/scenes/splash/dino/Render0017.png differ diff --git a/scenes/splash/dino/Render0017.png.import b/scenes/splash/dino/Render0017.png.import new file mode 100644 index 00000000..0b2c2593 --- /dev/null +++ b/scenes/splash/dino/Render0017.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cnllmukyrs07o" +path="res://.godot/imported/Render0017.png-dcaebcccb16b96a78d00c81388d38b3d.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://scenes/splash/dino/Render0017.png" +dest_files=["res://.godot/imported/Render0017.png-dcaebcccb16b96a78d00c81388d38b3d.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/scenes/splash/dino/Render0018.png b/scenes/splash/dino/Render0018.png new file mode 100644 index 00000000..31c619e3 Binary files /dev/null and b/scenes/splash/dino/Render0018.png differ diff --git a/scenes/splash/dino/Render0018.png.import b/scenes/splash/dino/Render0018.png.import new file mode 100644 index 00000000..81a2f9bb --- /dev/null +++ b/scenes/splash/dino/Render0018.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bysgspu1uklaj" +path="res://.godot/imported/Render0018.png-fb229b03cb11e162cab7ff166d93a47b.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://scenes/splash/dino/Render0018.png" +dest_files=["res://.godot/imported/Render0018.png-fb229b03cb11e162cab7ff166d93a47b.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/scenes/splash/dino/Render0019.png b/scenes/splash/dino/Render0019.png new file mode 100644 index 00000000..31c619e3 Binary files /dev/null and b/scenes/splash/dino/Render0019.png differ diff --git a/scenes/splash/dino/Render0019.png.import b/scenes/splash/dino/Render0019.png.import new file mode 100644 index 00000000..dd1066a1 --- /dev/null +++ b/scenes/splash/dino/Render0019.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://d2i5w3curjjrc" +path="res://.godot/imported/Render0019.png-6b2688328409d7e70a6574b49b264f13.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://scenes/splash/dino/Render0019.png" +dest_files=["res://.godot/imported/Render0019.png-6b2688328409d7e70a6574b49b264f13.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/scenes/splash/dino/Render0020.png b/scenes/splash/dino/Render0020.png new file mode 100644 index 00000000..31c619e3 Binary files /dev/null and b/scenes/splash/dino/Render0020.png differ diff --git a/scenes/splash/dino/Render0020.png.import b/scenes/splash/dino/Render0020.png.import new file mode 100644 index 00000000..d1f26a11 --- /dev/null +++ b/scenes/splash/dino/Render0020.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bge0uh3rri18y" +path="res://.godot/imported/Render0020.png-c97cd5f891b049c25a9ecb489d17351b.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://scenes/splash/dino/Render0020.png" +dest_files=["res://.godot/imported/Render0020.png-c97cd5f891b049c25a9ecb489d17351b.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/scenes/splash/dino/Render0021.png b/scenes/splash/dino/Render0021.png new file mode 100644 index 00000000..31c619e3 Binary files /dev/null and b/scenes/splash/dino/Render0021.png differ diff --git a/scenes/splash/dino/Render0021.png.import b/scenes/splash/dino/Render0021.png.import new file mode 100644 index 00000000..a7d0b9d2 --- /dev/null +++ b/scenes/splash/dino/Render0021.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bjvfg8v7paow2" +path="res://.godot/imported/Render0021.png-5baf946e083df6e522ce7c0bc7dcf025.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://scenes/splash/dino/Render0021.png" +dest_files=["res://.godot/imported/Render0021.png-5baf946e083df6e522ce7c0bc7dcf025.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/scenes/splash/dino/Render0022.png b/scenes/splash/dino/Render0022.png new file mode 100644 index 00000000..31c619e3 Binary files /dev/null and b/scenes/splash/dino/Render0022.png differ diff --git a/scenes/splash/dino/Render0022.png.import b/scenes/splash/dino/Render0022.png.import new file mode 100644 index 00000000..ba5e7abe --- /dev/null +++ b/scenes/splash/dino/Render0022.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://ewqu3mclfs6c" +path="res://.godot/imported/Render0022.png-60bce78a8e16ad124013197b92958d40.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://scenes/splash/dino/Render0022.png" +dest_files=["res://.godot/imported/Render0022.png-60bce78a8e16ad124013197b92958d40.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/scenes/splash/dino/Render0023.png b/scenes/splash/dino/Render0023.png new file mode 100644 index 00000000..31c619e3 Binary files /dev/null and b/scenes/splash/dino/Render0023.png differ diff --git a/scenes/splash/dino/Render0023.png.import b/scenes/splash/dino/Render0023.png.import new file mode 100644 index 00000000..11554ea7 --- /dev/null +++ b/scenes/splash/dino/Render0023.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://7nbo4iudfojf" +path="res://.godot/imported/Render0023.png-e877c6caa3fb6bbf2a31024af7a49640.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://scenes/splash/dino/Render0023.png" +dest_files=["res://.godot/imported/Render0023.png-e877c6caa3fb6bbf2a31024af7a49640.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/scenes/splash/dino/Render0024.png b/scenes/splash/dino/Render0024.png new file mode 100644 index 00000000..31c619e3 Binary files /dev/null and b/scenes/splash/dino/Render0024.png differ diff --git a/scenes/splash/dino/Render0024.png.import b/scenes/splash/dino/Render0024.png.import new file mode 100644 index 00000000..0a609a78 --- /dev/null +++ b/scenes/splash/dino/Render0024.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://c8ctuf25a6uie" +path="res://.godot/imported/Render0024.png-bd68ee02556356ea3dcf8e49c8653906.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://scenes/splash/dino/Render0024.png" +dest_files=["res://.godot/imported/Render0024.png-bd68ee02556356ea3dcf8e49c8653906.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/scenes/splash/dino/Render0025.png b/scenes/splash/dino/Render0025.png new file mode 100644 index 00000000..31c619e3 Binary files /dev/null and b/scenes/splash/dino/Render0025.png differ diff --git a/scenes/splash/dino/Render0025.png.import b/scenes/splash/dino/Render0025.png.import new file mode 100644 index 00000000..58d61324 --- /dev/null +++ b/scenes/splash/dino/Render0025.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dv8dbtbhofxo" +path="res://.godot/imported/Render0025.png-5db4809a7c3d3288ef7c0ff11d929119.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://scenes/splash/dino/Render0025.png" +dest_files=["res://.godot/imported/Render0025.png-5db4809a7c3d3288ef7c0ff11d929119.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/scenes/splash/dino/Render0026.png b/scenes/splash/dino/Render0026.png new file mode 100644 index 00000000..31c619e3 Binary files /dev/null and b/scenes/splash/dino/Render0026.png differ diff --git a/scenes/splash/dino/Render0026.png.import b/scenes/splash/dino/Render0026.png.import new file mode 100644 index 00000000..1282ed29 --- /dev/null +++ b/scenes/splash/dino/Render0026.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b4suruuapjkh2" +path="res://.godot/imported/Render0026.png-77fb4f567a83726d52196efe19d0f93d.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://scenes/splash/dino/Render0026.png" +dest_files=["res://.godot/imported/Render0026.png-77fb4f567a83726d52196efe19d0f93d.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/scenes/splash/dino/Render0027.png b/scenes/splash/dino/Render0027.png new file mode 100644 index 00000000..31c619e3 Binary files /dev/null and b/scenes/splash/dino/Render0027.png differ diff --git a/scenes/splash/dino/Render0027.png.import b/scenes/splash/dino/Render0027.png.import new file mode 100644 index 00000000..351861e9 --- /dev/null +++ b/scenes/splash/dino/Render0027.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dj7gb22q2y3qq" +path="res://.godot/imported/Render0027.png-e1b17fb574c98e9960cf410f7f1557a2.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://scenes/splash/dino/Render0027.png" +dest_files=["res://.godot/imported/Render0027.png-e1b17fb574c98e9960cf410f7f1557a2.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/scenes/splash/dino/Render0028.png b/scenes/splash/dino/Render0028.png new file mode 100644 index 00000000..31c619e3 Binary files /dev/null and b/scenes/splash/dino/Render0028.png differ diff --git a/scenes/splash/dino/Render0028.png.import b/scenes/splash/dino/Render0028.png.import new file mode 100644 index 00000000..b7266556 --- /dev/null +++ b/scenes/splash/dino/Render0028.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dg2a46d32at3t" +path="res://.godot/imported/Render0028.png-8fa811f8d4d8bea16e533422c8439325.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://scenes/splash/dino/Render0028.png" +dest_files=["res://.godot/imported/Render0028.png-8fa811f8d4d8bea16e533422c8439325.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/scenes/splash/dino/Render0029.png b/scenes/splash/dino/Render0029.png new file mode 100644 index 00000000..31c619e3 Binary files /dev/null and b/scenes/splash/dino/Render0029.png differ diff --git a/scenes/splash/dino/Render0029.png.import b/scenes/splash/dino/Render0029.png.import new file mode 100644 index 00000000..2565ea43 --- /dev/null +++ b/scenes/splash/dino/Render0029.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://50icxn20btnq" +path="res://.godot/imported/Render0029.png-f007eebed3cdc1d58572b147d39d3996.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://scenes/splash/dino/Render0029.png" +dest_files=["res://.godot/imported/Render0029.png-f007eebed3cdc1d58572b147d39d3996.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/scenes/splash/dino/Render0030.png b/scenes/splash/dino/Render0030.png new file mode 100644 index 00000000..31c619e3 Binary files /dev/null and b/scenes/splash/dino/Render0030.png differ diff --git a/scenes/splash/dino/Render0030.png.import b/scenes/splash/dino/Render0030.png.import new file mode 100644 index 00000000..7fa05030 --- /dev/null +++ b/scenes/splash/dino/Render0030.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dd00100w3siit" +path="res://.godot/imported/Render0030.png-3640f1f9c65c54619af1a21159e7ceb1.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://scenes/splash/dino/Render0030.png" +dest_files=["res://.godot/imported/Render0030.png-3640f1f9c65c54619af1a21159e7ceb1.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/scenes/splash/monologue_eye/frame_1.png.import b/scenes/splash/monologue_eye/frame_1.png.import index eb2b6e33..ed283543 100644 --- a/scenes/splash/monologue_eye/frame_1.png.import +++ b/scenes/splash/monologue_eye/frame_1.png.import @@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/frame_1.png-147f33cbcbe9df68a844afe932874042. compress/mode=0 compress/high_quality=false compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 compress/hdr_compression=1 compress/normal_map=0 compress/channel_pack=0 @@ -25,6 +27,10 @@ mipmaps/generate=false mipmaps/limit=-1 roughness/mode=0 roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 process/fix_alpha_border=true process/premult_alpha=false process/normal_map_invert_y=false diff --git a/scenes/splash/monologue_eye/frame_2.png.import b/scenes/splash/monologue_eye/frame_2.png.import index e283dfb3..a708ac52 100644 --- a/scenes/splash/monologue_eye/frame_2.png.import +++ b/scenes/splash/monologue_eye/frame_2.png.import @@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/frame_2.png-42ab9f647cba04dfc332a1585f7c86ea. compress/mode=0 compress/high_quality=false compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 compress/hdr_compression=1 compress/normal_map=0 compress/channel_pack=0 @@ -25,6 +27,10 @@ mipmaps/generate=false mipmaps/limit=-1 roughness/mode=0 roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 process/fix_alpha_border=true process/premult_alpha=false process/normal_map_invert_y=false diff --git a/scenes/splash/monologue_eye/frame_3.png.import b/scenes/splash/monologue_eye/frame_3.png.import index 67614576..41bdab42 100644 --- a/scenes/splash/monologue_eye/frame_3.png.import +++ b/scenes/splash/monologue_eye/frame_3.png.import @@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/frame_3.png-3a7a807425b0ddd9699f56c885c47046. compress/mode=0 compress/high_quality=false compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 compress/hdr_compression=1 compress/normal_map=0 compress/channel_pack=0 @@ -25,6 +27,10 @@ mipmaps/generate=false mipmaps/limit=-1 roughness/mode=0 roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 process/fix_alpha_border=true process/premult_alpha=false process/normal_map_invert_y=false diff --git a/scenes/splash/splash.gd b/scenes/splash/splash.gd index c1d04aea..3b7986fb 100644 --- a/scenes/splash/splash.gd +++ b/scenes/splash/splash.gd @@ -1,34 +1,28 @@ extends Control @export_file var load_scene: String -@export var min_display_time: float = 0.2 -@export var after_blink_time: float = 0.5 -@onready var timer = $tMinDisplayTime -@onready var title = $CenterContainer/TextureRect -@onready var eye = $CenterContainer/TextureRect/AnimatedSprite2D +@onready var sprite = $AnimatedSprite2D func _ready() -> void: - timer.start(min_display_time) ResourceLoader.load_threaded_request(load_scene) - title.connect("item_rect_changed", _on_item_rect_changed) + item_rect_changed.connect(_on_item_rect_changed) + _on_item_rect_changed() func _process(_delta: float) -> void: var status := ResourceLoader.load_threaded_get_status(load_scene) - if status == ResourceLoader.ThreadLoadStatus.THREAD_LOAD_LOADED and timer.is_stopped(): + if status == ResourceLoader.ThreadLoadStatus.THREAD_LOAD_LOADED: var scene := ResourceLoader.load_threaded_get(load_scene) - eye.play("blink") - await eye.animation_finished - await get_tree().create_timer(after_blink_time).timeout + sprite.play("blink") + await sprite.animation_finished - get_window().unresizable = false get_tree().change_scene_to_packed(scene) func _on_item_rect_changed() -> void: - eye.global_position.x = title.position.x + 143 - eye.global_position.y = title.position.y + 40 + var vp: Rect2 = get_viewport_rect() + sprite.global_position = vp.size / 2 diff --git a/scenes/splash/splash.tscn b/scenes/splash/splash.tscn index afc5fc0a..3c056716 100644 --- a/scenes/splash/splash.tscn +++ b/scenes/splash/splash.tscn @@ -1,28 +1,129 @@ -[gd_scene load_steps=7 format=3 uid="uid://bakm53e6ecbk8"] +[gd_scene load_steps=33 format=3 uid="uid://bakm53e6ecbk8"] [ext_resource type="Script" uid="uid://c0nc2j7o3qbfe" path="res://scenes/splash/splash.gd" id="1_pl0ug"] -[ext_resource type="Texture2D" uid="uid://bddodmw1pm42r" path="res://title_banner@0.5x.png" id="2_rikux"] -[ext_resource type="Texture2D" uid="uid://cbfudkvndq872" path="res://scenes/splash/monologue_eye/frame_1.png" id="3_qdaos"] -[ext_resource type="Texture2D" uid="uid://dp3p88mc7f4k4" path="res://scenes/splash/monologue_eye/frame_3.png" id="5_783yv"] -[ext_resource type="Texture2D" uid="uid://dea6b1sjaitkq" path="res://scenes/splash/monologue_eye/frame_2.png" id="7_ueewa"] +[ext_resource type="Texture2D" uid="uid://c41kgi20w10ks" path="res://scenes/splash/dino/Render0001.png" id="2_u6rph"] +[ext_resource type="Texture2D" uid="uid://bb8loih7rtsm7" path="res://scenes/splash/dino/Render0002.png" id="3_sfa60"] +[ext_resource type="Texture2D" uid="uid://bkcu31j26iae2" path="res://scenes/splash/dino/Render0003.png" id="4_slhqk"] +[ext_resource type="Texture2D" uid="uid://drdnk23jjdwhh" path="res://scenes/splash/dino/Render0004.png" id="5_oxsyg"] +[ext_resource type="Texture2D" uid="uid://dt4bk5bfbm3yy" path="res://scenes/splash/dino/Render0005.png" id="6_i1u52"] +[ext_resource type="Texture2D" uid="uid://cbf4cp1cctyy4" path="res://scenes/splash/dino/Render0006.png" id="7_rrr64"] +[ext_resource type="Texture2D" uid="uid://yw1qkpxfsphn" path="res://scenes/splash/dino/Render0007.png" id="8_38atd"] +[ext_resource type="Texture2D" uid="uid://b14o2y1e6e3hx" path="res://scenes/splash/dino/Render0008.png" id="9_1wfnp"] +[ext_resource type="Texture2D" uid="uid://dxwyfggk3n36h" path="res://scenes/splash/dino/Render0009.png" id="10_3sqgo"] +[ext_resource type="Texture2D" uid="uid://bnnm4e1auy3jf" path="res://scenes/splash/dino/Render0010.png" id="11_hde8r"] +[ext_resource type="Texture2D" uid="uid://capb5oodtr03d" path="res://scenes/splash/dino/Render0011.png" id="12_kopq8"] +[ext_resource type="Texture2D" uid="uid://d3xd0b7slaext" path="res://scenes/splash/dino/Render0012.png" id="13_ocr2a"] +[ext_resource type="Texture2D" uid="uid://cm2jva4mjfmbd" path="res://scenes/splash/dino/Render0013.png" id="14_wk58s"] +[ext_resource type="Texture2D" uid="uid://bp1pq3d3nohvw" path="res://scenes/splash/dino/Render0014.png" id="15_pacsv"] +[ext_resource type="Texture2D" uid="uid://ba87aujsth7cl" path="res://scenes/splash/dino/Render0015.png" id="16_tm5oe"] +[ext_resource type="Texture2D" uid="uid://b0ealo6tadsem" path="res://scenes/splash/dino/Render0016.png" id="17_sotjw"] +[ext_resource type="Texture2D" uid="uid://cnllmukyrs07o" path="res://scenes/splash/dino/Render0017.png" id="18_7g2nk"] +[ext_resource type="Texture2D" uid="uid://bysgspu1uklaj" path="res://scenes/splash/dino/Render0018.png" id="19_hgma0"] +[ext_resource type="Texture2D" uid="uid://d2i5w3curjjrc" path="res://scenes/splash/dino/Render0019.png" id="20_42o70"] +[ext_resource type="Texture2D" uid="uid://bge0uh3rri18y" path="res://scenes/splash/dino/Render0020.png" id="21_hdejy"] +[ext_resource type="Texture2D" uid="uid://bjvfg8v7paow2" path="res://scenes/splash/dino/Render0021.png" id="22_o4era"] +[ext_resource type="Texture2D" uid="uid://ewqu3mclfs6c" path="res://scenes/splash/dino/Render0022.png" id="23_t80or"] +[ext_resource type="Texture2D" uid="uid://7nbo4iudfojf" path="res://scenes/splash/dino/Render0023.png" id="24_ysi88"] +[ext_resource type="Texture2D" uid="uid://c8ctuf25a6uie" path="res://scenes/splash/dino/Render0024.png" id="25_7nks1"] +[ext_resource type="Texture2D" uid="uid://dv8dbtbhofxo" path="res://scenes/splash/dino/Render0025.png" id="26_6j2es"] +[ext_resource type="Texture2D" uid="uid://b4suruuapjkh2" path="res://scenes/splash/dino/Render0026.png" id="27_bx5ox"] +[ext_resource type="Texture2D" uid="uid://dj7gb22q2y3qq" path="res://scenes/splash/dino/Render0027.png" id="28_wv76i"] +[ext_resource type="Texture2D" uid="uid://dg2a46d32at3t" path="res://scenes/splash/dino/Render0028.png" id="29_ltc0p"] +[ext_resource type="Texture2D" uid="uid://50icxn20btnq" path="res://scenes/splash/dino/Render0029.png" id="30_hc4f3"] +[ext_resource type="Texture2D" uid="uid://dd00100w3siit" path="res://scenes/splash/dino/Render0030.png" id="31_ohppt"] [sub_resource type="SpriteFrames" id="SpriteFrames_tj644"] animations = [{ "frames": [{ "duration": 1.0, -"texture": ExtResource("3_qdaos") +"texture": ExtResource("2_u6rph") }, { "duration": 1.0, -"texture": ExtResource("7_ueewa") +"texture": ExtResource("3_sfa60") }, { -"duration": 2.0, -"texture": ExtResource("5_783yv") +"duration": 1.0, +"texture": ExtResource("4_slhqk") +}, { +"duration": 1.0, +"texture": ExtResource("5_oxsyg") +}, { +"duration": 1.0, +"texture": ExtResource("6_i1u52") +}, { +"duration": 1.0, +"texture": ExtResource("7_rrr64") +}, { +"duration": 1.0, +"texture": ExtResource("8_38atd") +}, { +"duration": 1.0, +"texture": ExtResource("9_1wfnp") +}, { +"duration": 1.0, +"texture": ExtResource("10_3sqgo") +}, { +"duration": 1.0, +"texture": ExtResource("11_hde8r") +}, { +"duration": 1.0, +"texture": ExtResource("12_kopq8") +}, { +"duration": 1.0, +"texture": ExtResource("13_ocr2a") +}, { +"duration": 1.0, +"texture": ExtResource("14_wk58s") +}, { +"duration": 1.0, +"texture": ExtResource("15_pacsv") +}, { +"duration": 1.0, +"texture": ExtResource("16_tm5oe") +}, { +"duration": 1.0, +"texture": ExtResource("17_sotjw") +}, { +"duration": 1.0, +"texture": ExtResource("18_7g2nk") +}, { +"duration": 1.0, +"texture": ExtResource("19_hgma0") +}, { +"duration": 1.0, +"texture": ExtResource("20_42o70") +}, { +"duration": 1.0, +"texture": ExtResource("21_hdejy") +}, { +"duration": 1.0, +"texture": ExtResource("22_o4era") +}, { +"duration": 1.0, +"texture": ExtResource("23_t80or") +}, { +"duration": 1.0, +"texture": ExtResource("24_ysi88") +}, { +"duration": 1.0, +"texture": ExtResource("25_7nks1") +}, { +"duration": 1.0, +"texture": ExtResource("26_6j2es") }, { "duration": 1.0, -"texture": ExtResource("7_ueewa") +"texture": ExtResource("27_bx5ox") }, { "duration": 1.0, -"texture": ExtResource("3_qdaos") +"texture": ExtResource("28_wv76i") +}, { +"duration": 1.0, +"texture": ExtResource("29_ltc0p") +}, { +"duration": 1.0, +"texture": ExtResource("30_hc4f3") +}, { +"duration": 1.0, +"texture": ExtResource("31_ohppt") }], "loop": false, "name": &"blink", @@ -39,35 +140,17 @@ grow_vertical = 2 script = ExtResource("1_pl0ug") load_scene = "res://scenes/main/app.tscn" -[node name="ColorRect" type="ColorRect" parent="."] +[node name="PanelContainer" type="PanelContainer" parent="."] layout_mode = 1 anchors_preset = 15 anchor_right = 1.0 anchor_bottom = 1.0 grow_horizontal = 2 grow_vertical = 2 -color = Color(0.117647, 0.117647, 0.129412, 1) -[node name="CenterContainer" type="CenterContainer" parent="."] -layout_mode = 1 -anchors_preset = 15 -anchor_right = 1.0 -anchor_bottom = 1.0 -grow_horizontal = 2 -grow_vertical = 2 - -[node name="TextureRect" type="TextureRect" parent="CenterContainer"] -custom_minimum_size = Vector2(768, 0) -layout_mode = 2 -texture = ExtResource("2_rikux") -expand_mode = 5 -stretch_mode = 5 - -[node name="AnimatedSprite2D" type="AnimatedSprite2D" parent="CenterContainer/TextureRect"] -position = Vector2(142, 40) -scale = Vector2(0.263, 0.26) +[node name="AnimatedSprite2D" type="AnimatedSprite2D" parent="."] +scale = Vector2(0.5, 0.5) sprite_frames = SubResource("SpriteFrames_tj644") animation = &"blink" - -[node name="tMinDisplayTime" type="Timer" parent="."] -one_shot = true +frame = 29 +frame_progress = 1.0 diff --git a/src/common/property.gd b/src/common/property.gd new file mode 100644 index 00000000..4a80f580 --- /dev/null +++ b/src/common/property.gd @@ -0,0 +1,186 @@ +class_name Property extends RefCounted + +signal value_changed(old_value: Variant, new_value: Variant) + +var name: String = "" +var value: Variant = 0 +var type: String = "" +var _settings: Dictionary = {} +var settings: Dictionary = {} +var descriptor +var _bindings: Array = [] + +const DEFAULT_SETTINGS := { + "visible_in_graph": true, + "visible_in_inspector": true, + "editable": true, + "exposable": true, + "exposed": false, + "export": false, + "category": "General", + "label": "", +} + +## Tracks input connections to this property (nodes connecting TO this property) +var connected_from: Array[Dictionary] = [] # [{node_name: String, property_name: String, port: int}] + +## Tracks output connections from this property (nodes this property connects TO) +var connected_to: Array[Dictionary] = [] # [{node_name: String, property_name: String, port: int}] + +## Property Settings: +## - visible_in_graph: Whether property shows as a row in graph node view +## - visible_in_inspector: Whether property shows in inspector panel +## - editable: Whether property value can be edited (enforced in inspector) +## - exposed: Whether property has input port (left side) for receiving connections +## - export: Whether property has output port (right side) for sending connections +## - is_main_property: Whether this is the main connectable property of the node + + +func _init(pname: String, pvalue: Variant, ptype: String, psettings: Dictionary = {}) -> void: + name = pname + value = pvalue + type = ptype + descriptor = FieldBucket.get_descriptor(ptype) + _settings = DEFAULT_SETTINGS.duplicate(true) + if descriptor and descriptor.default_settings: + _settings.merge(descriptor.default_settings, true) + if psettings: + _settings.merge(psettings, true) + if not _settings.get("category"): + _settings["category"] = DEFAULT_SETTINGS["category"] + if _settings.get("label", "") == "": + _settings.erase("label") + + +func bind_field(field: Field, target_owner: InspectableObject = null): + if not is_instance_valid(field): + return null + if not field.is_inside_tree(): + field.tree_entered.connect( + _on_field_tree_entered.bind(field, target_owner), CONNECT_ONE_SHOT + ) + return null + var binding = FieldBucket.bind(self, field, target_owner) + if binding: + _bindings.append(binding) + return binding + + +func _on_field_tree_entered(field: Field, target_owner: InspectableObject) -> void: + bind_field(field, target_owner) + + +func set_value(new_value: Variant) -> void: + if value == new_value: + return + var old_value: Variant = value + value = new_value + value_changed.emit(old_value, new_value) + + +func get_value() -> Variant: + return value + + +func get_settings() -> Dictionary: + var merged_settings: Dictionary = settings.duplicate(true) + merged_settings.merge(_settings) + return merged_settings + + +func has_settings(skey) -> bool: + return get_settings().has(skey) + + +func get_settings_value(skey: String, default_value: Variant = null) -> Variant: + return get_settings().get(skey, default_value) + + +func get_display_name() -> String: + var label: String = get_settings_value("label", "") + if label.is_empty(): + label = name + return Util.to_readable_name(label) + + +func get_category() -> String: + return get_settings_value("category", "General") + + +func is_input_connected() -> bool: + return connected_from.size() > 0 + + +func is_output_connected() -> bool: + return connected_to.size() > 0 + + +func is_port_connected() -> bool: + return is_input_connected() or is_output_connected() + + +func is_intput_connected() -> bool: + return is_input_connected() + + +func add_connection_from(node_id: String, property_name: String) -> void: + var conn = {"node_id": node_id, "property_name": property_name} + if conn not in connected_from: + connected_from.append(conn) + + +func add_connection_to(node_id: String, property_name: String) -> void: + var conn = {"node_id": node_id, "property_name": property_name} + if conn not in connected_to: + connected_to.append(conn) + + +func remove_connection_from(node_id: String, property_name: String) -> void: + connected_from = connected_from.filter( + func(c): return not (c["node_id"] == node_id and c["property_name"] == property_name) + ) + + +func remove_connection_to(node_id: String, property_name: String) -> void: + connected_to = connected_to.filter( + func(c): return not (c["node_id"] == node_id and c["property_name"] == property_name) + ) + + +func clear_connections() -> void: + connected_from.clear() + connected_to.clear() + + +func refresh_bindings() -> void: + _bindings = _bindings.filter(func(binding): return binding and binding.is_active()) + for binding in _bindings: + binding.refresh() + + +func get_descriptor(): + if descriptor == null: + descriptor = FieldBucket.get_descriptor(type) + return descriptor + + +func _to_dict() -> Dictionary: + var dict: Dictionary = {} + if not settings.is_empty(): + dict["_editor_settings"] = settings + + if get_settings_value("exposed") and not connected_from.is_empty(): + dict["from_node"] = connected_from + dict["value"] = get_value() + + if get_settings_value("export"): + dict["to_node"] = connected_to + return dict + + +# Do not trigger undo/redo +func _from_dict(dict: Dictionary) -> void: + value = dict.get("value", value) + settings = dict.get("_editor_settings", settings) + connected_from = dict.get("from_node", connected_from) + connected_to = dict.get("to_node", connected_to) diff --git a/src/common/property.gd.uid b/src/common/property.gd.uid new file mode 100644 index 00000000..a56a8f95 --- /dev/null +++ b/src/common/property.gd.uid @@ -0,0 +1 @@ +uid://cvxcfitjpar4y diff --git a/title_banner.png.import b/title_banner.png.import index 6f73a2b5..08291d01 100644 --- a/title_banner.png.import +++ b/title_banner.png.import @@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/title_banner.png-b6af4c016a12441d70edfc4828a8 compress/mode=0 compress/high_quality=false compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 compress/hdr_compression=1 compress/normal_map=0 compress/channel_pack=0 @@ -25,6 +27,10 @@ mipmaps/generate=false mipmaps/limit=-1 roughness/mode=0 roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 process/fix_alpha_border=true process/premult_alpha=false process/normal_map_invert_y=false diff --git a/title_banner@0.5x.png.import b/title_banner@0.5x.png.import index b7bac214..854e49bb 100644 --- a/title_banner@0.5x.png.import +++ b/title_banner@0.5x.png.import @@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/title_banner@0.5x.png-fcce4185ca69f38f8764502 compress/mode=0 compress/high_quality=false compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 compress/hdr_compression=1 compress/normal_map=0 compress/channel_pack=0 @@ -25,6 +27,10 @@ mipmaps/generate=false mipmaps/limit=-1 roughness/mode=0 roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 process/fix_alpha_border=true process/premult_alpha=false process/normal_map_invert_y=false diff --git a/ui/assets/cursors/closed_hand.svg.import b/ui/assets/cursors/closed_hand.svg.import index b12f0b11..c5160e0c 100644 --- a/ui/assets/cursors/closed_hand.svg.import +++ b/ui/assets/cursors/closed_hand.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://bdhmgrqrir12q" -path="res://.godot/imported/closed_hand.svg-2e3453a9ca7ef3b953b6711566c92755.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/closed_hand.svg-2e3453a9ca7ef3b953b6711566c92755.dpitex" [deps] source_file="res://ui/assets/cursors/closed_hand.svg" -dest_files=["res://.godot/imported/closed_hand.svg-2e3453a9ca7ef3b953b6711566c92755.ctex"] +dest_files=["res://.godot/imported/closed_hand.svg-2e3453a9ca7ef3b953b6711566c92755.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/cursors/cursor.svg.import b/ui/assets/cursors/cursor.svg.import index 26afe26e..1d802f36 100644 --- a/ui/assets/cursors/cursor.svg.import +++ b/ui/assets/cursors/cursor.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://dhlu3mvdkvea6" -path="res://.godot/imported/cursor.svg-cb17606446184733929991836c986519.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/cursor.svg-cb17606446184733929991836c986519.dpitex" [deps] source_file="res://ui/assets/cursors/cursor.svg" -dest_files=["res://.godot/imported/cursor.svg-cb17606446184733929991836c986519.ctex"] +dest_files=["res://.godot/imported/cursor.svg-cb17606446184733929991836c986519.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/cursors/hand.svg.import b/ui/assets/cursors/hand.svg.import index 1ddf285f..1e9206d2 100644 --- a/ui/assets/cursors/hand.svg.import +++ b/ui/assets/cursors/hand.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://cu75pg7vsf7qi" -path="res://.godot/imported/hand.svg-9d7dd8186197dcbfc6e6ad3b81b01648.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/hand.svg-9d7dd8186197dcbfc6e6ad3b81b01648.dpitex" [deps] source_file="res://ui/assets/cursors/hand.svg" -dest_files=["res://.godot/imported/hand.svg-9d7dd8186197dcbfc6e6ad3b81b01648.ctex"] +dest_files=["res://.godot/imported/hand.svg-9d7dd8186197dcbfc6e6ad3b81b01648.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/fonts/CourierNewPS-BoldMT.ttf.import b/ui/assets/fonts/CourierNewPS-BoldMT.ttf.import index 9dd5ab85..a5355734 100644 --- a/ui/assets/fonts/CourierNewPS-BoldMT.ttf.import +++ b/ui/assets/fonts/CourierNewPS-BoldMT.ttf.import @@ -21,6 +21,7 @@ msdf_pixel_range=8 msdf_size=48 allow_system_fallback=true force_autohinter=false +modulate_color_glyphs=false hinting=1 subpixel_positioning=4 keep_rounding_remainders=true diff --git a/ui/assets/fonts/CourierNewPS-ItalicMT.ttf.import b/ui/assets/fonts/CourierNewPS-ItalicMT.ttf.import index 24fe5396..9a9a52cf 100644 --- a/ui/assets/fonts/CourierNewPS-ItalicMT.ttf.import +++ b/ui/assets/fonts/CourierNewPS-ItalicMT.ttf.import @@ -21,6 +21,7 @@ msdf_pixel_range=8 msdf_size=48 allow_system_fallback=true force_autohinter=false +modulate_color_glyphs=false hinting=1 subpixel_positioning=4 keep_rounding_remainders=true diff --git a/ui/assets/fonts/CourierNewPSMT.ttf.import b/ui/assets/fonts/CourierNewPSMT.ttf.import index 2197aec0..4def57fb 100644 --- a/ui/assets/fonts/CourierNewPSMT.ttf.import +++ b/ui/assets/fonts/CourierNewPSMT.ttf.import @@ -21,6 +21,7 @@ msdf_pixel_range=8 msdf_size=48 allow_system_fallback=true force_autohinter=false +modulate_color_glyphs=false hinting=1 subpixel_positioning=4 keep_rounding_remainders=true diff --git a/ui/assets/fonts/GeneralSans-Bold.otf.import b/ui/assets/fonts/GeneralSans-Bold.otf.import index c5798a0f..9ecab4ba 100644 --- a/ui/assets/fonts/GeneralSans-Bold.otf.import +++ b/ui/assets/fonts/GeneralSans-Bold.otf.import @@ -21,10 +21,11 @@ msdf_pixel_range=8 msdf_size=48 allow_system_fallback=true force_autohinter=false +modulate_color_glyphs=false hinting=1 subpixel_positioning=4 keep_rounding_remainders=true -oversampling=0.0 +oversampling=2.0 Fallbacks=null fallbacks=[] Compress=null diff --git a/ui/assets/fonts/GeneralSans-BoldItalic.otf.import b/ui/assets/fonts/GeneralSans-BoldItalic.otf.import index d504e870..63e68d39 100644 --- a/ui/assets/fonts/GeneralSans-BoldItalic.otf.import +++ b/ui/assets/fonts/GeneralSans-BoldItalic.otf.import @@ -21,15 +21,22 @@ msdf_pixel_range=8 msdf_size=48 allow_system_fallback=true force_autohinter=false +modulate_color_glyphs=false hinting=1 subpixel_positioning=4 keep_rounding_remainders=true -oversampling=0.0 +oversampling=2.0 Fallbacks=null fallbacks=[] Compress=null compress=true -preload=[] +preload=[{ +"chars": [], +"glyphs": [], +"name": "Nouvelle configuration", +"size": Vector2i(16, 0), +&"variation_embolden": 0.0 +}] language_support={} script_support={} opentype_features={} diff --git a/ui/assets/fonts/GeneralSans-Extralight.otf.import b/ui/assets/fonts/GeneralSans-Extralight.otf.import index cb5fe973..c11df6e5 100644 --- a/ui/assets/fonts/GeneralSans-Extralight.otf.import +++ b/ui/assets/fonts/GeneralSans-Extralight.otf.import @@ -21,15 +21,22 @@ msdf_pixel_range=8 msdf_size=48 allow_system_fallback=true force_autohinter=false +modulate_color_glyphs=false hinting=1 subpixel_positioning=4 keep_rounding_remainders=true -oversampling=0.0 +oversampling=2.0 Fallbacks=null fallbacks=[] Compress=null compress=true -preload=[] +preload=[{ +"chars": [], +"glyphs": [], +"name": "Nouvelle configuration", +"size": Vector2i(16, 0), +&"variation_embolden": 0.0 +}] language_support={} script_support={} opentype_features={} diff --git a/ui/assets/fonts/GeneralSans-ExtralightItalic.otf.import b/ui/assets/fonts/GeneralSans-ExtralightItalic.otf.import index 4b6fe0a7..28967deb 100644 --- a/ui/assets/fonts/GeneralSans-ExtralightItalic.otf.import +++ b/ui/assets/fonts/GeneralSans-ExtralightItalic.otf.import @@ -21,15 +21,22 @@ msdf_pixel_range=8 msdf_size=48 allow_system_fallback=true force_autohinter=false +modulate_color_glyphs=false hinting=1 subpixel_positioning=4 keep_rounding_remainders=true -oversampling=0.0 +oversampling=2.0 Fallbacks=null fallbacks=[] Compress=null compress=true -preload=[] +preload=[{ +"chars": [], +"glyphs": [], +"name": "Nouvelle configuration", +"size": Vector2i(16, 0), +&"variation_embolden": 0.0 +}] language_support={} script_support={} opentype_features={} diff --git a/ui/assets/fonts/GeneralSans-Italic.otf.import b/ui/assets/fonts/GeneralSans-Italic.otf.import index 566271a8..07da4880 100644 --- a/ui/assets/fonts/GeneralSans-Italic.otf.import +++ b/ui/assets/fonts/GeneralSans-Italic.otf.import @@ -21,15 +21,22 @@ msdf_pixel_range=8 msdf_size=48 allow_system_fallback=true force_autohinter=false +modulate_color_glyphs=false hinting=1 subpixel_positioning=4 keep_rounding_remainders=true -oversampling=0.0 +oversampling=2.0 Fallbacks=null fallbacks=[] Compress=null compress=true -preload=[] +preload=[{ +"chars": [], +"glyphs": [], +"name": "Nouvelle configuration", +"size": Vector2i(16, 0), +&"variation_embolden": 0.0 +}] language_support={} script_support={} opentype_features={} diff --git a/ui/assets/fonts/GeneralSans-Light.otf.import b/ui/assets/fonts/GeneralSans-Light.otf.import index 8db9b3ba..010a3d69 100644 --- a/ui/assets/fonts/GeneralSans-Light.otf.import +++ b/ui/assets/fonts/GeneralSans-Light.otf.import @@ -21,15 +21,22 @@ msdf_pixel_range=8 msdf_size=48 allow_system_fallback=true force_autohinter=false +modulate_color_glyphs=false hinting=1 subpixel_positioning=4 keep_rounding_remainders=true -oversampling=0.0 +oversampling=2.0 Fallbacks=null fallbacks=[] Compress=null compress=true -preload=[] +preload=[{ +"chars": [], +"glyphs": [], +"name": "Nouvelle configuration", +"size": Vector2i(16, 0), +&"variation_embolden": 0.0 +}] language_support={} script_support={} opentype_features={} diff --git a/ui/assets/fonts/GeneralSans-LightItalic.otf.import b/ui/assets/fonts/GeneralSans-LightItalic.otf.import index a42f79d1..8e9c4a2b 100644 --- a/ui/assets/fonts/GeneralSans-LightItalic.otf.import +++ b/ui/assets/fonts/GeneralSans-LightItalic.otf.import @@ -21,15 +21,22 @@ msdf_pixel_range=8 msdf_size=48 allow_system_fallback=true force_autohinter=false +modulate_color_glyphs=false hinting=1 subpixel_positioning=4 keep_rounding_remainders=true -oversampling=0.0 +oversampling=2.0 Fallbacks=null fallbacks=[] Compress=null compress=true -preload=[] +preload=[{ +"chars": [], +"glyphs": [], +"name": "Nouvelle configuration", +"size": Vector2i(16, 0), +&"variation_embolden": 0.0 +}] language_support={} script_support={} opentype_features={} diff --git a/ui/assets/fonts/GeneralSans-Medium.otf.import b/ui/assets/fonts/GeneralSans-Medium.otf.import index aba933b4..43c89b3f 100644 --- a/ui/assets/fonts/GeneralSans-Medium.otf.import +++ b/ui/assets/fonts/GeneralSans-Medium.otf.import @@ -21,15 +21,22 @@ msdf_pixel_range=8 msdf_size=48 allow_system_fallback=true force_autohinter=false +modulate_color_glyphs=false hinting=1 subpixel_positioning=4 keep_rounding_remainders=true -oversampling=0.0 +oversampling=2.0 Fallbacks=null fallbacks=[] Compress=null compress=true -preload=[] +preload=[{ +"chars": [], +"glyphs": [], +"name": "Nouvelle configuration", +"size": Vector2i(16, 0), +&"variation_embolden": 0.0 +}] language_support={} script_support={} opentype_features={} diff --git a/ui/assets/fonts/GeneralSans-MediumItalic.otf.import b/ui/assets/fonts/GeneralSans-MediumItalic.otf.import index fa77a3b4..aa83228a 100644 --- a/ui/assets/fonts/GeneralSans-MediumItalic.otf.import +++ b/ui/assets/fonts/GeneralSans-MediumItalic.otf.import @@ -21,15 +21,22 @@ msdf_pixel_range=8 msdf_size=48 allow_system_fallback=true force_autohinter=false +modulate_color_glyphs=false hinting=1 subpixel_positioning=4 keep_rounding_remainders=true -oversampling=0.0 +oversampling=2.0 Fallbacks=null fallbacks=[] Compress=null compress=true -preload=[] +preload=[{ +"chars": [], +"glyphs": [], +"name": "Nouvelle configuration", +"size": Vector2i(16, 0), +&"variation_embolden": 0.0 +}] language_support={} script_support={} opentype_features={} diff --git a/ui/assets/fonts/GeneralSans-Regular.otf.import b/ui/assets/fonts/GeneralSans-Regular.otf.import index 37850d24..b45d5aaf 100644 --- a/ui/assets/fonts/GeneralSans-Regular.otf.import +++ b/ui/assets/fonts/GeneralSans-Regular.otf.import @@ -21,15 +21,22 @@ msdf_pixel_range=8 msdf_size=48 allow_system_fallback=true force_autohinter=false +modulate_color_glyphs=false hinting=1 subpixel_positioning=4 keep_rounding_remainders=true -oversampling=0.0 +oversampling=2.0 Fallbacks=null fallbacks=[] Compress=null compress=true -preload=[] +preload=[{ +"chars": [], +"glyphs": [], +"name": "Nouvelle configuration", +"size": Vector2i(16, 0), +&"variation_embolden": 0.0 +}] language_support={} script_support={} opentype_features={} diff --git a/ui/assets/fonts/GeneralSans-Semibold.otf.import b/ui/assets/fonts/GeneralSans-Semibold.otf.import index 7de9ed1e..00e48935 100644 --- a/ui/assets/fonts/GeneralSans-Semibold.otf.import +++ b/ui/assets/fonts/GeneralSans-Semibold.otf.import @@ -21,15 +21,22 @@ msdf_pixel_range=8 msdf_size=48 allow_system_fallback=true force_autohinter=false +modulate_color_glyphs=false hinting=1 subpixel_positioning=4 keep_rounding_remainders=true -oversampling=0.0 +oversampling=2.0 Fallbacks=null fallbacks=[] Compress=null compress=true -preload=[] +preload=[{ +"chars": [], +"glyphs": [], +"name": "Nouvelle configuration", +"size": Vector2i(16, 0), +&"variation_embolden": 0.0 +}] language_support={} script_support={} opentype_features={} diff --git a/ui/assets/fonts/GeneralSans-SemiboldItalic.otf.import b/ui/assets/fonts/GeneralSans-SemiboldItalic.otf.import index 94813f6d..6b775981 100644 --- a/ui/assets/fonts/GeneralSans-SemiboldItalic.otf.import +++ b/ui/assets/fonts/GeneralSans-SemiboldItalic.otf.import @@ -21,15 +21,22 @@ msdf_pixel_range=8 msdf_size=48 allow_system_fallback=true force_autohinter=false +modulate_color_glyphs=false hinting=1 subpixel_positioning=4 keep_rounding_remainders=true -oversampling=0.0 +oversampling=2.0 Fallbacks=null fallbacks=[] Compress=null compress=true -preload=[] +preload=[{ +"chars": [], +"glyphs": [], +"name": "Nouvelle configuration", +"size": Vector2i(16, 0), +&"variation_embolden": 0.0 +}] language_support={} script_support={} opentype_features={} diff --git a/ui/assets/fonts/Montserrat-Variable.ttf.import b/ui/assets/fonts/Montserrat-Variable.ttf.import index 7915eb2f..ee1aca6d 100644 --- a/ui/assets/fonts/Montserrat-Variable.ttf.import +++ b/ui/assets/fonts/Montserrat-Variable.ttf.import @@ -21,6 +21,7 @@ msdf_pixel_range=8 msdf_size=48 allow_system_fallback=true force_autohinter=false +modulate_color_glyphs=false hinting=1 subpixel_positioning=4 keep_rounding_remainders=true diff --git a/ui/assets/icons/action.svg.import b/ui/assets/icons/action.svg.import index 366afe8a..8b09c5fd 100644 --- a/ui/assets/icons/action.svg.import +++ b/ui/assets/icons/action.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://eihi1vti8evl" -path="res://.godot/imported/action.svg-89cea7d04591ce66b5d87f37eced72b1.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/action.svg-89cea7d04591ce66b5d87f37eced72b1.dpitex" [deps] source_file="res://ui/assets/icons/action.svg" -dest_files=["res://.godot/imported/action.svg-89cea7d04591ce66b5d87f37eced72b1.ctex"] +dest_files=["res://.godot/imported/action.svg-89cea7d04591ce66b5d87f37eced72b1.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/arrow_down.svg.import b/ui/assets/icons/arrow_down.svg.import index 21a0eea3..5e591439 100644 --- a/ui/assets/icons/arrow_down.svg.import +++ b/ui/assets/icons/arrow_down.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://cweh5vxhmobip" -path="res://.godot/imported/arrow_down.svg-ba844a722d541a14d34604aa5d60faed.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/arrow_down.svg-ba844a722d541a14d34604aa5d60faed.dpitex" [deps] source_file="res://ui/assets/icons/arrow_down.svg" -dest_files=["res://.godot/imported/arrow_down.svg-ba844a722d541a14d34604aa5d60faed.ctex"] +dest_files=["res://.godot/imported/arrow_down.svg-ba844a722d541a14d34604aa5d60faed.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/arrow_left.svg.import b/ui/assets/icons/arrow_left.svg.import index 7d63cc96..49a8608f 100644 --- a/ui/assets/icons/arrow_left.svg.import +++ b/ui/assets/icons/arrow_left.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://c0cmik715jqff" -path="res://.godot/imported/arrow_left.svg-9dffcbcd8b7c9383c91750e06cc250f7.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/arrow_left.svg-9dffcbcd8b7c9383c91750e06cc250f7.dpitex" [deps] source_file="res://ui/assets/icons/arrow_left.svg" -dest_files=["res://.godot/imported/arrow_left.svg-9dffcbcd8b7c9383c91750e06cc250f7.ctex"] +dest_files=["res://.godot/imported/arrow_left.svg-9dffcbcd8b7c9383c91750e06cc250f7.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/arrow_right.svg.import b/ui/assets/icons/arrow_right.svg.import index 34d4d3a8..93acb82b 100644 --- a/ui/assets/icons/arrow_right.svg.import +++ b/ui/assets/icons/arrow_right.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://cb6n6enqfvclw" -path="res://.godot/imported/arrow_right.svg-d5d5883fac403e011270c3f14d3a830d.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/arrow_right.svg-d5d5883fac403e011270c3f14d3a830d.dpitex" [deps] source_file="res://ui/assets/icons/arrow_right.svg" -dest_files=["res://.godot/imported/arrow_right.svg-d5d5883fac403e011270c3f14d3a830d.ctex"] +dest_files=["res://.godot/imported/arrow_right.svg-d5d5883fac403e011270c3f14d3a830d.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/arrow_up.svg.import b/ui/assets/icons/arrow_up.svg.import index dce78ce0..b8058dd3 100644 --- a/ui/assets/icons/arrow_up.svg.import +++ b/ui/assets/icons/arrow_up.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://du0bedfddmsrg" -path="res://.godot/imported/arrow_up.svg-8c4ac4bf74e35a00d25b71c740cadc39.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/arrow_up.svg-8c4ac4bf74e35a00d25b71c740cadc39.dpitex" [deps] source_file="res://ui/assets/icons/arrow_up.svg" -dest_files=["res://.godot/imported/arrow_up.svg-8c4ac4bf74e35a00d25b71c740cadc39.ctex"] +dest_files=["res://.godot/imported/arrow_up.svg-8c4ac4bf74e35a00d25b71c740cadc39.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/bool_icon.png.import b/ui/assets/icons/bool_icon.png.import index 46f9eda8..4c9bd180 100644 --- a/ui/assets/icons/bool_icon.png.import +++ b/ui/assets/icons/bool_icon.png.import @@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/bool_icon.png-0bc2af2cd4f36c82452dbe7b6c39e89 compress/mode=0 compress/high_quality=false compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 compress/hdr_compression=1 compress/normal_map=0 compress/channel_pack=0 @@ -25,6 +27,10 @@ mipmaps/generate=false mipmaps/limit=-1 roughness/mode=0 roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 process/fix_alpha_border=true process/premult_alpha=false process/normal_map_invert_y=false diff --git a/ui/assets/icons/calendar.svg.import b/ui/assets/icons/calendar.svg.import index 7fcd9f79..6c1d2e79 100644 --- a/ui/assets/icons/calendar.svg.import +++ b/ui/assets/icons/calendar.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://bjt74refsmu3w" -path="res://.godot/imported/calendar.svg-4a7185fbaf173d39221d95b4ab58b11b.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/calendar.svg-4a7185fbaf173d39221d95b4ab58b11b.dpitex" [deps] source_file="res://ui/assets/icons/calendar.svg" -dest_files=["res://.godot/imported/calendar.svg-4a7185fbaf173d39221d95b4ab58b11b.ctex"] +dest_files=["res://.godot/imported/calendar.svg-4a7185fbaf173d39221d95b4ab58b11b.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/cell_empty.svg.import b/ui/assets/icons/cell_empty.svg.import index 4c7f7339..72578de7 100644 --- a/ui/assets/icons/cell_empty.svg.import +++ b/ui/assets/icons/cell_empty.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://nnm7d2srfc40" -path="res://.godot/imported/cell_empty.svg-3a31b0fb8349cf6d35aadccfc5d890c7.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/cell_empty.svg-3a31b0fb8349cf6d35aadccfc5d890c7.dpitex" [deps] source_file="res://ui/assets/icons/cell_empty.svg" -dest_files=["res://.godot/imported/cell_empty.svg-3a31b0fb8349cf6d35aadccfc5d890c7.ctex"] +dest_files=["res://.godot/imported/cell_empty.svg-3a31b0fb8349cf6d35aadccfc5d890c7.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/cell_left.svg.import b/ui/assets/icons/cell_left.svg.import index f32f0386..2549aa26 100644 --- a/ui/assets/icons/cell_left.svg.import +++ b/ui/assets/icons/cell_left.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://c4nngbw70jdd0" -path="res://.godot/imported/cell_left.svg-a17cbd49cb4662b081893f117bad8b6b.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/cell_left.svg-a17cbd49cb4662b081893f117bad8b6b.dpitex" [deps] source_file="res://ui/assets/icons/cell_left.svg" -dest_files=["res://.godot/imported/cell_left.svg-a17cbd49cb4662b081893f117bad8b6b.ctex"] +dest_files=["res://.godot/imported/cell_left.svg-a17cbd49cb4662b081893f117bad8b6b.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/cell_middle.svg.import b/ui/assets/icons/cell_middle.svg.import index 63bbb18f..9c1b5d1d 100644 --- a/ui/assets/icons/cell_middle.svg.import +++ b/ui/assets/icons/cell_middle.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://e7nc5xoqpgmi" -path="res://.godot/imported/cell_middle.svg-979cd41102c064a6a9901bde47ea0298.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/cell_middle.svg-979cd41102c064a6a9901bde47ea0298.dpitex" [deps] source_file="res://ui/assets/icons/cell_middle.svg" -dest_files=["res://.godot/imported/cell_middle.svg-979cd41102c064a6a9901bde47ea0298.ctex"] +dest_files=["res://.godot/imported/cell_middle.svg-979cd41102c064a6a9901bde47ea0298.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/cell_right.svg.import b/ui/assets/icons/cell_right.svg.import index 8e13952c..0605bf97 100644 --- a/ui/assets/icons/cell_right.svg.import +++ b/ui/assets/icons/cell_right.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://bcow4e2eus2ik" -path="res://.godot/imported/cell_right.svg-98c96745d13a175ce2c488d00ad91fb0.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/cell_right.svg-98c96745d13a175ce2c488d00ad91fb0.dpitex" [deps] source_file="res://ui/assets/icons/cell_right.svg" -dest_files=["res://.godot/imported/cell_right.svg-98c96745d13a175ce2c488d00ad91fb0.ctex"] +dest_files=["res://.godot/imported/cell_right.svg-98c96745d13a175ce2c488d00ad91fb0.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/cell_single.svg.import b/ui/assets/icons/cell_single.svg.import index 8af2441e..9d25d76b 100644 --- a/ui/assets/icons/cell_single.svg.import +++ b/ui/assets/icons/cell_single.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://bjra4bs2l0m6x" -path="res://.godot/imported/cell_single.svg-0c58d2764fe2b5f4012fcc9b54fc46d1.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/cell_single.svg-0c58d2764fe2b5f4012fcc9b54fc46d1.dpitex" [deps] source_file="res://ui/assets/icons/cell_single.svg" -dest_files=["res://.godot/imported/cell_single.svg-0c58d2764fe2b5f4012fcc9b54fc46d1.ctex"] +dest_files=["res://.godot/imported/cell_single.svg-0c58d2764fe2b5f4012fcc9b54fc46d1.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/character.svg.import b/ui/assets/icons/character.svg.import index 3ef8ec84..f67d3230 100644 --- a/ui/assets/icons/character.svg.import +++ b/ui/assets/icons/character.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://bfmsxfn26cvfn" -path="res://.godot/imported/character.svg-9eaafa5794c4e9dcd6a6e2176ac897bc.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/character.svg-9eaafa5794c4e9dcd6a6e2176ac897bc.dpitex" [deps] source_file="res://ui/assets/icons/character.svg" -dest_files=["res://.godot/imported/character.svg-9eaafa5794c4e9dcd6a6e2176ac897bc.ctex"] +dest_files=["res://.godot/imported/character.svg-9eaafa5794c4e9dcd6a6e2176ac897bc.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/check.svg.import b/ui/assets/icons/check.svg.import index d401f7a7..198dbd8a 100644 --- a/ui/assets/icons/check.svg.import +++ b/ui/assets/icons/check.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://rrcqi68frkrm" -path="res://.godot/imported/check.svg-aed49858c602f08277040dc13320eb4c.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/check.svg-aed49858c602f08277040dc13320eb4c.dpitex" [deps] source_file="res://ui/assets/icons/check.svg" -dest_files=["res://.godot/imported/check.svg-aed49858c602f08277040dc13320eb4c.ctex"] +dest_files=["res://.godot/imported/check.svg-aed49858c602f08277040dc13320eb4c.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/choice.svg.import b/ui/assets/icons/choice.svg.import index 0e8cb413..ec981dff 100644 --- a/ui/assets/icons/choice.svg.import +++ b/ui/assets/icons/choice.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://cx0jcmldcyn1n" -path="res://.godot/imported/choice.svg-affa86a6b966b61fb0ef343a93bbeb1b.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/choice.svg-affa86a6b966b61fb0ef343a93bbeb1b.dpitex" [deps] source_file="res://ui/assets/icons/choice.svg" -dest_files=["res://.godot/imported/choice.svg-affa86a6b966b61fb0ef343a93bbeb1b.ctex"] +dest_files=["res://.godot/imported/choice.svg-affa86a6b966b61fb0ef343a93bbeb1b.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/close_icon.png.import b/ui/assets/icons/close_icon.png.import index c2a8dd36..0d518ee4 100644 --- a/ui/assets/icons/close_icon.png.import +++ b/ui/assets/icons/close_icon.png.import @@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/close_icon.png-63e207f5d16862e2844785b444e12a compress/mode=0 compress/high_quality=false compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 compress/hdr_compression=1 compress/normal_map=0 compress/channel_pack=0 @@ -25,6 +27,10 @@ mipmaps/generate=false mipmaps/limit=-1 roughness/mode=0 roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 process/fix_alpha_border=true process/premult_alpha=false process/normal_map_invert_y=false diff --git a/ui/assets/icons/close_icon_black.png.import b/ui/assets/icons/close_icon_black.png.import index 96372ff7..a9a79926 100644 --- a/ui/assets/icons/close_icon_black.png.import +++ b/ui/assets/icons/close_icon_black.png.import @@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/close_icon_black.png-2d4e6bbb111eb762f36fc575 compress/mode=0 compress/high_quality=false compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 compress/hdr_compression=1 compress/normal_map=0 compress/channel_pack=0 @@ -25,6 +27,10 @@ mipmaps/generate=false mipmaps/limit=-1 roughness/mode=0 roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 process/fix_alpha_border=true process/premult_alpha=false process/normal_map_invert_y=false diff --git a/ui/assets/icons/comment.svg.import b/ui/assets/icons/comment.svg.import index e255d599..c6fa5eb4 100644 --- a/ui/assets/icons/comment.svg.import +++ b/ui/assets/icons/comment.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://dupbtpe7jq82k" -path="res://.godot/imported/comment.svg-5e3bbeaaef2d610777ecffd93b566df6.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/comment.svg-5e3bbeaaef2d610777ecffd93b566df6.dpitex" [deps] source_file="res://ui/assets/icons/comment.svg" -dest_files=["res://.godot/imported/comment.svg-5e3bbeaaef2d610777ecffd93b566df6.ctex"] +dest_files=["res://.godot/imported/comment.svg-5e3bbeaaef2d610777ecffd93b566df6.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/condition.svg.import b/ui/assets/icons/condition.svg.import index 7575f16b..8cec19b1 100644 --- a/ui/assets/icons/condition.svg.import +++ b/ui/assets/icons/condition.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://iqm5av5qduiw" -path="res://.godot/imported/condition.svg-e465084597d0556fe9eb0b96268215eb.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/condition.svg-e465084597d0556fe9eb0b96268215eb.dpitex" [deps] source_file="res://ui/assets/icons/condition.svg" -dest_files=["res://.godot/imported/condition.svg-e465084597d0556fe9eb0b96268215eb.ctex"] +dest_files=["res://.godot/imported/condition.svg-e465084597d0556fe9eb0b96268215eb.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/config_icon.png.import b/ui/assets/icons/config_icon.png.import index 27f78dc4..1df49094 100644 --- a/ui/assets/icons/config_icon.png.import +++ b/ui/assets/icons/config_icon.png.import @@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/config_icon.png-ea533e1ab946d067ed90bb64ca50a compress/mode=0 compress/high_quality=false compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 compress/hdr_compression=1 compress/normal_map=0 compress/channel_pack=0 @@ -25,6 +27,10 @@ mipmaps/generate=false mipmaps/limit=-1 roughness/mode=0 roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 process/fix_alpha_border=true process/premult_alpha=false process/normal_map_invert_y=false diff --git a/ui/assets/icons/copy.png.import b/ui/assets/icons/copy.png.import index dcbade5a..aeeec590 100644 --- a/ui/assets/icons/copy.png.import +++ b/ui/assets/icons/copy.png.import @@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/copy.png-581491c44d4bbc2a345e45100bab1871.cte compress/mode=0 compress/high_quality=false compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 compress/hdr_compression=1 compress/normal_map=0 compress/channel_pack=0 @@ -25,6 +27,10 @@ mipmaps/generate=false mipmaps/limit=-1 roughness/mode=0 roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 process/fix_alpha_border=true process/premult_alpha=false process/normal_map_invert_y=false diff --git a/ui/assets/icons/cross.svg.import b/ui/assets/icons/cross.svg.import index 3ed6436f..12e8d5e5 100644 --- a/ui/assets/icons/cross.svg.import +++ b/ui/assets/icons/cross.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://b0umav8s8l2qa" -path="res://.godot/imported/cross.svg-b21953d55678fcb60f5e327c0ce12c2c.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/cross.svg-b21953d55678fcb60f5e327c0ce12c2c.dpitex" [deps] source_file="res://ui/assets/icons/cross.svg" -dest_files=["res://.godot/imported/cross.svg-b21953d55678fcb60f5e327c0ce12c2c.ctex"] +dest_files=["res://.godot/imported/cross.svg-b21953d55678fcb60f5e327c0ce12c2c.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/dice.svg.import b/ui/assets/icons/dice.svg.import index 592ce0ab..445377d8 100644 --- a/ui/assets/icons/dice.svg.import +++ b/ui/assets/icons/dice.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://dbi7c572d4f8y" -path="res://.godot/imported/dice.svg-3fcf558d02707b2ab7683e8b71f673ad.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/dice.svg-3fcf558d02707b2ab7683e8b71f673ad.dpitex" [deps] source_file="res://ui/assets/icons/dice.svg" -dest_files=["res://.godot/imported/dice.svg-3fcf558d02707b2ab7683e8b71f673ad.ctex"] +dest_files=["res://.godot/imported/dice.svg-3fcf558d02707b2ab7683e8b71f673ad.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/dot_icon.png.import b/ui/assets/icons/dot_icon.png.import index da709840..d5349242 100644 --- a/ui/assets/icons/dot_icon.png.import +++ b/ui/assets/icons/dot_icon.png.import @@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/dot_icon.png-52c3b31fad0194c0c36339bdd3bde68c compress/mode=0 compress/high_quality=false compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 compress/hdr_compression=1 compress/normal_map=0 compress/channel_pack=0 @@ -25,6 +27,10 @@ mipmaps/generate=false mipmaps/limit=-1 roughness/mode=0 roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 process/fix_alpha_border=true process/premult_alpha=false process/normal_map_invert_y=false diff --git a/ui/assets/icons/dots_grid.svg.import b/ui/assets/icons/dots_grid.svg.import index 4935848f..72272232 100644 --- a/ui/assets/icons/dots_grid.svg.import +++ b/ui/assets/icons/dots_grid.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://bv81uyypsna2u" -path="res://.godot/imported/dots_grid.svg-5b2af8497b8455d866dc46f705a3a432.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/dots_grid.svg-5b2af8497b8455d866dc46f705a3a432.dpitex" [deps] source_file="res://ui/assets/icons/dots_grid.svg" -dest_files=["res://.godot/imported/dots_grid.svg-5b2af8497b8455d866dc46f705a3a432.ctex"] +dest_files=["res://.godot/imported/dots_grid.svg-5b2af8497b8455d866dc46f705a3a432.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/exit.png.import b/ui/assets/icons/exit.png.import index 26b5d016..2c9b5cb6 100644 --- a/ui/assets/icons/exit.png.import +++ b/ui/assets/icons/exit.png.import @@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/exit.png-89bb20104225ee47e1c62bcf63e94c1a.cte compress/mode=0 compress/high_quality=false compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 compress/hdr_compression=1 compress/normal_map=0 compress/channel_pack=0 @@ -25,6 +27,10 @@ mipmaps/generate=false mipmaps/limit=-1 roughness/mode=0 roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 process/fix_alpha_border=true process/premult_alpha=false process/normal_map_invert_y=false diff --git a/ui/assets/icons/exit.svg.import b/ui/assets/icons/exit.svg.import index 703dc4c2..f3b78464 100644 --- a/ui/assets/icons/exit.svg.import +++ b/ui/assets/icons/exit.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://b8r5v6gy8jyyn" -path="res://.godot/imported/exit.svg-c9f57222511a31936a0e1bf2afef851e.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/exit.svg-c9f57222511a31936a0e1bf2afef851e.dpitex" [deps] source_file="res://ui/assets/icons/exit.svg" -dest_files=["res://.godot/imported/exit.svg-c9f57222511a31936a0e1bf2afef851e.ctex"] +dest_files=["res://.godot/imported/exit.svg-c9f57222511a31936a0e1bf2afef851e.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/expand.svg.import b/ui/assets/icons/expand.svg.import index 61d9e5df..5ce09a42 100644 --- a/ui/assets/icons/expand.svg.import +++ b/ui/assets/icons/expand.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://bu603ytypk2jb" -path="res://.godot/imported/expand.svg-62a0a6cb2ee0399977756028db93b4c0.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/expand.svg-62a0a6cb2ee0399977756028db93b4c0.dpitex" [deps] source_file="res://ui/assets/icons/expand.svg" -dest_files=["res://.godot/imported/expand.svg-62a0a6cb2ee0399977756028db93b4c0.ctex"] +dest_files=["res://.godot/imported/expand.svg-62a0a6cb2ee0399977756028db93b4c0.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/exposed.svg b/ui/assets/icons/exposed.svg new file mode 100644 index 00000000..0c87ff88 --- /dev/null +++ b/ui/assets/icons/exposed.svg @@ -0,0 +1,4 @@ + + + + diff --git a/ui/assets/icons/exposed.svg.import b/ui/assets/icons/exposed.svg.import new file mode 100644 index 00000000..9757f5f9 --- /dev/null +++ b/ui/assets/icons/exposed.svg.import @@ -0,0 +1,18 @@ +[remap] + +importer="svg" +type="DPITexture" +uid="uid://d4fp2shj4o5sk" +path="res://.godot/imported/exposed.svg-d424bd564c350cae69407722de283e3e.dpitex" + +[deps] + +source_file="res://ui/assets/icons/exposed.svg" +dest_files=["res://.godot/imported/exposed.svg-d424bd564c350cae69407722de283e3e.dpitex"] + +[params] + +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/eye.svg.import b/ui/assets/icons/eye.svg.import index c2bacc97..be223b38 100644 --- a/ui/assets/icons/eye.svg.import +++ b/ui/assets/icons/eye.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://dh2il37b3nhyo" -path="res://.godot/imported/eye.svg-5a82bbf625997d04d893b49e9429d918.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/eye.svg-5a82bbf625997d04d893b49e9429d918.dpitex" [deps] source_file="res://ui/assets/icons/eye.svg" -dest_files=["res://.godot/imported/eye.svg-5a82bbf625997d04d893b49e9429d918.ctex"] +dest_files=["res://.godot/imported/eye.svg-5a82bbf625997d04d893b49e9429d918.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/eye_closed.svg.import b/ui/assets/icons/eye_closed.svg.import index e979e831..5ed7ccf1 100644 --- a/ui/assets/icons/eye_closed.svg.import +++ b/ui/assets/icons/eye_closed.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://bjbs0odxsndlq" -path="res://.godot/imported/eye_closed.svg-1d4509f467a37dac8e22fc42086b82fc.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/eye_closed.svg-1d4509f467a37dac8e22fc42086b82fc.dpitex" [deps] source_file="res://ui/assets/icons/eye_closed.svg" -dest_files=["res://.godot/imported/eye_closed.svg-1d4509f467a37dac8e22fc42086b82fc.ctex"] +dest_files=["res://.godot/imported/eye_closed.svg-1d4509f467a37dac8e22fc42086b82fc.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/file.svg.import b/ui/assets/icons/file.svg.import index 23741512..4b6f5c39 100644 --- a/ui/assets/icons/file.svg.import +++ b/ui/assets/icons/file.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://c77fmeslcdgo7" -path="res://.godot/imported/file.svg-dd7077f29278cdb1656a9b1ebb36e6bd.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/file.svg-dd7077f29278cdb1656a9b1ebb36e6bd.dpitex" [deps] source_file="res://ui/assets/icons/file.svg" -dest_files=["res://.godot/imported/file.svg-dd7077f29278cdb1656a9b1ebb36e6bd.ctex"] +dest_files=["res://.godot/imported/file.svg-dd7077f29278cdb1656a9b1ebb36e6bd.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/file_character.svg.import b/ui/assets/icons/file_character.svg.import index 6f672434..480c4e44 100644 --- a/ui/assets/icons/file_character.svg.import +++ b/ui/assets/icons/file_character.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://tnslcne4ae6q" -path="res://.godot/imported/file_character.svg-927860812a469cabc966bd5edd0f8b95.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/file_character.svg-927860812a469cabc966bd5edd0f8b95.dpitex" [deps] source_file="res://ui/assets/icons/file_character.svg" -dest_files=["res://.godot/imported/file_character.svg-927860812a469cabc966bd5edd0f8b95.ctex"] +dest_files=["res://.godot/imported/file_character.svg-927860812a469cabc966bd5edd0f8b95.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/file_plus.svg.import b/ui/assets/icons/file_plus.svg.import index 175447c1..6c400db5 100644 --- a/ui/assets/icons/file_plus.svg.import +++ b/ui/assets/icons/file_plus.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://faci8gjgsxub" -path="res://.godot/imported/file_plus.svg-e9ac3957ca4145979ac72d07cde5f05a.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/file_plus.svg-e9ac3957ca4145979ac72d07cde5f05a.dpitex" [deps] source_file="res://ui/assets/icons/file_plus.svg" -dest_files=["res://.godot/imported/file_plus.svg-e9ac3957ca4145979ac72d07cde5f05a.ctex"] +dest_files=["res://.godot/imported/file_plus.svg-e9ac3957ca4145979ac72d07cde5f05a.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/filter_funnel.svg.import b/ui/assets/icons/filter_funnel.svg.import index 09f03a6e..6be67c57 100644 --- a/ui/assets/icons/filter_funnel.svg.import +++ b/ui/assets/icons/filter_funnel.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://c6xst2uouq7d2" -path="res://.godot/imported/filter_funnel.svg-7a9398c7c058c3d3c6c389b09e9652ce.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/filter_funnel.svg-7a9398c7c058c3d3c6c389b09e9652ce.dpitex" [deps] source_file="res://ui/assets/icons/filter_funnel.svg" -dest_files=["res://.godot/imported/filter_funnel.svg-7a9398c7c058c3d3c6c389b09e9652ce.ctex"] +dest_files=["res://.godot/imported/filter_funnel.svg-7a9398c7c058c3d3c6c389b09e9652ce.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/folder.svg.import b/ui/assets/icons/folder.svg.import index ea53cb16..47c7313a 100644 --- a/ui/assets/icons/folder.svg.import +++ b/ui/assets/icons/folder.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://87majwdgoajd" -path="res://.godot/imported/folder.svg-18ec41b2c3c3a12bc6a3e991fda7eb40.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/folder.svg-18ec41b2c3c3a12bc6a3e991fda7eb40.dpitex" [deps] source_file="res://ui/assets/icons/folder.svg" -dest_files=["res://.godot/imported/folder.svg-18ec41b2c3c3a12bc6a3e991fda7eb40.ctex"] +dest_files=["res://.godot/imported/folder.svg-18ec41b2c3c3a12bc6a3e991fda7eb40.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/folder_download.svg.import b/ui/assets/icons/folder_download.svg.import index bc38bfae..b1ab8dad 100644 --- a/ui/assets/icons/folder_download.svg.import +++ b/ui/assets/icons/folder_download.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://dmx3uqn8v7q4e" -path="res://.godot/imported/folder_download.svg-9cf05bfddbd173374b7055956c4e8343.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/folder_download.svg-9cf05bfddbd173374b7055956c4e8343.dpitex" [deps] source_file="res://ui/assets/icons/folder_download.svg" -dest_files=["res://.godot/imported/folder_download.svg-9cf05bfddbd173374b7055956c4e8343.ctex"] +dest_files=["res://.godot/imported/folder_download.svg-9cf05bfddbd173374b7055956c4e8343.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/folder_icon.png.import b/ui/assets/icons/folder_icon.png.import index 5f750299..aedfc776 100644 --- a/ui/assets/icons/folder_icon.png.import +++ b/ui/assets/icons/folder_icon.png.import @@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/folder_icon.png-07715a9796114aae484d3567d0abe compress/mode=0 compress/high_quality=false compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 compress/hdr_compression=1 compress/normal_map=0 compress/channel_pack=0 @@ -25,6 +27,10 @@ mipmaps/generate=false mipmaps/limit=-1 roughness/mode=0 roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 process/fix_alpha_border=true process/premult_alpha=false process/normal_map_invert_y=false diff --git a/ui/assets/icons/folder_search.svg.import b/ui/assets/icons/folder_search.svg.import index c6ab36a9..d9c3e24e 100644 --- a/ui/assets/icons/folder_search.svg.import +++ b/ui/assets/icons/folder_search.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://bbw07aw88fo0p" -path="res://.godot/imported/folder_search.svg-4362508f18fefe7404e910c84c8304e2.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/folder_search.svg-4362508f18fefe7404e910c84c8304e2.dpitex" [deps] source_file="res://ui/assets/icons/folder_search.svg" -dest_files=["res://.godot/imported/folder_search.svg-4362508f18fefe7404e910c84c8304e2.ctex"] +dest_files=["res://.godot/imported/folder_search.svg-4362508f18fefe7404e910c84c8304e2.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/grid.svg.import b/ui/assets/icons/grid.svg.import index 5c8fffcf..a9e6c5b5 100644 --- a/ui/assets/icons/grid.svg.import +++ b/ui/assets/icons/grid.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://cvel6ifgyclof" -path="res://.godot/imported/grid.svg-6a34e8c39e1213823a63f4b397a10223.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/grid.svg-6a34e8c39e1213823a63f4b397a10223.dpitex" [deps] source_file="res://ui/assets/icons/grid.svg" -dest_files=["res://.godot/imported/grid.svg-6a34e8c39e1213823a63f4b397a10223.ctex"] +dest_files=["res://.godot/imported/grid.svg-6a34e8c39e1213823a63f4b397a10223.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/help_icon.png.import b/ui/assets/icons/help_icon.png.import index 74bf7410..b6711cc8 100644 --- a/ui/assets/icons/help_icon.png.import +++ b/ui/assets/icons/help_icon.png.import @@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/help_icon.png-9b4e9b76a02c80aaa31a337cd102241 compress/mode=0 compress/high_quality=false compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 compress/hdr_compression=1 compress/normal_map=0 compress/channel_pack=0 @@ -25,6 +27,10 @@ mipmaps/generate=false mipmaps/limit=-1 roughness/mode=0 roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 process/fix_alpha_border=true process/premult_alpha=false process/normal_map_invert_y=false diff --git a/ui/assets/icons/image_down.svg.import b/ui/assets/icons/image_down.svg.import index 17f4d982..ece1db4d 100644 --- a/ui/assets/icons/image_down.svg.import +++ b/ui/assets/icons/image_down.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://bey5byxlx7jji" -path="res://.godot/imported/image_down.svg-acc4a344e8c65c7feb6c94aaef10f508.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/image_down.svg-acc4a344e8c65c7feb6c94aaef10f508.dpitex" [deps] source_file="res://ui/assets/icons/image_down.svg" -dest_files=["res://.godot/imported/image_down.svg-acc4a344e8c65c7feb6c94aaef10f508.ctex"] +dest_files=["res://.godot/imported/image_down.svg-acc4a344e8c65c7feb6c94aaef10f508.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/improt_cell.svg.import b/ui/assets/icons/improt_cell.svg.import index 20253c8d..21cd635b 100644 --- a/ui/assets/icons/improt_cell.svg.import +++ b/ui/assets/icons/improt_cell.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://c07ekrem76mk3" -path="res://.godot/imported/improt_cell.svg-69131e44375e64e7e1b2fda89997b214.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/improt_cell.svg-69131e44375e64e7e1b2fda89997b214.dpitex" [deps] source_file="res://ui/assets/icons/improt_cell.svg" -dest_files=["res://.godot/imported/improt_cell.svg-69131e44375e64e7e1b2fda89997b214.ctex"] +dest_files=["res://.godot/imported/improt_cell.svg-69131e44375e64e7e1b2fda89997b214.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=2.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/int_icon.png.import b/ui/assets/icons/int_icon.png.import index 25826a26..ed16037f 100644 --- a/ui/assets/icons/int_icon.png.import +++ b/ui/assets/icons/int_icon.png.import @@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/int_icon.png-ed7c36cd8a0633daff3e0cf227bd235d compress/mode=0 compress/high_quality=false compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 compress/hdr_compression=1 compress/normal_map=0 compress/channel_pack=0 @@ -25,6 +27,10 @@ mipmaps/generate=false mipmaps/limit=-1 roughness/mode=0 roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 process/fix_alpha_border=true process/premult_alpha=false process/normal_map_invert_y=false diff --git a/ui/assets/icons/layout_right.svg.import b/ui/assets/icons/layout_right.svg.import index d43c0029..6634706b 100644 --- a/ui/assets/icons/layout_right.svg.import +++ b/ui/assets/icons/layout_right.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://cfpgu1noth4uf" -path="res://.godot/imported/layout_right.svg-31c3b25a7924e01b1337c6ab228028e5.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/layout_right.svg-31c3b25a7924e01b1337c6ab228028e5.dpitex" [deps] source_file="res://ui/assets/icons/layout_right.svg" -dest_files=["res://.godot/imported/layout_right.svg-31c3b25a7924e01b1337c6ab228028e5.ctex"] +dest_files=["res://.godot/imported/layout_right.svg-31c3b25a7924e01b1337c6ab228028e5.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/link.svg.import b/ui/assets/icons/link.svg.import index c255a162..172e2a75 100644 --- a/ui/assets/icons/link.svg.import +++ b/ui/assets/icons/link.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://q4df0swsn207" -path="res://.godot/imported/link.svg-da884fb1938f339f47467a3fa13a6c67.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/link.svg-da884fb1938f339f47467a3fa13a6c67.dpitex" [deps] source_file="res://ui/assets/icons/link.svg" -dest_files=["res://.godot/imported/link.svg-da884fb1938f339f47467a3fa13a6c67.ctex"] +dest_files=["res://.godot/imported/link.svg-da884fb1938f339f47467a3fa13a6c67.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/logo_white.svg.import b/ui/assets/icons/logo_white.svg.import index 5f615f9d..85af35f2 100644 --- a/ui/assets/icons/logo_white.svg.import +++ b/ui/assets/icons/logo_white.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://dd8v3hpxxk33d" -path="res://.godot/imported/logo_white.svg-9b22651952339bccf9269a0af7ea05cc.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/logo_white.svg-9b22651952339bccf9269a0af7ea05cc.dpitex" [deps] source_file="res://ui/assets/icons/logo_white.svg" -dest_files=["res://.godot/imported/logo_white.svg-9b22651952339bccf9269a0af7ea05cc.ctex"] +dest_files=["res://.godot/imported/logo_white.svg-9b22651952339bccf9269a0af7ea05cc.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/media_loop.svg.import b/ui/assets/icons/media_loop.svg.import index 05510620..923feb73 100644 --- a/ui/assets/icons/media_loop.svg.import +++ b/ui/assets/icons/media_loop.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://b5pe3oxlthl2i" -path="res://.godot/imported/media_loop.svg-bfcb30a7b7efe13bb9befc850fea02ad.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/media_loop.svg-bfcb30a7b7efe13bb9befc850fea02ad.dpitex" [deps] source_file="res://ui/assets/icons/media_loop.svg" -dest_files=["res://.godot/imported/media_loop.svg-bfcb30a7b7efe13bb9befc850fea02ad.ctex"] +dest_files=["res://.godot/imported/media_loop.svg-bfcb30a7b7efe13bb9befc850fea02ad.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/media_play.svg.import b/ui/assets/icons/media_play.svg.import index ad200ffd..ab0f467d 100644 --- a/ui/assets/icons/media_play.svg.import +++ b/ui/assets/icons/media_play.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://bficqn5yhfmah" -path="res://.godot/imported/media_play.svg-5cf4a5c1d08beef6e9ebbc5baefb537a.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/media_play.svg-5cf4a5c1d08beef6e9ebbc5baefb537a.dpitex" [deps] source_file="res://ui/assets/icons/media_play.svg" -dest_files=["res://.godot/imported/media_play.svg-5cf4a5c1d08beef6e9ebbc5baefb537a.ctex"] +dest_files=["res://.godot/imported/media_play.svg-5cf4a5c1d08beef6e9ebbc5baefb537a.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/media_play_backward.svg.import b/ui/assets/icons/media_play_backward.svg.import index e8d39a96..1418768c 100644 --- a/ui/assets/icons/media_play_backward.svg.import +++ b/ui/assets/icons/media_play_backward.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://08g8utdd2kai" -path="res://.godot/imported/media_play_backward.svg-6bfdbfa5122824cfde055f679f4a4078.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/media_play_backward.svg-6bfdbfa5122824cfde055f679f4a4078.dpitex" [deps] source_file="res://ui/assets/icons/media_play_backward.svg" -dest_files=["res://.godot/imported/media_play_backward.svg-6bfdbfa5122824cfde055f679f4a4078.ctex"] +dest_files=["res://.godot/imported/media_play_backward.svg-6bfdbfa5122824cfde055f679f4a4078.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/media_skip_backward.svg.import b/ui/assets/icons/media_skip_backward.svg.import index 9646ce33..371c039a 100644 --- a/ui/assets/icons/media_skip_backward.svg.import +++ b/ui/assets/icons/media_skip_backward.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://bowdhs0emx5i2" -path="res://.godot/imported/media_skip_backward.svg-99b74c1f4f45bf5e508ef1508a91cedb.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/media_skip_backward.svg-99b74c1f4f45bf5e508ef1508a91cedb.dpitex" [deps] source_file="res://ui/assets/icons/media_skip_backward.svg" -dest_files=["res://.godot/imported/media_skip_backward.svg-99b74c1f4f45bf5e508ef1508a91cedb.ctex"] +dest_files=["res://.godot/imported/media_skip_backward.svg-99b74c1f4f45bf5e508ef1508a91cedb.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/media_skip_forward.svg.import b/ui/assets/icons/media_skip_forward.svg.import index 9d78cf43..4770a7da 100644 --- a/ui/assets/icons/media_skip_forward.svg.import +++ b/ui/assets/icons/media_skip_forward.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://8cxo7ofybuix" -path="res://.godot/imported/media_skip_forward.svg-8acd7a6efa3466e2a74163538b55041d.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/media_skip_forward.svg-8acd7a6efa3466e2a74163538b55041d.dpitex" [deps] source_file="res://ui/assets/icons/media_skip_forward.svg" -dest_files=["res://.godot/imported/media_skip_forward.svg-8acd7a6efa3466e2a74163538b55041d.ctex"] +dest_files=["res://.godot/imported/media_skip_forward.svg-8acd7a6efa3466e2a74163538b55041d.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/media_stop.svg.import b/ui/assets/icons/media_stop.svg.import index b370ed48..eb44e99e 100644 --- a/ui/assets/icons/media_stop.svg.import +++ b/ui/assets/icons/media_stop.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://ctm64x2sdw2y2" -path="res://.godot/imported/media_stop.svg-a1a80d37ff29a5f89fd182a2ee5be62c.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/media_stop.svg-a1a80d37ff29a5f89fd182a2ee5be62c.dpitex" [deps] source_file="res://ui/assets/icons/media_stop.svg" -dest_files=["res://.godot/imported/media_stop.svg-a1a80d37ff29a5f89fd182a2ee5be62c.ctex"] +dest_files=["res://.godot/imported/media_stop.svg-a1a80d37ff29a5f89fd182a2ee5be62c.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/minus_min.svg.import b/ui/assets/icons/minus_min.svg.import index 3b67b8d8..74aee1e0 100644 --- a/ui/assets/icons/minus_min.svg.import +++ b/ui/assets/icons/minus_min.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://2avo8aox8ls2" -path="res://.godot/imported/minus_min.svg-5ae019e38e0730ebccb59b2b00c6ed61.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/minus_min.svg-5ae019e38e0730ebccb59b2b00c6ed61.dpitex" [deps] source_file="res://ui/assets/icons/minus_min.svg" -dest_files=["res://.godot/imported/minus_min.svg-5ae019e38e0730ebccb59b2b00c6ed61.ctex"] +dest_files=["res://.godot/imported/minus_min.svg-5ae019e38e0730ebccb59b2b00c6ed61.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/move.svg.import b/ui/assets/icons/move.svg.import index 095f9b5b..d0129c1a 100644 --- a/ui/assets/icons/move.svg.import +++ b/ui/assets/icons/move.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://blumv8ks5udd0" -path="res://.godot/imported/move.svg-02773225dd69d6b087d1f5350234f226.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/move.svg-02773225dd69d6b087d1f5350234f226.dpitex" [deps] source_file="res://ui/assets/icons/move.svg" -dest_files=["res://.godot/imported/move.svg-02773225dd69d6b087d1f5350234f226.ctex"] +dest_files=["res://.godot/imported/move.svg-02773225dd69d6b087d1f5350234f226.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/new_file_icon.png.import b/ui/assets/icons/new_file_icon.png.import index 037525e5..7e63b104 100644 --- a/ui/assets/icons/new_file_icon.png.import +++ b/ui/assets/icons/new_file_icon.png.import @@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/new_file_icon.png-03f076b44da6a67b9b336d7fd15 compress/mode=0 compress/high_quality=false compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 compress/hdr_compression=1 compress/normal_map=0 compress/channel_pack=0 @@ -25,6 +27,10 @@ mipmaps/generate=false mipmaps/limit=-1 roughness/mode=0 roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 process/fix_alpha_border=true process/premult_alpha=false process/normal_map_invert_y=false diff --git a/ui/assets/icons/node.svg.import b/ui/assets/icons/node.svg.import index 348be620..b569a509 100644 --- a/ui/assets/icons/node.svg.import +++ b/ui/assets/icons/node.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://dricxnc8d6oam" -path="res://.godot/imported/node.svg-f625aceed4ae1a6d24afe0a60b536868.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/node.svg-f625aceed4ae1a6d24afe0a60b536868.dpitex" [deps] source_file="res://ui/assets/icons/node.svg" -dest_files=["res://.godot/imported/node.svg-f625aceed4ae1a6d24afe0a60b536868.ctex"] +dest_files=["res://.godot/imported/node.svg-f625aceed4ae1a6d24afe0a60b536868.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/object.svg b/ui/assets/icons/object.svg new file mode 100644 index 00000000..a709768e --- /dev/null +++ b/ui/assets/icons/object.svg @@ -0,0 +1,3 @@ + + + diff --git a/ui/assets/icons/object.svg.import b/ui/assets/icons/object.svg.import new file mode 100644 index 00000000..9e181c75 --- /dev/null +++ b/ui/assets/icons/object.svg.import @@ -0,0 +1,18 @@ +[remap] + +importer="svg" +type="DPITexture" +uid="uid://cxyieo7jnlvkm" +path="res://.godot/imported/object.svg-e3a0713805ea8ed4ba90e3101bf0d51d.dpitex" + +[deps] + +source_file="res://ui/assets/icons/object.svg" +dest_files=["res://.godot/imported/object.svg-e3a0713805ea8ed4ba90e3101bf0d51d.dpitex"] + +[params] + +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/offset_cross.svg.import b/ui/assets/icons/offset_cross.svg.import index f5b42535..24dbba44 100644 --- a/ui/assets/icons/offset_cross.svg.import +++ b/ui/assets/icons/offset_cross.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://c7ee44ql1gv6b" -path="res://.godot/imported/offset_cross.svg-fa6ba8866adb942e2f9497d32f98f219.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/offset_cross.svg-fa6ba8866adb942e2f9497d32f98f219.dpitex" [deps] source_file="res://ui/assets/icons/offset_cross.svg" -dest_files=["res://.godot/imported/offset_cross.svg-fa6ba8866adb942e2f9497d32f98f219.ctex"] +dest_files=["res://.godot/imported/offset_cross.svg-fa6ba8866adb942e2f9497d32f98f219.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=4.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/path.svg.import b/ui/assets/icons/path.svg.import index c6b643ae..262a2e3a 100644 --- a/ui/assets/icons/path.svg.import +++ b/ui/assets/icons/path.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://bmpfvosa78tot" -path="res://.godot/imported/path.svg-41a42a51f6587400da9006aee062b4bc.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/path.svg-41a42a51f6587400da9006aee062b4bc.dpitex" [deps] source_file="res://ui/assets/icons/path.svg" -dest_files=["res://.godot/imported/path.svg-41a42a51f6587400da9006aee062b4bc.ctex"] +dest_files=["res://.godot/imported/path.svg-41a42a51f6587400da9006aee062b4bc.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/pen.svg.import b/ui/assets/icons/pen.svg.import index f3b96fcd..174c8b09 100644 --- a/ui/assets/icons/pen.svg.import +++ b/ui/assets/icons/pen.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://dixramdai4iq4" -path="res://.godot/imported/pen.svg-8b9edd9c40f973206eb1e8ec00453c78.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/pen.svg-8b9edd9c40f973206eb1e8ec00453c78.dpitex" [deps] source_file="res://ui/assets/icons/pen.svg" -dest_files=["res://.godot/imported/pen.svg-8b9edd9c40f973206eb1e8ec00453c78.ctex"] +dest_files=["res://.godot/imported/pen.svg-8b9edd9c40f973206eb1e8ec00453c78.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/picture.svg.import b/ui/assets/icons/picture.svg.import index 04f02951..9a0d1e6f 100644 --- a/ui/assets/icons/picture.svg.import +++ b/ui/assets/icons/picture.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://csskef1726pia" -path="res://.godot/imported/picture.svg-fb6e9ca01b12bc3ac51c48cf77dff73d.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/picture.svg-fb6e9ca01b12bc3ac51c48cf77dff73d.dpitex" [deps] source_file="res://ui/assets/icons/picture.svg" -dest_files=["res://.godot/imported/picture.svg-fb6e9ca01b12bc3ac51c48cf77dff73d.ctex"] +dest_files=["res://.godot/imported/picture.svg-fb6e9ca01b12bc3ac51c48cf77dff73d.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/play.svg.import b/ui/assets/icons/play.svg.import index b6d19dfd..03476935 100644 --- a/ui/assets/icons/play.svg.import +++ b/ui/assets/icons/play.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://b272tbdmvxj20" -path="res://.godot/imported/play.svg-6e11631c470fc7234c44a516961b928d.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/play.svg-6e11631c470fc7234c44a516961b928d.dpitex" [deps] source_file="res://ui/assets/icons/play.svg" -dest_files=["res://.godot/imported/play.svg-6e11631c470fc7234c44a516961b928d.ctex"] +dest_files=["res://.godot/imported/play.svg-6e11631c470fc7234c44a516961b928d.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/plus.svg.import b/ui/assets/icons/plus.svg.import index 1ba9f56c..932ebbab 100644 --- a/ui/assets/icons/plus.svg.import +++ b/ui/assets/icons/plus.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://hlck6y4i3l5q" -path="res://.godot/imported/plus.svg-2aec05a24ba3fce411ff8c07d0216505.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/plus.svg-2aec05a24ba3fce411ff8c07d0216505.dpitex" [deps] source_file="res://ui/assets/icons/plus.svg" -dest_files=["res://.godot/imported/plus.svg-2aec05a24ba3fce411ff8c07d0216505.ctex"] +dest_files=["res://.godot/imported/plus.svg-2aec05a24ba3fce411ff8c07d0216505.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/plus_min.svg.import b/ui/assets/icons/plus_min.svg.import index fc95b74d..3c6b4f2f 100644 --- a/ui/assets/icons/plus_min.svg.import +++ b/ui/assets/icons/plus_min.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://xiahr3jughjg" -path="res://.godot/imported/plus_min.svg-d59fdc210a7c0d10d974d1630fcd3160.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/plus_min.svg-d59fdc210a7c0d10d974d1630fcd3160.dpitex" [deps] source_file="res://ui/assets/icons/plus_min.svg" -dest_files=["res://.godot/imported/plus_min.svg-d59fdc210a7c0d10d974d1630fcd3160.ctex"] +dest_files=["res://.godot/imported/plus_min.svg-d59fdc210a7c0d10d974d1630fcd3160.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/px_character.png b/ui/assets/icons/px_character.png new file mode 100644 index 00000000..4a1872db Binary files /dev/null and b/ui/assets/icons/px_character.png differ diff --git a/ui/assets/icons/px_character.png.import b/ui/assets/icons/px_character.png.import new file mode 100644 index 00000000..8b6faa55 --- /dev/null +++ b/ui/assets/icons/px_character.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dd4l57i1csm18" +path="res://.godot/imported/px_character.png-36485977ecc4fa24e5383e7c00c00380.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://ui/assets/icons/px_character.png" +dest_files=["res://.godot/imported/px_character.png-36485977ecc4fa24e5383e7c00c00380.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/ui/assets/icons/recording.svg.import b/ui/assets/icons/recording.svg.import index ca19ad9b..10261f2a 100644 --- a/ui/assets/icons/recording.svg.import +++ b/ui/assets/icons/recording.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://cogl1yv0fxcm0" -path="res://.godot/imported/recording.svg-fd6b02caaf2c0c82bbcc7b1672a860aa.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/recording.svg-fd6b02caaf2c0c82bbcc7b1672a860aa.dpitex" [deps] source_file="res://ui/assets/icons/recording.svg" -dest_files=["res://.godot/imported/recording.svg-fd6b02caaf2c0c82bbcc7b1672a860aa.ctex"] +dest_files=["res://.godot/imported/recording.svg-fd6b02caaf2c0c82bbcc7b1672a860aa.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/root.svg.import b/ui/assets/icons/root.svg.import index c20bf61c..ec92b77d 100644 --- a/ui/assets/icons/root.svg.import +++ b/ui/assets/icons/root.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://djqan6ktvu3gg" -path="res://.godot/imported/root.svg-a7e7915a457085f02dd5b3dd6e4c5932.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/root.svg-a7e7915a457085f02dd5b3dd6e4c5932.dpitex" [deps] source_file="res://ui/assets/icons/root.svg" -dest_files=["res://.godot/imported/root.svg-a7e7915a457085f02dd5b3dd6e4c5932.ctex"] +dest_files=["res://.godot/imported/root.svg-a7e7915a457085f02dd5b3dd6e4c5932.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/search.svg.import b/ui/assets/icons/search.svg.import index 1234316a..34e9f249 100644 --- a/ui/assets/icons/search.svg.import +++ b/ui/assets/icons/search.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://7cgdpf2fr6p6" -path="res://.godot/imported/search.svg-8cadf8079107f4438b3983b0b7aa4949.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/search.svg-8cadf8079107f4438b3983b0b7aa4949.dpitex" [deps] source_file="res://ui/assets/icons/search.svg" -dest_files=["res://.godot/imported/search.svg-8cadf8079107f4438b3983b0b7aa4949.ctex"] +dest_files=["res://.godot/imported/search.svg-8cadf8079107f4438b3983b0b7aa4949.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/settings.svg.import b/ui/assets/icons/settings.svg.import index 468d96ff..38f089aa 100644 --- a/ui/assets/icons/settings.svg.import +++ b/ui/assets/icons/settings.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://d4fesqfd2v8fd" -path="res://.godot/imported/settings.svg-c46ee68c0fee76b79327321b0ec3cca9.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/settings.svg-c46ee68c0fee76b79327321b0ec3cca9.dpitex" [deps] source_file="res://ui/assets/icons/settings.svg" -dest_files=["res://.godot/imported/settings.svg-c46ee68c0fee76b79327321b0ec3cca9.ctex"] +dest_files=["res://.godot/imported/settings.svg-c46ee68c0fee76b79327321b0ec3cca9.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/side_panel_mode.png.import b/ui/assets/icons/side_panel_mode.png.import index 794b727f..c20b912f 100644 --- a/ui/assets/icons/side_panel_mode.png.import +++ b/ui/assets/icons/side_panel_mode.png.import @@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/side_panel_mode.png-8d1679ccbd6f7603bba8ee1ec compress/mode=0 compress/high_quality=false compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 compress/hdr_compression=1 compress/normal_map=0 compress/channel_pack=0 @@ -25,6 +27,10 @@ mipmaps/generate=false mipmaps/limit=-1 roughness/mode=0 roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 process/fix_alpha_border=true process/premult_alpha=false process/normal_map_invert_y=false diff --git a/ui/assets/icons/slot.svg b/ui/assets/icons/slot.svg index 57129077..2f1e8276 100644 --- a/ui/assets/icons/slot.svg +++ b/ui/assets/icons/slot.svg @@ -1,3 +1,3 @@ - - + + diff --git a/ui/assets/icons/slot.svg.import b/ui/assets/icons/slot.svg.import index 831510dc..09bd0ad0 100644 --- a/ui/assets/icons/slot.svg.import +++ b/ui/assets/icons/slot.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://dsb6opwewlipc" -path="res://.godot/imported/slot.svg-7512eb906f1c8e0921720e836517d8dd.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/slot.svg-7512eb906f1c8e0921720e836517d8dd.dpitex" [deps] source_file="res://ui/assets/icons/slot.svg" -dest_files=["res://.godot/imported/slot.svg-7512eb906f1c8e0921720e836517d8dd.ctex"] +dest_files=["res://.godot/imported/slot.svg-7512eb906f1c8e0921720e836517d8dd.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/slot_in.svg b/ui/assets/icons/slot_in.svg new file mode 100644 index 00000000..8651ed7a --- /dev/null +++ b/ui/assets/icons/slot_in.svg @@ -0,0 +1,3 @@ + + + diff --git a/ui/assets/icons/slot_in.svg.import b/ui/assets/icons/slot_in.svg.import new file mode 100644 index 00000000..a1a9d4e5 --- /dev/null +++ b/ui/assets/icons/slot_in.svg.import @@ -0,0 +1,18 @@ +[remap] + +importer="svg" +type="DPITexture" +uid="uid://dg8g8bw67365f" +path="res://.godot/imported/slot_in.svg-9728f97a87edc6ee8d977b05f41d534e.dpitex" + +[deps] + +source_file="res://ui/assets/icons/slot_in.svg" +dest_files=["res://.godot/imported/slot_in.svg-9728f97a87edc6ee8d977b05f41d534e.dpitex"] + +[params] + +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/slot_left.svg b/ui/assets/icons/slot_left.svg deleted file mode 100644 index 453a240f..00000000 --- a/ui/assets/icons/slot_left.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/ui/assets/icons/slot_node.svg b/ui/assets/icons/slot_node.svg new file mode 100644 index 00000000..c624e5c1 --- /dev/null +++ b/ui/assets/icons/slot_node.svg @@ -0,0 +1,3 @@ + + + diff --git a/ui/assets/icons/slot_node.svg.import b/ui/assets/icons/slot_node.svg.import new file mode 100644 index 00000000..64c16f12 --- /dev/null +++ b/ui/assets/icons/slot_node.svg.import @@ -0,0 +1,18 @@ +[remap] + +importer="svg" +type="DPITexture" +uid="uid://dqfhmm5xqls6u" +path="res://.godot/imported/slot_node.svg-990bb35e7c371fe2109f9161bd311cce.dpitex" + +[deps] + +source_file="res://ui/assets/icons/slot_node.svg" +dest_files=["res://.godot/imported/slot_node.svg-990bb35e7c371fe2109f9161bd311cce.dpitex"] + +[params] + +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/slot_out.svg b/ui/assets/icons/slot_out.svg new file mode 100644 index 00000000..b45f77d6 --- /dev/null +++ b/ui/assets/icons/slot_out.svg @@ -0,0 +1,3 @@ + + + diff --git a/ui/assets/icons/slot_out.svg.import b/ui/assets/icons/slot_out.svg.import new file mode 100644 index 00000000..9dd61665 --- /dev/null +++ b/ui/assets/icons/slot_out.svg.import @@ -0,0 +1,18 @@ +[remap] + +importer="svg" +type="DPITexture" +uid="uid://bbudj20nubmr3" +path="res://.godot/imported/slot_out.svg-2492886c5426afdc81c5df6d7c2bc795.dpitex" + +[deps] + +source_file="res://ui/assets/icons/slot_out.svg" +dest_files=["res://.godot/imported/slot_out.svg-2492886c5426afdc81c5df6d7c2bc795.dpitex"] + +[params] + +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/slot_right.svg b/ui/assets/icons/slot_right.svg deleted file mode 100644 index 9c952598..00000000 --- a/ui/assets/icons/slot_right.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/ui/assets/icons/sparkles.svg.import b/ui/assets/icons/sparkles.svg.import index fdd23382..55a11c14 100644 --- a/ui/assets/icons/sparkles.svg.import +++ b/ui/assets/icons/sparkles.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://dd6wdpndndufl" -path="res://.godot/imported/sparkles.svg-38158dff79dbfe4cd6546951a63d7513.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/sparkles.svg-38158dff79dbfe4cd6546951a63d7513.dpitex" [deps] source_file="res://ui/assets/icons/sparkles.svg" -dest_files=["res://.godot/imported/sparkles.svg-38158dff79dbfe4cd6546951a63d7513.ctex"] +dest_files=["res://.godot/imported/sparkles.svg-38158dff79dbfe4cd6546951a63d7513.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/star.svg.import b/ui/assets/icons/star.svg.import index 3648b2ff..deb58c99 100644 --- a/ui/assets/icons/star.svg.import +++ b/ui/assets/icons/star.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://bogfuvhttgn1v" -path="res://.godot/imported/star.svg-9d050bc3c1ee183ab53abdc76a3f0ea4.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/star.svg-9d050bc3c1ee183ab53abdc76a3f0ea4.dpitex" [deps] source_file="res://ui/assets/icons/star.svg" -dest_files=["res://.godot/imported/star.svg-9d050bc3c1ee183ab53abdc76a3f0ea4.ctex"] +dest_files=["res://.godot/imported/star.svg-9d050bc3c1ee183ab53abdc76a3f0ea4.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/star_full.svg.import b/ui/assets/icons/star_full.svg.import index da5bcf61..72281a21 100644 --- a/ui/assets/icons/star_full.svg.import +++ b/ui/assets/icons/star_full.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://degqh4fiyy5q7" -path="res://.godot/imported/star_full.svg-600206e11e3287e6d34f7f695b4fae83.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/star_full.svg-600206e11e3287e6d34f7f695b4fae83.dpitex" [deps] source_file="res://ui/assets/icons/star_full.svg" -dest_files=["res://.godot/imported/star_full.svg-600206e11e3287e6d34f7f695b4fae83.ctex"] +dest_files=["res://.godot/imported/star_full.svg-600206e11e3287e6d34f7f695b4fae83.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/story_file.svg.import b/ui/assets/icons/story_file.svg.import index ef0b676e..8a154fbc 100644 --- a/ui/assets/icons/story_file.svg.import +++ b/ui/assets/icons/story_file.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://dh5pqexvqelgr" -path="res://.godot/imported/story_file.svg-358a15444b72001dd607e5f16b13094e.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/story_file.svg-358a15444b72001dd607e5f16b13094e.dpitex" [deps] source_file="res://ui/assets/icons/story_file.svg" -dest_files=["res://.godot/imported/story_file.svg-358a15444b72001dd607e5f16b13094e.ctex"] +dest_files=["res://.godot/imported/story_file.svg-358a15444b72001dd607e5f16b13094e.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/str_icon.png.import b/ui/assets/icons/str_icon.png.import index 01f41368..7a0cefc2 100644 --- a/ui/assets/icons/str_icon.png.import +++ b/ui/assets/icons/str_icon.png.import @@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/str_icon.png-8ca382e7db66e9cfe98d3ed38a6840f4 compress/mode=0 compress/high_quality=false compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 compress/hdr_compression=1 compress/normal_map=0 compress/channel_pack=0 @@ -25,6 +27,10 @@ mipmaps/generate=false mipmaps/limit=-1 roughness/mode=0 roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 process/fix_alpha_border=true process/premult_alpha=false process/normal_map_invert_y=false diff --git a/ui/assets/icons/text.svg.import b/ui/assets/icons/text.svg.import index a449543f..23bdcb67 100644 --- a/ui/assets/icons/text.svg.import +++ b/ui/assets/icons/text.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://b28iomp56v1c8" -path="res://.godot/imported/text.svg-f12730dd150189529254abdf2a0e4477.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/text.svg-f12730dd150189529254abdf2a0e4477.dpitex" [deps] source_file="res://ui/assets/icons/text.svg" -dest_files=["res://.godot/imported/text.svg-f12730dd150189529254abdf2a0e4477.ctex"] +dest_files=["res://.godot/imported/text.svg-f12730dd150189529254abdf2a0e4477.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/textbox_mode.png.import b/ui/assets/icons/textbox_mode.png.import index 7c7bc090..8162b339 100644 --- a/ui/assets/icons/textbox_mode.png.import +++ b/ui/assets/icons/textbox_mode.png.import @@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/textbox_mode.png-2c66a415327262c19ab1b5baa0c6 compress/mode=0 compress/high_quality=false compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 compress/hdr_compression=1 compress/normal_map=0 compress/channel_pack=0 @@ -25,6 +27,10 @@ mipmaps/generate=false mipmaps/limit=-1 roughness/mode=0 roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 process/fix_alpha_border=true process/premult_alpha=false process/normal_map_invert_y=false diff --git a/ui/assets/icons/time.svg.import b/ui/assets/icons/time.svg.import index 87633a58..88cefcaf 100644 --- a/ui/assets/icons/time.svg.import +++ b/ui/assets/icons/time.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://choeykqmdmkm6" -path="res://.godot/imported/time.svg-f3195264abb11aaf5366306fe281ffce.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/time.svg-f3195264abb11aaf5366306fe281ffce.dpitex" [deps] source_file="res://ui/assets/icons/time.svg" -dest_files=["res://.godot/imported/time.svg-f3195264abb11aaf5366306fe281ffce.ctex"] +dest_files=["res://.godot/imported/time.svg-f3195264abb11aaf5366306fe281ffce.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/toggle.svg.import b/ui/assets/icons/toggle.svg.import index fcbbc239..47559dab 100644 --- a/ui/assets/icons/toggle.svg.import +++ b/ui/assets/icons/toggle.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://dltidudnc0ig4" -path="res://.godot/imported/toggle.svg-8beead1392fe293bddccb24536de320e.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/toggle.svg-8beead1392fe293bddccb24536de320e.dpitex" [deps] source_file="res://ui/assets/icons/toggle.svg" -dest_files=["res://.godot/imported/toggle.svg-8beead1392fe293bddccb24536de320e.ctex"] +dest_files=["res://.godot/imported/toggle.svg-8beead1392fe293bddccb24536de320e.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/toggle_off.svg.import b/ui/assets/icons/toggle_off.svg.import index 2cb8732c..db7974f4 100644 --- a/ui/assets/icons/toggle_off.svg.import +++ b/ui/assets/icons/toggle_off.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://dsjl0jdgaayu8" -path="res://.godot/imported/toggle_off.svg-b4decedaf4ff04bb807c4a46db2c5ee9.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/toggle_off.svg-b4decedaf4ff04bb807c4a46db2c5ee9.dpitex" [deps] source_file="res://ui/assets/icons/toggle_off.svg" -dest_files=["res://.godot/imported/toggle_off.svg-b4decedaf4ff04bb807c4a46db2c5ee9.ctex"] +dest_files=["res://.godot/imported/toggle_off.svg-b4decedaf4ff04bb807c4a46db2c5ee9.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/toggle_on.svg.import b/ui/assets/icons/toggle_on.svg.import index f1edf801..56c66905 100644 --- a/ui/assets/icons/toggle_on.svg.import +++ b/ui/assets/icons/toggle_on.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://cenp7to5aeciv" -path="res://.godot/imported/toggle_on.svg-e6030d5275cc3e6903bc8c9eb1d5fcd6.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/toggle_on.svg-e6030d5275cc3e6903bc8c9eb1d5fcd6.dpitex" [deps] source_file="res://ui/assets/icons/toggle_on.svg" -dest_files=["res://.godot/imported/toggle_on.svg-e6030d5275cc3e6903bc8c9eb1d5fcd6.ctex"] +dest_files=["res://.godot/imported/toggle_on.svg-e6030d5275cc3e6903bc8c9eb1d5fcd6.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/trash.svg.import b/ui/assets/icons/trash.svg.import index 21489aca..eab243ea 100644 --- a/ui/assets/icons/trash.svg.import +++ b/ui/assets/icons/trash.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://hmjhxdsk3pwj" -path="res://.godot/imported/trash.svg-8e3a1edf4d1ed72bc18f8ac99c6641da.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/trash.svg-8e3a1edf4d1ed72bc18f8ac99c6641da.dpitex" [deps] source_file="res://ui/assets/icons/trash.svg" -dest_files=["res://.godot/imported/trash.svg-8e3a1edf4d1ed72bc18f8ac99c6641da.ctex"] +dest_files=["res://.godot/imported/trash.svg-8e3a1edf4d1ed72bc18f8ac99c6641da.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/trash_min.svg.import b/ui/assets/icons/trash_min.svg.import index fb9c6c88..e178944d 100644 --- a/ui/assets/icons/trash_min.svg.import +++ b/ui/assets/icons/trash_min.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://fcpb4fd7uma3" -path="res://.godot/imported/trash_min.svg-e96161714aef429f1b62e394c1db86d1.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/trash_min.svg-e96161714aef429f1b62e394c1db86d1.dpitex" [deps] source_file="res://ui/assets/icons/trash_min.svg" -dest_files=["res://.godot/imported/trash_min.svg-e96161714aef429f1b62e394c1db86d1.ctex"] +dest_files=["res://.godot/imported/trash_min.svg-e96161714aef429f1b62e394c1db86d1.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/ui_close.svg.import b/ui/assets/icons/ui_close.svg.import index 14c5e0aa..92dddb62 100644 --- a/ui/assets/icons/ui_close.svg.import +++ b/ui/assets/icons/ui_close.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://kk5em170gn2b" -path="res://.godot/imported/ui_close.svg-076d4f5a3ec70c68b7317eb59bc98596.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/ui_close.svg-076d4f5a3ec70c68b7317eb59bc98596.dpitex" [deps] source_file="res://ui/assets/icons/ui_close.svg" -dest_files=["res://.godot/imported/ui_close.svg-076d4f5a3ec70c68b7317eb59bc98596.ctex"] +dest_files=["res://.godot/imported/ui_close.svg-076d4f5a3ec70c68b7317eb59bc98596.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/ui_maximize.svg.import b/ui/assets/icons/ui_maximize.svg.import index d5057c57..89f072fc 100644 --- a/ui/assets/icons/ui_maximize.svg.import +++ b/ui/assets/icons/ui_maximize.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://c4ib88gq1pbjr" -path="res://.godot/imported/ui_maximize.svg-6fdac7ebdd4643a4a2e6a7e1da7b5ae2.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/ui_maximize.svg-6fdac7ebdd4643a4a2e6a7e1da7b5ae2.dpitex" [deps] source_file="res://ui/assets/icons/ui_maximize.svg" -dest_files=["res://.godot/imported/ui_maximize.svg-6fdac7ebdd4643a4a2e6a7e1da7b5ae2.ctex"] +dest_files=["res://.godot/imported/ui_maximize.svg-6fdac7ebdd4643a4a2e6a7e1da7b5ae2.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/ui_minimize.svg.import b/ui/assets/icons/ui_minimize.svg.import index 4400deb9..4bd2bf57 100644 --- a/ui/assets/icons/ui_minimize.svg.import +++ b/ui/assets/icons/ui_minimize.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://wij3oqtk1gqe" -path="res://.godot/imported/ui_minimize.svg-69f299b5766bece959ce093aa08cbcdd.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/ui_minimize.svg-69f299b5766bece959ce093aa08cbcdd.dpitex" [deps] source_file="res://ui/assets/icons/ui_minimize.svg" -dest_files=["res://.godot/imported/ui_minimize.svg-69f299b5766bece959ce093aa08cbcdd.ctex"] +dest_files=["res://.godot/imported/ui_minimize.svg-69f299b5766bece959ce093aa08cbcdd.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/ui_reduce.svg.import b/ui/assets/icons/ui_reduce.svg.import index c0498b70..33bbfd3b 100644 --- a/ui/assets/icons/ui_reduce.svg.import +++ b/ui/assets/icons/ui_reduce.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://cxek38x4sufp5" -path="res://.godot/imported/ui_reduce.svg-f16069b8b6cbc2a2d84de1fc43cd5d8b.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/ui_reduce.svg-f16069b8b6cbc2a2d84de1fc43cd5d8b.dpitex" [deps] source_file="res://ui/assets/icons/ui_reduce.svg" -dest_files=["res://.godot/imported/ui_reduce.svg-f16069b8b6cbc2a2d84de1fc43cd5d8b.ctex"] +dest_files=["res://.godot/imported/ui_reduce.svg-f16069b8b6cbc2a2d84de1fc43cd5d8b.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/unexposable.svg b/ui/assets/icons/unexposable.svg new file mode 100644 index 00000000..d447a82e --- /dev/null +++ b/ui/assets/icons/unexposable.svg @@ -0,0 +1,3 @@ + + + diff --git a/ui/assets/icons/unexposable.svg.import b/ui/assets/icons/unexposable.svg.import new file mode 100644 index 00000000..1b858246 --- /dev/null +++ b/ui/assets/icons/unexposable.svg.import @@ -0,0 +1,18 @@ +[remap] + +importer="svg" +type="DPITexture" +uid="uid://qs0nswphmi80" +path="res://.godot/imported/unexposable.svg-071e11abf0bd720eed1d7d5f04176d8a.dpitex" + +[deps] + +source_file="res://ui/assets/icons/unexposable.svg" +dest_files=["res://.godot/imported/unexposable.svg-071e11abf0bd720eed1d7d5f04176d8a.dpitex"] + +[params] + +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/unexposed.svg b/ui/assets/icons/unexposed.svg new file mode 100644 index 00000000..66928df5 --- /dev/null +++ b/ui/assets/icons/unexposed.svg @@ -0,0 +1,3 @@ + + + diff --git a/ui/assets/icons/unexposed.svg.import b/ui/assets/icons/unexposed.svg.import new file mode 100644 index 00000000..4be42c98 --- /dev/null +++ b/ui/assets/icons/unexposed.svg.import @@ -0,0 +1,18 @@ +[remap] + +importer="svg" +type="DPITexture" +uid="uid://x3csrllomotc" +path="res://.godot/imported/unexposed.svg-38ee52dd1817a5ef1bf2a75430518018.dpitex" + +[deps] + +source_file="res://ui/assets/icons/unexposed.svg" +dest_files=["res://.godot/imported/unexposed.svg-38ee52dd1817a5ef1bf2a75430518018.dpitex"] + +[params] + +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/upload.svg.import b/ui/assets/icons/upload.svg.import index e9814a8c..b1580e23 100644 --- a/ui/assets/icons/upload.svg.import +++ b/ui/assets/icons/upload.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://bpgyletubbyq" -path="res://.godot/imported/upload.svg-adffb124d89942e718999881cec1ee18.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/upload.svg-adffb124d89942e718999881cec1ee18.dpitex" [deps] source_file="res://ui/assets/icons/upload.svg" -dest_files=["res://.godot/imported/upload.svg-adffb124d89942e718999881cec1ee18.ctex"] +dest_files=["res://.godot/imported/upload.svg-adffb124d89942e718999881cec1ee18.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/variables.svg.import b/ui/assets/icons/variables.svg.import index ed56105a..03ca9bfe 100644 --- a/ui/assets/icons/variables.svg.import +++ b/ui/assets/icons/variables.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://b46sqb5g0spae" -path="res://.godot/imported/variables.svg-067e9dca7014970f6e37bbf8c84ae70c.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/variables.svg-067e9dca7014970f6e37bbf8c84ae70c.dpitex" [deps] source_file="res://ui/assets/icons/variables.svg" -dest_files=["res://.godot/imported/variables.svg-067e9dca7014970f6e37bbf8c84ae70c.ctex"] +dest_files=["res://.godot/imported/variables.svg-067e9dca7014970f6e37bbf8c84ae70c.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/assets/icons/vertical_dots.svg b/ui/assets/icons/vertical_dots.svg new file mode 100644 index 00000000..ee9efbc0 --- /dev/null +++ b/ui/assets/icons/vertical_dots.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/ui/assets/icons/slot_right.svg.import b/ui/assets/icons/vertical_dots.svg.import similarity index 59% rename from ui/assets/icons/slot_right.svg.import rename to ui/assets/icons/vertical_dots.svg.import index a0a0d7c1..42b01459 100644 --- a/ui/assets/icons/slot_right.svg.import +++ b/ui/assets/icons/vertical_dots.svg.import @@ -2,22 +2,24 @@ importer="texture" type="CompressedTexture2D" -uid="uid://bexlgpgwakbrr" -path="res://.godot/imported/slot_right.svg-8add5ca45ef21dcad026b04cdcc1f76c.ctex" +uid="uid://c3adrbx54m4c3" +path="res://.godot/imported/vertical_dots.svg-8c243fa55c65bb827f052611a2649e72.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://ui/assets/icons/slot_right.svg" -dest_files=["res://.godot/imported/slot_right.svg-8add5ca45ef21dcad026b04cdcc1f76c.ctex"] +source_file="res://ui/assets/icons/vertical_dots.svg" +dest_files=["res://.godot/imported/vertical_dots.svg-8c243fa55c65bb827f052611a2649e72.ctex"] [params] compress/mode=0 compress/high_quality=false compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 compress/hdr_compression=1 compress/normal_map=0 compress/channel_pack=0 @@ -25,6 +27,10 @@ mipmaps/generate=false mipmaps/limit=-1 roughness/mode=0 roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 process/fix_alpha_border=true process/premult_alpha=false process/normal_map_invert_y=false diff --git a/ui/assets/icons/vertical_dots_unfocus.svg b/ui/assets/icons/vertical_dots_unfocus.svg new file mode 100644 index 00000000..1f597540 --- /dev/null +++ b/ui/assets/icons/vertical_dots_unfocus.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/common/ui/fields/character_field/assets/portrait_placeholder.svg.import b/ui/assets/icons/vertical_dots_unfocus.svg.import similarity index 58% rename from common/ui/fields/character_field/assets/portrait_placeholder.svg.import rename to ui/assets/icons/vertical_dots_unfocus.svg.import index 0a4deb37..8a8931f7 100644 --- a/common/ui/fields/character_field/assets/portrait_placeholder.svg.import +++ b/ui/assets/icons/vertical_dots_unfocus.svg.import @@ -2,22 +2,24 @@ importer="texture" type="CompressedTexture2D" -uid="uid://ddah0eo1qhki4" -path="res://.godot/imported/portrait_placeholder.svg-3f112112b6ad9b59dbf2e76175184d46.ctex" +uid="uid://beolc2wkdg6ey" +path="res://.godot/imported/vertical_dots_unfocus.svg-4e7d2bd64ded9042e49bd4e28323dd3b.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://common/ui/fields/character_field/assets/portrait_placeholder.svg" -dest_files=["res://.godot/imported/portrait_placeholder.svg-3f112112b6ad9b59dbf2e76175184d46.ctex"] +source_file="res://ui/assets/icons/vertical_dots_unfocus.svg" +dest_files=["res://.godot/imported/vertical_dots_unfocus.svg-4e7d2bd64ded9042e49bd4e28323dd3b.ctex"] [params] compress/mode=0 compress/high_quality=false compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 compress/hdr_compression=1 compress/normal_map=0 compress/channel_pack=0 @@ -25,6 +27,10 @@ mipmaps/generate=false mipmaps/limit=-1 roughness/mode=0 roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 process/fix_alpha_border=true process/premult_alpha=false process/normal_map_invert_y=false diff --git a/ui/theme_default/assets/checked.svg.import b/ui/theme_default/assets/checked.svg.import index 40f49153..b76941ec 100644 --- a/ui/theme_default/assets/checked.svg.import +++ b/ui/theme_default/assets/checked.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://cfk4fuhncchxg" -path="res://.godot/imported/checked.svg-a2e3aa6723c978ceb1086430232b6ef8.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/checked.svg-a2e3aa6723c978ceb1086430232b6ef8.dpitex" [deps] source_file="res://ui/theme_default/assets/checked.svg" -dest_files=["res://.godot/imported/checked.svg-a2e3aa6723c978ceb1086430232b6ef8.ctex"] +dest_files=["res://.godot/imported/checked.svg-a2e3aa6723c978ceb1086430232b6ef8.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/theme_default/assets/checked_disabled.svg.import b/ui/theme_default/assets/checked_disabled.svg.import index 298e8040..c66e49e3 100644 --- a/ui/theme_default/assets/checked_disabled.svg.import +++ b/ui/theme_default/assets/checked_disabled.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://bs272e68nsf7r" -path="res://.godot/imported/checked_disabled.svg-f39b51af6b974695633280859d9076d9.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/checked_disabled.svg-f39b51af6b974695633280859d9076d9.dpitex" [deps] source_file="res://ui/theme_default/assets/checked_disabled.svg" -dest_files=["res://.godot/imported/checked_disabled.svg-f39b51af6b974695633280859d9076d9.ctex"] +dest_files=["res://.godot/imported/checked_disabled.svg-f39b51af6b974695633280859d9076d9.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/theme_default/assets/dash.svg.import b/ui/theme_default/assets/dash.svg.import index 9fcdcdb6..b86884e7 100644 --- a/ui/theme_default/assets/dash.svg.import +++ b/ui/theme_default/assets/dash.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://b1xjwwcy2gms8" -path="res://.godot/imported/dash.svg-507e14f61e6cc6045017967ea4a29ae8.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/dash.svg-507e14f61e6cc6045017967ea4a29ae8.dpitex" [deps] source_file="res://ui/theme_default/assets/dash.svg" -dest_files=["res://.godot/imported/dash.svg-507e14f61e6cc6045017967ea4a29ae8.ctex"] +dest_files=["res://.godot/imported/dash.svg-507e14f61e6cc6045017967ea4a29ae8.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/theme_default/assets/grabber.svg.import b/ui/theme_default/assets/grabber.svg.import index d8e8b144..dda8b224 100644 --- a/ui/theme_default/assets/grabber.svg.import +++ b/ui/theme_default/assets/grabber.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://bprc86xjlnexd" -path="res://.godot/imported/grabber.svg-abeade4349148784d1485f8ef9a7bfd2.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/grabber.svg-abeade4349148784d1485f8ef9a7bfd2.dpitex" [deps] source_file="res://ui/theme_default/assets/grabber.svg" -dest_files=["res://.godot/imported/grabber.svg-abeade4349148784d1485f8ef9a7bfd2.ctex"] +dest_files=["res://.godot/imported/grabber.svg-abeade4349148784d1485f8ef9a7bfd2.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/theme_default/assets/radio_checked.svg.import b/ui/theme_default/assets/radio_checked.svg.import index 5e2753f4..be46038f 100644 --- a/ui/theme_default/assets/radio_checked.svg.import +++ b/ui/theme_default/assets/radio_checked.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://ukfdhtpsv36d" -path="res://.godot/imported/radio_checked.svg-f599e463893a63e77a1dd4af36a0358e.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/radio_checked.svg-f599e463893a63e77a1dd4af36a0358e.dpitex" [deps] source_file="res://ui/theme_default/assets/radio_checked.svg" -dest_files=["res://.godot/imported/radio_checked.svg-f599e463893a63e77a1dd4af36a0358e.ctex"] +dest_files=["res://.godot/imported/radio_checked.svg-f599e463893a63e77a1dd4af36a0358e.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/theme_default/assets/radio_checked_disabled.svg.import b/ui/theme_default/assets/radio_checked_disabled.svg.import index a9d373d9..a8587062 100644 --- a/ui/theme_default/assets/radio_checked_disabled.svg.import +++ b/ui/theme_default/assets/radio_checked_disabled.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://cev1bkvk42y1b" -path="res://.godot/imported/radio_checked_disabled.svg-49bdf8cfebc4f192a76777ccbdc67936.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/radio_checked_disabled.svg-49bdf8cfebc4f192a76777ccbdc67936.dpitex" [deps] source_file="res://ui/theme_default/assets/radio_checked_disabled.svg" -dest_files=["res://.godot/imported/radio_checked_disabled.svg-49bdf8cfebc4f192a76777ccbdc67936.ctex"] +dest_files=["res://.godot/imported/radio_checked_disabled.svg-49bdf8cfebc4f192a76777ccbdc67936.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/theme_default/assets/radio_unchecked.svg.import b/ui/theme_default/assets/radio_unchecked.svg.import index b6cf5ff8..415d72d9 100644 --- a/ui/theme_default/assets/radio_unchecked.svg.import +++ b/ui/theme_default/assets/radio_unchecked.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://dkn12tgqxnutf" -path="res://.godot/imported/radio_unchecked.svg-8b33c4e8be7415b64a2339859729a66b.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/radio_unchecked.svg-8b33c4e8be7415b64a2339859729a66b.dpitex" [deps] source_file="res://ui/theme_default/assets/radio_unchecked.svg" -dest_files=["res://.godot/imported/radio_unchecked.svg-8b33c4e8be7415b64a2339859729a66b.ctex"] +dest_files=["res://.godot/imported/radio_unchecked.svg-8b33c4e8be7415b64a2339859729a66b.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/theme_default/assets/radio_unchecked_disabled.svg.import b/ui/theme_default/assets/radio_unchecked_disabled.svg.import index db4c8a78..14901353 100644 --- a/ui/theme_default/assets/radio_unchecked_disabled.svg.import +++ b/ui/theme_default/assets/radio_unchecked_disabled.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://br60sxpbxl5hm" -path="res://.godot/imported/radio_unchecked_disabled.svg-02b04de59a43ed2df9d95e7fbce4c130.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/radio_unchecked_disabled.svg-02b04de59a43ed2df9d95e7fbce4c130.dpitex" [deps] source_file="res://ui/theme_default/assets/radio_unchecked_disabled.svg" -dest_files=["res://.godot/imported/radio_unchecked_disabled.svg-02b04de59a43ed2df9d95e7fbce4c130.ctex"] +dest_files=["res://.godot/imported/radio_unchecked_disabled.svg-02b04de59a43ed2df9d95e7fbce4c130.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/theme_default/assets/unchecked.svg.import b/ui/theme_default/assets/unchecked.svg.import index a28ccf82..a7558569 100644 --- a/ui/theme_default/assets/unchecked.svg.import +++ b/ui/theme_default/assets/unchecked.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://dugiq0wty3mb0" -path="res://.godot/imported/unchecked.svg-4985d678b5bc215ed850e5a684f10cfe.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/unchecked.svg-4985d678b5bc215ed850e5a684f10cfe.dpitex" [deps] source_file="res://ui/theme_default/assets/unchecked.svg" -dest_files=["res://.godot/imported/unchecked.svg-4985d678b5bc215ed850e5a684f10cfe.ctex"] +dest_files=["res://.godot/imported/unchecked.svg-4985d678b5bc215ed850e5a684f10cfe.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/theme_default/assets/unchecked_disabled.svg.import b/ui/theme_default/assets/unchecked_disabled.svg.import index 1506bb38..3709285d 100644 --- a/ui/theme_default/assets/unchecked_disabled.svg.import +++ b/ui/theme_default/assets/unchecked_disabled.svg.import @@ -1,37 +1,18 @@ [remap] -importer="texture" -type="CompressedTexture2D" +importer="svg" +type="DPITexture" uid="uid://dgv4wsdayk8l5" -path="res://.godot/imported/unchecked_disabled.svg-5584a5db223afa90b5f1116dbaf91a4f.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/unchecked_disabled.svg-5584a5db223afa90b5f1116dbaf91a4f.dpitex" [deps] source_file="res://ui/theme_default/assets/unchecked_disabled.svg" -dest_files=["res://.godot/imported/unchecked_disabled.svg-5584a5db223afa90b5f1116dbaf91a4f.ctex"] +dest_files=["res://.godot/imported/unchecked_disabled.svg-5584a5db223afa90b5f1116dbaf91a4f.dpitex"] [params] -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +base_scale=1.0 +saturation=1.0 +color_map={} +compress=true diff --git a/ui/theme_default/color_palette.gd.uid b/ui/theme_default/color_palette.gd.uid new file mode 100644 index 00000000..c22386ed --- /dev/null +++ b/ui/theme_default/color_palette.gd.uid @@ -0,0 +1 @@ +uid://cc8mgjr11gim0 diff --git a/ui/theme_default/color_palette_light.gd.uid b/ui/theme_default/color_palette_light.gd.uid new file mode 100644 index 00000000..f6c28ced --- /dev/null +++ b/ui/theme_default/color_palette_light.gd.uid @@ -0,0 +1 @@ +uid://bu2k4un21v8l6 diff --git a/ui/theme_default/main.tres b/ui/theme_default/main.tres index 774210c9..6f351a6c 100644 --- a/ui/theme_default/main.tres +++ b/ui/theme_default/main.tres @@ -1,13 +1,11 @@ -[gd_resource type="Theme" script_class="MonologueTheme" load_steps=92 format=3 uid="uid://budfhk1hudcfj"] +[gd_resource type="Theme" load_steps=112 format=3 uid="uid://budfhk1hudcfj"] [ext_resource type="Texture2D" uid="uid://cfk4fuhncchxg" path="res://ui/theme_default/assets/checked.svg" id="1_ks7w5"] -[ext_resource type="Texture2D" uid="uid://dsb6opwewlipc" path="res://ui/assets/icons/slot.svg" id="1_yjacf"] [ext_resource type="Texture2D" uid="uid://cenp7to5aeciv" path="res://ui/assets/icons/toggle_on.svg" id="2_btlbu"] [ext_resource type="Texture2D" uid="uid://bs272e68nsf7r" path="res://ui/theme_default/assets/checked_disabled.svg" id="2_uqgmq"] [ext_resource type="Texture2D" uid="uid://dsjl0jdgaayu8" path="res://ui/assets/icons/toggle_off.svg" id="3_5qsde"] [ext_resource type="FontFile" uid="uid://dmd74vvvqx340" path="res://ui/assets/fonts/CourierNewPSMT.ttf" id="4_flt0i"] [ext_resource type="Texture2D" uid="uid://bprc86xjlnexd" path="res://ui/theme_default/assets/grabber.svg" id="4_gye7x"] -[ext_resource type="Script" uid="uid://c2nmcbo0pbk5u" path="res://ui/theme_default/theme_default.gd" id="5_gye7x"] [ext_resource type="Texture2D" uid="uid://b1xjwwcy2gms8" path="res://ui/theme_default/assets/dash.svg" id="6_6ojxv"] [ext_resource type="Texture2D" uid="uid://dugiq0wty3mb0" path="res://ui/theme_default/assets/unchecked.svg" id="7_rb0lk"] [ext_resource type="Texture2D" uid="uid://ukfdhtpsv36d" path="res://ui/theme_default/assets/radio_checked.svg" id="7_tydhh"] @@ -16,908 +14,1128 @@ [ext_resource type="Texture2D" uid="uid://dkn12tgqxnutf" path="res://ui/theme_default/assets/radio_unchecked.svg" id="9_2ase2"] [ext_resource type="Texture2D" uid="uid://br60sxpbxl5hm" path="res://ui/theme_default/assets/radio_unchecked_disabled.svg" id="10_ks7w5"] +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_ttl1t"] +content_margin_left = 8.0 +content_margin_top = 4.0 +content_margin_right = 8.0 +content_margin_bottom = 4.0 +bg_color = Color(0.11305001, 0.1137283, 0.133, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_2ase2"] +content_margin_left = 4.0 +content_margin_top = 4.0 +content_margin_right = 4.0 +content_margin_bottom = 4.0 +draw_center = false +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_ks7w5"] content_margin_left = 8.0 content_margin_top = 4.0 content_margin_right = 8.0 content_margin_bottom = 4.0 -bg_color = Color(0.403922, 0.384314, 0.470588, 0.05) -border_color = Color(0.890196, 0.894118, 0.921569, 0.2) -corner_radius_top_left = 6 -corner_radius_top_right = 6 -corner_radius_bottom_right = 6 -corner_radius_bottom_left = 6 +bg_color = Color(0.17827001, 0.17921962, 0.2062, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_uqgmq"] content_margin_left = 8.0 -content_margin_top = 8.0 +content_margin_top = 4.0 content_margin_right = 8.0 -content_margin_bottom = 8.0 -bg_color = Color(0.0980392, 0.0980392, 0.109804, 1) -draw_center = false -border_color = Color(0.890196, 0.894118, 0.921569, 0.2) -corner_radius_top_left = 6 -corner_radius_top_right = 6 -corner_radius_bottom_right = 6 -corner_radius_bottom_left = 6 +content_margin_bottom = 4.0 +bg_color = Color(0.203425, 0.20434555, 0.2305, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_rb0lk"] content_margin_left = 8.0 content_margin_top = 4.0 content_margin_right = 8.0 content_margin_bottom = 4.0 -bg_color = Color(0.403922, 0.384314, 0.470588, 0.2) -border_color = Color(0.890196, 0.894118, 0.921569, 0.2) -corner_radius_top_left = 6 -corner_radius_top_right = 6 -corner_radius_bottom_right = 6 -corner_radius_bottom_left = 6 +bg_color = Color(0.1615, 0.162469, 0.19, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_30fyb"] content_margin_left = 8.0 content_margin_top = 4.0 content_margin_right = 8.0 content_margin_bottom = 4.0 -bg_color = Color(0.403922, 0.384314, 0.470588, 0.075) -border_color = Color(0.890196, 0.894118, 0.921569, 0.2) -corner_radius_top_left = 6 -corner_radius_top_right = 6 -corner_radius_bottom_right = 6 -corner_radius_bottom_left = 6 +bg_color = Color(0.6862745, 0.27058825, 0.28235295, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_hxw5v"] content_margin_left = 8.0 content_margin_top = 4.0 content_margin_right = 8.0 content_margin_bottom = 4.0 -bg_color = Color(0.403922, 0.384314, 0.470588, 0.15) -border_color = Color(0.890196, 0.894118, 0.921569, 0.2) -corner_radius_top_left = 6 -corner_radius_top_right = 6 -corner_radius_bottom_right = 6 -corner_radius_bottom_left = 6 +bg_color = Color(0.7176471, 0.34352943, 0.35411766, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_jwwfe"] content_margin_left = 8.0 -content_margin_top = 8.0 +content_margin_top = 4.0 content_margin_right = 8.0 -content_margin_bottom = 8.0 -bg_color = Color(0.819608, 0.313726, 0.313726, 1) -border_color = Color(0.890196, 0.894118, 0.921569, 0.2) -corner_radius_top_left = 6 -corner_radius_top_right = 6 -corner_radius_bottom_right = 6 -corner_radius_bottom_left = 6 +content_margin_bottom = 4.0 +bg_color = Color(0.7176471, 0.34352943, 0.35411766, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_isxcr"] content_margin_left = 8.0 content_margin_top = 4.0 content_margin_right = 8.0 content_margin_bottom = 4.0 -bg_color = Color(0.768627, 0.180392, 0.25098, 0.05) -border_color = Color(0.890196, 0.894118, 0.921569, 0.2) -corner_radius_top_left = 6 -corner_radius_top_right = 6 -corner_radius_bottom_right = 6 -corner_radius_bottom_left = 6 +bg_color = Color(0.73333335, 0.38, 0.39000002, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_pnw2l"] content_margin_left = 8.0 content_margin_top = 4.0 content_margin_right = 8.0 content_margin_bottom = 4.0 -bg_color = Color(0.768627, 0.180392, 0.25098, 0.2) -border_color = Color(0.890196, 0.894118, 0.921569, 0.2) -corner_radius_top_left = 6 -corner_radius_top_right = 6 -corner_radius_bottom_right = 6 -corner_radius_bottom_left = 6 +bg_color = Color(0.73333335, 0.38, 0.39000002, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_qr2ui"] content_margin_left = 8.0 content_margin_top = 4.0 content_margin_right = 8.0 content_margin_bottom = 4.0 -bg_color = Color(0.768627, 0.180392, 0.25098, 0.25) -border_color = Color(0.890196, 0.894118, 0.921569, 0.2) -corner_radius_top_left = 6 -corner_radius_top_right = 6 -corner_radius_bottom_right = 6 -corner_radius_bottom_left = 6 +bg_color = Color(0.73333335, 0.38, 0.39000002, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_nxpu0"] content_margin_left = 8.0 content_margin_top = 4.0 content_margin_right = 8.0 content_margin_bottom = 4.0 -bg_color = Color(0.768627, 0.180392, 0.25098, 0.15) -border_color = Color(0.890196, 0.894118, 0.921569, 0.2) -corner_radius_top_left = 6 -corner_radius_top_right = 6 -corner_radius_bottom_right = 6 -corner_radius_bottom_left = 6 +bg_color = Color(0.73333335, 0.38, 0.39000002, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_8t50g"] -content_margin_left = 0.0 -content_margin_top = 0.0 -content_margin_right = 0.0 -content_margin_bottom = 0.0 -bg_color = Color(0.0980392, 0.0980392, 0.109804, 1) -draw_center = false -border_color = Color(0.890196, 0.894118, 0.921569, 0.2) -corner_radius_top_left = 6 -corner_radius_top_right = 6 -corner_radius_bottom_right = 6 -corner_radius_bottom_left = 6 +content_margin_left = 8.0 +content_margin_top = 4.0 +content_margin_right = 8.0 +content_margin_bottom = 4.0 +bg_color = Color(0.5380392, 0.12627451, 0.17568628, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_00o8r"] -content_margin_left = 0.0 -content_margin_top = 0.0 -content_margin_right = 0.0 -content_margin_bottom = 0.0 -bg_color = Color(0.0980392, 0.0980392, 0.109804, 1) -draw_center = false -border_color = Color(0.890196, 0.894118, 0.921569, 0.2) -corner_radius_top_left = 6 -corner_radius_top_right = 6 -corner_radius_bottom_right = 6 -corner_radius_bottom_left = 6 +content_margin_left = 8.0 +content_margin_top = 4.0 +content_margin_right = 8.0 +content_margin_bottom = 4.0 +bg_color = Color(0.5380392, 0.12627451, 0.17568628, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_a5c6f"] -content_margin_left = 0.0 -content_margin_top = 0.0 -content_margin_right = 0.0 -content_margin_bottom = 0.0 -bg_color = Color(0.0980392, 0.0980392, 0.109804, 1) -draw_center = false -border_color = Color(0.890196, 0.894118, 0.921569, 0.2) -corner_radius_top_left = 6 -corner_radius_top_right = 6 -corner_radius_bottom_right = 6 -corner_radius_bottom_left = 6 +content_margin_left = 8.0 +content_margin_top = 4.0 +content_margin_right = 8.0 +content_margin_bottom = 4.0 +bg_color = Color(0.79176474, 0.26235294, 0.32588238, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_vsni6"] -content_margin_left = 0.0 -content_margin_top = 0.0 -content_margin_right = 0.0 -content_margin_bottom = 0.0 -bg_color = Color(0.0980392, 0.0980392, 0.109804, 1) -draw_center = false -border_color = Color(0.890196, 0.894118, 0.921569, 0.2) -corner_radius_top_left = 6 -corner_radius_top_right = 6 -corner_radius_bottom_right = 6 -corner_radius_bottom_left = 6 +content_margin_left = 8.0 +content_margin_top = 4.0 +content_margin_right = 8.0 +content_margin_bottom = 4.0 +bg_color = Color(0.79176474, 0.26235294, 0.32588238, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_2fovc"] content_margin_left = 8.0 -content_margin_top = 8.0 +content_margin_top = 4.0 content_margin_right = 8.0 -content_margin_bottom = 8.0 -bg_color = Color(0.403922, 0.384314, 0.470588, 0.075) -border_color = Color(0.890196, 0.894118, 0.921569, 0.2) -corner_radius_top_left = 6 -corner_radius_top_right = 6 -corner_radius_bottom_right = 6 -corner_radius_bottom_left = 6 +content_margin_bottom = 4.0 +bg_color = Color(0.80333334, 0.30333334, 0.36333334, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_25yn7"] -content_margin_left = 0.0 -content_margin_top = 0.0 -content_margin_right = 0.0 -content_margin_bottom = 0.0 -bg_color = Color(0.182745, 0.182157, 0.206275, 1) -border_color = Color(0.890196, 0.894118, 0.921569, 0.2) +content_margin_left = 8.0 +content_margin_top = 4.0 +content_margin_right = 8.0 +content_margin_bottom = 4.0 +bg_color = Color(0.80333334, 0.30333334, 0.36333334, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_vvgve"] content_margin_left = 8.0 -content_margin_top = 8.0 +content_margin_top = 4.0 content_margin_right = 8.0 -content_margin_bottom = 8.0 -bg_color = Color(0.182745, 0.182157, 0.206275, 1) -border_width_left = 1 -border_color = Color(0.890196, 0.894118, 0.921569, 0.2) +content_margin_bottom = 4.0 +bg_color = Color(0.76862746, 0.18039216, 0.2509804, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_7fun3"] +content_margin_left = 8.0 +content_margin_top = 4.0 +content_margin_right = 8.0 +content_margin_bottom = 4.0 +bg_color = Color(0.80333334, 0.30333334, 0.36333334, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_wlc2a"] +content_margin_left = 8.0 +content_margin_top = 4.0 +content_margin_right = 8.0 +content_margin_bottom = 4.0 +bg_color = Color(0.80333334, 0.30333334, 0.36333334, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_0ta60"] content_margin_left = 0.0 content_margin_top = 0.0 content_margin_right = 0.0 content_margin_bottom = 0.0 -bg_color = Color(0.182745, 0.182157, 0.206275, 1) -border_color = Color(0.890196, 0.894118, 0.921569, 0.2) -expand_margin_left = 7.0 -expand_margin_top = 8.0 -expand_margin_right = 8.0 -expand_margin_bottom = 8.0 +draw_center = false +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_wlc2a"] +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_1uy7d"] +content_margin_left = 4.0 +content_margin_top = 4.0 +content_margin_right = 4.0 +content_margin_bottom = 4.0 +bg_color = Color(0.16707191, 0.16704, 0.183, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_6hq17"] +content_margin_left = 4.0 +content_margin_top = 4.0 +content_margin_right = 4.0 +content_margin_bottom = 4.0 +bg_color = Color(0.1615, 0.162469, 0.19, 1) + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_8qegs"] +content_margin_left = 4.0 +content_margin_top = 4.0 +content_margin_right = 4.0 +content_margin_bottom = 4.0 +bg_color = Color(0.123233594, 0.1232, 0.14, 1) +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.123233594, 0.1232, 0.14, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_qd482"] +content_margin_left = 4.0 +content_margin_top = 4.0 +content_margin_right = 4.0 +content_margin_bottom = 4.0 +bg_color = Color(0.123233594, 0.1232, 0.14, 1) +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.123233594, 0.1232, 0.14, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_85xuj"] content_margin_left = 8.0 -content_margin_top = 8.0 +content_margin_top = 4.0 content_margin_right = 8.0 -content_margin_bottom = 8.0 -bg_color = Color(0.403922, 0.384314, 0.470588, 0.1) -border_width_left = 1 -border_width_top = 1 -border_width_right = 1 -border_width_bottom = 1 -border_color = Color(0.890196, 0.894118, 0.921569, 0.25) -corner_radius_top_left = 6 -corner_radius_top_right = 6 -corner_radius_bottom_right = 6 -corner_radius_bottom_left = 6 +content_margin_bottom = 4.0 +bg_color = Color(0.1615, 0.162469, 0.19, 1) +draw_center = false +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_0ta60"] +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_qccfg"] +content_margin_left = 4.0 +content_margin_top = 4.0 +content_margin_right = 4.0 +content_margin_bottom = 4.0 +bg_color = Color(0.123233594, 0.1232, 0.14, 1) +border_width_left = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.123233594, 0.1232, 0.14, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_a8gsr"] +content_margin_left = 4.0 +content_margin_top = 4.0 +content_margin_right = 4.0 +content_margin_bottom = 4.0 +bg_color = Color(0.123233594, 0.1232, 0.14, 1) +border_width_left = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.123233594, 0.1232, 0.14, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_8epah"] content_margin_left = 8.0 -content_margin_top = 8.0 +content_margin_top = 4.0 content_margin_right = 8.0 -content_margin_bottom = 8.0 -bg_color = Color(1, 1, 1, 0) -border_width_left = 1 +content_margin_bottom = 4.0 +bg_color = Color(0.123233594, 0.1232, 0.14, 1) border_width_top = 1 -border_width_right = 1 -border_width_bottom = 1 -border_color = Color(0.890196, 0.894118, 0.921569, 0.15) -corner_radius_top_left = 6 -corner_radius_top_right = 6 -corner_radius_bottom_right = 6 -corner_radius_bottom_left = 6 +border_color = Color(1, 1, 1, 0) +corner_radius_top_left = 2 +corner_radius_top_right = 2 -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_1uy7d"] +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_j2kio"] +content_margin_left = 4.0 +content_margin_top = 4.0 +content_margin_right = 4.0 +content_margin_bottom = 0.0 +bg_color = Color(0.1615, 0.162469, 0.19, 1) +border_color = Color(0.123233594, 0.1232, 0.14, 1) + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_q56mj"] +content_margin_left = 4.0 +content_margin_top = 4.0 +content_margin_right = 4.0 +content_margin_bottom = 0.0 +bg_color = Color(0.1615, 0.162469, 0.19, 1) +border_color = Color(0.123233594, 0.1232, 0.14, 1) + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_hvbmk"] content_margin_left = 8.0 content_margin_top = 8.0 content_margin_right = 8.0 content_margin_bottom = 8.0 +bg_color = Color(0.123233594, 0.1232, 0.14, 1) +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.123233594, 0.1232, 0.14, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_lvjcx"] +content_margin_left = 4.0 +content_margin_top = 4.0 +content_margin_right = 4.0 +content_margin_bottom = 4.0 +bg_color = Color(0.17827001, 0.17921962, 0.2062, 1) +draw_center = false +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.8901961, 0.89411765, 0.92156863, 0.5) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_qi7n2"] +content_margin_left = 4.0 +content_margin_top = 4.0 +content_margin_right = 4.0 +content_margin_bottom = 4.0 +bg_color = Color(0.203425, 0.20434555, 0.2305, 1) +draw_center = false +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.8901961, 0.89411765, 0.92156863, 0.6) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_kp0xv"] +content_margin_left = 4.0 +content_margin_top = 4.0 +content_margin_right = 4.0 +content_margin_bottom = 4.0 bg_color = Color(1, 1, 1, 0) -border_width_left = 1 -border_width_top = 1 -border_width_right = 1 -border_width_bottom = 1 -border_color = Color(0.890196, 0.894118, 0.921569, 0.15) -corner_radius_top_left = 6 -corner_radius_top_right = 6 -corner_radius_bottom_right = 6 -corner_radius_bottom_left = 6 +draw_center = false +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.8901961, 0.89411765, 0.92156863, 0.3) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_6hq17"] +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_sdjsm"] content_margin_left = 0.0 content_margin_top = 0.0 content_margin_right = 0.0 content_margin_bottom = 0.0 -bg_color = Color(0.0980392, 0.0980392, 0.109804, 1) -border_color = Color(0.890196, 0.894118, 0.921569, 0.2) +bg_color = Color(0.089999996, 0.09064, 0.1, 1) -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_8qegs"] -content_margin_left = 8.0 -content_margin_top = 8.0 -content_margin_right = 8.0 -content_margin_bottom = 8.0 -bg_color = Color(0.182745, 0.182157, 0.206275, 1) -border_width_left = 1 -border_width_right = 1 -border_width_bottom = 1 -border_color = Color(0.890196, 0.894118, 0.921569, 0.2) -corner_radius_bottom_right = 6 -corner_radius_bottom_left = 6 +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_eudc8"] +content_margin_left = 4.0 +content_margin_top = 4.0 +content_margin_right = 4.0 +content_margin_bottom = 4.0 +bg_color = Color(0.123233594, 0.1232, 0.14, 1) +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.123233594, 0.1232, 0.14, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 shadow_color = Color(0, 0, 0, 0.15) -shadow_size = 30 +shadow_size = 10 -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_qd482"] -content_margin_left = 8.0 -content_margin_top = 8.0 -content_margin_right = 8.0 -content_margin_bottom = 8.0 -bg_color = Color(0.182745, 0.182157, 0.206275, 1) -border_width_left = 1 -border_width_right = 1 -border_width_bottom = 1 -border_color = Color(0.890196, 0.894118, 0.921569, 0.3) -corner_radius_bottom_right = 6 -corner_radius_bottom_left = 6 +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_xm1xm"] +content_margin_left = 4.0 +content_margin_top = 4.0 +content_margin_right = 4.0 +content_margin_bottom = 4.0 +bg_color = Color(0.123233594, 0.1232, 0.14, 1) +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.21091023, 0.21088001, 0.22600001, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 shadow_color = Color(0, 0, 0, 0.15) -shadow_size = 30 +shadow_size = 10 -[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_85xuj"] +[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_qhjh4"] -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_qccfg"] -content_margin_left = 8.0 -content_margin_top = 8.0 -content_margin_right = 8.0 -content_margin_bottom = 8.0 -bg_color = Color(0.0980392, 0.0980392, 0.109804, 1) -border_width_left = 1 -border_width_top = 1 -border_width_right = 1 -border_color = Color(0.890196, 0.894118, 0.921569, 0.2) -corner_radius_top_left = 6 -corner_radius_top_right = 6 -shadow_color = Color(0, 0, 0, 0.15) -shadow_size = 30 +[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_txkog"] -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_a8gsr"] -content_margin_left = 8.0 -content_margin_top = 8.0 -content_margin_right = 8.0 -content_margin_bottom = 8.0 -bg_color = Color(0.0980392, 0.0980392, 0.109804, 1) -border_width_left = 1 -border_width_top = 1 -border_width_right = 1 -border_color = Color(0.890196, 0.894118, 0.921569, 0.3) -corner_radius_top_left = 6 -corner_radius_top_right = 6 -shadow_color = Color(0, 0, 0, 0.15) -shadow_size = 30 +[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_axeq1"] -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_8epah"] -content_margin_left = 8.0 -content_margin_top = 8.0 -content_margin_right = 8.0 -content_margin_bottom = 8.0 -bg_color = Color(0.182745, 0.182157, 0.206275, 1) -border_color = Color(0.890196, 0.894118, 0.921569, 0.2) -corner_radius_top_left = 6 -corner_radius_top_right = 6 -corner_radius_bottom_right = 6 -corner_radius_bottom_left = 6 - -[sub_resource type="StyleBoxTexture" id="StyleBoxTexture_j2kio"] +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_qd60x"] +content_margin_left = 4.0 +content_margin_top = 4.0 +content_margin_right = 4.0 +content_margin_bottom = 4.0 +bg_color = Color(0.123233594, 0.1232, 0.14, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxTexture" id="StyleBoxTexture_poo5t"] texture = ExtResource("6_6ojxv") texture_margin_top = 1.0 axis_stretch_horizontal = 2 axis_stretch_vertical = 2 -modulate_color = Color(0.890196, 0.894118, 0.921569, 0.2) +modulate_color = Color(0.123233594, 0.1232, 0.14, 1) -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_q56mj"] -content_margin_left = 8.0 -content_margin_top = 8.0 -content_margin_right = 8.0 -content_margin_bottom = 8.0 -bg_color = Color(0.324235, 0.324549, 0.349333, 1) -border_color = Color(0.890196, 0.894118, 0.921569, 0.2) +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_blikl"] +content_margin_left = 4.0 +content_margin_top = 4.0 +content_margin_right = 4.0 +content_margin_bottom = 4.0 +bg_color = Color(0.123233594, 0.1232, 0.14, 1) corner_radius_top_left = 5 corner_radius_top_right = 5 corner_radius_bottom_right = 5 corner_radius_bottom_left = 5 -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_hvbmk"] +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_v58ty"] content_margin_left = 2.0 content_margin_top = 2.0 content_margin_right = 2.0 content_margin_bottom = 2.0 -bg_color = Color(0.0980392, 0.0980392, 0.109804, 1) draw_center = false -border_color = Color(0.324235, 0.324549, 0.349333, 1) +border_color = Color(0.123233594, 0.1232, 0.14, 1) -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_lvjcx"] +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_yj5pq"] content_margin_left = 2.0 content_margin_top = 2.0 content_margin_right = 2.0 content_margin_bottom = 2.0 -bg_color = Color(0.0980392, 0.0980392, 0.109804, 1) -border_color = Color(0.324235, 0.324549, 0.349333, 1) +border_color = Color(0.123233594, 0.1232, 0.14, 1) -[sub_resource type="StyleBoxLine" id="StyleBoxLine_qi7n2"] -color = Color(0.890196, 0.894118, 0.921569, 0.2) +[sub_resource type="StyleBoxLine" id="StyleBoxLine_y6go5"] +color = Color(0.123233594, 0.1232, 0.14, 1) grow_begin = 0.0 grow_end = 0.0 -[sub_resource type="StyleBoxLine" id="StyleBoxLine_kp0xv"] -color = Color(0.890196, 0.894118, 0.921569, 0.2) -grow_begin = 8.0 -grow_end = 8.0 +[sub_resource type="StyleBoxLine" id="StyleBoxLine_kik2p"] +color = Color(0.123233594, 0.1232, 0.14, 1) +grow_begin = 4.0 +grow_end = 4.0 -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_sdjsm"] +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_huxsq"] content_margin_top = 5.0 -bg_color = Color(0.819608, 0.313726, 0.313726, 1) +bg_color = Color(0.6862745, 0.27058825, 0.28235295, 1) corner_radius_top_left = 5 corner_radius_top_right = 5 corner_radius_bottom_right = 5 corner_radius_bottom_left = 5 -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_eudc8"] +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_6yqil"] content_margin_top = 5.0 -bg_color = Color(0.662745, 0.658824, 0.752941, 0.15) +bg_color = Color(0.1615, 0.162469, 0.19, 1) corner_radius_top_left = 5 corner_radius_top_right = 5 corner_radius_bottom_right = 5 corner_radius_bottom_left = 5 -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_xm1xm"] -content_margin_left = 8.0 -content_margin_top = 8.0 -content_margin_right = 8.0 -content_margin_bottom = 8.0 -bg_color = Color(0.0980392, 0.0980392, 0.109804, 1) +[sub_resource type="Texture2D" id="Texture2D_j1x70"] +resource_local_to_scene = false +resource_name = "" + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_5eo3a"] +content_margin_left = 4.0 +content_margin_top = 4.0 +content_margin_right = 4.0 +content_margin_bottom = 4.0 +bg_color = Color(0.123233594, 0.1232, 0.14, 1) + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_l5wh6"] +content_margin_left = 0.0 +content_margin_top = 0.0 +content_margin_right = 0.0 +content_margin_bottom = 0.0 +bg_color = Color(0.123233594, 0.1232, 0.14, 1) +expand_margin_left = 3.0 +expand_margin_top = 4.0 +expand_margin_right = 4.0 +expand_margin_bottom = 4.0 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_c4a6a"] +content_margin_left = 4.0 +content_margin_top = 4.0 +content_margin_right = 4.0 +content_margin_bottom = 4.0 draw_center = false -border_color = Color(0.890196, 0.894118, 0.921569, 0.2) -corner_radius_top_left = 6 -corner_radius_top_right = 6 -corner_radius_bottom_right = 6 -corner_radius_bottom_left = 6 +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_qhjh4"] +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_xlkkc"] content_margin_left = 0.0 content_margin_top = 0.0 content_margin_right = 0.0 content_margin_bottom = 0.0 -bg_color = Color(0.0980392, 0.0980392, 0.109804, 1) draw_center = false -border_color = Color(0.890196, 0.894118, 0.921569, 0.2) -corner_radius_top_left = 6 -corner_radius_top_right = 6 -corner_radius_bottom_right = 6 -corner_radius_bottom_left = 6 +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_txkog"] +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_qdp3q"] content_margin_left = 8.0 content_margin_top = 4.0 content_margin_right = 8.0 content_margin_bottom = 4.0 -bg_color = Color(0.662745, 0.658824, 0.752941, 0.05) -border_color = Color(0.890196, 0.894118, 0.921569, 0.2) -corner_radius_top_left = 6 -corner_radius_top_right = 6 -corner_radius_bottom_right = 6 -corner_radius_bottom_left = 6 +bg_color = Color(0.12920001, 0.1299752, 0.152, 1) +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.123233594, 0.1232, 0.14, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_axeq1"] +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_s45bh"] content_margin_left = 8.0 content_margin_top = 4.0 content_margin_right = 8.0 content_margin_bottom = 4.0 -bg_color = Color(0.403922, 0.384314, 0.470588, 0.15) +bg_color = Color(0.1615, 0.162469, 0.19, 1) draw_center = false border_width_left = 1 border_width_top = 1 border_width_right = 1 border_width_bottom = 1 -border_color = Color(0.890196, 0.894118, 0.921569, 0.2) -corner_radius_top_left = 6 -corner_radius_top_right = 6 -corner_radius_bottom_right = 6 -corner_radius_bottom_left = 6 +border_color = Color(0.123233594, 0.1232, 0.14, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_qd60x"] -content_margin_left = 8.0 -content_margin_top = 4.0 -content_margin_right = 8.0 -content_margin_bottom = 4.0 -bg_color = Color(0.403922, 0.384314, 0.470588, 0.15) -border_color = Color(0.890196, 0.894118, 0.921569, 0.2) -corner_radius_top_left = 6 -corner_radius_top_right = 6 -corner_radius_bottom_right = 6 -corner_radius_bottom_left = 6 - -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_poo5t"] +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_raufu"] content_margin_left = 8.0 content_margin_top = 4.0 content_margin_right = 8.0 content_margin_bottom = 4.0 -bg_color = Color(0.662745, 0.658824, 0.752941, 0.05) -border_color = Color(0.890196, 0.894118, 0.921569, 0.2) -corner_radius_top_left = 6 -corner_radius_top_right = 6 -corner_radius_bottom_right = 6 -corner_radius_bottom_left = 6 +bg_color = Color(0.1615, 0.162469, 0.19, 1) +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.123233594, 0.1232, 0.14, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_blikl"] +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_e7orh"] content_margin_left = 8.0 content_margin_top = 4.0 content_margin_right = 8.0 content_margin_bottom = 4.0 -bg_color = Color(0.0980392, 0.0980392, 0.109804, 1) +bg_color = Color(0.123233594, 0.1232, 0.14, 1) border_width_left = 1 border_width_top = 1 border_width_right = 1 border_width_bottom = 1 -border_color = Color(0.890196, 0.894118, 0.921569, 0.2) -corner_radius_top_left = 6 -corner_radius_top_right = 6 -corner_radius_bottom_right = 6 -corner_radius_bottom_left = 6 +border_color = Color(0.123233594, 0.1232, 0.14, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_v58ty"] +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_eggpx"] content_margin_left = 8.0 content_margin_top = 4.0 content_margin_right = 8.0 content_margin_bottom = 4.0 -bg_color = Color(0.403922, 0.384314, 0.470588, 0.15) -border_color = Color(0.890196, 0.894118, 0.921569, 0.2) -corner_radius_top_left = 6 -corner_radius_top_right = 6 -corner_radius_bottom_right = 6 -corner_radius_bottom_left = 6 +bg_color = Color(0.1615, 0.162469, 0.19, 1) +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.123233594, 0.1232, 0.14, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_yj5pq"] -content_margin_left = 8.0 -content_margin_top = 4.0 -content_margin_right = 8.0 -content_margin_bottom = 4.0 -bg_color = Color(0.0980392, 0.0980392, 0.109804, 1) -border_color = Color(0.890196, 0.894118, 0.921569, 0.2) -corner_radius_top_left = 6 -corner_radius_top_right = 6 -corner_radius_bottom_right = 6 -corner_radius_bottom_left = 6 +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_tm0m6"] +content_margin_left = 4.0 +content_margin_top = 2.0 +content_margin_right = 4.0 +content_margin_bottom = 2.0 +bg_color = Color(0.123233594, 0.1232, 0.14, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_y6go5"] +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_c1m33"] content_margin_left = 8.0 content_margin_top = 4.0 content_margin_right = 8.0 content_margin_bottom = 4.0 -bg_color = Color(0.403922, 0.384314, 0.470588, 0.05) -border_color = Color(0.890196, 0.894118, 0.921569, 0.2) -corner_radius_top_left = 6 -corner_radius_top_right = 6 -corner_radius_bottom_right = 6 -corner_radius_bottom_left = 6 - -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_kik2p"] -content_margin_left = 8.0 +bg_color = Color(0.12920001, 0.1299752, 0.152, 1) +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.123233594, 0.1232, 0.14, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_3f21d"] +content_margin_left = 4.0 content_margin_top = 4.0 -content_margin_right = 8.0 +content_margin_right = 4.0 content_margin_bottom = 4.0 -bg_color = Color(0.403922, 0.384314, 0.470588, 0.2) -border_color = Color(0.890196, 0.894118, 0.921569, 0.2) -corner_radius_top_left = 6 -corner_radius_top_right = 6 -corner_radius_bottom_right = 6 -corner_radius_bottom_left = 6 +draw_center = false +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_huxsq"] +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_j02or"] content_margin_left = 8.0 content_margin_top = 4.0 content_margin_right = 8.0 content_margin_bottom = 4.0 -bg_color = Color(0.403922, 0.384314, 0.470588, 0.25) -border_color = Color(0.890196, 0.894118, 0.921569, 0.2) -corner_radius_top_left = 6 -corner_radius_top_right = 6 -corner_radius_bottom_right = 6 -corner_radius_bottom_left = 6 +bg_color = Color(0.203425, 0.20434555, 0.2305, 1) +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.123233594, 0.1232, 0.14, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_6yqil"] +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_78rkj"] content_margin_left = 8.0 content_margin_top = 4.0 content_margin_right = 8.0 content_margin_bottom = 4.0 -bg_color = Color(0.403922, 0.384314, 0.470588, 0.15) -border_color = Color(0.890196, 0.894118, 0.921569, 0.2) -corner_radius_top_left = 6 -corner_radius_top_right = 6 -corner_radius_bottom_right = 6 -corner_radius_bottom_left = 6 - -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_j1x70"] -content_margin_left = 8.0 -content_margin_top = 8.0 -content_margin_right = 8.0 -content_margin_bottom = 8.0 -bg_color = Color(0.182745, 0.182157, 0.206275, 1) -border_width_left = 1 -border_width_top = 1 -border_width_right = 1 -border_width_bottom = 1 -border_color = Color(0.256471, 0.257255, 0.272157, 1) -corner_radius_top_left = 14 -corner_radius_top_right = 14 -corner_radius_bottom_right = 14 -corner_radius_bottom_left = 14 - -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_5eo3a"] -content_margin_left = 8.0 -content_margin_top = 8.0 -content_margin_right = 8.0 -content_margin_bottom = 8.0 -bg_color = Color(0.182745, 0.182157, 0.206275, 1) -border_color = Color(0.890196, 0.894118, 0.921569, 0.2) -corner_radius_top_left = 6 -corner_radius_top_right = 6 -corner_radius_bottom_right = 6 -corner_radius_bottom_left = 6 +bg_color = Color(0.24535, 0.24622211, 0.271, 1) +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.123233594, 0.1232, 0.14, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_l5wh6"] +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_61iib"] content_margin_left = 8.0 content_margin_top = 4.0 content_margin_right = 8.0 content_margin_bottom = 4.0 -bg_color = Color(0.403922, 0.384314, 0.470588, 0.15) -border_color = Color(0.890196, 0.894118, 0.921569, 0.2) -corner_radius_top_left = 6 -corner_radius_top_right = 6 -corner_radius_bottom_right = 6 -corner_radius_bottom_left = 6 +bg_color = Color(0.1615, 0.162469, 0.19, 1) +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.123233594, 0.1232, 0.14, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_c4a6a"] -content_margin_left = 8.0 -content_margin_top = 8.0 -content_margin_right = 8.0 -content_margin_bottom = 8.0 -bg_color = Color(0.182745, 0.182157, 0.206275, 1) -border_width_left = 1 -border_width_top = 1 -border_width_right = 1 -border_width_bottom = 1 -border_color = Color(0.256471, 0.257255, 0.272157, 1) -corner_radius_top_left = 6 -corner_radius_top_right = 6 -corner_radius_bottom_right = 6 -corner_radius_bottom_left = 6 - -[sub_resource type="StyleBoxLine" id="StyleBoxLine_xlkkc"] -color = Color(0.890196, 0.894118, 0.921569, 1) -grow_begin = 0.0 -grow_end = 0.0 -vertical = true - -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_qdp3q"] +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_ydnyu"] content_margin_left = 4.0 content_margin_top = 4.0 content_margin_right = 4.0 content_margin_bottom = 4.0 -bg_color = Color(0.0980392, 0.0980392, 0.109804, 1) -draw_center = false -border_color = Color(0.890196, 0.894118, 0.921569, 0.2) -corner_radius_top_left = 6 -corner_radius_top_right = 6 -corner_radius_bottom_right = 6 -corner_radius_bottom_left = 6 +bg_color = Color(0.123233594, 0.1232, 0.14, 1) +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.123233594, 0.1232, 0.14, 1) +corner_radius_top_left = 7 +corner_radius_top_right = 7 +corner_radius_bottom_right = 7 +corner_radius_bottom_left = 7 -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_s45bh"] +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_onp0e"] content_margin_left = 4.0 content_margin_top = 4.0 content_margin_right = 4.0 content_margin_bottom = 4.0 -bg_color = Color(0.662745, 0.658824, 0.752941, 0.15) -border_color = Color(0.890196, 0.894118, 0.921569, 0.2) -corner_radius_top_left = 6 -corner_radius_bottom_left = 6 +bg_color = Color(0.123233594, 0.1232, 0.14, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_raufu"] +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_olm6c"] +content_margin_left = 8.0 +content_margin_top = 4.0 +content_margin_right = 8.0 +content_margin_bottom = 4.0 +bg_color = Color(0.1615, 0.162469, 0.19, 1) +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.123233594, 0.1232, 0.14, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_k4pvp"] content_margin_left = 4.0 content_margin_top = 4.0 content_margin_right = 4.0 content_margin_bottom = 4.0 -bg_color = Color(0.662745, 0.658824, 0.752941, 0.15) -border_color = Color(0.890196, 0.894118, 0.921569, 0.2) -corner_radius_top_right = 6 -corner_radius_bottom_right = 6 +bg_color = Color(0.123233594, 0.1232, 0.14, 1) +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.123233594, 0.1232, 0.14, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxLine" id="StyleBoxLine_bdyw7"] +color = Color(0.8901961, 0.89411765, 0.92156863, 0.15) +grow_begin = 0.0 +grow_end = 0.0 +vertical = true -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_e7orh"] -content_margin_left = 0.0 -content_margin_top = 0.0 -content_margin_right = 0.0 -content_margin_bottom = 0.0 -bg_color = Color(0.662745, 0.658824, 0.752941, 0.15) +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_5aedr"] +content_margin_left = 2.0 +content_margin_top = 2.0 +content_margin_right = 2.0 +content_margin_bottom = 2.0 draw_center = false -border_color = Color(0.890196, 0.894118, 0.921569, 0.2) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_eggpx"] +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_ibb5s"] +content_margin_left = 2.0 +content_margin_top = 2.0 +content_margin_right = 2.0 +content_margin_bottom = 2.0 +bg_color = Color(0.1615, 0.162469, 0.19, 1) +corner_radius_top_left = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_341sr"] +content_margin_left = 2.0 +content_margin_top = 2.0 +content_margin_right = 2.0 +content_margin_bottom = 2.0 +bg_color = Color(0.1615, 0.162469, 0.19, 1) +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_xrd2a"] content_margin_left = 0.0 content_margin_top = 0.0 content_margin_right = 0.0 content_margin_bottom = 0.0 -bg_color = Color(0.403922, 0.384314, 0.470588, 0.15) +bg_color = Color(0.1615, 0.162469, 0.19, 1) draw_center = false -border_color = Color(0.890196, 0.894118, 0.921569, 0.2) -corner_radius_top_left = 6 -corner_radius_top_right = 6 -corner_radius_bottom_right = 6 -corner_radius_bottom_left = 6 +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.123233594, 0.1232, 0.14, 1) -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_tm0m6"] +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_muvro"] content_margin_left = 0.0 content_margin_top = 0.0 content_margin_right = 0.0 content_margin_bottom = 0.0 -bg_color = Color(0.662745, 0.658824, 0.752941, 0.075) -border_color = Color(0.890196, 0.894118, 0.921569, 0.2) -corner_radius_top_left = 6 -corner_radius_top_right = 6 -corner_radius_bottom_right = 6 -corner_radius_bottom_left = 6 +bg_color = Color(0.1615, 0.162469, 0.19, 1) +draw_center = false +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.123233594, 0.1232, 0.14, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 -[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_c1m33"] +[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_tafav"] -[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_3f21d"] +[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_hcwh5"] -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_j02or"] +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_20gek"] content_margin_left = 8.0 -content_margin_top = 8.0 +content_margin_top = 4.0 content_margin_right = 8.0 -content_margin_bottom = 8.0 -bg_color = Color(0.0980392, 0.0980392, 0.109804, 1) +content_margin_bottom = 4.0 +bg_color = Color(0.1615, 0.162469, 0.19, 1) draw_center = false border_width_right = 1 -border_color = Color(0.890196, 0.894118, 0.921569, 0.2) -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_78rkj"] +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_wxysu"] content_margin_left = 8.0 -content_margin_top = 8.0 +content_margin_top = 4.0 content_margin_right = 8.0 -content_margin_bottom = 8.0 -bg_color = Color(0.0980392, 0.0980392, 0.109804, 1) +content_margin_bottom = 4.0 +bg_color = Color(0.1615, 0.162469, 0.19, 1) draw_center = false border_width_right = 1 -border_color = Color(0.890196, 0.894118, 0.921569, 0.2) -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_61iib"] +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_bb1tf"] content_margin_left = 8.0 -content_margin_top = 8.0 +content_margin_top = 4.0 content_margin_right = 8.0 -content_margin_bottom = 8.0 -bg_color = Color(0.0980392, 0.0980392, 0.109804, 1) +content_margin_bottom = 4.0 +bg_color = Color(0.1615, 0.162469, 0.19, 1) draw_center = false border_width_right = 1 -border_color = Color(0.890196, 0.894118, 0.921569, 0.2) -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_ydnyu"] +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_bn5ll"] content_margin_left = 8.0 -content_margin_top = 8.0 +content_margin_top = 4.0 content_margin_right = 8.0 -content_margin_bottom = 8.0 -bg_color = Color(0.819608, 0.313726, 0.313726, 1) +content_margin_bottom = 4.0 +bg_color = Color(0.6862745, 0.27058825, 0.28235295, 1) border_width_right = 1 -border_color = Color(0.890196, 0.894118, 0.921569, 0.2) -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_onp0e"] +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_l4tsf"] content_margin_left = 8.0 -content_margin_top = 8.0 +content_margin_top = 4.0 content_margin_right = 8.0 -content_margin_bottom = 8.0 -bg_color = Color(0.0980392, 0.0980392, 0.109804, 1) +content_margin_bottom = 4.0 +bg_color = Color(0.1615, 0.162469, 0.19, 1) draw_center = false border_width_right = 1 -border_color = Color(0.890196, 0.894118, 0.921569, 0.2) -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_olm6c"] +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_cfrtq"] content_margin_left = 8.0 content_margin_top = 4.0 content_margin_right = 8.0 content_margin_bottom = 4.0 -bg_color = Color(0.403922, 0.384314, 0.470588, 0.15) +bg_color = Color(0.1615, 0.162469, 0.19, 1) draw_center = false border_width_left = 1 border_width_top = 1 border_width_right = 1 border_width_bottom = 1 -border_color = Color(0.890196, 0.894118, 0.921569, 0.2) -corner_radius_top_left = 6 -corner_radius_top_right = 6 -corner_radius_bottom_right = 6 -corner_radius_bottom_left = 6 +border_color = Color(0.123233594, 0.1232, 0.14, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_k4pvp"] +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_wl3tv"] content_margin_left = 8.0 content_margin_top = 4.0 content_margin_right = 8.0 content_margin_bottom = 4.0 -bg_color = Color(0.403922, 0.384314, 0.470588, 0.15) -border_color = Color(0.890196, 0.894118, 0.921569, 0.2) -corner_radius_top_left = 6 -corner_radius_top_right = 6 -corner_radius_bottom_right = 6 -corner_radius_bottom_left = 6 - -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_bdyw7"] +bg_color = Color(0.1615, 0.162469, 0.19, 1) +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.123233594, 0.1232, 0.14, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_nj65x"] content_margin_left = 8.0 content_margin_top = 4.0 content_margin_right = 8.0 content_margin_bottom = 4.0 -bg_color = Color(0.662745, 0.658824, 0.752941, 0.05) -border_color = Color(0.890196, 0.894118, 0.921569, 0.2) -corner_radius_top_left = 6 -corner_radius_top_right = 6 -corner_radius_bottom_right = 6 -corner_radius_bottom_left = 6 - -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_5aedr"] -content_margin_left = 8.0 -content_margin_top = 8.0 -content_margin_right = 8.0 -content_margin_bottom = 8.0 -bg_color = Color(0.182745, 0.182157, 0.206275, 1) -border_width_right = 1 +bg_color = Color(0.12920001, 0.1299752, 0.152, 1) +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.123233594, 0.1232, 0.14, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_wlq5o"] +content_margin_left = 4.0 +content_margin_top = 4.0 +content_margin_right = 4.0 +content_margin_bottom = 4.0 +bg_color = Color(0.123233594, 0.1232, 0.14, 1) +border_width_right = 2 border_color = Color(0, 0, 0, 1) -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_ibb5s"] -content_margin_left = 8.0 -content_margin_top = 8.0 -content_margin_right = 8.0 -content_margin_bottom = 8.0 -bg_color = Color(0.182745, 0.182157, 0.206275, 1) -border_width_bottom = 1 +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_l8c38"] +content_margin_left = 4.0 +content_margin_top = 4.0 +content_margin_right = 4.0 +content_margin_bottom = 4.0 +bg_color = Color(0.123233594, 0.1232, 0.14, 1) +border_width_bottom = 2 border_color = Color(0, 0, 0, 1) -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_341sr"] -content_margin_left = 8.0 -content_margin_top = 8.0 -content_margin_right = 8.0 -content_margin_bottom = 8.0 -bg_color = Color(0.0980392, 0.0980392, 0.109804, 1) +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_hpmfn"] +content_margin_left = 4.0 +content_margin_top = 4.0 +content_margin_right = 4.0 +content_margin_bottom = 4.0 +bg_color = Color(0.123233594, 0.1232, 0.14, 0.5) + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_iqjph"] +content_margin_left = 4.0 +content_margin_top = 4.0 +content_margin_right = 4.0 +content_margin_bottom = 4.0 draw_center = false -border_color = Color(0.890196, 0.894118, 0.921569, 0.2) -corner_radius_top_left = 6 -corner_radius_top_right = 6 -corner_radius_bottom_right = 6 -corner_radius_bottom_left = 6 +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_xrd2a"] +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_r5cmq"] content_margin_left = 8.0 -content_margin_top = 8.0 +content_margin_top = 4.0 content_margin_right = 8.0 -content_margin_bottom = 8.0 -bg_color = Color(0.0980392, 0.0980392, 0.109804, 1) -border_color = Color(0.890196, 0.894118, 0.921569, 0.2) -corner_radius_top_left = 6 -corner_radius_top_right = 6 -corner_radius_bottom_right = 6 -corner_radius_bottom_left = 6 +content_margin_bottom = 4.0 +bg_color = Color(0.17827001, 0.17921962, 0.2062, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_muvro"] +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_7awlc"] +content_margin_left = 4.0 +content_margin_top = 4.0 +content_margin_right = 4.0 +content_margin_bottom = 4.0 +bg_color = Color(0.123233594, 0.1232, 0.14, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_pr7s7"] content_margin_left = 8.0 -content_margin_top = 8.0 +content_margin_top = 4.0 content_margin_right = 8.0 -content_margin_bottom = 8.0 -bg_color = Color(0.182745, 0.182157, 0.206275, 1) -border_color = Color(0.890196, 0.894118, 0.921569, 0.2) +content_margin_bottom = 4.0 +bg_color = Color(0.203425, 0.20434555, 0.2305, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_s188x"] +content_margin_left = 4.0 +content_margin_top = 4.0 +content_margin_right = 4.0 +content_margin_bottom = 4.0 +bg_color = Color(0.123233594, 0.1232, 0.14, 1) -[sub_resource type="StyleBoxLine" id="StyleBoxLine_tafav"] -color = Color(0.890196, 0.894118, 0.921569, 0.2) +[sub_resource type="StyleBoxLine" id="StyleBoxLine_a40tc"] +color = Color(0.123233594, 0.1232, 0.14, 1) grow_begin = 0.0 grow_end = 0.0 vertical = true +[sub_resource type="StyleBoxLine" id="StyleBoxLine_pw02n"] +color = Color(0.123233594, 0.1232, 0.14, 1) +grow_begin = 4.0 +grow_end = 4.0 +vertical = true + +[sub_resource type="Texture2D" id="Texture2D_wreqa"] +resource_local_to_scene = false +resource_name = "" + [resource] -Button/colors/font_color = Color(0.890196, 0.894118, 0.921569, 0.8) -Button/colors/font_disabled_color = Color(0.890196, 0.894118, 0.921569, 0.3) -Button/colors/font_focus_color = Color(0.890196, 0.894118, 0.921569, 1) -Button/colors/font_hover_color = Color(0.890196, 0.894118, 0.921569, 1) -Button/colors/font_hover_pressed_color = Color(0.890196, 0.894118, 0.921569, 1) -Button/colors/font_pressed_color = Color(0.890196, 0.894118, 0.921569, 1) -Button/colors/icon_disabled_color = Color(0.890196, 0.894118, 0.921569, 0.3) -Button/colors/icon_normal_color = Color(0.890196, 0.894118, 0.921569, 0.8) +Button/colors/font_color = Color(0.8901961, 0.89411765, 0.92156863, 0.75) +Button/colors/font_disabled_color = Color(0.8901961, 0.89411765, 0.92156863, 0.35) +Button/colors/font_focus_color = Color(0.8901961, 0.89411765, 0.92156863, 1) +Button/colors/font_hover_color = Color(0.8901961, 0.89411765, 0.92156863, 1) +Button/colors/font_hover_pressed_color = Color(0.8901961, 0.89411765, 0.92156863, 1) +Button/colors/font_pressed_color = Color(0.8901961, 0.89411765, 0.92156863, 1) +Button/colors/icon_disabled_color = Color(0.8901961, 0.89411765, 0.92156863, 0.35) +Button/colors/icon_normal_color = Color(0.8901961, 0.89411765, 0.92156863, 0.75) +Button/constants/h_separation = 4 +Button/constants/icon_max_width = 15 Button/constants/outline_size = 0 -Button/styles/disabled = SubResource("StyleBoxFlat_ks7w5") -Button/styles/disabled_mirrored = SubResource("StyleBoxFlat_ks7w5") -Button/styles/focus = SubResource("StyleBoxFlat_uqgmq") -Button/styles/hover = SubResource("StyleBoxFlat_rb0lk") -Button/styles/hover_mirrored = SubResource("StyleBoxFlat_rb0lk") -Button/styles/hover_pressed = SubResource("StyleBoxFlat_30fyb") -Button/styles/hover_pressed_mirrored = SubResource("StyleBoxFlat_30fyb") -Button/styles/normal = SubResource("StyleBoxFlat_hxw5v") -Button/styles/normal_mirrored = SubResource("StyleBoxFlat_hxw5v") -Button/styles/pressed = SubResource("StyleBoxFlat_30fyb") -Button/styles/pressed_mirrored = SubResource("StyleBoxFlat_30fyb") +Button/styles/disabled = SubResource("StyleBoxFlat_ttl1t") +Button/styles/disabled_mirrored = SubResource("StyleBoxFlat_ttl1t") +Button/styles/focus = SubResource("StyleBoxFlat_2ase2") +Button/styles/hover = SubResource("StyleBoxFlat_ks7w5") +Button/styles/hover_mirrored = SubResource("StyleBoxFlat_ks7w5") +Button/styles/hover_pressed = SubResource("StyleBoxFlat_uqgmq") +Button/styles/hover_pressed_mirrored = SubResource("StyleBoxFlat_uqgmq") +Button/styles/normal = SubResource("StyleBoxFlat_rb0lk") +Button/styles/normal_mirrored = SubResource("StyleBoxFlat_rb0lk") +Button/styles/pressed = SubResource("StyleBoxFlat_uqgmq") +Button/styles/pressed_mirrored = SubResource("StyleBoxFlat_uqgmq") ButtonAccent/base_type = &"Button" -ButtonAccent/styles/disabled = SubResource("StyleBoxFlat_jwwfe") -ButtonAccent/styles/disabled_mirrored = SubResource("StyleBoxFlat_jwwfe") -ButtonAccent/styles/focus = SubResource("StyleBoxFlat_jwwfe") -ButtonAccent/styles/hover = SubResource("StyleBoxFlat_jwwfe") +ButtonAccent/styles/disabled = SubResource("StyleBoxFlat_30fyb") +ButtonAccent/styles/disabled_mirrored = SubResource("StyleBoxFlat_30fyb") +ButtonAccent/styles/focus = SubResource("StyleBoxFlat_30fyb") +ButtonAccent/styles/hover = SubResource("StyleBoxFlat_hxw5v") ButtonAccent/styles/hover_mirrored = SubResource("StyleBoxFlat_jwwfe") -ButtonAccent/styles/hover_pressed = SubResource("StyleBoxFlat_jwwfe") -ButtonAccent/styles/hover_pressed_mirrored = SubResource("StyleBoxFlat_jwwfe") -ButtonAccent/styles/normal = SubResource("StyleBoxFlat_jwwfe") -ButtonAccent/styles/normal_mirrored = SubResource("StyleBoxFlat_jwwfe") -ButtonAccent/styles/pressed = SubResource("StyleBoxFlat_jwwfe") -ButtonAccent/styles/pressed_mirrored = SubResource("StyleBoxFlat_jwwfe") +ButtonAccent/styles/hover_pressed = SubResource("StyleBoxFlat_isxcr") +ButtonAccent/styles/hover_pressed_mirrored = SubResource("StyleBoxFlat_pnw2l") +ButtonAccent/styles/normal = SubResource("StyleBoxFlat_30fyb") +ButtonAccent/styles/normal_mirrored = SubResource("StyleBoxFlat_30fyb") +ButtonAccent/styles/pressed = SubResource("StyleBoxFlat_qr2ui") +ButtonAccent/styles/pressed_mirrored = SubResource("StyleBoxFlat_nxpu0") ButtonWarning/base_type = &"Button" ButtonWarning/constants/outline_size = 0 -ButtonWarning/styles/disabled = SubResource("StyleBoxFlat_isxcr") -ButtonWarning/styles/disabled_mirrored = SubResource("StyleBoxFlat_isxcr") -ButtonWarning/styles/focus = SubResource("StyleBoxFlat_uqgmq") -ButtonWarning/styles/hover = SubResource("StyleBoxFlat_pnw2l") -ButtonWarning/styles/hover_mirrored = SubResource("StyleBoxFlat_pnw2l") -ButtonWarning/styles/hover_pressed = SubResource("StyleBoxFlat_qr2ui") -ButtonWarning/styles/hover_pressed_mirrored = SubResource("StyleBoxFlat_qr2ui") -ButtonWarning/styles/normal = SubResource("StyleBoxFlat_nxpu0") -ButtonWarning/styles/normal_mirrored = SubResource("StyleBoxFlat_nxpu0") -ButtonWarning/styles/pressed = SubResource("StyleBoxFlat_qr2ui") -ButtonWarning/styles/pressed_mirrored = SubResource("StyleBoxFlat_qr2ui") -CheckBox/colors/font_hover_pressed_color = Color(0.890196, 0.894118, 0.921569, 1) -CheckBox/colors/font_pressed_color = Color(0.890196, 0.894118, 0.921569, 0.7) -CheckBox/constants/h_separation = 8 +ButtonWarning/styles/disabled = SubResource("StyleBoxFlat_8t50g") +ButtonWarning/styles/disabled_mirrored = SubResource("StyleBoxFlat_00o8r") +ButtonWarning/styles/focus = SubResource("StyleBoxFlat_2ase2") +ButtonWarning/styles/hover = SubResource("StyleBoxFlat_a5c6f") +ButtonWarning/styles/hover_mirrored = SubResource("StyleBoxFlat_vsni6") +ButtonWarning/styles/hover_pressed = SubResource("StyleBoxFlat_2fovc") +ButtonWarning/styles/hover_pressed_mirrored = SubResource("StyleBoxFlat_25yn7") +ButtonWarning/styles/normal = SubResource("StyleBoxFlat_vvgve") +ButtonWarning/styles/normal_mirrored = SubResource("StyleBoxFlat_vvgve") +ButtonWarning/styles/pressed = SubResource("StyleBoxFlat_7fun3") +ButtonWarning/styles/pressed_mirrored = SubResource("StyleBoxFlat_wlc2a") +CheckBox/colors/font_hover_pressed_color = Color(0.8901961, 0.89411765, 0.92156863, 1) +CheckBox/colors/font_pressed_color = Color(0.8901961, 0.89411765, 0.92156863, 0.75) +CheckBox/constants/h_separation = 4 CheckBox/icons/checked = ExtResource("1_ks7w5") CheckBox/icons/checked_disabled = ExtResource("2_uqgmq") CheckBox/icons/radio_checked = ExtResource("7_tydhh") @@ -926,138 +1144,166 @@ CheckBox/icons/radio_unchecked = ExtResource("9_2ase2") CheckBox/icons/radio_unchecked_disabled = ExtResource("10_ks7w5") CheckBox/icons/unchecked = ExtResource("7_rb0lk") CheckBox/icons/unchecked_disabled = ExtResource("8_30fyb") -CheckBox/styles/disabled = SubResource("StyleBoxFlat_8t50g") -CheckBox/styles/disabled_mirrored = SubResource("StyleBoxFlat_8t50g") -CheckBox/styles/focus = SubResource("StyleBoxFlat_00o8r") -CheckBox/styles/hover = SubResource("StyleBoxFlat_00o8r") -CheckBox/styles/hover_mirrored = SubResource("StyleBoxFlat_00o8r") -CheckBox/styles/hover_pressed = SubResource("StyleBoxFlat_a5c6f") -CheckBox/styles/hover_pressed_mirrored = SubResource("StyleBoxFlat_a5c6f") -CheckBox/styles/normal = SubResource("StyleBoxFlat_vsni6") -CheckBox/styles/normal_mirrored = SubResource("StyleBoxFlat_vsni6") -CheckBox/styles/pressed = SubResource("StyleBoxFlat_a5c6f") -CheckBox/styles/pressed_mirrored = SubResource("StyleBoxFlat_a5c6f") -CheckButton/colors/font_focus_color = Color(0.890196, 0.894118, 0.921569, 0.7) -CheckButton/colors/font_hover_pressed_color = Color(0.890196, 0.894118, 0.921569, 1) -CheckButton/colors/font_pressed_color = Color(0.890196, 0.894118, 0.921569, 1) +CheckBox/styles/disabled = SubResource("StyleBoxFlat_0ta60") +CheckBox/styles/disabled_mirrored = SubResource("StyleBoxFlat_0ta60") +CheckBox/styles/focus = SubResource("StyleBoxFlat_0ta60") +CheckBox/styles/hover = SubResource("StyleBoxFlat_0ta60") +CheckBox/styles/hover_mirrored = SubResource("StyleBoxFlat_0ta60") +CheckBox/styles/hover_pressed = SubResource("StyleBoxFlat_0ta60") +CheckBox/styles/hover_pressed_mirrored = SubResource("StyleBoxFlat_0ta60") +CheckBox/styles/normal = SubResource("StyleBoxFlat_0ta60") +CheckBox/styles/normal_mirrored = SubResource("StyleBoxFlat_0ta60") +CheckBox/styles/pressed = SubResource("StyleBoxFlat_0ta60") +CheckBox/styles/pressed_mirrored = SubResource("StyleBoxFlat_0ta60") +CheckButton/colors/font_focus_color = Color(0.8901961, 0.89411765, 0.92156863, 0.75) +CheckButton/colors/font_hover_pressed_color = Color(0.8901961, 0.89411765, 0.92156863, 1) +CheckButton/colors/font_pressed_color = Color(0.8901961, 0.89411765, 0.92156863, 1) CheckButton/icons/checked = ExtResource("2_btlbu") CheckButton/icons/unchecked = ExtResource("3_5qsde") -CheckButton/styles/disabled = SubResource("StyleBoxFlat_8t50g") -CheckButton/styles/disabled_mirrored = SubResource("StyleBoxFlat_8t50g") -CheckButton/styles/focus = SubResource("StyleBoxFlat_00o8r") -CheckButton/styles/hover = SubResource("StyleBoxFlat_00o8r") -CheckButton/styles/hover_mirrored = SubResource("StyleBoxFlat_00o8r") -CheckButton/styles/hover_pressed = SubResource("StyleBoxFlat_a5c6f") -CheckButton/styles/hover_pressed_mirrored = SubResource("StyleBoxFlat_a5c6f") -CheckButton/styles/normal = SubResource("StyleBoxFlat_vsni6") -CheckButton/styles/normal_mirrored = SubResource("StyleBoxFlat_vsni6") -CheckButton/styles/pressed = SubResource("StyleBoxFlat_a5c6f") -CheckButton/styles/pressed_mirrored = SubResource("StyleBoxFlat_a5c6f") +CheckButton/styles/disabled = SubResource("StyleBoxFlat_0ta60") +CheckButton/styles/disabled_mirrored = SubResource("StyleBoxFlat_0ta60") +CheckButton/styles/focus = SubResource("StyleBoxFlat_0ta60") +CheckButton/styles/hover = SubResource("StyleBoxFlat_0ta60") +CheckButton/styles/hover_mirrored = SubResource("StyleBoxFlat_0ta60") +CheckButton/styles/hover_pressed = SubResource("StyleBoxFlat_0ta60") +CheckButton/styles/hover_pressed_mirrored = SubResource("StyleBoxFlat_0ta60") +CheckButton/styles/normal = SubResource("StyleBoxFlat_0ta60") +CheckButton/styles/normal_mirrored = SubResource("StyleBoxFlat_0ta60") +CheckButton/styles/pressed = SubResource("StyleBoxFlat_0ta60") +CheckButton/styles/pressed_mirrored = SubResource("StyleBoxFlat_0ta60") CollapsibleFieldPanel/base_type = &"PanelContainer" -CollapsibleFieldPanel/styles/panel = SubResource("StyleBoxFlat_2fovc") +CollapsibleFieldPanel/styles/panel = SubResource("StyleBoxFlat_1uy7d") EditorBackground/base_type = &"PanelContainer" -EditorBackground/styles/panel = SubResource("StyleBoxFlat_25yn7") -EditorSidePanel/base_type = &"PanelContainer" -EditorSidePanel/styles/panel = SubResource("StyleBoxFlat_vvgve") -EditorSidePanelTopBox/base_type = &"PanelContainer" -EditorSidePanelTopBox/styles/panel = SubResource("StyleBoxFlat_7fun3") +EditorBackground/styles/panel = SubResource("StyleBoxFlat_6hq17") +EditorSection/base_type = &"TabContainer" +EditorSection/colors/font_disabled_color = Color(0.8901961, 0.89411765, 0.92156863, 0.35) +EditorSection/colors/font_hover_color = Color(0.8901961, 0.89411765, 0.92156863, 1) +EditorSection/colors/font_selected_color = Color(0.8901961, 0.89411765, 0.92156863, 1) +EditorSection/colors/font_unselected_color = Color(0.8901961, 0.89411765, 0.92156863, 0.75) +EditorSection/constants/icon_max_width = 16 +EditorSection/constants/icon_separation = 4 +EditorSection/constants/side_margin = 1 +EditorSection/font_sizes/font_size = 16 +EditorSection/styles/panel_focus = SubResource("StyleBoxFlat_8qegs") +EditorSection/styles/panel_unfocus = SubResource("StyleBoxFlat_qd482") +EditorSection/styles/tab_disabled = SubResource("StyleBoxFlat_85xuj") +EditorSection/styles/tab_focus = SubResource("StyleBoxFlat_85xuj") +EditorSection/styles/tab_hovered = SubResource("StyleBoxFlat_85xuj") +EditorSection/styles/tab_panel_focus = SubResource("StyleBoxFlat_qccfg") +EditorSection/styles/tab_panel_unfocus = SubResource("StyleBoxFlat_a8gsr") +EditorSection/styles/tab_selected = SubResource("StyleBoxFlat_8epah") +EditorSection/styles/tab_unselected = SubResource("StyleBoxFlat_85xuj") +EditorSection/styles/tabbar_background_focus = SubResource("StyleBoxFlat_j2kio") +EditorSection/styles/tabbar_background_unfocus = SubResource("StyleBoxFlat_q56mj") FieldContainer/base_type = &"VBoxContainer" -FieldContainer/constants/separation = 4 -FlatButton/colors/font_color = Color(0.890196, 0.894118, 0.921569, 0.8) -FlatButton/colors/font_disabled_color = Color(0.890196, 0.894118, 0.921569, 0.3) -FlatButton/colors/font_focus_color = Color(0.890196, 0.894118, 0.921569, 1) -FlatButton/colors/font_hover_color = Color(0.890196, 0.894118, 0.921569, 1) -FlatButton/colors/font_hover_pressed_color = Color(0.890196, 0.894118, 0.921569, 1) -FlatButton/colors/font_pressed_color = Color(0.890196, 0.894118, 0.921569, 1) -FlatButton/colors/icon_disabled_color = Color(0.890196, 0.894118, 0.921569, 0.3) -FlatButton/colors/icon_normal_color = Color(0.890196, 0.894118, 0.921569, 0.8) +FieldContainer/constants/separation = 2 +FieldPanel/base_type = &"PanelContainer" +FieldPanel/styles/panel = SubResource("StyleBoxFlat_hvbmk") +FlatButton/colors/font_color = Color(0.8901961, 0.89411765, 0.92156863, 0.75) +FlatButton/colors/font_disabled_color = Color(0.8901961, 0.89411765, 0.92156863, 0.35) +FlatButton/colors/font_focus_color = Color(0.8901961, 0.89411765, 0.92156863, 1) +FlatButton/colors/font_hover_color = Color(0.8901961, 0.89411765, 0.92156863, 1) +FlatButton/colors/font_hover_pressed_color = Color(0.8901961, 0.89411765, 0.92156863, 1) +FlatButton/colors/font_pressed_color = Color(0.8901961, 0.89411765, 0.92156863, 1) +FlatButton/colors/icon_disabled_color = Color(0.8901961, 0.89411765, 0.92156863, 0.35) +FlatButton/colors/icon_normal_color = Color(0.8901961, 0.89411765, 0.92156863, 0.75) FlatButton/constants/outline_size = 0 -FlatButton/styles/disabled = SubResource("StyleBoxFlat_ks7w5") -FlatButton/styles/disabled_mirrored = SubResource("StyleBoxFlat_ks7w5") -FlatButton/styles/hover = SubResource("StyleBoxFlat_wlc2a") -FlatButton/styles/hover_mirrored = SubResource("StyleBoxFlat_wlc2a") -FlatButton/styles/hover_pressed = SubResource("StyleBoxFlat_0ta60") -FlatButton/styles/hover_pressed_mirrored = SubResource("StyleBoxFlat_0ta60") -FlatButton/styles/normal = SubResource("StyleBoxFlat_1uy7d") -FlatButton/styles/normal_mirrored = SubResource("StyleBoxFlat_1uy7d") -FlatButton/styles/pressed = SubResource("StyleBoxFlat_0ta60") -FlatButton/styles/pressed_mirrored = SubResource("StyleBoxFlat_0ta60") -GraphEdit/colors/grid_major = Color(0.890196, 0.894118, 0.921569, 0.15) -GraphEdit/colors/grid_minor = Color(0.890196, 0.894118, 0.921569, 0.15) -GraphEdit/styles/panel = SubResource("StyleBoxFlat_6hq17") -GraphNode/constants/separation = 8 -GraphNode/icons/port = ExtResource("1_yjacf") -GraphNode/styles/panel = SubResource("StyleBoxFlat_8qegs") -GraphNode/styles/panel_selected = SubResource("StyleBoxFlat_qd482") -GraphNode/styles/slot = SubResource("StyleBoxEmpty_85xuj") -GraphNode/styles/titlebar = SubResource("StyleBoxFlat_qccfg") -GraphNode/styles/titlebar_selected = SubResource("StyleBoxFlat_a8gsr") +FlatButton/styles/disabled = SubResource("StyleBoxFlat_ttl1t") +FlatButton/styles/disabled_mirrored = SubResource("StyleBoxFlat_ttl1t") +FlatButton/styles/hover = SubResource("StyleBoxFlat_lvjcx") +FlatButton/styles/hover_mirrored = SubResource("StyleBoxFlat_lvjcx") +FlatButton/styles/hover_pressed = SubResource("StyleBoxFlat_qi7n2") +FlatButton/styles/hover_pressed_mirrored = SubResource("StyleBoxFlat_qi7n2") +FlatButton/styles/normal = SubResource("StyleBoxFlat_kp0xv") +FlatButton/styles/normal_mirrored = SubResource("StyleBoxFlat_kp0xv") +FlatButton/styles/pressed = SubResource("StyleBoxFlat_qi7n2") +FlatButton/styles/pressed_mirrored = SubResource("StyleBoxFlat_qi7n2") +GraphEdit/colors/grid_major = Color(0.8901961, 0.89411765, 0.92156863, 0.15) +GraphEdit/colors/grid_minor = Color(0.8901961, 0.89411765, 0.92156863, 0.15) +GraphEdit/styles/panel = SubResource("StyleBoxFlat_sdjsm") +GraphNode/constants/separation = 4 +GraphNode/styles/panel = SubResource("StyleBoxFlat_eudc8") +GraphNode/styles/panel_selected = SubResource("StyleBoxFlat_xm1xm") +GraphNode/styles/slot = SubResource("StyleBoxEmpty_qhjh4") +GraphNode/styles/titlebar = SubResource("StyleBoxEmpty_txkog") +GraphNode/styles/titlebar_selected = SubResource("StyleBoxEmpty_axeq1") GraphNodePicker/base_type = &"PanelContainer" -GraphNodePicker/styles/panel = SubResource("StyleBoxFlat_8epah") -HBoxContainer/constants/separation = 8 +GraphNodePicker/styles/panel = SubResource("StyleBoxFlat_qd60x") +GraphNodeTitleLabel/font_sizes/font_size = 1 +GraphNodeViewRownHBox/base_type = &"HBoxContainer" +GraphNodeViewRownHBox/constants/separation = 20 +GraphNodeViewTitleLabel/base_type = &"Label" +GraphNodeViewTitleLabel/colors/font_color = Color(0.8901961, 0.89411765, 0.92156863, 1) +GraphNodeViewTitleLabel/font_sizes/font_size = 18 +GraphNodeViewValueLabel/base_type = &"Label" +GraphNodeViewValueLabel/colors/font_color = Color(0.8901961, 0.89411765, 0.92156863, 0.5) +GraphNodeViewValueLabel/font_sizes/font_size = 16 +HBoxContainer/constants/separation = 4 HDottedSeparator/base_type = &"HSeparator" HDottedSeparator/constants/separation = 1 -HDottedSeparator/styles/separator = SubResource("StyleBoxTexture_j2kio") -HScrollBar/styles/grabber = SubResource("StyleBoxFlat_q56mj") -HScrollBar/styles/grabber_highlight = SubResource("StyleBoxFlat_q56mj") -HScrollBar/styles/grabber_pressed = SubResource("StyleBoxFlat_q56mj") -HScrollBar/styles/scroll = SubResource("StyleBoxFlat_hvbmk") -HScrollBar/styles/scroll_focus = SubResource("StyleBoxFlat_lvjcx") +HDottedSeparator/styles/separator = SubResource("StyleBoxTexture_poo5t") +HScrollBar/styles/grabber = SubResource("StyleBoxFlat_blikl") +HScrollBar/styles/grabber_highlight = SubResource("StyleBoxFlat_blikl") +HScrollBar/styles/grabber_pressed = SubResource("StyleBoxFlat_blikl") +HScrollBar/styles/scroll = SubResource("StyleBoxFlat_v58ty") +HScrollBar/styles/scroll_focus = SubResource("StyleBoxFlat_yj5pq") HSeparator/constants/separation = 1 -HSeparator/styles/separator = SubResource("StyleBoxLine_qi7n2") +HSeparator/styles/separator = SubResource("StyleBoxLine_y6go5") HSeparatorGrow/base_type = &"HSeparator" HSeparatorGrow/constants/separation = 1 -HSeparatorGrow/styles/separator = SubResource("StyleBoxLine_kp0xv") +HSeparatorGrow/styles/separator = SubResource("StyleBoxLine_kik2p") HSlider/icons/grabber = ExtResource("4_gye7x") HSlider/icons/grabber_disabled = ExtResource("4_gye7x") HSlider/icons/grabber_highlight = ExtResource("4_gye7x") -HSlider/styles/grabber_area = SubResource("StyleBoxFlat_sdjsm") -HSlider/styles/grabber_area_highlight = SubResource("StyleBoxFlat_sdjsm") -HSlider/styles/slider = SubResource("StyleBoxFlat_eudc8") +HSlider/styles/grabber_area = SubResource("StyleBoxFlat_huxsq") +HSlider/styles/grabber_area_highlight = SubResource("StyleBoxFlat_huxsq") +HSlider/styles/slider = SubResource("StyleBoxFlat_6yqil") +HSplitContainer/constants/separation = 4 +HSplitContainer/icons/grabber = SubResource("Texture2D_j1x70") +InspectorPanel/base_type = &"PanelContainer" +InspectorPanel/styles/panel = SubResource("StyleBoxFlat_5eo3a") +InspectorPanelTopBox/base_type = &"PanelContainer" +InspectorPanelTopBox/styles/panel = SubResource("StyleBoxFlat_l5wh6") ItemContainer/base_type = &"PanelContainer" -ItemContainer/styles/panel = SubResource("StyleBoxFlat_xm1xm") +ItemContainer/styles/panel = SubResource("StyleBoxFlat_c4a6a") ItemContainerFlat/base_type = &"PanelContainer" -ItemContainerFlat/styles/panel = SubResource("StyleBoxFlat_qhjh4") -Label/colors/font_color = Color(0.890196, 0.894118, 0.921569, 1) -LineEdit/styles/disabled = SubResource("StyleBoxFlat_txkog") -LineEdit/styles/focus = SubResource("StyleBoxFlat_axeq1") -LineEdit/styles/normal = SubResource("StyleBoxFlat_qd60x") +ItemContainerFlat/styles/panel = SubResource("StyleBoxFlat_xlkkc") +Label/colors/font_color = Color(0.8901961, 0.89411765, 0.92156863, 1) +LineEdit/styles/disabled = SubResource("StyleBoxFlat_qdp3q") +LineEdit/styles/focus = SubResource("StyleBoxFlat_s45bh") +LineEdit/styles/normal = SubResource("StyleBoxFlat_raufu") LineEditPortraitOption/base_type = &"LineEdit" -LineEditPortraitOption/colors/font_color = Color(0.890196, 0.894118, 0.921569, 1) -LineEditPortraitOption/colors/font_uneditable_color = Color(0.890196, 0.894118, 0.921569, 1) -LineEditPortraitOption/styles/disabled = SubResource("StyleBoxFlat_poo5t") -LineEditPortraitOption/styles/focus = SubResource("StyleBoxFlat_blikl") -LineEditPortraitOption/styles/normal = SubResource("StyleBoxFlat_v58ty") -MarginContainer/constants/margin_bottom = 8 -MarginContainer/constants/margin_left = 8 -MarginContainer/constants/margin_right = 8 -MarginContainer/constants/margin_top = 8 +LineEditPortraitOption/colors/font_color = Color(0.8901961, 0.89411765, 0.92156863, 1) +LineEditPortraitOption/colors/font_uneditable_color = Color(0.8901961, 0.89411765, 0.92156863, 1) +LineEditPortraitOption/styles/disabled = SubResource("StyleBoxFlat_qdp3q") +LineEditPortraitOption/styles/focus = SubResource("StyleBoxFlat_e7orh") +LineEditPortraitOption/styles/normal = SubResource("StyleBoxFlat_eggpx") NodeValue/base_type = &"Label" -NodeValue/colors/font_color = Color(0.890196, 0.894118, 0.921569, 1) -NodeValue/styles/normal = SubResource("StyleBoxFlat_yj5pq") +NodeValue/colors/font_color = Color(0.8901961, 0.89411765, 0.92156863, 1) +NodeValue/styles/normal = SubResource("StyleBoxFlat_tm0m6") NoteLabel/base_type = &"Label" -NoteLabel/colors/font_color = Color(0.890196, 0.894118, 0.921569, 0.6) -OptionButton/constants/arrow_margin = 8 -OptionButton/constants/h_separation = 8 -OptionButton/styles/disabled = SubResource("StyleBoxFlat_y6go5") -OptionButton/styles/disabled_mirrored = SubResource("StyleBoxFlat_y6go5") -OptionButton/styles/focus = SubResource("StyleBoxFlat_uqgmq") -OptionButton/styles/hover = SubResource("StyleBoxFlat_kik2p") -OptionButton/styles/hover_mirrored = SubResource("StyleBoxFlat_kik2p") -OptionButton/styles/hover_pressed = SubResource("StyleBoxFlat_huxsq") -OptionButton/styles/hover_pressed_mirrored = SubResource("StyleBoxFlat_huxsq") -OptionButton/styles/normal = SubResource("StyleBoxFlat_6yqil") -OptionButton/styles/normal_mirrored = SubResource("StyleBoxFlat_6yqil") -OptionButton/styles/pressed = SubResource("StyleBoxFlat_huxsq") -OptionButton/styles/pressed_mirrored = SubResource("StyleBoxFlat_huxsq") +NoteLabel/colors/font_color = Color(0.8901961, 0.89411765, 0.92156863, 0.6) +OptionButton/constants/arrow_margin = 4 +OptionButton/constants/h_separation = 4 +OptionButton/styles/disabled = SubResource("StyleBoxFlat_c1m33") +OptionButton/styles/disabled_mirrored = SubResource("StyleBoxFlat_c1m33") +OptionButton/styles/focus = SubResource("StyleBoxFlat_3f21d") +OptionButton/styles/hover = SubResource("StyleBoxFlat_j02or") +OptionButton/styles/hover_mirrored = SubResource("StyleBoxFlat_j02or") +OptionButton/styles/hover_pressed = SubResource("StyleBoxFlat_78rkj") +OptionButton/styles/hover_pressed_mirrored = SubResource("StyleBoxFlat_78rkj") +OptionButton/styles/normal = SubResource("StyleBoxFlat_61iib") +OptionButton/styles/normal_mirrored = SubResource("StyleBoxFlat_61iib") +OptionButton/styles/pressed = SubResource("StyleBoxFlat_78rkj") +OptionButton/styles/pressed_mirrored = SubResource("StyleBoxFlat_78rkj") OuterPanel/base_type = &"PanelContainer" -OuterPanel/styles/panel = SubResource("StyleBoxFlat_j1x70") -Panel/styles/panel = SubResource("StyleBoxFlat_5eo3a") -PanelContainer/styles/panel = SubResource("StyleBoxFlat_5eo3a") -PopupMenu/constants/h_separation = 8 +OuterPanel/styles/panel = SubResource("StyleBoxFlat_ydnyu") +Panel/styles/panel = SubResource("StyleBoxFlat_onp0e") +PanelContainer/styles/panel = SubResource("StyleBoxFlat_onp0e") +PopupMenu/constants/h_separation = 4 PopupMenu/constants/icon_max_width = 14 -PopupMenu/constants/item_end_padding = 8 -PopupMenu/constants/item_start_padding = 8 +PopupMenu/constants/item_end_padding = 4 +PopupMenu/constants/item_start_padding = 4 PopupMenu/constants/v_separation = 4 PopupMenu/font_sizes/font_size = 16 PopupMenu/icons/checked = ExtResource("1_ks7w5") @@ -1068,88 +1314,86 @@ PopupMenu/icons/radio_unchecked = ExtResource("9_2ase2") PopupMenu/icons/radio_unchecked_disabled = ExtResource("10_ks7w5") PopupMenu/icons/unchecked = ExtResource("7_rb0lk") PopupMenu/icons/unchecked_disabled = ExtResource("8_30fyb") -PopupMenu/styles/hover = SubResource("StyleBoxFlat_l5wh6") -PopupMenu/styles/panel = SubResource("StyleBoxFlat_c4a6a") -PopupMenu/styles/separator = SubResource("StyleBoxLine_xlkkc") +PopupMenu/styles/hover = SubResource("StyleBoxFlat_olm6c") +PopupMenu/styles/panel = SubResource("StyleBoxFlat_k4pvp") +PopupMenu/styles/separator = SubResource("StyleBoxLine_bdyw7") SpinBoxButtonLeft/base_type = &"Button" -SpinBoxButtonLeft/styles/disabled = SubResource("StyleBoxFlat_qdp3q") -SpinBoxButtonLeft/styles/focus = SubResource("StyleBoxFlat_qdp3q") -SpinBoxButtonLeft/styles/hover = SubResource("StyleBoxFlat_qdp3q") -SpinBoxButtonLeft/styles/normal = SubResource("StyleBoxFlat_qdp3q") -SpinBoxButtonLeft/styles/pressed = SubResource("StyleBoxFlat_s45bh") +SpinBoxButtonLeft/styles/disabled = SubResource("StyleBoxFlat_5aedr") +SpinBoxButtonLeft/styles/focus = SubResource("StyleBoxFlat_5aedr") +SpinBoxButtonLeft/styles/hover = SubResource("StyleBoxFlat_5aedr") +SpinBoxButtonLeft/styles/normal = SubResource("StyleBoxFlat_5aedr") +SpinBoxButtonLeft/styles/pressed = SubResource("StyleBoxFlat_ibb5s") SpinBoxButtonRight/base_type = &"Button" -SpinBoxButtonRight/styles/disabled = SubResource("StyleBoxFlat_qdp3q") -SpinBoxButtonRight/styles/focus = SubResource("StyleBoxFlat_qdp3q") -SpinBoxButtonRight/styles/hover = SubResource("StyleBoxFlat_qdp3q") -SpinBoxButtonRight/styles/normal = SubResource("StyleBoxFlat_qdp3q") -SpinBoxButtonRight/styles/pressed = SubResource("StyleBoxFlat_raufu") -SpinBoxLineEdit/base_type = &"LineEdit" -SpinBoxLineEdit/styles/focus = SubResource("StyleBoxFlat_e7orh") -SpinBoxLineEdit/styles/normal = SubResource("StyleBoxFlat_eggpx") -SpinBoxLineEdit/styles/read_only = SubResource("StyleBoxFlat_eggpx") -SpinBoxPanel/base_type = &"PanelContainer" -SpinBoxPanel/styles/panel = SubResource("StyleBoxFlat_tm0m6") -TabBar/colors/font_disabled_color = Color(0.890196, 0.894118, 0.921569, 0.3) -TabBar/colors/font_hovered_color = Color(0.890196, 0.894118, 0.921569, 1) -TabBar/colors/font_selected_color = Color(0.890196, 0.894118, 0.921569, 1) -TabBar/colors/font_unselected_color = Color(0.890196, 0.894118, 0.921569, 0.8) -TabBar/constants/h_separation = 8 -TabBar/font_sizes/font_size = 16 -TabBar/styles/button_highlight = SubResource("StyleBoxEmpty_c1m33") -TabBar/styles/button_pressed = SubResource("StyleBoxEmpty_3f21d") -TabBar/styles/tab_disabled = SubResource("StyleBoxFlat_j02or") -TabBar/styles/tab_focus = SubResource("StyleBoxFlat_78rkj") -TabBar/styles/tab_hovered = SubResource("StyleBoxFlat_61iib") -TabBar/styles/tab_selected = SubResource("StyleBoxFlat_ydnyu") -TabBar/styles/tab_unselected = SubResource("StyleBoxFlat_onp0e") +SpinBoxButtonRight/styles/disabled = SubResource("StyleBoxFlat_5aedr") +SpinBoxButtonRight/styles/focus = SubResource("StyleBoxFlat_5aedr") +SpinBoxButtonRight/styles/hover = SubResource("StyleBoxFlat_5aedr") +SpinBoxButtonRight/styles/normal = SubResource("StyleBoxFlat_5aedr") +SpinBoxButtonRight/styles/pressed = SubResource("StyleBoxFlat_341sr") +SpinBoxLineEdit/styles/focus = SubResource("StyleBoxFlat_xrd2a") +SpinBoxLineEdit/styles/normal = SubResource("StyleBoxFlat_muvro") +SpinBoxLineEdit/styles/read_only = SubResource("StyleBoxFlat_muvro") +TabBar/colors/font_disabled_color = Color(0.8901961, 0.89411765, 0.92156863, 0.35) +TabBar/colors/font_hovered_color = Color(0.8901961, 0.89411765, 0.92156863, 1) +TabBar/colors/font_selected_color = Color(0.8901961, 0.89411765, 0.92156863, 1) +TabBar/colors/font_unselected_color = Color(0.8901961, 0.89411765, 0.92156863, 0.75) +TabBar/constants/h_separation = 4 +TabBar/styles/button_highlight = SubResource("StyleBoxEmpty_tafav") +TabBar/styles/button_pressed = SubResource("StyleBoxEmpty_hcwh5") +TabBar/styles/tab_disabled = SubResource("StyleBoxFlat_20gek") +TabBar/styles/tab_focus = SubResource("StyleBoxFlat_wxysu") +TabBar/styles/tab_hovered = SubResource("StyleBoxFlat_bb1tf") +TabBar/styles/tab_selected = SubResource("StyleBoxFlat_bn5ll") +TabBar/styles/tab_unselected = SubResource("StyleBoxFlat_l4tsf") TextEdit/font_sizes/font_size = 16 TextEdit/fonts/font = ExtResource("4_flt0i") -TextEdit/styles/focus = SubResource("StyleBoxFlat_olm6c") -TextEdit/styles/normal = SubResource("StyleBoxFlat_k4pvp") -TextEdit/styles/read_only = SubResource("StyleBoxFlat_bdyw7") +TextEdit/styles/focus = SubResource("StyleBoxFlat_cfrtq") +TextEdit/styles/normal = SubResource("StyleBoxFlat_wl3tv") +TextEdit/styles/read_only = SubResource("StyleBoxFlat_nj65x") TimelineCellNumber/base_type = &"PanelContainer" -TimelineCellNumber/styles/panel = SubResource("StyleBoxFlat_5aedr") +TimelineCellNumber/styles/panel = SubResource("StyleBoxFlat_wlq5o") TimelineLayerPanel/base_type = &"PanelContainer" -TimelineLayerPanel/styles/panel = SubResource("StyleBoxFlat_ibb5s") -Tree/colors/relashion_ship_line_color = Color(0.890196, 0.894118, 0.921569, 0.1) +TimelineLayerPanel/styles/panel = SubResource("StyleBoxFlat_l8c38") +TooltipPanel/styles/panel = SubResource("StyleBoxFlat_hpmfn") +Tree/colors/relationship_line_color = Color(0.123233594, 0.1232, 0.14, 0.5) Tree/constants/children_hl_line_width = 0 Tree/constants/draw_guides = 0 Tree/constants/draw_relationship_lines = 1 -Tree/constants/h_separation = 8 +Tree/constants/h_separation = 4 Tree/constants/icon_max_width = 14 -Tree/constants/inner_item_margin_bottom = 8 -Tree/constants/inner_item_margin_left = 8 -Tree/constants/inner_item_margin_right = 8 -Tree/constants/inner_item_margin_top = 8 -Tree/constants/parent_hl_line_width = 1 +Tree/constants/inner_item_margin_bottom = 4 +Tree/constants/inner_item_margin_left = 4 +Tree/constants/inner_item_margin_right = 4 +Tree/constants/inner_item_margin_top = 4 +Tree/constants/parent_hl_line_width = 2 Tree/constants/relationship_line_width = 0 -Tree/constants/v_separation = 4 +Tree/constants/v_separation = 2 Tree/icons/checked = ExtResource("1_ks7w5") Tree/icons/checked_disabled = ExtResource("2_uqgmq") Tree/icons/unchecked = ExtResource("7_rb0lk") Tree/icons/unchecked_disabled = ExtResource("8_30fyb") -Tree/styles/focus = SubResource("StyleBoxFlat_341sr") -Tree/styles/hovered = SubResource("StyleBoxFlat_rb0lk") -Tree/styles/hovered_dimmed = SubResource("StyleBoxFlat_rb0lk") -Tree/styles/panel = SubResource("StyleBoxFlat_xrd2a") -Tree/styles/selected = SubResource("StyleBoxFlat_30fyb") -Tree/styles/selected_focus = SubResource("StyleBoxFlat_30fyb") +Tree/styles/focus = SubResource("StyleBoxFlat_iqjph") +Tree/styles/hovered = SubResource("StyleBoxFlat_r5cmq") +Tree/styles/hovered_dimmed = SubResource("StyleBoxFlat_r5cmq") +Tree/styles/panel = SubResource("StyleBoxFlat_7awlc") +Tree/styles/selected = SubResource("StyleBoxFlat_pr7s7") +Tree/styles/selected_focus = SubResource("StyleBoxFlat_pr7s7") TreeContainer/base_type = &"PanelContainer" -TreeContainer/styles/panel = SubResource("StyleBoxFlat_muvro") -VBoxContainer/constants/separation = 8 +TreeContainer/styles/panel = SubResource("StyleBoxFlat_s188x") +VBoxContainer/constants/separation = 4 VDottedSeparator/base_type = &"VSeparator" VDottedSeparator/constants/separation = 1 -VDottedSeparator/styles/separator = SubResource("StyleBoxTexture_j2kio") -VScrollBar/styles/grabber = SubResource("StyleBoxFlat_q56mj") -VScrollBar/styles/grabber_highlight = SubResource("StyleBoxFlat_q56mj") -VScrollBar/styles/grabber_pressed = SubResource("StyleBoxFlat_q56mj") -VScrollBar/styles/scroll = SubResource("StyleBoxFlat_hvbmk") -VScrollBar/styles/scroll_focus = SubResource("StyleBoxFlat_lvjcx") +VDottedSeparator/styles/separator = SubResource("StyleBoxTexture_poo5t") +VScrollBar/styles/grabber = SubResource("StyleBoxFlat_blikl") +VScrollBar/styles/grabber_highlight = SubResource("StyleBoxFlat_blikl") +VScrollBar/styles/grabber_pressed = SubResource("StyleBoxFlat_blikl") +VScrollBar/styles/scroll = SubResource("StyleBoxFlat_v58ty") +VScrollBar/styles/scroll_focus = SubResource("StyleBoxFlat_yj5pq") VSeparator/constants/separation = 1 -VSeparator/styles/separator = SubResource("StyleBoxLine_tafav") +VSeparator/styles/separator = SubResource("StyleBoxLine_a40tc") VSeparatorGrow/base_type = &"VSeparator" VSeparatorGrow/constants/separation = 1 -VSeparatorGrow/styles/separator = SubResource("StyleBoxLine_xlkkc") +VSeparatorGrow/styles/separator = SubResource("StyleBoxLine_pw02n") +VSplitContainer/constants/separation = 4 +VSplitContainer/icons/grabber = SubResource("Texture2D_wreqa") WarnLabel/base_type = &"Label" -WarnLabel/colors/font_color = Color(0.768627, 0.180392, 0.25098, 1) -script = ExtResource("5_gye7x") +WarnLabel/colors/font_color = Color(0.76862746, 0.18039216, 0.2509804, 1) diff --git a/ui/theme_default/main_light.tres b/ui/theme_default/main_light.tres new file mode 100644 index 00000000..e8abcea5 --- /dev/null +++ b/ui/theme_default/main_light.tres @@ -0,0 +1,1399 @@ +[gd_resource type="Theme" load_steps=112 format=3 uid="uid://dqonphj15f5go"] + +[ext_resource type="Texture2D" uid="uid://cfk4fuhncchxg" path="res://ui/theme_default/assets/checked.svg" id="1_b2qi4"] +[ext_resource type="Texture2D" uid="uid://bs272e68nsf7r" path="res://ui/theme_default/assets/checked_disabled.svg" id="2_08syj"] +[ext_resource type="Texture2D" uid="uid://ukfdhtpsv36d" path="res://ui/theme_default/assets/radio_checked.svg" id="3_tu84w"] +[ext_resource type="Texture2D" uid="uid://cev1bkvk42y1b" path="res://ui/theme_default/assets/radio_checked_disabled.svg" id="4_isyn0"] +[ext_resource type="Texture2D" uid="uid://dkn12tgqxnutf" path="res://ui/theme_default/assets/radio_unchecked.svg" id="5_oa1gu"] +[ext_resource type="Texture2D" uid="uid://br60sxpbxl5hm" path="res://ui/theme_default/assets/radio_unchecked_disabled.svg" id="6_knckn"] +[ext_resource type="Texture2D" uid="uid://dugiq0wty3mb0" path="res://ui/theme_default/assets/unchecked.svg" id="7_7auvm"] +[ext_resource type="Texture2D" uid="uid://dgv4wsdayk8l5" path="res://ui/theme_default/assets/unchecked_disabled.svg" id="8_ye7ju"] +[ext_resource type="Texture2D" uid="uid://cenp7to5aeciv" path="res://ui/assets/icons/toggle_on.svg" id="9_rpcbm"] +[ext_resource type="Texture2D" uid="uid://dsjl0jdgaayu8" path="res://ui/assets/icons/toggle_off.svg" id="10_sig8f"] +[ext_resource type="Texture2D" uid="uid://b1xjwwcy2gms8" path="res://ui/theme_default/assets/dash.svg" id="11_swbut"] +[ext_resource type="Texture2D" uid="uid://bprc86xjlnexd" path="res://ui/theme_default/assets/grabber.svg" id="12_g81to"] +[ext_resource type="FontFile" uid="uid://dmd74vvvqx340" path="res://ui/assets/fonts/CourierNewPSMT.ttf" id="13_rjam5"] + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_3e5lh"] +content_margin_left = 8.0 +content_margin_top = 4.0 +content_margin_right = 8.0 +content_margin_bottom = 4.0 +bg_color = Color(0.55439997, 0.55649436, 0.616, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_b2qi4"] +content_margin_left = 4.0 +content_margin_top = 4.0 +content_margin_right = 4.0 +content_margin_bottom = 4.0 +draw_center = false +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_08syj"] +content_margin_left = 8.0 +content_margin_top = 4.0 +content_margin_right = 8.0 +content_margin_bottom = 4.0 +bg_color = Color(0.79616, 0.7990921, 0.8824, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_tu84w"] +content_margin_left = 8.0 +content_margin_top = 4.0 +content_margin_right = 8.0 +content_margin_bottom = 4.0 +bg_color = Color(0.8024, 0.80524236, 0.886, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_isyn0"] +content_margin_left = 8.0 +content_margin_top = 4.0 +content_margin_right = 8.0 +content_margin_bottom = 4.0 +bg_color = Color(0.792, 0.79499197, 0.88, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_oa1gu"] +content_margin_left = 8.0 +content_margin_top = 4.0 +content_margin_right = 8.0 +content_margin_bottom = 4.0 +bg_color = Color(0.6862745, 0.27058825, 0.28235295, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_knckn"] +content_margin_left = 8.0 +content_margin_top = 4.0 +content_margin_right = 8.0 +content_margin_bottom = 4.0 +bg_color = Color(0.7176471, 0.34352943, 0.35411766, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_7auvm"] +content_margin_left = 8.0 +content_margin_top = 4.0 +content_margin_right = 8.0 +content_margin_bottom = 4.0 +bg_color = Color(0.7176471, 0.34352943, 0.35411766, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_ye7ju"] +content_margin_left = 8.0 +content_margin_top = 4.0 +content_margin_right = 8.0 +content_margin_bottom = 4.0 +bg_color = Color(0.73333335, 0.38, 0.39000002, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_rpcbm"] +content_margin_left = 8.0 +content_margin_top = 4.0 +content_margin_right = 8.0 +content_margin_bottom = 4.0 +bg_color = Color(0.73333335, 0.38, 0.39000002, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_sig8f"] +content_margin_left = 8.0 +content_margin_top = 4.0 +content_margin_right = 8.0 +content_margin_bottom = 4.0 +bg_color = Color(0.73333335, 0.38, 0.39000002, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_swbut"] +content_margin_left = 8.0 +content_margin_top = 4.0 +content_margin_right = 8.0 +content_margin_bottom = 4.0 +bg_color = Color(0.73333335, 0.38, 0.39000002, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_g81to"] +content_margin_left = 8.0 +content_margin_top = 4.0 +content_margin_right = 8.0 +content_margin_bottom = 4.0 +bg_color = Color(0.5380392, 0.12627451, 0.17568628, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_rjam5"] +content_margin_left = 8.0 +content_margin_top = 4.0 +content_margin_right = 8.0 +content_margin_bottom = 4.0 +bg_color = Color(0.5380392, 0.12627451, 0.17568628, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_acgbe"] +content_margin_left = 8.0 +content_margin_top = 4.0 +content_margin_right = 8.0 +content_margin_bottom = 4.0 +bg_color = Color(0.79176474, 0.26235294, 0.32588238, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_qn4jy"] +content_margin_left = 8.0 +content_margin_top = 4.0 +content_margin_right = 8.0 +content_margin_bottom = 4.0 +bg_color = Color(0.79176474, 0.26235294, 0.32588238, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_qb5dd"] +content_margin_left = 8.0 +content_margin_top = 4.0 +content_margin_right = 8.0 +content_margin_bottom = 4.0 +bg_color = Color(0.80333334, 0.30333334, 0.36333334, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_imev2"] +content_margin_left = 8.0 +content_margin_top = 4.0 +content_margin_right = 8.0 +content_margin_bottom = 4.0 +bg_color = Color(0.80333334, 0.30333334, 0.36333334, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_o4p38"] +content_margin_left = 8.0 +content_margin_top = 4.0 +content_margin_right = 8.0 +content_margin_bottom = 4.0 +bg_color = Color(0.76862746, 0.18039216, 0.2509804, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_vkfxj"] +content_margin_left = 8.0 +content_margin_top = 4.0 +content_margin_right = 8.0 +content_margin_bottom = 4.0 +bg_color = Color(0.80333334, 0.30333334, 0.36333334, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_bxhmy"] +content_margin_left = 8.0 +content_margin_top = 4.0 +content_margin_right = 8.0 +content_margin_bottom = 4.0 +bg_color = Color(0.80333334, 0.30333334, 0.36333334, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_a2bp7"] +content_margin_left = 0.0 +content_margin_top = 0.0 +content_margin_right = 0.0 +content_margin_bottom = 0.0 +draw_center = false +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_44wn6"] +content_margin_left = 4.0 +content_margin_top = 4.0 +content_margin_right = 4.0 +content_margin_bottom = 4.0 +bg_color = Color(0.85421985, 0.85408, 0.924, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_o0wu7"] +content_margin_left = 4.0 +content_margin_top = 4.0 +content_margin_right = 4.0 +content_margin_bottom = 4.0 +bg_color = Color(0.792, 0.79499197, 0.88, 1) + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_nvbok"] +content_margin_left = 4.0 +content_margin_top = 4.0 +content_margin_right = 4.0 +content_margin_bottom = 4.0 +bg_color = Color(0.8465472, 0.8464, 0.92, 1) +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.8465472, 0.8464, 0.92, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_3mndf"] +content_margin_left = 4.0 +content_margin_top = 4.0 +content_margin_right = 4.0 +content_margin_bottom = 4.0 +bg_color = Color(0.8465472, 0.8464, 0.92, 1) +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.8465472, 0.8464, 0.92, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_527mg"] +content_margin_left = 8.0 +content_margin_top = 4.0 +content_margin_right = 8.0 +content_margin_bottom = 4.0 +bg_color = Color(0.792, 0.79499197, 0.88, 1) +draw_center = false +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_i8mda"] +content_margin_left = 4.0 +content_margin_top = 4.0 +content_margin_right = 4.0 +content_margin_bottom = 4.0 +bg_color = Color(0.8465472, 0.8464, 0.92, 1) +border_width_left = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.8465472, 0.8464, 0.92, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_mx3by"] +content_margin_left = 4.0 +content_margin_top = 4.0 +content_margin_right = 4.0 +content_margin_bottom = 4.0 +bg_color = Color(0.8465472, 0.8464, 0.92, 1) +border_width_left = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.8465472, 0.8464, 0.92, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_fqct4"] +content_margin_left = 8.0 +content_margin_top = 4.0 +content_margin_right = 8.0 +content_margin_bottom = 4.0 +bg_color = Color(0.8465472, 0.8464, 0.92, 1) +border_width_top = 1 +border_color = Color(1, 1, 1, 0) +corner_radius_top_left = 2 +corner_radius_top_right = 2 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_ysogw"] +content_margin_left = 4.0 +content_margin_top = 4.0 +content_margin_right = 4.0 +content_margin_bottom = 0.0 +bg_color = Color(0.792, 0.79499197, 0.88, 1) +border_color = Color(0.8465472, 0.8464, 0.92, 1) + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_vtds3"] +content_margin_left = 4.0 +content_margin_top = 4.0 +content_margin_right = 4.0 +content_margin_bottom = 0.0 +bg_color = Color(0.792, 0.79499197, 0.88, 1) +border_color = Color(0.8465472, 0.8464, 0.92, 1) + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_wmw1a"] +content_margin_left = 8.0 +content_margin_top = 8.0 +content_margin_right = 8.0 +content_margin_bottom = 8.0 +bg_color = Color(0.8465472, 0.8464, 0.92, 1) +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.8465472, 0.8464, 0.92, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_dsx4i"] +content_margin_left = 4.0 +content_margin_top = 4.0 +content_margin_right = 4.0 +content_margin_bottom = 4.0 +bg_color = Color(0.79616, 0.7990921, 0.8824, 1) +draw_center = false +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.101960786, 0.101960786, 0.12156863, 0.5) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_fsxj2"] +content_margin_left = 4.0 +content_margin_top = 4.0 +content_margin_right = 4.0 +content_margin_bottom = 4.0 +bg_color = Color(0.8024, 0.80524236, 0.886, 1) +draw_center = false +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.101960786, 0.101960786, 0.12156863, 0.6) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_gi72q"] +content_margin_left = 4.0 +content_margin_top = 4.0 +content_margin_right = 4.0 +content_margin_bottom = 4.0 +bg_color = Color(1, 1, 1, 0) +draw_center = false +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.101960786, 0.101960786, 0.12156863, 0.3) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_vuv6b"] +content_margin_left = 0.0 +content_margin_top = 0.0 +content_margin_right = 0.0 +content_margin_bottom = 0.0 +bg_color = Color(0.9025, 0.90554, 0.95, 1) + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_g3pr0"] +content_margin_left = 4.0 +content_margin_top = 4.0 +content_margin_right = 4.0 +content_margin_bottom = 4.0 +bg_color = Color(0.8465472, 0.8464, 0.92, 1) +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.8465472, 0.8464, 0.92, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 +shadow_color = Color(0, 0, 0, 0.15) +shadow_size = 10 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_tayai"] +content_margin_left = 4.0 +content_margin_top = 4.0 +content_margin_right = 4.0 +content_margin_bottom = 4.0 +bg_color = Color(0.8465472, 0.8464, 0.92, 1) +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.86189246, 0.86176, 0.92800003, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 +shadow_color = Color(0, 0, 0, 0.15) +shadow_size = 10 + +[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_i3fi2"] + +[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_ivm1f"] + +[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_gl5uq"] + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_cnoru"] +content_margin_left = 4.0 +content_margin_top = 4.0 +content_margin_right = 4.0 +content_margin_bottom = 4.0 +bg_color = Color(0.8465472, 0.8464, 0.92, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxTexture" id="StyleBoxTexture_mepdu"] +texture = ExtResource("11_swbut") +texture_margin_top = 1.0 +axis_stretch_horizontal = 2 +axis_stretch_vertical = 2 +modulate_color = Color(0.8465472, 0.8464, 0.92, 1) + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_ou2x4"] +content_margin_left = 4.0 +content_margin_top = 4.0 +content_margin_right = 4.0 +content_margin_bottom = 4.0 +bg_color = Color(0.8465472, 0.8464, 0.92, 1) +corner_radius_top_left = 5 +corner_radius_top_right = 5 +corner_radius_bottom_right = 5 +corner_radius_bottom_left = 5 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_jmhep"] +content_margin_left = 2.0 +content_margin_top = 2.0 +content_margin_right = 2.0 +content_margin_bottom = 2.0 +draw_center = false +border_color = Color(0.8465472, 0.8464, 0.92, 1) + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_wp044"] +content_margin_left = 2.0 +content_margin_top = 2.0 +content_margin_right = 2.0 +content_margin_bottom = 2.0 +border_color = Color(0.8465472, 0.8464, 0.92, 1) + +[sub_resource type="StyleBoxLine" id="StyleBoxLine_d5f0v"] +color = Color(0.8465472, 0.8464, 0.92, 1) +grow_begin = 0.0 +grow_end = 0.0 + +[sub_resource type="StyleBoxLine" id="StyleBoxLine_hr4y8"] +color = Color(0.8465472, 0.8464, 0.92, 1) +grow_begin = 4.0 +grow_end = 4.0 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_so0kf"] +content_margin_top = 5.0 +bg_color = Color(0.6862745, 0.27058825, 0.28235295, 1) +corner_radius_top_left = 5 +corner_radius_top_right = 5 +corner_radius_bottom_right = 5 +corner_radius_bottom_left = 5 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_uno5m"] +content_margin_top = 5.0 +bg_color = Color(0.792, 0.79499197, 0.88, 1) +corner_radius_top_left = 5 +corner_radius_top_right = 5 +corner_radius_bottom_right = 5 +corner_radius_bottom_left = 5 + +[sub_resource type="Texture2D" id="Texture2D_elft6"] +resource_local_to_scene = false +resource_name = "" + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_fxlcd"] +content_margin_left = 4.0 +content_margin_top = 4.0 +content_margin_right = 4.0 +content_margin_bottom = 4.0 +bg_color = Color(0.8465472, 0.8464, 0.92, 1) + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_gs0sm"] +content_margin_left = 0.0 +content_margin_top = 0.0 +content_margin_right = 0.0 +content_margin_bottom = 0.0 +bg_color = Color(0.8465472, 0.8464, 0.92, 1) +expand_margin_left = 3.0 +expand_margin_top = 4.0 +expand_margin_right = 4.0 +expand_margin_bottom = 4.0 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_awaqr"] +content_margin_left = 4.0 +content_margin_top = 4.0 +content_margin_right = 4.0 +content_margin_bottom = 4.0 +draw_center = false +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_ohvfc"] +content_margin_left = 0.0 +content_margin_top = 0.0 +content_margin_right = 0.0 +content_margin_bottom = 0.0 +draw_center = false +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_l5obt"] +content_margin_left = 8.0 +content_margin_top = 4.0 +content_margin_right = 8.0 +content_margin_bottom = 4.0 +bg_color = Color(0.6336, 0.6359936, 0.704, 1) +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.8465472, 0.8464, 0.92, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_xnpyr"] +content_margin_left = 8.0 +content_margin_top = 4.0 +content_margin_right = 8.0 +content_margin_bottom = 4.0 +bg_color = Color(0.792, 0.79499197, 0.88, 1) +draw_center = false +border_width_left = 1 +border_width_top = 1 +border_width_right = 1 +border_width_bottom = 1 +border_color = Color(0.8465472, 0.8464, 0.92, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_id83p"] +content_margin_left = 8.0 +content_margin_top = 4.0 +content_margin_right = 8.0 +content_margin_bottom = 4.0 +bg_color = Color(0.792, 0.79499197, 0.88, 1) +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.8465472, 0.8464, 0.92, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_dvogh"] +content_margin_left = 8.0 +content_margin_top = 4.0 +content_margin_right = 8.0 +content_margin_bottom = 4.0 +bg_color = Color(0.8465472, 0.8464, 0.92, 1) +border_width_left = 1 +border_width_top = 1 +border_width_right = 1 +border_width_bottom = 1 +border_color = Color(0.8465472, 0.8464, 0.92, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_gde16"] +content_margin_left = 8.0 +content_margin_top = 4.0 +content_margin_right = 8.0 +content_margin_bottom = 4.0 +bg_color = Color(0.792, 0.79499197, 0.88, 1) +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.8465472, 0.8464, 0.92, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_7s07t"] +content_margin_left = 4.0 +content_margin_top = 2.0 +content_margin_right = 4.0 +content_margin_bottom = 2.0 +bg_color = Color(0.8465472, 0.8464, 0.92, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_u41jf"] +content_margin_left = 8.0 +content_margin_top = 4.0 +content_margin_right = 8.0 +content_margin_bottom = 4.0 +bg_color = Color(0.6336, 0.6359936, 0.704, 1) +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.8465472, 0.8464, 0.92, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_p4r8a"] +content_margin_left = 4.0 +content_margin_top = 4.0 +content_margin_right = 4.0 +content_margin_bottom = 4.0 +draw_center = false +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_m1f6q"] +content_margin_left = 8.0 +content_margin_top = 4.0 +content_margin_right = 8.0 +content_margin_bottom = 4.0 +bg_color = Color(0.8024, 0.80524236, 0.886, 1) +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.8465472, 0.8464, 0.92, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_vwfpw"] +content_margin_left = 8.0 +content_margin_top = 4.0 +content_margin_right = 8.0 +content_margin_bottom = 4.0 +bg_color = Color(0.8128, 0.81549275, 0.892, 1) +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.8465472, 0.8464, 0.92, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_pr0vt"] +content_margin_left = 8.0 +content_margin_top = 4.0 +content_margin_right = 8.0 +content_margin_bottom = 4.0 +bg_color = Color(0.792, 0.79499197, 0.88, 1) +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.8465472, 0.8464, 0.92, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_o00pm"] +content_margin_left = 4.0 +content_margin_top = 4.0 +content_margin_right = 4.0 +content_margin_bottom = 4.0 +bg_color = Color(0.8465472, 0.8464, 0.92, 1) +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.8465472, 0.8464, 0.92, 1) +corner_radius_top_left = 7 +corner_radius_top_right = 7 +corner_radius_bottom_right = 7 +corner_radius_bottom_left = 7 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_pt64k"] +content_margin_left = 4.0 +content_margin_top = 4.0 +content_margin_right = 4.0 +content_margin_bottom = 4.0 +bg_color = Color(0.8465472, 0.8464, 0.92, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_jl5gi"] +content_margin_left = 8.0 +content_margin_top = 4.0 +content_margin_right = 8.0 +content_margin_bottom = 4.0 +bg_color = Color(0.792, 0.79499197, 0.88, 1) +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.8465472, 0.8464, 0.92, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_1dwqt"] +content_margin_left = 4.0 +content_margin_top = 4.0 +content_margin_right = 4.0 +content_margin_bottom = 4.0 +bg_color = Color(0.8465472, 0.8464, 0.92, 1) +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.8465472, 0.8464, 0.92, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxLine" id="StyleBoxLine_u44o0"] +color = Color(0.101960786, 0.101960786, 0.12156863, 0.15) +grow_begin = 0.0 +grow_end = 0.0 +vertical = true + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_7imkf"] +content_margin_left = 2.0 +content_margin_top = 2.0 +content_margin_right = 2.0 +content_margin_bottom = 2.0 +draw_center = false +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_757px"] +content_margin_left = 2.0 +content_margin_top = 2.0 +content_margin_right = 2.0 +content_margin_bottom = 2.0 +bg_color = Color(0.792, 0.79499197, 0.88, 1) +corner_radius_top_left = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_k7qqj"] +content_margin_left = 2.0 +content_margin_top = 2.0 +content_margin_right = 2.0 +content_margin_bottom = 2.0 +bg_color = Color(0.792, 0.79499197, 0.88, 1) +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_2h8wk"] +content_margin_left = 0.0 +content_margin_top = 0.0 +content_margin_right = 0.0 +content_margin_bottom = 0.0 +bg_color = Color(0.792, 0.79499197, 0.88, 1) +draw_center = false +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.8465472, 0.8464, 0.92, 1) + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_as1jf"] +content_margin_left = 0.0 +content_margin_top = 0.0 +content_margin_right = 0.0 +content_margin_bottom = 0.0 +bg_color = Color(0.792, 0.79499197, 0.88, 1) +draw_center = false +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.8465472, 0.8464, 0.92, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_3nmiw"] + +[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_uqofd"] + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_rommv"] +content_margin_left = 8.0 +content_margin_top = 4.0 +content_margin_right = 8.0 +content_margin_bottom = 4.0 +bg_color = Color(0.792, 0.79499197, 0.88, 1) +draw_center = false +border_width_right = 1 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_awp3q"] +content_margin_left = 8.0 +content_margin_top = 4.0 +content_margin_right = 8.0 +content_margin_bottom = 4.0 +bg_color = Color(0.792, 0.79499197, 0.88, 1) +draw_center = false +border_width_right = 1 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_2bi2w"] +content_margin_left = 8.0 +content_margin_top = 4.0 +content_margin_right = 8.0 +content_margin_bottom = 4.0 +bg_color = Color(0.792, 0.79499197, 0.88, 1) +draw_center = false +border_width_right = 1 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_1ol3k"] +content_margin_left = 8.0 +content_margin_top = 4.0 +content_margin_right = 8.0 +content_margin_bottom = 4.0 +bg_color = Color(0.6862745, 0.27058825, 0.28235295, 1) +border_width_right = 1 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_gw6sl"] +content_margin_left = 8.0 +content_margin_top = 4.0 +content_margin_right = 8.0 +content_margin_bottom = 4.0 +bg_color = Color(0.792, 0.79499197, 0.88, 1) +draw_center = false +border_width_right = 1 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_qwa1j"] +content_margin_left = 8.0 +content_margin_top = 4.0 +content_margin_right = 8.0 +content_margin_bottom = 4.0 +bg_color = Color(0.792, 0.79499197, 0.88, 1) +draw_center = false +border_width_left = 1 +border_width_top = 1 +border_width_right = 1 +border_width_bottom = 1 +border_color = Color(0.8465472, 0.8464, 0.92, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_65p8d"] +content_margin_left = 8.0 +content_margin_top = 4.0 +content_margin_right = 8.0 +content_margin_bottom = 4.0 +bg_color = Color(0.792, 0.79499197, 0.88, 1) +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.8465472, 0.8464, 0.92, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_u8cn3"] +content_margin_left = 8.0 +content_margin_top = 4.0 +content_margin_right = 8.0 +content_margin_bottom = 4.0 +bg_color = Color(0.6336, 0.6359936, 0.704, 1) +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.8465472, 0.8464, 0.92, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_h57ct"] +content_margin_left = 4.0 +content_margin_top = 4.0 +content_margin_right = 4.0 +content_margin_bottom = 4.0 +bg_color = Color(0.8465472, 0.8464, 0.92, 1) +border_width_right = 2 +border_color = Color(0, 0, 0, 1) + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_ro7hf"] +content_margin_left = 4.0 +content_margin_top = 4.0 +content_margin_right = 4.0 +content_margin_bottom = 4.0 +bg_color = Color(0.8465472, 0.8464, 0.92, 1) +border_width_bottom = 2 +border_color = Color(0, 0, 0, 1) + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_nippr"] +content_margin_left = 4.0 +content_margin_top = 4.0 +content_margin_right = 4.0 +content_margin_bottom = 4.0 +bg_color = Color(0.8465472, 0.8464, 0.92, 0.5) + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_ketgd"] +content_margin_left = 4.0 +content_margin_top = 4.0 +content_margin_right = 4.0 +content_margin_bottom = 4.0 +draw_center = false +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_djw5w"] +content_margin_left = 8.0 +content_margin_top = 4.0 +content_margin_right = 8.0 +content_margin_bottom = 4.0 +bg_color = Color(0.79616, 0.7990921, 0.8824, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_xcwen"] +content_margin_left = 4.0 +content_margin_top = 4.0 +content_margin_right = 4.0 +content_margin_bottom = 4.0 +bg_color = Color(0.8465472, 0.8464, 0.92, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_up874"] +content_margin_left = 8.0 +content_margin_top = 4.0 +content_margin_right = 8.0 +content_margin_bottom = 4.0 +bg_color = Color(0.8024, 0.80524236, 0.886, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_raifk"] +content_margin_left = 4.0 +content_margin_top = 4.0 +content_margin_right = 4.0 +content_margin_bottom = 4.0 +bg_color = Color(0.8465472, 0.8464, 0.92, 1) + +[sub_resource type="StyleBoxLine" id="StyleBoxLine_7pkjl"] +color = Color(0.8465472, 0.8464, 0.92, 1) +grow_begin = 0.0 +grow_end = 0.0 +vertical = true + +[sub_resource type="StyleBoxLine" id="StyleBoxLine_wulin"] +color = Color(0.8465472, 0.8464, 0.92, 1) +grow_begin = 4.0 +grow_end = 4.0 +vertical = true + +[sub_resource type="Texture2D" id="Texture2D_f0qw8"] +resource_local_to_scene = false +resource_name = "" + +[resource] +Button/colors/font_color = Color(0.101960786, 0.101960786, 0.12156863, 0.75) +Button/colors/font_disabled_color = Color(0.101960786, 0.101960786, 0.12156863, 0.35) +Button/colors/font_focus_color = Color(0.101960786, 0.101960786, 0.12156863, 1) +Button/colors/font_hover_color = Color(0.101960786, 0.101960786, 0.12156863, 1) +Button/colors/font_hover_pressed_color = Color(0.101960786, 0.101960786, 0.12156863, 1) +Button/colors/font_pressed_color = Color(0.101960786, 0.101960786, 0.12156863, 1) +Button/colors/icon_disabled_color = Color(0.101960786, 0.101960786, 0.12156863, 0.35) +Button/colors/icon_normal_color = Color(0.101960786, 0.101960786, 0.12156863, 0.75) +Button/constants/h_separation = 4 +Button/constants/icon_max_width = 15 +Button/constants/outline_size = 0 +Button/styles/disabled = SubResource("StyleBoxFlat_3e5lh") +Button/styles/disabled_mirrored = SubResource("StyleBoxFlat_3e5lh") +Button/styles/focus = SubResource("StyleBoxFlat_b2qi4") +Button/styles/hover = SubResource("StyleBoxFlat_08syj") +Button/styles/hover_mirrored = SubResource("StyleBoxFlat_08syj") +Button/styles/hover_pressed = SubResource("StyleBoxFlat_tu84w") +Button/styles/hover_pressed_mirrored = SubResource("StyleBoxFlat_tu84w") +Button/styles/normal = SubResource("StyleBoxFlat_isyn0") +Button/styles/normal_mirrored = SubResource("StyleBoxFlat_isyn0") +Button/styles/pressed = SubResource("StyleBoxFlat_tu84w") +Button/styles/pressed_mirrored = SubResource("StyleBoxFlat_tu84w") +ButtonAccent/base_type = &"Button" +ButtonAccent/styles/disabled = SubResource("StyleBoxFlat_oa1gu") +ButtonAccent/styles/disabled_mirrored = SubResource("StyleBoxFlat_oa1gu") +ButtonAccent/styles/focus = SubResource("StyleBoxFlat_oa1gu") +ButtonAccent/styles/hover = SubResource("StyleBoxFlat_knckn") +ButtonAccent/styles/hover_mirrored = SubResource("StyleBoxFlat_7auvm") +ButtonAccent/styles/hover_pressed = SubResource("StyleBoxFlat_ye7ju") +ButtonAccent/styles/hover_pressed_mirrored = SubResource("StyleBoxFlat_rpcbm") +ButtonAccent/styles/normal = SubResource("StyleBoxFlat_oa1gu") +ButtonAccent/styles/normal_mirrored = SubResource("StyleBoxFlat_oa1gu") +ButtonAccent/styles/pressed = SubResource("StyleBoxFlat_sig8f") +ButtonAccent/styles/pressed_mirrored = SubResource("StyleBoxFlat_swbut") +ButtonWarning/base_type = &"Button" +ButtonWarning/constants/outline_size = 0 +ButtonWarning/styles/disabled = SubResource("StyleBoxFlat_g81to") +ButtonWarning/styles/disabled_mirrored = SubResource("StyleBoxFlat_rjam5") +ButtonWarning/styles/focus = SubResource("StyleBoxFlat_b2qi4") +ButtonWarning/styles/hover = SubResource("StyleBoxFlat_acgbe") +ButtonWarning/styles/hover_mirrored = SubResource("StyleBoxFlat_qn4jy") +ButtonWarning/styles/hover_pressed = SubResource("StyleBoxFlat_qb5dd") +ButtonWarning/styles/hover_pressed_mirrored = SubResource("StyleBoxFlat_imev2") +ButtonWarning/styles/normal = SubResource("StyleBoxFlat_o4p38") +ButtonWarning/styles/normal_mirrored = SubResource("StyleBoxFlat_o4p38") +ButtonWarning/styles/pressed = SubResource("StyleBoxFlat_vkfxj") +ButtonWarning/styles/pressed_mirrored = SubResource("StyleBoxFlat_bxhmy") +CheckBox/colors/font_hover_pressed_color = Color(0.101960786, 0.101960786, 0.12156863, 1) +CheckBox/colors/font_pressed_color = Color(0.101960786, 0.101960786, 0.12156863, 0.75) +CheckBox/constants/h_separation = 4 +CheckBox/icons/checked = ExtResource("1_b2qi4") +CheckBox/icons/checked_disabled = ExtResource("2_08syj") +CheckBox/icons/radio_checked = ExtResource("3_tu84w") +CheckBox/icons/radio_checked_disabled = ExtResource("4_isyn0") +CheckBox/icons/radio_unchecked = ExtResource("5_oa1gu") +CheckBox/icons/radio_unchecked_disabled = ExtResource("6_knckn") +CheckBox/icons/unchecked = ExtResource("7_7auvm") +CheckBox/icons/unchecked_disabled = ExtResource("8_ye7ju") +CheckBox/styles/disabled = SubResource("StyleBoxFlat_a2bp7") +CheckBox/styles/disabled_mirrored = SubResource("StyleBoxFlat_a2bp7") +CheckBox/styles/focus = SubResource("StyleBoxFlat_a2bp7") +CheckBox/styles/hover = SubResource("StyleBoxFlat_a2bp7") +CheckBox/styles/hover_mirrored = SubResource("StyleBoxFlat_a2bp7") +CheckBox/styles/hover_pressed = SubResource("StyleBoxFlat_a2bp7") +CheckBox/styles/hover_pressed_mirrored = SubResource("StyleBoxFlat_a2bp7") +CheckBox/styles/normal = SubResource("StyleBoxFlat_a2bp7") +CheckBox/styles/normal_mirrored = SubResource("StyleBoxFlat_a2bp7") +CheckBox/styles/pressed = SubResource("StyleBoxFlat_a2bp7") +CheckBox/styles/pressed_mirrored = SubResource("StyleBoxFlat_a2bp7") +CheckButton/colors/font_focus_color = Color(0.101960786, 0.101960786, 0.12156863, 0.75) +CheckButton/colors/font_hover_pressed_color = Color(0.101960786, 0.101960786, 0.12156863, 1) +CheckButton/colors/font_pressed_color = Color(0.101960786, 0.101960786, 0.12156863, 1) +CheckButton/icons/checked = ExtResource("9_rpcbm") +CheckButton/icons/unchecked = ExtResource("10_sig8f") +CheckButton/styles/disabled = SubResource("StyleBoxFlat_a2bp7") +CheckButton/styles/disabled_mirrored = SubResource("StyleBoxFlat_a2bp7") +CheckButton/styles/focus = SubResource("StyleBoxFlat_a2bp7") +CheckButton/styles/hover = SubResource("StyleBoxFlat_a2bp7") +CheckButton/styles/hover_mirrored = SubResource("StyleBoxFlat_a2bp7") +CheckButton/styles/hover_pressed = SubResource("StyleBoxFlat_a2bp7") +CheckButton/styles/hover_pressed_mirrored = SubResource("StyleBoxFlat_a2bp7") +CheckButton/styles/normal = SubResource("StyleBoxFlat_a2bp7") +CheckButton/styles/normal_mirrored = SubResource("StyleBoxFlat_a2bp7") +CheckButton/styles/pressed = SubResource("StyleBoxFlat_a2bp7") +CheckButton/styles/pressed_mirrored = SubResource("StyleBoxFlat_a2bp7") +CollapsibleFieldPanel/base_type = &"PanelContainer" +CollapsibleFieldPanel/styles/panel = SubResource("StyleBoxFlat_44wn6") +EditorBackground/base_type = &"PanelContainer" +EditorBackground/styles/panel = SubResource("StyleBoxFlat_o0wu7") +EditorSection/base_type = &"TabContainer" +EditorSection/colors/font_disabled_color = Color(0.101960786, 0.101960786, 0.12156863, 0.35) +EditorSection/colors/font_hover_color = Color(0.101960786, 0.101960786, 0.12156863, 1) +EditorSection/colors/font_selected_color = Color(0.101960786, 0.101960786, 0.12156863, 1) +EditorSection/colors/font_unselected_color = Color(0.101960786, 0.101960786, 0.12156863, 0.75) +EditorSection/constants/icon_max_width = 16 +EditorSection/constants/icon_separation = 4 +EditorSection/constants/side_margin = 1 +EditorSection/font_sizes/font_size = 16 +EditorSection/styles/panel_focus = SubResource("StyleBoxFlat_nvbok") +EditorSection/styles/panel_unfocus = SubResource("StyleBoxFlat_3mndf") +EditorSection/styles/tab_disabled = SubResource("StyleBoxFlat_527mg") +EditorSection/styles/tab_focus = SubResource("StyleBoxFlat_527mg") +EditorSection/styles/tab_hovered = SubResource("StyleBoxFlat_527mg") +EditorSection/styles/tab_panel_focus = SubResource("StyleBoxFlat_i8mda") +EditorSection/styles/tab_panel_unfocus = SubResource("StyleBoxFlat_mx3by") +EditorSection/styles/tab_selected = SubResource("StyleBoxFlat_fqct4") +EditorSection/styles/tab_unselected = SubResource("StyleBoxFlat_527mg") +EditorSection/styles/tabbar_background_focus = SubResource("StyleBoxFlat_ysogw") +EditorSection/styles/tabbar_background_unfocus = SubResource("StyleBoxFlat_vtds3") +FieldContainer/base_type = &"VBoxContainer" +FieldContainer/constants/separation = 2 +FieldPanel/base_type = &"PanelContainer" +FieldPanel/styles/panel = SubResource("StyleBoxFlat_wmw1a") +FlatButton/colors/font_color = Color(0.101960786, 0.101960786, 0.12156863, 0.75) +FlatButton/colors/font_disabled_color = Color(0.101960786, 0.101960786, 0.12156863, 0.35) +FlatButton/colors/font_focus_color = Color(0.101960786, 0.101960786, 0.12156863, 1) +FlatButton/colors/font_hover_color = Color(0.101960786, 0.101960786, 0.12156863, 1) +FlatButton/colors/font_hover_pressed_color = Color(0.101960786, 0.101960786, 0.12156863, 1) +FlatButton/colors/font_pressed_color = Color(0.101960786, 0.101960786, 0.12156863, 1) +FlatButton/colors/icon_disabled_color = Color(0.101960786, 0.101960786, 0.12156863, 0.35) +FlatButton/colors/icon_normal_color = Color(0.101960786, 0.101960786, 0.12156863, 0.75) +FlatButton/constants/outline_size = 0 +FlatButton/styles/disabled = SubResource("StyleBoxFlat_3e5lh") +FlatButton/styles/disabled_mirrored = SubResource("StyleBoxFlat_3e5lh") +FlatButton/styles/hover = SubResource("StyleBoxFlat_dsx4i") +FlatButton/styles/hover_mirrored = SubResource("StyleBoxFlat_dsx4i") +FlatButton/styles/hover_pressed = SubResource("StyleBoxFlat_fsxj2") +FlatButton/styles/hover_pressed_mirrored = SubResource("StyleBoxFlat_fsxj2") +FlatButton/styles/normal = SubResource("StyleBoxFlat_gi72q") +FlatButton/styles/normal_mirrored = SubResource("StyleBoxFlat_gi72q") +FlatButton/styles/pressed = SubResource("StyleBoxFlat_fsxj2") +FlatButton/styles/pressed_mirrored = SubResource("StyleBoxFlat_fsxj2") +GraphEdit/colors/grid_major = Color(0.101960786, 0.101960786, 0.12156863, 0.15) +GraphEdit/colors/grid_minor = Color(0.101960786, 0.101960786, 0.12156863, 0.15) +GraphEdit/styles/panel = SubResource("StyleBoxFlat_vuv6b") +GraphNode/constants/separation = 4 +GraphNode/styles/panel = SubResource("StyleBoxFlat_g3pr0") +GraphNode/styles/panel_selected = SubResource("StyleBoxFlat_tayai") +GraphNode/styles/slot = SubResource("StyleBoxEmpty_i3fi2") +GraphNode/styles/titlebar = SubResource("StyleBoxEmpty_ivm1f") +GraphNode/styles/titlebar_selected = SubResource("StyleBoxEmpty_gl5uq") +GraphNodePicker/base_type = &"PanelContainer" +GraphNodePicker/styles/panel = SubResource("StyleBoxFlat_cnoru") +GraphNodeTitleLabel/font_sizes/font_size = 1 +GraphNodeViewRownHBox/base_type = &"HBoxContainer" +GraphNodeViewRownHBox/constants/separation = 20 +GraphNodeViewTitleLabel/base_type = &"Label" +GraphNodeViewTitleLabel/colors/font_color = Color(0.101960786, 0.101960786, 0.12156863, 1) +GraphNodeViewTitleLabel/font_sizes/font_size = 18 +GraphNodeViewValueLabel/base_type = &"Label" +GraphNodeViewValueLabel/colors/font_color = Color(0.101960786, 0.101960786, 0.12156863, 0.5) +GraphNodeViewValueLabel/font_sizes/font_size = 16 +HBoxContainer/constants/separation = 4 +HDottedSeparator/base_type = &"HSeparator" +HDottedSeparator/constants/separation = 1 +HDottedSeparator/styles/separator = SubResource("StyleBoxTexture_mepdu") +HScrollBar/styles/grabber = SubResource("StyleBoxFlat_ou2x4") +HScrollBar/styles/grabber_highlight = SubResource("StyleBoxFlat_ou2x4") +HScrollBar/styles/grabber_pressed = SubResource("StyleBoxFlat_ou2x4") +HScrollBar/styles/scroll = SubResource("StyleBoxFlat_jmhep") +HScrollBar/styles/scroll_focus = SubResource("StyleBoxFlat_wp044") +HSeparator/constants/separation = 1 +HSeparator/styles/separator = SubResource("StyleBoxLine_d5f0v") +HSeparatorGrow/base_type = &"HSeparator" +HSeparatorGrow/constants/separation = 1 +HSeparatorGrow/styles/separator = SubResource("StyleBoxLine_hr4y8") +HSlider/icons/grabber = ExtResource("12_g81to") +HSlider/icons/grabber_disabled = ExtResource("12_g81to") +HSlider/icons/grabber_highlight = ExtResource("12_g81to") +HSlider/styles/grabber_area = SubResource("StyleBoxFlat_so0kf") +HSlider/styles/grabber_area_highlight = SubResource("StyleBoxFlat_so0kf") +HSlider/styles/slider = SubResource("StyleBoxFlat_uno5m") +HSplitContainer/constants/separation = 4 +HSplitContainer/icons/grabber = SubResource("Texture2D_elft6") +InspectorPanel/base_type = &"PanelContainer" +InspectorPanel/styles/panel = SubResource("StyleBoxFlat_fxlcd") +InspectorPanelTopBox/base_type = &"PanelContainer" +InspectorPanelTopBox/styles/panel = SubResource("StyleBoxFlat_gs0sm") +ItemContainer/base_type = &"PanelContainer" +ItemContainer/styles/panel = SubResource("StyleBoxFlat_awaqr") +ItemContainerFlat/base_type = &"PanelContainer" +ItemContainerFlat/styles/panel = SubResource("StyleBoxFlat_ohvfc") +Label/colors/font_color = Color(0.101960786, 0.101960786, 0.12156863, 1) +LineEdit/styles/disabled = SubResource("StyleBoxFlat_l5obt") +LineEdit/styles/focus = SubResource("StyleBoxFlat_xnpyr") +LineEdit/styles/normal = SubResource("StyleBoxFlat_id83p") +LineEditPortraitOption/base_type = &"LineEdit" +LineEditPortraitOption/colors/font_color = Color(0.101960786, 0.101960786, 0.12156863, 1) +LineEditPortraitOption/colors/font_uneditable_color = Color(0.101960786, 0.101960786, 0.12156863, 1) +LineEditPortraitOption/styles/disabled = SubResource("StyleBoxFlat_l5obt") +LineEditPortraitOption/styles/focus = SubResource("StyleBoxFlat_dvogh") +LineEditPortraitOption/styles/normal = SubResource("StyleBoxFlat_gde16") +NodeValue/base_type = &"Label" +NodeValue/colors/font_color = Color(0.101960786, 0.101960786, 0.12156863, 1) +NodeValue/styles/normal = SubResource("StyleBoxFlat_7s07t") +NoteLabel/base_type = &"Label" +NoteLabel/colors/font_color = Color(0.101960786, 0.101960786, 0.12156863, 0.6) +OptionButton/constants/arrow_margin = 4 +OptionButton/constants/h_separation = 4 +OptionButton/styles/disabled = SubResource("StyleBoxFlat_u41jf") +OptionButton/styles/disabled_mirrored = SubResource("StyleBoxFlat_u41jf") +OptionButton/styles/focus = SubResource("StyleBoxFlat_p4r8a") +OptionButton/styles/hover = SubResource("StyleBoxFlat_m1f6q") +OptionButton/styles/hover_mirrored = SubResource("StyleBoxFlat_m1f6q") +OptionButton/styles/hover_pressed = SubResource("StyleBoxFlat_vwfpw") +OptionButton/styles/hover_pressed_mirrored = SubResource("StyleBoxFlat_vwfpw") +OptionButton/styles/normal = SubResource("StyleBoxFlat_pr0vt") +OptionButton/styles/normal_mirrored = SubResource("StyleBoxFlat_pr0vt") +OptionButton/styles/pressed = SubResource("StyleBoxFlat_vwfpw") +OptionButton/styles/pressed_mirrored = SubResource("StyleBoxFlat_vwfpw") +OuterPanel/base_type = &"PanelContainer" +OuterPanel/styles/panel = SubResource("StyleBoxFlat_o00pm") +Panel/styles/panel = SubResource("StyleBoxFlat_pt64k") +PanelContainer/styles/panel = SubResource("StyleBoxFlat_pt64k") +PopupMenu/constants/h_separation = 4 +PopupMenu/constants/icon_max_width = 14 +PopupMenu/constants/item_end_padding = 4 +PopupMenu/constants/item_start_padding = 4 +PopupMenu/constants/v_separation = 4 +PopupMenu/font_sizes/font_size = 16 +PopupMenu/icons/checked = ExtResource("1_b2qi4") +PopupMenu/icons/checked_disabled = ExtResource("2_08syj") +PopupMenu/icons/radio_checked = ExtResource("3_tu84w") +PopupMenu/icons/radio_checked_disabled = ExtResource("4_isyn0") +PopupMenu/icons/radio_unchecked = ExtResource("5_oa1gu") +PopupMenu/icons/radio_unchecked_disabled = ExtResource("6_knckn") +PopupMenu/icons/unchecked = ExtResource("7_7auvm") +PopupMenu/icons/unchecked_disabled = ExtResource("8_ye7ju") +PopupMenu/styles/hover = SubResource("StyleBoxFlat_jl5gi") +PopupMenu/styles/panel = SubResource("StyleBoxFlat_1dwqt") +PopupMenu/styles/separator = SubResource("StyleBoxLine_u44o0") +SpinBoxButtonLeft/base_type = &"Button" +SpinBoxButtonLeft/styles/disabled = SubResource("StyleBoxFlat_7imkf") +SpinBoxButtonLeft/styles/focus = SubResource("StyleBoxFlat_7imkf") +SpinBoxButtonLeft/styles/hover = SubResource("StyleBoxFlat_7imkf") +SpinBoxButtonLeft/styles/normal = SubResource("StyleBoxFlat_7imkf") +SpinBoxButtonLeft/styles/pressed = SubResource("StyleBoxFlat_757px") +SpinBoxButtonRight/base_type = &"Button" +SpinBoxButtonRight/styles/disabled = SubResource("StyleBoxFlat_7imkf") +SpinBoxButtonRight/styles/focus = SubResource("StyleBoxFlat_7imkf") +SpinBoxButtonRight/styles/hover = SubResource("StyleBoxFlat_7imkf") +SpinBoxButtonRight/styles/normal = SubResource("StyleBoxFlat_7imkf") +SpinBoxButtonRight/styles/pressed = SubResource("StyleBoxFlat_k7qqj") +SpinBoxLineEdit/styles/focus = SubResource("StyleBoxFlat_2h8wk") +SpinBoxLineEdit/styles/normal = SubResource("StyleBoxFlat_as1jf") +SpinBoxLineEdit/styles/read_only = SubResource("StyleBoxFlat_as1jf") +TabBar/colors/font_disabled_color = Color(0.101960786, 0.101960786, 0.12156863, 0.35) +TabBar/colors/font_hovered_color = Color(0.101960786, 0.101960786, 0.12156863, 1) +TabBar/colors/font_selected_color = Color(0.101960786, 0.101960786, 0.12156863, 1) +TabBar/colors/font_unselected_color = Color(0.101960786, 0.101960786, 0.12156863, 0.75) +TabBar/constants/h_separation = 4 +TabBar/styles/button_highlight = SubResource("StyleBoxEmpty_3nmiw") +TabBar/styles/button_pressed = SubResource("StyleBoxEmpty_uqofd") +TabBar/styles/tab_disabled = SubResource("StyleBoxFlat_rommv") +TabBar/styles/tab_focus = SubResource("StyleBoxFlat_awp3q") +TabBar/styles/tab_hovered = SubResource("StyleBoxFlat_2bi2w") +TabBar/styles/tab_selected = SubResource("StyleBoxFlat_1ol3k") +TabBar/styles/tab_unselected = SubResource("StyleBoxFlat_gw6sl") +TextEdit/font_sizes/font_size = 16 +TextEdit/fonts/font = ExtResource("13_rjam5") +TextEdit/styles/focus = SubResource("StyleBoxFlat_qwa1j") +TextEdit/styles/normal = SubResource("StyleBoxFlat_65p8d") +TextEdit/styles/read_only = SubResource("StyleBoxFlat_u8cn3") +TimelineCellNumber/base_type = &"PanelContainer" +TimelineCellNumber/styles/panel = SubResource("StyleBoxFlat_h57ct") +TimelineLayerPanel/base_type = &"PanelContainer" +TimelineLayerPanel/styles/panel = SubResource("StyleBoxFlat_ro7hf") +TooltipPanel/styles/panel = SubResource("StyleBoxFlat_nippr") +Tree/colors/relationship_line_color = Color(0.8465472, 0.8464, 0.92, 0.5) +Tree/constants/children_hl_line_width = 0 +Tree/constants/draw_guides = 0 +Tree/constants/draw_relationship_lines = 1 +Tree/constants/h_separation = 4 +Tree/constants/icon_max_width = 14 +Tree/constants/inner_item_margin_bottom = 4 +Tree/constants/inner_item_margin_left = 4 +Tree/constants/inner_item_margin_right = 4 +Tree/constants/inner_item_margin_top = 4 +Tree/constants/parent_hl_line_width = 2 +Tree/constants/relationship_line_width = 0 +Tree/constants/v_separation = 2 +Tree/icons/checked = ExtResource("1_b2qi4") +Tree/icons/checked_disabled = ExtResource("2_08syj") +Tree/icons/unchecked = ExtResource("7_7auvm") +Tree/icons/unchecked_disabled = ExtResource("8_ye7ju") +Tree/styles/focus = SubResource("StyleBoxFlat_ketgd") +Tree/styles/hovered = SubResource("StyleBoxFlat_djw5w") +Tree/styles/hovered_dimmed = SubResource("StyleBoxFlat_djw5w") +Tree/styles/panel = SubResource("StyleBoxFlat_xcwen") +Tree/styles/selected = SubResource("StyleBoxFlat_up874") +Tree/styles/selected_focus = SubResource("StyleBoxFlat_up874") +TreeContainer/base_type = &"PanelContainer" +TreeContainer/styles/panel = SubResource("StyleBoxFlat_raifk") +VBoxContainer/constants/separation = 4 +VDottedSeparator/base_type = &"VSeparator" +VDottedSeparator/constants/separation = 1 +VDottedSeparator/styles/separator = SubResource("StyleBoxTexture_mepdu") +VScrollBar/styles/grabber = SubResource("StyleBoxFlat_ou2x4") +VScrollBar/styles/grabber_highlight = SubResource("StyleBoxFlat_ou2x4") +VScrollBar/styles/grabber_pressed = SubResource("StyleBoxFlat_ou2x4") +VScrollBar/styles/scroll = SubResource("StyleBoxFlat_jmhep") +VScrollBar/styles/scroll_focus = SubResource("StyleBoxFlat_wp044") +VSeparator/constants/separation = 1 +VSeparator/styles/separator = SubResource("StyleBoxLine_7pkjl") +VSeparatorGrow/base_type = &"VSeparator" +VSeparatorGrow/constants/separation = 1 +VSeparatorGrow/styles/separator = SubResource("StyleBoxLine_wulin") +VSplitContainer/constants/separation = 4 +VSplitContainer/icons/grabber = SubResource("Texture2D_f0qw8") +WarnLabel/base_type = &"Label" +WarnLabel/colors/font_color = Color(0.76862746, 0.18039216, 0.2509804, 1) diff --git a/ui/theme_default/theme_builder.gd b/ui/theme_default/theme_builder.gd new file mode 100644 index 00000000..508fda44 --- /dev/null +++ b/ui/theme_default/theme_builder.gd @@ -0,0 +1,789 @@ +@tool +class_name ThemeBuilder extends RefCounted +## Modular theme builder that constructs Monologue themes from theme settingss + +const ICON_CHECKED := preload("res://ui/theme_default/assets/checked.svg") +const ICON_UNCHECKED := preload("res://ui/theme_default/assets/unchecked.svg") +const ICON_CHECKED_DISABLED := preload("res://ui/theme_default/assets/checked_disabled.svg") +const ICON_UNCHECKED_DISABLED := preload("res://ui/theme_default/assets/unchecked_disabled.svg") +const ICON_RADIO_CHECKED := preload("res://ui/theme_default/assets/radio_checked.svg") +const ICON_RADIO_UNCHECKED := preload("res://ui/theme_default/assets/radio_unchecked.svg") +const ICON_RADIO_CHECKED_DISABLED := preload( + "res://ui/theme_default/assets/radio_checked_disabled.svg" +) +const ICON_RADIO_UNCHECKED_DISABLED := preload( + "res://ui/theme_default/assets/radio_unchecked_disabled.svg" +) +const ICON_SLIDER_GRABBER := preload("res://ui/theme_default/assets/grabber.svg") + + +## Build a complete theme from a theme settings +static func build_theme(settings: ThemeSettings) -> Theme: + var theme := Theme.new() + var styles := ThemeStyles.new(settings) + + _build_buttons(theme, settings, styles) + _build_checkboxes(theme, settings, styles) + _build_inputs(theme, settings, styles) + _build_panels(theme, settings, styles) + _build_scrollbars(theme, settings, styles) + _build_separators(theme, settings, styles) + _build_sliders(theme, settings, styles) + _build_tabs(theme, settings, styles) + _build_tree(theme, settings, styles) + _build_graph_elements(theme, settings, styles) + _build_popup_menu(theme, settings, styles) + _build_labels(theme, settings, styles) + + return theme + + +## Build button styles +static func _build_buttons(theme: Theme, settings: ThemeSettings, styles: ThemeStyles) -> void: + # Regular Button + var btn_normal := styles.create_button(settings.button_background) + var btn_hover := styles.create_button(settings.button_hover) + var btn_pressed := styles.create_button(settings.button_pressed) + var btn_disabled := styles.create_button(settings.darken(settings.button_background, 0.3)) + var btn_empty := styles.create_empty() + + theme.set_stylebox("normal", "Button", btn_normal) + theme.set_stylebox("hover", "Button", btn_hover) + theme.set_stylebox("pressed", "Button", btn_pressed) + theme.set_stylebox("disabled", "Button", btn_disabled) + theme.set_stylebox("focus", "Button", btn_empty) + + # Mirror variants + theme.set_stylebox("normal_mirrored", "Button", btn_normal) + theme.set_stylebox("hover_mirrored", "Button", btn_hover) + theme.set_stylebox("pressed_mirrored", "Button", btn_pressed) + theme.set_stylebox("hover_pressed", "Button", btn_pressed) + theme.set_stylebox("hover_pressed_mirrored", "Button", btn_pressed) + theme.set_stylebox("disabled_mirrored", "Button", btn_disabled) + + # Button colors + theme.set_color("font_color", "Button", settings.text_secondary) + theme.set_color("font_disabled_color", "Button", settings.text_disabled) + theme.set_color("font_focus_color", "Button", settings.text) + theme.set_color("font_hover_color", "Button", settings.text) + theme.set_color("font_hover_pressed_color", "Button", settings.text) + theme.set_color("font_pressed_color", "Button", settings.text) + theme.set_color("icon_disabled_color", "Button", settings.text_disabled) + theme.set_color("icon_normal_color", "Button", settings.text_secondary) + + # Button constants + theme.set_constant("outline_size", "Button", 0) + theme.set_constant("icon_max_width", "Button", 15) + theme.set_constant("h_separation", "Button", styles.base_spacing) + + # ButtonAccent variation + theme.set_type_variation("ButtonAccent", "Button") + var btn_accent := styles.create_button(settings.accent) + theme.set_stylebox("normal", "ButtonAccent", btn_accent) + theme.set_stylebox( + "hover", "ButtonAccent", styles.create_button(settings.lighten(settings.accent, 0.1)) + ) + theme.set_stylebox( + "pressed", "ButtonAccent", styles.create_button(settings.lighten(settings.accent, 0.15)) + ) + theme.set_stylebox("disabled", "ButtonAccent", btn_accent) + theme.set_stylebox("normal_mirrored", "ButtonAccent", btn_accent) + theme.set_stylebox( + "hover_mirrored", + "ButtonAccent", + styles.create_button(settings.lighten(settings.accent, 0.1)) + ) + theme.set_stylebox( + "pressed_mirrored", + "ButtonAccent", + styles.create_button(settings.lighten(settings.accent, 0.15)) + ) + theme.set_stylebox("disabled_mirrored", "ButtonAccent", btn_accent) + theme.set_stylebox("focus", "ButtonAccent", btn_accent) + theme.set_stylebox( + "hover_pressed", + "ButtonAccent", + styles.create_button(settings.lighten(settings.accent, 0.15)) + ) + theme.set_stylebox( + "hover_pressed_mirrored", + "ButtonAccent", + styles.create_button(settings.lighten(settings.accent, 0.15)) + ) + + # ButtonWarning variation + theme.set_type_variation("ButtonWarning", "Button") + var btn_warning := styles.create_button(settings.warning) + theme.set_stylebox("normal", "ButtonWarning", btn_warning) + theme.set_stylebox( + "hover", "ButtonWarning", styles.create_button(settings.lighten(settings.warning, 0.1)) + ) + theme.set_stylebox( + "pressed", "ButtonWarning", styles.create_button(settings.lighten(settings.warning, 0.15)) + ) + theme.set_stylebox( + "disabled", "ButtonWarning", styles.create_button(settings.darken(settings.warning, 0.3)) + ) + theme.set_stylebox("normal_mirrored", "ButtonWarning", btn_warning) + theme.set_stylebox( + "hover_mirrored", + "ButtonWarning", + styles.create_button(settings.lighten(settings.warning, 0.1)) + ) + theme.set_stylebox( + "pressed_mirrored", + "ButtonWarning", + styles.create_button(settings.lighten(settings.warning, 0.15)) + ) + theme.set_stylebox( + "disabled_mirrored", + "ButtonWarning", + styles.create_button(settings.darken(settings.warning, 0.3)) + ) + theme.set_stylebox("focus", "ButtonWarning", btn_empty) + theme.set_stylebox( + "hover_pressed", + "ButtonWarning", + styles.create_button(settings.lighten(settings.warning, 0.15)) + ) + theme.set_stylebox( + "hover_pressed_mirrored", + "ButtonWarning", + styles.create_button(settings.lighten(settings.warning, 0.15)) + ) + theme.set_constant("outline_size", "ButtonWarning", 0) + + # FlatButton variation (outlined button) + var flat_btn_normal := styles.create_empty() + flat_btn_normal.bg_color = Color.TRANSPARENT + flat_btn_normal.set_border_width_all(styles.border_width) + flat_btn_normal.border_color = settings.with_alpha(settings.text, 0.3) + + var flat_btn_hover := flat_btn_normal.duplicate() + flat_btn_hover.bg_color = settings.hover_overlay + flat_btn_hover.border_color = settings.with_alpha(settings.text, 0.5) + + var flat_btn_pressed := flat_btn_normal.duplicate() + flat_btn_pressed.bg_color = settings.pressed_overlay + flat_btn_pressed.border_color = settings.with_alpha(settings.text, 0.6) + + theme.set_color("font_color", "FlatButton", settings.text_secondary) + theme.set_color("font_disabled_color", "FlatButton", settings.text_disabled) + theme.set_color("font_focus_color", "FlatButton", settings.text) + theme.set_color("font_hover_color", "FlatButton", settings.text) + theme.set_color("font_hover_pressed_color", "FlatButton", settings.text) + theme.set_color("font_pressed_color", "FlatButton", settings.text) + theme.set_color("icon_disabled_color", "FlatButton", settings.text_disabled) + theme.set_color("icon_normal_color", "FlatButton", settings.text_secondary) + theme.set_constant("outline_size", "FlatButton", 0) + theme.set_stylebox("disabled", "FlatButton", btn_disabled) + theme.set_stylebox("disabled_mirrored", "FlatButton", btn_disabled) + theme.set_stylebox("normal", "FlatButton", flat_btn_normal) + theme.set_stylebox("normal_mirrored", "FlatButton", flat_btn_normal) + theme.set_stylebox("hover", "FlatButton", flat_btn_hover) + theme.set_stylebox("hover_mirrored", "FlatButton", flat_btn_hover) + theme.set_stylebox("hover_pressed", "FlatButton", flat_btn_pressed) + theme.set_stylebox("hover_pressed_mirrored", "FlatButton", flat_btn_pressed) + theme.set_stylebox("pressed", "FlatButton", flat_btn_pressed) + theme.set_stylebox("pressed_mirrored", "FlatButton", flat_btn_pressed) + + +## Build checkbox and toggle styles +static func _build_checkboxes(theme: Theme, settings: ThemeSettings, styles: ThemeStyles) -> void: + var empty := styles.create_empty() + empty.set_content_margin_all(0) + + theme.set_color("font_hover_pressed_color", "CheckBox", settings.text) + theme.set_color("font_pressed_color", "CheckBox", settings.text_secondary) + theme.set_constant("h_separation", "CheckBox", styles.base_spacing) + theme.set_icon("checked", "CheckBox", ICON_CHECKED) + theme.set_icon("unchecked", "CheckBox", ICON_UNCHECKED) + theme.set_icon("radio_checked", "CheckBox", ICON_RADIO_CHECKED) + theme.set_icon("radio_unchecked", "CheckBox", ICON_RADIO_UNCHECKED) + theme.set_icon("checked_disabled", "CheckBox", ICON_CHECKED_DISABLED) + theme.set_icon("unchecked_disabled", "CheckBox", ICON_UNCHECKED_DISABLED) + theme.set_icon("radio_checked_disabled", "CheckBox", ICON_RADIO_CHECKED_DISABLED) + theme.set_icon("radio_unchecked_disabled", "CheckBox", ICON_RADIO_UNCHECKED_DISABLED) + theme.set_stylebox("focus", "CheckBox", empty) + theme.set_stylebox("disabled", "CheckBox", empty) + theme.set_stylebox("disabled_mirrored", "CheckBox", empty) + theme.set_stylebox("hover", "CheckBox", empty) + theme.set_stylebox("hover_mirrored", "CheckBox", empty) + theme.set_stylebox("hover_pressed", "CheckBox", empty) + theme.set_stylebox("hover_pressed_mirrored", "CheckBox", empty) + theme.set_stylebox("pressed", "CheckBox", empty) + theme.set_stylebox("pressed_mirrored", "CheckBox", empty) + theme.set_stylebox("normal", "CheckBox", empty) + theme.set_stylebox("normal_mirrored", "CheckBox", empty) + + # CheckButton (toggle) + theme.set_color("font_focus_color", "CheckButton", settings.text_secondary) + theme.set_color("font_hover_pressed_color", "CheckButton", settings.text) + theme.set_color("font_pressed_color", "CheckButton", settings.text) + theme.set_icon("checked", "CheckButton", preload("res://ui/assets/icons/toggle_on.svg")) + theme.set_icon("unchecked", "CheckButton", preload("res://ui/assets/icons/toggle_off.svg")) + theme.set_stylebox("focus", "CheckButton", empty) + theme.set_stylebox("disabled", "CheckButton", empty) + theme.set_stylebox("disabled_mirrored", "CheckButton", empty) + theme.set_stylebox("hover", "CheckButton", empty) + theme.set_stylebox("hover_mirrored", "CheckButton", empty) + theme.set_stylebox("hover_pressed", "CheckButton", empty) + theme.set_stylebox("hover_pressed_mirrored", "CheckButton", empty) + theme.set_stylebox("pressed", "CheckButton", empty) + theme.set_stylebox("pressed_mirrored", "CheckButton", empty) + theme.set_stylebox("normal", "CheckButton", empty) + theme.set_stylebox("normal_mirrored", "CheckButton", empty) + + +## Build input field styles (LineEdit, TextEdit, SpinBox) +static func _build_inputs(theme: Theme, settings: ThemeSettings, styles: ThemeStyles) -> void: + var input_normal := styles.create_input(settings.input_background) + var input_focus := input_normal.duplicate() + input_focus.draw_center = false + input_focus.set_border_width_all(1) + var input_disabled := styles.create_input(settings.darken(settings.input_background, 0.2)) + + # LineEdit + theme.set_stylebox("normal", "LineEdit", input_normal) + theme.set_stylebox("focus", "LineEdit", input_focus) + theme.set_stylebox("disabled", "LineEdit", input_disabled) + + # LineEditPortraitOption variation + theme.set_type_variation("LineEditPortraitOption", "LineEdit") + var po_input := input_normal.duplicate() + var po_focus := po_input.duplicate() + po_focus.draw_center = true + po_focus.bg_color = settings.panel_background + po_focus.set_border_width_all(1) + + theme.set_color("font_uneditable_color", "LineEditPortraitOption", settings.text) + theme.set_color("font_color", "LineEditPortraitOption", settings.text) + theme.set_stylebox("normal", "LineEditPortraitOption", po_input) + theme.set_stylebox("focus", "LineEditPortraitOption", po_focus) + theme.set_stylebox("disabled", "LineEditPortraitOption", input_disabled) + + # TextEdit + theme.set_font("font", "TextEdit", preload("res://ui/assets/fonts/CourierNewPSMT.ttf")) + theme.set_font_size("font_size", "TextEdit", 16) + theme.set_stylebox("normal", "TextEdit", input_normal.duplicate()) + theme.set_stylebox("focus", "TextEdit", input_focus.duplicate()) + theme.set_stylebox("read_only", "TextEdit", input_disabled.duplicate()) + + # SpinBox components + theme.set_type_variation("SpinBoxButtonLeft", "Button") + theme.set_type_variation("SpinBoxButtonRight", "Button") + + var spin_btn := styles.create_empty() + spin_btn.set_content_margin_all(styles.base_spacing / 2) + var spin_btn_pressed := styles.create_panel(settings.button_background) + spin_btn_pressed.set_content_margin_all(styles.base_spacing / 2) + + var spin_btn_pressed_left := spin_btn_pressed.duplicate() + spin_btn_pressed_left.corner_radius_top_right = 0 + spin_btn_pressed_left.corner_radius_bottom_right = 0 + + var spin_btn_pressed_right := spin_btn_pressed.duplicate() + spin_btn_pressed_right.corner_radius_top_left = 0 + spin_btn_pressed_right.corner_radius_bottom_left = 0 + + theme.set_stylebox("normal", "SpinBoxButtonLeft", spin_btn) + theme.set_stylebox("pressed", "SpinBoxButtonLeft", spin_btn_pressed_left) + theme.set_stylebox("focus", "SpinBoxButtonLeft", spin_btn) + theme.set_stylebox("hover", "SpinBoxButtonLeft", spin_btn) + theme.set_stylebox("disabled", "SpinBoxButtonLeft", spin_btn) + + theme.set_stylebox("normal", "SpinBoxButtonRight", spin_btn) + theme.set_stylebox("pressed", "SpinBoxButtonRight", spin_btn_pressed_right) + theme.set_stylebox("focus", "SpinBoxButtonRight", spin_btn) + theme.set_stylebox("hover", "SpinBoxButtonRight", spin_btn) + theme.set_stylebox("disabled", "SpinBoxButtonRight", spin_btn) + + # SpinBoxLineEdit variation + # FIXME: A type associated with a built-in class cannot be marked as a variation + # of another type (variation: "SpinBoxLineEdit", base: "LineEdit"). + theme.set_type_variation("SpinBoxLineEdit", "LineEdit") + var spin_input := styles.create_input(settings.input_background) + spin_input.draw_center = false + spin_input.set_content_margin_all(0) + var spin_input_focus := spin_input.duplicate() + spin_input_focus.bg_color = settings.button_background + spin_input_focus.set_corner_radius_all(0) + + theme.set_stylebox("normal", "SpinBoxLineEdit", spin_input) + theme.set_stylebox("focus", "SpinBoxLineEdit", spin_input_focus) + theme.set_stylebox("read_only", "SpinBoxLineEdit", spin_input) + + +## Build panel and container styles +static func _build_panels(theme: Theme, settings: ThemeSettings, styles: ThemeStyles) -> void: + # Base Panel/PanelContainer + var panel := styles.create_panel(settings.panel_background) + theme.set_stylebox("panel", "Panel", panel) + theme.set_stylebox("panel", "PanelContainer", panel) + + # EditorBackground + theme.set_type_variation("EditorBackground", "PanelContainer") + var bg := styles.create_panel(settings.secondary) + bg.set_corner_radius_all(0) + theme.set_stylebox("panel", "EditorBackground", bg) + + # InspectorPanel + theme.set_type_variation("InspectorPanel", "PanelContainer") + var inspector := styles.create_panel(settings.panel_background) + inspector.set_corner_radius_all(0) + inspector.set_border_width_all(0) + theme.set_stylebox("panel", "InspectorPanel", inspector) + + # InspectorPanelTopBox + theme.set_type_variation("InspectorPanelTopBox", "PanelContainer") + var top_box := styles.create_panel(settings.panel_background) + top_box.set_corner_radius_all(0) + top_box.set_border_width_all(0) + top_box.set_content_margin_all(0) + top_box.set_expand_margin_all(styles.base_spacing) + top_box.expand_margin_left -= 1 + theme.set_stylebox("panel", "InspectorPanelTopBox", top_box) + + # FoldableContainer + var f_panel := styles.create_panel(settings.darken(settings.secondary, 0.15), false) + #f_panel.border_color = settings.lighten(settings.border, 0.1) + var f_title_collapsed_panel := f_panel.duplicate() + f_title_collapsed_panel.bg_color = settings.secondary + f_title_collapsed_panel.set_content_margin_all(styles.base_spacing) + var f_title_panel := f_title_collapsed_panel.duplicate() + + #f_panel.draw_center = false + f_panel.border_width_top = 0 + f_panel.corner_radius_top_left = 0 + f_panel.corner_radius_top_right = 0 + f_title_panel.corner_radius_bottom_left = 0 + f_title_panel.corner_radius_bottom_right = 0 + + theme.set_font_size("font_size", "FoldableContainer", 18) + #theme.set_font("font", "FoldableContainer", preload("res://ui/assets/fonts/GeneralSans-SemiBold.otf")) + theme.set_stylebox("focus", "FoldableContainer", styles.create_empty()) + theme.set_stylebox("panel", "FoldableContainer", f_panel) + theme.set_stylebox("title_panel", "FoldableContainer", f_title_panel) + theme.set_stylebox("title_hover_panel", "FoldableContainer", f_title_panel) + theme.set_stylebox("title_collapsed_panel", "FoldableContainer", f_title_collapsed_panel) + theme.set_stylebox("title_collapsed_hover_panel", "FoldableContainer", f_title_collapsed_panel) + + # FieldContainer + theme.set_type_variation("FieldContainer", "PanelContainer") + var field_container_panel := styles.create_panel(settings.panel_background) + field_container_panel.draw_center = false + theme.set_stylebox("panel", "FieldContainer", field_container_panel) + + # FieldPanel + theme.set_type_variation("FieldPanel", "PanelContainer") + var field_panel := styles.create_panel(settings.panel_background, false) + field_panel.set_content_margin_all(styles.base_spacing * 2) + theme.set_stylebox("panel", "FieldPanel", field_panel) + + # OuterPanel + theme.set_type_variation("OuterPanel", "PanelContainer") + var outer := styles.create_panel(settings.panel_background, true) + outer.set_corner_radius_all(styles.base_spacing + styles.corner_radius) + theme.set_stylebox("panel", "OuterPanel", outer) + + # ItemContainer variations + theme.set_type_variation("ItemContainer", "PanelContainer") + var item := styles.create_empty() + theme.set_stylebox("panel", "ItemContainer", item) + + theme.set_type_variation("ItemContainerFlat", "PanelContainer") + var item_flat := styles.create_empty() + item_flat.set_content_margin_all(0) + theme.set_stylebox("panel", "ItemContainerFlat", item_flat) + + # Timeline panels + theme.set_type_variation("TimelineCellNumber", "PanelContainer") + var timeline_cell := styles.create_panel(settings.panel_background) + timeline_cell.set_corner_radius_all(0) + timeline_cell.border_width_right = styles.border_width + timeline_cell.border_color = Color.BLACK + theme.set_stylebox("panel", "TimelineCellNumber", timeline_cell) + + theme.set_type_variation("TimelineLayerPanel", "PanelContainer") + var timeline_layer := styles.create_panel(settings.panel_background) + timeline_layer.set_corner_radius_all(0) + timeline_layer.border_width_bottom = styles.border_width + timeline_layer.border_color = Color.BLACK + theme.set_stylebox("panel", "TimelineLayerPanel", timeline_layer) + + # TreeContainer + theme.set_type_variation("TreeContainer", "PanelContainer") + var tree_container := styles.create_panel(settings.panel_background) + tree_container.set_corner_radius_all(0) + theme.set_stylebox("panel", "TreeContainer", tree_container) + + # TooltipPanel + var tooltip := styles.create_panel(settings.with_alpha(settings.panel_background, 0.5)) + tooltip.set_corner_radius_all(0) + theme.set_stylebox("panel", "TooltipPanel", tooltip) + + # Container separations + theme.set_type_variation("FieldContainer", "VBoxContainer") + theme.set_constant("separation", "HBoxContainer", styles.base_spacing) + theme.set_constant("separation", "VBoxContainer", styles.base_spacing) + theme.set_constant("separation", "FieldContainer", styles.base_spacing / 2) + + theme.set_constant("separation", "HSplitContainer", styles.base_spacing) + theme.set_constant("separation", "VSplitContainer", styles.base_spacing) + theme.set_icon("grabber", "HSplitContainer", Texture2D.new()) + theme.set_icon("grabber", "VSplitContainer", Texture2D.new()) + + # ListItemContainer + theme.set_type_variation("ListItemContainer", "PanelContainer") + var list_item_container := styles.create_panel(settings.darken(settings.secondary, 0.15), false) + theme.set_stylebox("panel", "ListItemContainer", list_item_container) + + +## Build scrollbar styles +static func _build_scrollbars(theme: Theme, settings: ThemeSettings, styles: ThemeStyles) -> void: + var scroll_empty := styles.create_empty() + scroll_empty.border_color = settings.border + scroll_empty.set_content_margin_all(2) + scroll_empty.set_corner_radius_all(0) + + var scroll_focus := scroll_empty.duplicate() + scroll_focus.draw_center = true + + var grabber := styles.create_panel(settings.border) + grabber.set_corner_radius_all(5) + + # VScrollBar + theme.set_stylebox("scroll", "VScrollBar", scroll_empty) + theme.set_stylebox("scroll_focus", "VScrollBar", scroll_focus) + theme.set_stylebox("grabber", "VScrollBar", grabber) + theme.set_stylebox("grabber_highlight", "VScrollBar", grabber) + theme.set_stylebox("grabber_pressed", "VScrollBar", grabber) + + # HScrollBar + theme.set_stylebox("scroll", "HScrollBar", scroll_empty) + theme.set_stylebox("scroll_focus", "HScrollBar", scroll_focus) + theme.set_stylebox("grabber", "HScrollBar", grabber) + theme.set_stylebox("grabber_highlight", "HScrollBar", grabber) + theme.set_stylebox("grabber_pressed", "HScrollBar", grabber) + + +## Build separator styles +static func _build_separators(theme: Theme, settings: ThemeSettings, styles: ThemeStyles) -> void: + var sep_h := styles.create_separator(false) + var sep_v := styles.create_separator(true) + + theme.set_constant("separation", "HSeparator", 1) + theme.set_constant("separation", "VSeparator", 1) + theme.set_stylebox("separator", "HSeparator", sep_h) + theme.set_stylebox("separator", "VSeparator", sep_v) + + # Dotted separator + theme.set_type_variation("HDottedSeparator", "HSeparator") + theme.set_type_variation("VDottedSeparator", "VSeparator") + + var dotted := StyleBoxTexture.new() + dotted.texture = preload("res://ui/theme_default/assets/dash.svg") + dotted.modulate_color = settings.border + dotted.axis_stretch_horizontal = StyleBoxTexture.AXIS_STRETCH_MODE_TILE_FIT + dotted.axis_stretch_vertical = StyleBoxTexture.AXIS_STRETCH_MODE_TILE_FIT + dotted.texture_margin_top = 1 + + theme.set_constant("separation", "HDottedSeparator", 1) + theme.set_constant("separation", "VDottedSeparator", 1) + theme.set_stylebox("separator", "HDottedSeparator", dotted) + theme.set_stylebox("separator", "VDottedSeparator", dotted) + + # Grow variants + theme.set_type_variation("HSeparatorGrow", "HSeparator") + theme.set_type_variation("VSeparatorGrow", "VSeparator") + var sep_grow_h := styles.create_separator(false) + sep_grow_h.grow_begin = styles.base_spacing + sep_grow_h.grow_end = styles.base_spacing + var sep_grow_v := styles.create_separator(true) + sep_grow_v.grow_begin = styles.base_spacing + sep_grow_v.grow_end = styles.base_spacing + + theme.set_constant("separation", "HSeparatorGrow", 1) + theme.set_constant("separation", "VSeparatorGrow", 1) + theme.set_stylebox("separator", "HSeparatorGrow", sep_grow_h) + theme.set_stylebox("separator", "VSeparatorGrow", sep_grow_v) + + +## Build slider styles +static func _build_sliders(theme: Theme, settings: ThemeSettings, styles: ThemeStyles) -> void: + var slider_track := StyleBoxFlat.new() + slider_track.content_margin_top = styles.base_spacing + slider_track.set_corner_radius_all(5) + slider_track.bg_color = settings.button_background + + var grabber_area := slider_track.duplicate() + grabber_area.bg_color = settings.accent + + theme.set_icon("grabber", "HSlider", ICON_SLIDER_GRABBER) + theme.set_icon("grabber_highlight", "HSlider", ICON_SLIDER_GRABBER) + theme.set_icon("grabber_disabled", "HSlider", ICON_SLIDER_GRABBER) + theme.set_stylebox("slider", "HSlider", slider_track) + theme.set_stylebox("grabber_area", "HSlider", grabber_area) + theme.set_stylebox("grabber_area_highlight", "HSlider", grabber_area) + + +## Build tab styles +static func _build_tabs(theme: Theme, settings: ThemeSettings, styles: ThemeStyles) -> void: + # TabBar + var tab_unselected := styles.create_button(settings.secondary) + tab_unselected.content_margin_top /= 2 + tab_unselected.content_margin_bottom /= 2 + + var tab_selected := tab_unselected.duplicate() + tab_selected.draw_center = true + tab_selected.bg_color = settings.accent + + theme.set_color("font_disabled_color", "TabBar", settings.text_disabled) + theme.set_color("font_unselected_color", "TabBar", settings.text_secondary) + theme.set_color("font_hovered_color", "TabBar", settings.text) + theme.set_color("font_selected_color", "TabBar", settings.text) + theme.set_constant("h_separation", "TabBar", styles.base_spacing) + #theme.set_font_size("font_size", "TabBar", 16) + theme.set_icon("close", "TabBar", preload("res://ui/assets/icons/ui_close.svg")) + theme.set_icon("menu", "TabBar", preload("res://ui/assets/icons/vertical_dots.svg")) + theme.set_icon("menu_highlight", "TabBar", preload("res://ui/assets/icons/vertical_dots.svg")) + theme.set_icon("increment", "TabContainer", preload("res://ui/assets/icons/arrow_right.svg")) + theme.set_icon( + "increment_highlight", "TabContainer", preload("res://ui/assets/icons/arrow_right.svg") + ) + theme.set_icon("decrement", "TabContainer", preload("res://ui/assets/icons/arrow_left.svg")) + theme.set_icon( + "decrement_highlight", "TabContainer", preload("res://ui/assets/icons/arrow_left.svg") + ) + theme.set_stylebox("button_highlight", "TabBar", StyleBoxEmpty.new()) + theme.set_stylebox("button_pressed", "TabBar", StyleBoxEmpty.new()) + theme.set_stylebox("tab_unselected", "TabBar", tab_unselected) + theme.set_stylebox("tab_hovered", "TabBar", tab_unselected.duplicate()) + theme.set_stylebox("tab_selected", "TabBar", tab_selected) + theme.set_stylebox("tab_disabled", "TabBar", tab_unselected.duplicate()) + theme.set_stylebox("tab_focus", "TabBar", tab_selected.duplicate()) + + # EditorSection (TabContainer variation) + theme.set_type_variation("EditorSection", "TabContainer") + var section_unfocus := styles.create_panel(settings.panel_background, true) + var section_focus := section_unfocus.duplicate() + section_focus.border_color = settings.border + #section_focus.border_color = settings.accent + + theme.set_icon( + "menu", "TabContainer", preload("res://ui/assets/icons/vertical_dots_unfocus.svg") + ) + theme.set_icon( + "menu_highlight", "TabContainer", preload("res://ui/assets/icons/vertical_dots.svg") + ) + theme.set_icon("increment", "TabContainer", preload("res://ui/assets/icons/arrow_right.svg")) + theme.set_icon( + "increment_highlight", "TabContainer", preload("res://ui/assets/icons/arrow_right.svg") + ) + theme.set_icon("decrement", "TabContainer", preload("res://ui/assets/icons/arrow_left.svg")) + theme.set_icon( + "decrement_highlight", "TabContainer", preload("res://ui/assets/icons/arrow_left.svg") + ) + + theme.set_stylebox("panel_unfocus", "EditorSection", section_unfocus) + theme.set_stylebox("panel_focus", "EditorSection", section_focus) + + var tab_panel_unfocus := section_unfocus.duplicate() + tab_panel_unfocus.border_width_top = 0 + #tab_panel_unfocus.corner_radius_top_left = 0 + #tab_panel_unfocus.corner_radius_top_right = 0 + + var tab_panel_focus := tab_panel_unfocus.duplicate() + tab_panel_focus.border_color = settings.border + #tab_panel_focus.border_color = settings.accent + + theme.set_stylebox("tab_panel_unfocus", "EditorSection", tab_panel_unfocus) + theme.set_stylebox("tab_panel_focus", "EditorSection", tab_panel_focus) + + var tabbar_bg_unfocus := styles.create_panel(settings.secondary, true) + tabbar_bg_unfocus.set_border_width_all(0) + tabbar_bg_unfocus.set_corner_radius_all(0) + tabbar_bg_unfocus.content_margin_bottom = 0 + #tabbar_bg_unfocus.corner_radius_top_left = styles.corner_radius + #tabbar_bg_unfocus.corner_radius_top_right = styles.corner_radius + + var tabbar_bg_focus := tabbar_bg_unfocus.duplicate() + tabbar_bg_focus.border_color = settings.border + #tabbar_bg_focus.border_color = settings.accent + + theme.set_stylebox("tabbar_background_unfocus", "EditorSection", tabbar_bg_unfocus) + theme.set_stylebox("tabbar_background_focus", "EditorSection", tabbar_bg_focus) + + var tab_sel := styles.create_button(settings.panel_background) + tab_sel.set_corner_radius_all(0) + tab_sel.corner_radius_top_left = styles.corner_radius - 1 + tab_sel.corner_radius_top_right = styles.corner_radius - 1 + tab_sel.border_color = Color.TRANSPARENT + tab_sel.border_width_top = 1 + + var tab_unsel := styles.create_button(settings.secondary) + tab_unsel.draw_center = false + + theme.set_stylebox("tab_selected", "EditorSection", tab_sel) + theme.set_stylebox("tab_unselected", "EditorSection", tab_unsel) + theme.set_stylebox("tab_focus", "EditorSection", tab_unsel) + theme.set_stylebox("tab_hovered", "EditorSection", tab_unsel) + theme.set_stylebox("tab_disabled", "EditorSection", tab_unsel) + + theme.set_color("font_unselected_color", "EditorSection", settings.text_secondary) + theme.set_color("font_disabled_color", "EditorSection", settings.text_disabled) + theme.set_color("font_hover_color", "EditorSection", settings.text) + theme.set_color("font_selected_color", "EditorSection", settings.text) + theme.set_constant("side_margin", "EditorSection", 1) + theme.set_constant("icon_separation", "EditorSection", styles.base_spacing) + theme.set_constant("icon_max_width", "EditorSection", 16) + theme.set_font_size("font_size", "EditorSection", 16) + + +## Build tree styles +static func _build_tree(theme: Theme, settings: ThemeSettings, styles: ThemeStyles) -> void: + var tree_panel := styles.create_panel(settings.panel_background) + var tree_empty := styles.create_empty() + var tree_hover := styles.create_button(settings.button_hover) + var tree_selected := styles.create_button(settings.button_pressed) + + theme.set_color("relationship_line_color", "Tree", settings.with_alpha(settings.border, 0.5)) + theme.set_constant("icon_max_width", "Tree", 14) + theme.set_constant("h_separation", "Tree", styles.base_spacing) + theme.set_constant("v_separation", "Tree", styles.base_spacing / 2) + theme.set_constant("inner_item_margin_bottom", "Tree", styles.base_spacing) + theme.set_constant("inner_item_margin_left", "Tree", styles.base_spacing) + theme.set_constant("inner_item_margin_top", "Tree", styles.base_spacing) + theme.set_constant("inner_item_margin_right", "Tree", styles.base_spacing) + theme.set_constant("draw_relationship_lines", "Tree", 1) + theme.set_constant("draw_guides", "Tree", 0) + theme.set_constant("relationship_line_width", "Tree", 0) + theme.set_constant("parent_hl_line_width", "Tree", styles.border_width) + theme.set_constant("children_hl_line_width", "Tree", 0) + theme.set_icon("checked", "Tree", ICON_CHECKED) + theme.set_icon("unchecked", "Tree", ICON_UNCHECKED) + theme.set_icon("checked_disabled", "Tree", ICON_CHECKED_DISABLED) + theme.set_icon("unchecked_disabled", "Tree", ICON_UNCHECKED_DISABLED) + theme.set_stylebox("panel", "Tree", tree_panel) + theme.set_stylebox("focus", "Tree", tree_empty) + theme.set_stylebox("hovered", "Tree", tree_hover) + theme.set_stylebox("hovered_dimmed", "Tree", tree_hover) + theme.set_stylebox("selected", "Tree", tree_selected) + theme.set_stylebox("selected_focus", "Tree", tree_selected) + + +## Build graph-related styles +static func _build_graph_elements( + theme: Theme, settings: ThemeSettings, styles: ThemeStyles +) -> void: + # GraphEdit + var graph_bg := styles.create_panel(settings.graph_bg) + graph_bg.set_content_margin_all(0) + graph_bg.set_corner_radius_all(0) + graph_bg.set_border_width_all(0) + + theme.set_color("grid_major", "GraphEdit", settings.with_alpha(settings.text, 0.15)) + theme.set_color("grid_minor", "GraphEdit", settings.with_alpha(settings.text, 0.15)) + theme.set_stylebox("panel", "GraphEdit", graph_bg) + + # GraphNode + var node_panel := styles.create_panel(settings.panel_background, true) + node_panel.shadow_color = settings.with_alpha(Color.BLACK, 0.05) + node_panel.shadow_size = 8 + + var node_selected := node_panel.duplicate() + node_selected.border_color = settings.lighten(settings.border, 0.1) + + theme.set_constant("separation", "GraphNode", styles.base_spacing) + theme.set_stylebox("panel", "GraphNode", node_panel) + theme.set_stylebox("panel_selected", "GraphNode", node_selected) + theme.set_stylebox("titlebar", "GraphNode", StyleBoxEmpty.new()) + theme.set_stylebox("titlebar_selected", "GraphNode", StyleBoxEmpty.new()) + theme.set_stylebox("slot", "GraphNode", StyleBoxEmpty.new()) + + # GraphNode label variants + theme.set_font_size("font_size", "GraphNodeTitleLabel", 1) + + theme.set_type_variation("GraphNodeViewTitleLabel", "Label") + theme.set_color("font_color", "GraphNodeViewTitleLabel", settings.text) + theme.set_font_size("font_size", "GraphNodeViewTitleLabel", 18) + + theme.set_type_variation("GraphNodeViewValueLabel", "Label") + theme.set_color( + "font_color", "GraphNodeViewValueLabel", settings.with_alpha(settings.text, 0.5) + ) + theme.set_font_size("font_size", "GraphNodeViewValueLabel", 16) + + theme.set_type_variation("GraphNodeViewRownHBox", "HBoxContainer") + theme.set_constant("separation", "GraphNodeViewRownHBox", styles.base_spacing * 5) + + # GraphNodePicker + theme.set_type_variation("GraphNodePicker", "PanelContainer") + var picker := styles.create_panel(settings.panel_background) + theme.set_stylebox("panel", "GraphNodePicker", picker) + + +## Build popup menu styles +static func _build_popup_menu(theme: Theme, settings: ThemeSettings, styles: ThemeStyles) -> void: + var menu_panel := styles.create_panel(settings.panel_background, true) + var menu_hover := styles.create_input(settings.surface_variant) + var menu_sep := styles.create_separator(true) + menu_sep.color = settings.with_alpha(settings.text, 0.15) + + theme.set_constant("icon_max_width", "PopupMenu", 14) + theme.set_constant("item_end_padding", "PopupMenu", styles.base_spacing) + theme.set_constant("item_start_padding", "PopupMenu", styles.base_spacing) + theme.set_constant("h_separation", "PopupMenu", styles.base_spacing) + theme.set_constant("v_separation", "PopupMenu", 4) + theme.set_font_size("font_size", "PopupMenu", 16) + theme.set_icon("checked", "PopupMenu", ICON_CHECKED) + theme.set_icon("unchecked", "PopupMenu", ICON_UNCHECKED) + theme.set_icon("radio_checked", "PopupMenu", ICON_RADIO_CHECKED) + theme.set_icon("radio_unchecked", "PopupMenu", ICON_RADIO_UNCHECKED) + theme.set_icon("checked_disabled", "PopupMenu", ICON_CHECKED_DISABLED) + theme.set_icon("unchecked_disabled", "PopupMenu", ICON_UNCHECKED_DISABLED) + theme.set_icon("radio_checked_disabled", "PopupMenu", ICON_RADIO_CHECKED_DISABLED) + theme.set_icon("radio_unchecked_disabled", "PopupMenu", ICON_RADIO_UNCHECKED_DISABLED) + theme.set_stylebox("panel", "PopupMenu", menu_panel) + theme.set_stylebox("hover", "PopupMenu", menu_hover) + theme.set_stylebox("separator", "PopupMenu", menu_sep) + + # OptionButton + var option_normal := styles.create_input(settings.surface_variant) + var option_hover := styles.create_input(settings.lighten(settings.surface_variant, 0.05)) + var option_pressed := styles.create_input(settings.lighten(settings.surface_variant, 0.1)) + var option_disabled := styles.create_input(settings.darken(settings.surface_variant, 0.2)) + var option_empty := styles.create_empty() + + theme.set_constant("arrow_margin", "OptionButton", styles.base_spacing) + theme.set_constant("h_separation", "OptionButton", styles.base_spacing) + theme.set_stylebox("disabled", "OptionButton", option_disabled) + theme.set_stylebox("disabled_mirrored", "OptionButton", option_disabled) + theme.set_stylebox("focus", "OptionButton", option_empty) + theme.set_stylebox("hover", "OptionButton", option_hover) + theme.set_stylebox("hover_mirrored", "OptionButton", option_hover) + theme.set_stylebox("hover_pressed", "OptionButton", option_pressed) + theme.set_stylebox("hover_pressed_mirrored", "OptionButton", option_pressed) + theme.set_stylebox("normal", "OptionButton", option_normal) + theme.set_stylebox("normal_mirrored", "OptionButton", option_normal) + theme.set_stylebox("pressed", "OptionButton", option_pressed) + theme.set_stylebox("pressed_mirrored", "OptionButton", option_pressed) + + +## Build label styles +static func _build_labels(theme: Theme, settings: ThemeSettings, styles: ThemeStyles) -> void: + var label_bg := styles.create_panel(settings.panel_background) + label_bg.content_margin_top = styles.base_spacing / 2 + label_bg.content_margin_bottom = styles.base_spacing / 2 + + theme.set_color("font_color", "Label", settings.text) + + theme.set_type_variation("NodeValue", "Label") + theme.set_color("font_color", "NodeValue", settings.text) + theme.set_stylebox("normal", "NodeValue", label_bg) + + theme.set_type_variation("NoteLabel", "Label") + theme.set_color("font_color", "NoteLabel", settings.with_alpha(settings.text, 0.6)) + + theme.set_type_variation("WarnLabel", "Label") + theme.set_color("font_color", "WarnLabel", settings.warning) diff --git a/ui/theme_default/theme_builder.gd.uid b/ui/theme_default/theme_builder.gd.uid new file mode 100644 index 00000000..f522e73f --- /dev/null +++ b/ui/theme_default/theme_builder.gd.uid @@ -0,0 +1 @@ +uid://bc342117tcw8t diff --git a/ui/theme_default/theme_default.gd b/ui/theme_default/theme_default.gd deleted file mode 100644 index 37ffcc81..00000000 --- a/ui/theme_default/theme_default.gd +++ /dev/null @@ -1,805 +0,0 @@ -@tool -class_name MonologueTheme extends Theme - -var scale: float -var dark_theme: bool = true -var contrast: float = 0.15 -# Colors -var text_color: Color = Color("e3e4eb") -var background_color: Color = Color("19191c") -var primary_color: Color = Color("a9a8c0") -var secondary_color: Color = Color("676278") -var accent_color: Color = Color("d15050") -var warn_color: Color = Color("c42e40") -# Constants -var base_spacing: int = 8 -var corner_radius: int = 6 -var relationship_line_opacity: float = 0.2 -var border_width: int = 1 - - -func _init() -> void: - scale = 1.0 - var _use_high_ppi: bool = scale >= 1.0 - - _generate_theme() - - -func _generate_theme() -> void: - # Globals - var base_margin: float = base_spacing - var base_border_color: Color = _get_text_color(0.2) - var outer_radius: float = base_spacing + corner_radius - - # Main stylebox - var base_sb: StyleBoxFlat = StyleBoxFlat.new() - base_sb.bg_color = background_color - base_sb.set_content_margin_all(base_margin) - base_sb.set_corner_radius_all(int(corner_radius)) - base_sb.border_color = base_border_color - - var base_empty_sb: StyleBoxFlat = base_sb.duplicate() - base_empty_sb.draw_center = false - - var base_field_sb: StyleBoxFlat = base_sb.duplicate() - base_field_sb.content_margin_top = base_spacing / 2 - base_field_sb.content_margin_bottom = base_spacing / 2 - base_field_sb.bg_color = _get_secondary_color(contrast) - - var button_sb: StyleBoxFlat = base_sb.duplicate() - button_sb.bg_color = _get_secondary_color(contrast) - button_sb.content_margin_left = base_margin - button_sb.content_margin_top = base_margin * 0.5 - button_sb.content_margin_right = base_margin - button_sb.content_margin_bottom = base_margin * 0.5 - - var button_hover_sb: StyleBoxFlat = button_sb.duplicate() - button_hover_sb.bg_color = _get_secondary_color(contrast + 0.05) - - var button_pressed_sb: StyleBoxFlat = button_sb.duplicate() - button_pressed_sb.bg_color = _get_secondary_color(contrast + 0.1) - - var button_disabled_sb: StyleBoxFlat = button_sb.duplicate() - button_disabled_sb.bg_color = _get_secondary_color(0.05) - - var flat_button_sb: StyleBoxFlat = base_sb.duplicate() - flat_button_sb.bg_color = Color.TRANSPARENT - flat_button_sb.set_border_width_all(border_width) - _set_border(flat_button_sb, _get_text_color(contrast)) - - var flat_button_hover_sb: StyleBoxFlat = flat_button_sb.duplicate() - flat_button_hover_sb.bg_color = _get_secondary_color(0.1) - _set_border(flat_button_hover_sb, _get_text_color(contrast + 0.05)) - - var flat_button_pressed_sb: StyleBoxFlat = flat_button_sb.duplicate() - button_pressed_sb.bg_color = _get_secondary_color(contrast / 2) - _set_border(flat_button_hover_sb, _get_text_color(contrast + 0.1)) - - # Button - - set_color("font_color", "Button", _get_text_color(0.8)) - set_color("font_disabled_color", "Button", _get_text_color(0.3)) - set_color("font_focus_color", "Button", text_color) - set_color("font_hover_color", "Button", text_color) - set_color("font_hover_pressed_color", "Button", text_color) - set_color("font_pressed_color", "Button", text_color) - set_color("icon_disabled_color", "Button", _get_text_color(0.3)) - set_color("icon_normal_color", "Button", _get_text_color(0.8)) - set_constant("outline_size", "Button", 0) - set_stylebox("disabled", "Button", button_disabled_sb) - set_stylebox("disabled_mirrored", "Button", button_disabled_sb) - set_stylebox("focus", "Button", base_empty_sb) - set_stylebox("hover", "Button", button_hover_sb) - set_stylebox("hover_mirrored", "Button", button_hover_sb) - set_stylebox("hover_pressed", "Button", button_pressed_sb) - set_stylebox("hover_pressed_mirrored", "Button", button_pressed_sb) - set_stylebox("normal", "Button", button_sb) - set_stylebox("normal_mirrored", "Button", button_sb) - set_stylebox("pressed", "Button", button_pressed_sb) - set_stylebox("pressed_mirrored", "Button", button_pressed_sb) - - # ButtonAccent - - set_type_variation("ButtonAccent", "Button") - - var button_accent_base_sb: StyleBoxFlat = base_sb.duplicate() - button_accent_base_sb.bg_color = accent_color - - set_stylebox("disabled", "ButtonAccent", button_accent_base_sb) - set_stylebox("disabled_mirrored", "ButtonAccent", button_accent_base_sb) - set_stylebox("focus", "ButtonAccent", button_accent_base_sb) - set_stylebox("hover", "ButtonAccent", button_accent_base_sb) - set_stylebox("hover_mirrored", "ButtonAccent", button_accent_base_sb) - set_stylebox("hover_pressed", "ButtonAccent", button_accent_base_sb) - set_stylebox("hover_pressed_mirrored", "ButtonAccent", button_accent_base_sb) - set_stylebox("normal", "ButtonAccent", button_accent_base_sb) - set_stylebox("normal_mirrored", "ButtonAccent", button_accent_base_sb) - set_stylebox("pressed", "ButtonAccent", button_accent_base_sb) - set_stylebox("pressed_mirrored", "ButtonAccent", button_accent_base_sb) - - # ButtonWarning - - set_type_variation("ButtonWarning", "Button") - - var delete_button_sb: StyleBoxFlat = button_sb.duplicate() - delete_button_sb.bg_color = _get_color(warn_color, contrast) - - var delete_button_hover_sb: StyleBoxFlat = button_sb.duplicate() - delete_button_hover_sb.bg_color = _get_color(warn_color, contrast + 0.05) - - var delete_button_pressed_sb: StyleBoxFlat = button_sb.duplicate() - delete_button_pressed_sb.bg_color = _get_color(warn_color, contrast + 0.1) - - var delete_button_disabled_sb: StyleBoxFlat = button_sb.duplicate() - delete_button_disabled_sb.bg_color = _get_color(warn_color, 0.05) - - set_constant("outline_size", "ButtonWarning", 0) - set_stylebox("disabled", "ButtonWarning", delete_button_disabled_sb) - set_stylebox("disabled_mirrored", "ButtonWarning", delete_button_disabled_sb) - set_stylebox("focus", "ButtonWarning", base_empty_sb) - set_stylebox("hover", "ButtonWarning", delete_button_hover_sb) - set_stylebox("hover_mirrored", "ButtonWarning", delete_button_hover_sb) - set_stylebox("hover_pressed", "ButtonWarning", delete_button_pressed_sb) - set_stylebox("hover_pressed_mirrored", "ButtonWarning", delete_button_pressed_sb) - set_stylebox("normal", "ButtonWarning", delete_button_sb) - set_stylebox("normal_mirrored", "ButtonWarning", delete_button_sb) - set_stylebox("pressed", "ButtonWarning", delete_button_pressed_sb) - set_stylebox("pressed_mirrored", "ButtonWarning", delete_button_pressed_sb) - - # CheckBox - - var check_box_sb: StyleBoxFlat = base_empty_sb.duplicate() - check_box_sb.set_content_margin_all(0) - - var check_box_hover_sb: StyleBoxFlat = check_box_sb.duplicate() - #check_box_hover_sb.bg_color = _get_primary_color(contrast) - - var check_box_pressed_sb: StyleBoxFlat = check_box_sb.duplicate() - #check_box_pressed_sb.bg_color = _get_primary_color(contrast) - - var check_box_disabled_sb: StyleBoxFlat = check_box_sb.duplicate() - #check_box_disabled_sb.bg_color = _get_primary_color(0.05) - - set_color("font_hover_pressed_color", "CheckBox", text_color) - set_color("font_pressed_color", "CheckBox", _get_text_color(0.7)) - set_constant("h_separation", "CheckBox", int(base_margin)) - set_icon("checked", "CheckBox", preload("res://ui/theme_default/assets/checked.svg")) - set_icon("unchecked", "CheckBox", preload("res://ui/theme_default/assets/unchecked.svg")) - set_icon( - "radio_checked", "CheckBox", preload("res://ui/theme_default/assets/radio_checked.svg") - ) - set_icon( - "radio_unchecked", "CheckBox", preload("res://ui/theme_default/assets/radio_unchecked.svg") - ) - set_icon( - "checked_disabled", - "CheckBox", - preload("res://ui/theme_default/assets/checked_disabled.svg") - ) - set_icon( - "unchecked_disabled", - "CheckBox", - preload("res://ui/theme_default/assets/unchecked_disabled.svg") - ) - set_icon( - "radio_checked_disabled", - "CheckBox", - preload("res://ui/theme_default/assets/radio_checked_disabled.svg") - ) - set_icon( - "radio_unchecked_disabled", - "CheckBox", - preload("res://ui/theme_default/assets/radio_unchecked_disabled.svg") - ) - set_stylebox("focus", "CheckBox", check_box_hover_sb) - set_stylebox("disabled", "CheckBox", check_box_disabled_sb) - set_stylebox("disabled_mirrored", "CheckBox", check_box_disabled_sb) - set_stylebox("hover", "CheckBox", check_box_hover_sb) - set_stylebox("hover_mirrored", "CheckBox", check_box_hover_sb) - set_stylebox("hover_pressed", "CheckBox", check_box_pressed_sb) - set_stylebox("hover_pressed_mirrored", "CheckBox", check_box_pressed_sb) - set_stylebox("pressed", "CheckBox", check_box_pressed_sb) - set_stylebox("pressed_mirrored", "CheckBox", check_box_pressed_sb) - set_stylebox("normal", "CheckBox", check_box_sb) - set_stylebox("normal_mirrored", "CheckBox", check_box_sb) - - # CheckButton - - set_color("font_focus_color", "CheckButton", _get_text_color(0.7)) - set_color("font_hover_pressed_color", "CheckButton", text_color) - set_color("font_pressed_color", "CheckButton", text_color) - set_icon("checked", "CheckButton", preload("res://ui/assets/icons/toggle_on.svg")) - set_icon("unchecked", "CheckButton", preload("res://ui/assets/icons/toggle_off.svg")) - set_stylebox("focus", "CheckButton", check_box_hover_sb) - set_stylebox("disabled", "CheckButton", check_box_disabled_sb) - set_stylebox("disabled_mirrored", "CheckButton", check_box_disabled_sb) - set_stylebox("hover", "CheckButton", check_box_hover_sb) - set_stylebox("hover_mirrored", "CheckButton", check_box_hover_sb) - set_stylebox("hover_pressed", "CheckButton", check_box_pressed_sb) - set_stylebox("hover_pressed_mirrored", "CheckButton", check_box_pressed_sb) - set_stylebox("pressed", "CheckButton", check_box_pressed_sb) - set_stylebox("pressed_mirrored", "CheckButton", check_box_pressed_sb) - set_stylebox("normal", "CheckButton", check_box_sb) - set_stylebox("normal_mirrored", "CheckButton", check_box_sb) - - # CollapsibleFieldPanel - - set_type_variation("CollapsibleFieldPanel", "PanelContainer") - var sb: StyleBoxFlat = base_sb.duplicate() - sb.bg_color = _get_secondary_color(contrast / 2) - set_stylebox("panel", "CollapsibleFieldPanel", sb) - - # EditorBackground - - set_type_variation("EditorBackground", "PanelContainer") - sb = base_sb.duplicate() - sb.bg_color = _get_primary_color(contrast, false) - sb.set_corner_radius_all(0) - sb.set_content_margin_all(0) - set_stylebox("panel", "EditorBackground", sb) - - # EditorSidePanel - - set_type_variation("EditorSidePanel", "PanelContainer") - sb = base_sb.duplicate() - sb.bg_color = _get_primary_color(contrast, false) - sb.set_corner_radius_all(0) - sb.set_border_width_all(0) - sb.border_width_left = 1 - set_stylebox("panel", "EditorSidePanel", sb) - - # EditorSidePanelTopBox - - set_type_variation("EditorSidePanelTopBox", "PanelContainer") - sb = base_sb.duplicate() - sb.bg_color = _get_primary_color(contrast, false) - sb.set_corner_radius_all(0) - sb.set_border_width_all(0) - sb.set_content_margin_all(0) - sb.set_expand_margin_all(base_spacing) - sb.expand_margin_left -= 1 - set_stylebox("panel", "EditorSidePanelTopBox", sb) - - # FlatButton - - set_color("font_color", "FlatButton", _get_text_color(0.8)) - set_color("font_disabled_color", "FlatButton", _get_text_color(0.3)) - set_color("font_focus_color", "FlatButton", text_color) - set_color("font_hover_color", "FlatButton", text_color) - set_color("font_hover_pressed_color", "FlatButton", text_color) - set_color("font_pressed_color", "FlatButton", text_color) - set_color("icon_disabled_color", "FlatButton", _get_text_color(0.3)) - set_color("icon_normal_color", "FlatButton", _get_text_color(0.8)) - set_constant("outline_size", "FlatButton", 0) - set_stylebox("disabled", "FlatButton", button_disabled_sb) - set_stylebox("disabled_mirrored", "FlatButton", button_disabled_sb) - set_stylebox("normal", "FlatButton", flat_button_sb) - set_stylebox("normal_mirrored", "FlatButton", flat_button_sb) - set_stylebox("hover", "FlatButton", flat_button_hover_sb) - set_stylebox("hover_mirrored", "FlatButton", flat_button_hover_sb) - set_stylebox("hover_pressed", "FlatButton", flat_button_pressed_sb) - set_stylebox("hover_pressed_mirrored", "FlatButton", flat_button_pressed_sb) - set_stylebox("pressed", "FlatButton", flat_button_pressed_sb) - set_stylebox("pressed_mirrored", "FlatButton", flat_button_pressed_sb) - - # GraphEdit - - sb = base_sb.duplicate() - sb.set_content_margin_all(0) - sb.set_corner_radius_all(0) - sb.set_border_width_all(0) - set_color("grid_major", "GraphEdit", _get_text_color(contrast)) - set_color("grid_minor", "GraphEdit", _get_text_color(contrast)) - set_stylebox("panel", "GraphEdit", sb) - - # GraphNode - - var graph_node_sb: StyleBoxFlat = base_sb.duplicate() - graph_node_sb.bg_color = _get_primary_color(contrast, false) - graph_node_sb.corner_radius_top_left = 0 - graph_node_sb.corner_radius_top_right = 0 - graph_node_sb.shadow_color = Color("#000000", contrast) - graph_node_sb.shadow_size = 30 - _set_border(graph_node_sb, base_border_color) - graph_node_sb.border_width_top = 0 - - var graph_node_selected_sb: StyleBoxFlat = graph_node_sb.duplicate() - graph_node_selected_sb.border_color.a += 0.1 - - var graph_node_titlebar_sb: StyleBoxFlat = base_sb.duplicate() - graph_node_titlebar_sb.corner_radius_bottom_left = 0 - graph_node_titlebar_sb.corner_radius_bottom_right = 0 - graph_node_titlebar_sb.shadow_color = Color("#000000", contrast) - graph_node_titlebar_sb.shadow_size = 30 - _set_border(graph_node_titlebar_sb, base_border_color) - graph_node_titlebar_sb.border_width_bottom = 0 - - var graph_node_titlebar_selected_sb: StyleBoxFlat = graph_node_titlebar_sb.duplicate() - graph_node_titlebar_selected_sb.border_color.a += 0.1 - - set_icon("port", "GraphNode", preload("res://ui/assets/icons/slot.svg")) - set_constant("separation", "GraphNode", base_spacing) - set_stylebox("panel", "GraphNode", graph_node_sb) - set_stylebox("panel_selected", "GraphNode", graph_node_selected_sb) - set_stylebox("titlebar", "GraphNode", graph_node_titlebar_sb) - set_stylebox("titlebar_selected", "GraphNode", graph_node_titlebar_selected_sb) - set_stylebox("slot", "GraphNode", StyleBoxEmpty.new()) - - # GraphNodePicker - - set_type_variation("GraphNodePicker", "PanelContainer") - sb = base_sb.duplicate() - sb.bg_color = _get_primary_color(contrast, false) - set_stylebox("panel", "GraphNodePicker", sb) - - # HBoxContainer & VBoxContainer - - set_type_variation("FieldContainer", "VBoxContainer") - - set_constant("separation", "HBoxContainer", base_spacing) - set_constant("separation", "VBoxContainer", base_spacing) - set_constant("separation", "FieldContainer", base_spacing / 2) - - # HDottedSeparator & VDottedSeparator - - set_type_variation("HDottedSeparator", "HSeparator") - set_type_variation("VDottedSeparator", "VSeparator") - var dotted_sb: StyleBoxTexture = StyleBoxTexture.new() - dotted_sb.texture = preload("res://ui/theme_default/assets/dash.svg") - dotted_sb.modulate_color = base_border_color - dotted_sb.axis_stretch_horizontal = StyleBoxTexture.AXIS_STRETCH_MODE_TILE_FIT - dotted_sb.axis_stretch_vertical = StyleBoxTexture.AXIS_STRETCH_MODE_TILE_FIT - dotted_sb.texture_margin_top = 1 - set_constant("separation", "HDottedSeparator", 1) - set_constant("separation", "VDottedSeparator", 1) - set_stylebox("separator", "HDottedSeparator", dotted_sb) - set_stylebox("separator", "VDottedSeparator", dotted_sb) - - # HSeparator & VSeparator - - var separator_sb: StyleBoxLine = StyleBoxLine.new() - separator_sb.color = base_border_color - separator_sb.vertical = false - separator_sb.grow_begin = 0 - separator_sb.grow_end = 0 - set_constant("separation", "HSeparator", 1) - set_constant("separation", "VSeparator", 1) - set_stylebox("separator", "HSeparator", separator_sb) - separator_sb = separator_sb.duplicate() - separator_sb.vertical = true - set_stylebox("separator", "VSeparator", separator_sb) - - # HSeparatorGrow & VSeparatorGrow - - set_type_variation("HSeparatorGrow", "HSeparator") - set_type_variation("VSeparatorGrow", "VSeparator") - separator_sb = separator_sb.duplicate() - separator_sb.vertical = false - separator_sb.grow_begin = base_spacing - separator_sb.grow_end = base_spacing - set_constant("separation", "HSeparatorGrow", 1) - set_constant("separation", "VSeparatorGrow", 1) - set_stylebox("separator", "HSeparatorGrow", separator_sb) - separator_sb = separator_sb.duplicate() - separator_sb.vertical = true - set_stylebox("separator", "VSeparatorGrow", separator_sb) - - # HSlider - - var slider_sb: StyleBoxFlat = StyleBoxFlat.new() - slider_sb.content_margin_top = 5 - slider_sb.set_corner_radius_all(5) - slider_sb.bg_color = _get_primary_color(contrast) - - var grabber_area: StyleBoxFlat = slider_sb.duplicate() - grabber_area.bg_color = accent_color - - set_icon("grabber", "HSlider", preload("res://ui/theme_default/assets/grabber.svg")) - set_icon("grabber_highlight", "HSlider", preload("res://ui/theme_default/assets/grabber.svg")) - set_icon("grabber_disabled", "HSlider", preload("res://ui/theme_default/assets/grabber.svg")) - set_stylebox("slider", "HSlider", slider_sb) - set_stylebox("grabber_area", "HSlider", grabber_area) - set_stylebox("grabber_area_highlight", "HSlider", grabber_area) - - # ItemContainer - - set_type_variation("ItemContainer", "PanelContainer") - - sb = base_empty_sb.duplicate() - set_stylebox("panel", "ItemContainer", sb) - - # ItemContainerFlat - - set_type_variation("ItemContainerFlat", "PanelContainer") - - sb = base_empty_sb.duplicate() - sb.set_content_margin_all(0) - set_stylebox("panel", "ItemContainerFlat", sb) - - # Label - - set_type_variation("NodeValue", "Label") - set_type_variation("NoteLabel", "Label") - set_type_variation("WarnLabel", "Label") - sb = base_sb.duplicate() - sb.content_margin_top = base_spacing / 2 - sb.content_margin_bottom = base_spacing / 2 - set_color("font_color", "Label", text_color) - set_color("font_color", "NodeValue", text_color) - set_color("font_color", "NoteLabel", _get_text_color(0.6)) - set_color("font_color", "WarnLabel", warn_color) - set_stylebox("normal", "NodeValue", sb) - - # LineEdit - - var line_edit_sb: StyleBoxFlat = base_field_sb.duplicate() - - var line_edit_focus_sb: StyleBoxFlat = line_edit_sb.duplicate() - line_edit_focus_sb.draw_center = false - line_edit_focus_sb.set_border_width_all(1) - - var line_edit_disabled_sb: StyleBoxFlat = line_edit_sb.duplicate() - line_edit_disabled_sb.bg_color = _get_primary_color(0.05) - - set_stylebox("normal", "LineEdit", line_edit_sb) - set_stylebox("focus", "LineEdit", line_edit_focus_sb) - set_stylebox("disabled", "LineEdit", line_edit_disabled_sb) - - # LineEditPortraitOption - - set_type_variation("LineEditPortraitOption", "LineEdit") - - var po_line_edit_sb: StyleBoxFlat = line_edit_sb.duplicate() - - var po_line_edit_focus_sb: StyleBoxFlat = po_line_edit_sb.duplicate() - po_line_edit_focus_sb.draw_center = true - po_line_edit_focus_sb.bg_color = background_color - po_line_edit_focus_sb.set_border_width_all(1) - - var po_line_edit_disabled_sb: StyleBoxFlat = line_edit_disabled_sb.duplicate() - - set_color("font_uneditable_color", "LineEditPortraitOption", text_color) - set_color("font_color", "LineEditPortraitOption", text_color) - set_stylebox("normal", "LineEditPortraitOption", po_line_edit_sb) - set_stylebox("focus", "LineEditPortraitOption", po_line_edit_focus_sb) - set_stylebox("disabled", "LineEditPortraitOption", po_line_edit_disabled_sb) - - # MarginContainer - - set_constant("margin_left", "MarginContainer", int(base_margin)) - set_constant("margin_top", "MarginContainer", int(base_margin)) - set_constant("margin_right", "MarginContainer", int(base_margin)) - set_constant("margin_bottom", "MarginContainer", int(base_margin)) - - # Panel - - sb = base_sb.duplicate() - sb.bg_color = _get_primary_color(contrast, false) - set_stylebox("panel", "Panel", sb) - set_stylebox("panel", "PanelContainer", sb) - - # PopupMenu - - sb = base_sb.duplicate() - sb.bg_color = _get_primary_color(contrast, false) - _set_border(sb, _get_color(base_border_color, base_border_color.a, false)) - var popup_menu_hover_sb: StyleBoxFlat = base_field_sb.duplicate() - popup_menu_hover_sb.bg_color = _get_secondary_color(contrast) - separator_sb.color = text_color - separator_sb.vertical = true - separator_sb.grow_begin = 0 - separator_sb.grow_end = 0 - set_constant("icon_max_width", "PopupMenu", 14) - set_constant("item_end_padding", "PopupMenu", base_spacing) - set_constant("item_start_padding", "PopupMenu", base_spacing) - set_constant("h_separation", "PopupMenu", base_spacing) - set_constant("v_separation", "PopupMenu", 4) - set_font_size("font_size", "PopupMenu", 16) - set_icon("checked", "PopupMenu", preload("res://ui/theme_default/assets/checked.svg")) - set_icon("unchecked", "PopupMenu", preload("res://ui/theme_default/assets/unchecked.svg")) - set_icon( - "radio_checked", "PopupMenu", preload("res://ui/theme_default/assets/radio_checked.svg") - ) - set_icon( - "radio_unchecked", "PopupMenu", preload("res://ui/theme_default/assets/radio_unchecked.svg") - ) - set_icon( - "checked_disabled", - "PopupMenu", - preload("res://ui/theme_default/assets/checked_disabled.svg") - ) - set_icon( - "unchecked_disabled", - "PopupMenu", - preload("res://ui/theme_default/assets/unchecked_disabled.svg") - ) - set_icon( - "radio_checked_disabled", - "PopupMenu", - preload("res://ui/theme_default/assets/radio_checked_disabled.svg") - ) - set_icon( - "radio_unchecked_disabled", - "PopupMenu", - preload("res://ui/theme_default/assets/radio_unchecked_disabled.svg") - ) - set_stylebox("panel", "PopupMenu", sb) - set_stylebox("hover", "PopupMenu", popup_menu_hover_sb) - set_stylebox("separator", "PopupMenu", separator_sb) - - # ScrollBar - var _side_panel_bg_color: Color = _get_primary_color(contrast, false) - var _scroll_bar_color: Color = _get_color( - base_border_color, base_border_color.a, false, _side_panel_bg_color - ) - - var scroll_sb: StyleBoxFlat = base_empty_sb.duplicate() - scroll_sb.border_color = _scroll_bar_color - scroll_sb.set_content_margin_all(2) - scroll_sb.set_corner_radius_all(0) - - # ScrollBar's focus stylebox is not working. - var scroll_focus_sb: StyleBoxFlat = scroll_sb.duplicate() - scroll_focus_sb.draw_center = true - - var grabber_sb: StyleBoxFlat = base_sb.duplicate() - grabber_sb.set_corner_radius_all(5) - grabber_sb.bg_color = _scroll_bar_color - - set_stylebox("scroll", "VScrollBar", scroll_sb) - set_stylebox("scroll_focus", "VScrollBar", scroll_focus_sb) - set_stylebox("grabber", "VScrollBar", grabber_sb) - set_stylebox("grabber", "VScrollBar", grabber_sb) - set_stylebox("grabber_highlight", "VScrollBar", grabber_sb) - set_stylebox("grabber_pressed", "VScrollBar", grabber_sb) - - set_stylebox("scroll", "HScrollBar", scroll_sb) - set_stylebox("scroll_focus", "HScrollBar", scroll_focus_sb) - set_stylebox("grabber", "HScrollBar", grabber_sb) - set_stylebox("grabber", "HScrollBar", grabber_sb) - set_stylebox("grabber_highlight", "HScrollBar", grabber_sb) - set_stylebox("grabber_pressed", "HScrollBar", grabber_sb) - - # SpinBoxButton - - set_type_variation("SpinBoxButtonLeft", "Button") - set_type_variation("SpinBoxButtonRight", "Button") - - var spin_box_button_sb: StyleBoxFlat = base_empty_sb.duplicate() - spin_box_button_sb.set_content_margin_all(base_spacing / 2) - var spin_box_button_pressed_sb: StyleBoxFlat = base_sb.duplicate() - spin_box_button_pressed_sb.set_content_margin_all(base_spacing / 2) - spin_box_button_pressed_sb.bg_color = _get_primary_color(contrast) - spin_box_button_pressed_sb.corner_radius_top_right = 0 - spin_box_button_pressed_sb.corner_radius_bottom_right = 0 - - set_stylebox("normal", "SpinBoxButtonLeft", spin_box_button_sb) - set_stylebox("pressed", "SpinBoxButtonLeft", spin_box_button_pressed_sb) - set_stylebox("focus", "SpinBoxButtonLeft", spin_box_button_sb) - set_stylebox("hover", "SpinBoxButtonLeft", spin_box_button_sb) - set_stylebox("disabled", "SpinBoxButtonLeft", spin_box_button_sb) - - spin_box_button_pressed_sb = spin_box_button_pressed_sb.duplicate() - spin_box_button_pressed_sb.set_corner_radius_all(corner_radius) - spin_box_button_pressed_sb.corner_radius_top_left = 0 - spin_box_button_pressed_sb.corner_radius_bottom_left = 0 - - set_stylebox("normal", "SpinBoxButtonRight", spin_box_button_sb) - set_stylebox("pressed", "SpinBoxButtonRight", spin_box_button_pressed_sb) - set_stylebox("focus", "SpinBoxButtonRight", spin_box_button_sb) - set_stylebox("hover", "SpinBoxButtonRight", spin_box_button_sb) - set_stylebox("disabled", "SpinBoxButtonRight", spin_box_button_sb) - - # SpinBoxLineEdit - - set_type_variation("SpinBoxLineEdit", "LineEdit") - - var spin_box_line_edit_sb: StyleBoxFlat = base_field_sb.duplicate() - spin_box_line_edit_sb.draw_center = false - spin_box_line_edit_sb.set_content_margin_all(0) - var spin_box_line_edit_focus_sb: StyleBoxFlat = spin_box_line_edit_sb.duplicate() - spin_box_line_edit_focus_sb.bg_color = _get_primary_color(contrast) - spin_box_line_edit_focus_sb.set_corner_radius_all(0) - - set_stylebox("normal", "SpinBoxLineEdit", spin_box_line_edit_sb) - set_stylebox("focus", "SpinBoxLineEdit", spin_box_line_edit_focus_sb) - set_stylebox("read_only", "SpinBoxLineEdit", spin_box_line_edit_sb) - - # SpinBoxPanel - - set_type_variation("SpinBoxPanel", "PanelContainer") - sb = base_sb.duplicate() - sb.bg_color = _get_primary_color(contrast / 2) - sb.set_content_margin_all(0) - set_stylebox("panel", "SpinBoxPanel", sb) - - # TabBar - - var tab_unselected_sb: StyleBoxFlat = base_sb.duplicate() - tab_unselected_sb.draw_center = false - tab_unselected_sb.set_border_width_all(0) - tab_unselected_sb.border_width_right = 1 - tab_unselected_sb.set_corner_radius_all(0) - - var tab_hovered_sb: StyleBoxFlat = tab_unselected_sb.duplicate() - var tab_selected_sb: StyleBoxFlat = tab_unselected_sb.duplicate() - tab_selected_sb.draw_center = true - tab_selected_sb.bg_color = accent_color - - var tab_disabled_sb: StyleBoxFlat = tab_unselected_sb.duplicate() - var tab_focus_sb: StyleBoxFlat = tab_unselected_sb.duplicate() - - set_color("font_disabled_color", "TabBar", _get_text_color(0.3)) - set_color("font_unselected_color", "TabBar", _get_text_color(0.8)) - set_color("font_hovered_color", "TabBar", text_color) - set_color("font_selected_color", "TabBar", text_color) - set_constant("h_separation", "TabBar", base_spacing) - set_font_size("font_size", "TabBar", 16) - set_stylebox("button_highlight", "TabBar", StyleBoxEmpty.new()) - set_stylebox("button_pressed", "TabBar", StyleBoxEmpty.new()) - set_stylebox("tab_unselected", "TabBar", tab_unselected_sb) - set_stylebox("tab_hovered", "TabBar", tab_hovered_sb) - set_stylebox("tab_selected", "TabBar", tab_selected_sb) - set_stylebox("tab_disabled", "TabBar", tab_disabled_sb) - set_stylebox("tab_focus", "TabBar", tab_focus_sb) - - # TextEdit - - var text_edit_sb: StyleBoxFlat = line_edit_sb.duplicate() - - var text_edit_focus_sb: StyleBoxFlat = line_edit_focus_sb.duplicate() - - var text_edit_disabled_sb: StyleBoxFlat = line_edit_disabled_sb.duplicate() - - set_font("font", "TextEdit", preload("res://ui/assets/fonts/CourierNewPSMT.ttf")) - set_font_size("font_size", "TextEdit", 16) - set_stylebox("normal", "TextEdit", text_edit_sb) - set_stylebox("focus", "TextEdit", text_edit_focus_sb) - set_stylebox("read_only", "TextEdit", text_edit_disabled_sb) - - # TimelineCellNumber - - set_type_variation("TimelineCellNumber", "PanelContainer") - - sb = base_sb.duplicate() - sb.set_corner_radius_all(0) - sb.bg_color = _get_primary_color(contrast, false) - sb.border_width_right = border_width - sb.border_color = Color.BLACK - - set_stylebox("panel", "TimelineCellNumber", sb) - - # TimelineLayerPanel - - set_type_variation("TimelineLayerPanel", "PanelContainer") - - sb = base_sb.duplicate() - sb.set_corner_radius_all(0) - sb.bg_color = _get_primary_color(contrast, false) - sb.border_width_bottom = border_width - sb.border_color = Color.BLACK - - set_stylebox("panel", "TimelineLayerPanel", sb) - - # Tree - - var tree_sb: StyleBoxFlat = base_sb.duplicate() - var tree_focus_sb: StyleBoxFlat = base_empty_sb.duplicate() - - set_color( - "relashion_ship_line_color", "Tree", Color(base_border_color, base_border_color.a / 2) - ) - #set_color("guide_color", "Tree", Color(base_border_color, base_border_color.a/2)) - set_constant("icon_max_width", "Tree", 14) - set_constant("h_separation", "Tree", base_spacing) - set_constant("v_separation", "Tree", base_spacing / 2) - set_constant("inner_item_margin_bottom", "Tree", base_spacing) - set_constant("inner_item_margin_left", "Tree", base_spacing) - set_constant("inner_item_margin_top", "Tree", base_spacing) - set_constant("inner_item_margin_right", "Tree", base_spacing) - set_constant("draw_relationship_lines", "Tree", 1) - set_constant("draw_guides", "Tree", 0) - set_constant("relationship_line_width", "Tree", 0) - set_constant("parent_hl_line_width", "Tree", border_width) - set_constant("children_hl_line_width", "Tree", 0) - set_icon("checked", "Tree", preload("res://ui/theme_default/assets/checked.svg")) - set_icon("unchecked", "Tree", preload("res://ui/theme_default/assets/unchecked.svg")) - set_icon( - "checked_disabled", "Tree", preload("res://ui/theme_default/assets/checked_disabled.svg") - ) - set_icon( - "unchecked_disabled", - "Tree", - preload("res://ui/theme_default/assets/unchecked_disabled.svg") - ) - set_stylebox("panel", "Tree", tree_sb) - set_stylebox("focus", "Tree", tree_focus_sb) - set_stylebox("hovered", "Tree", button_hover_sb) - set_stylebox("hovered_dimmed", "Tree", button_hover_sb) - set_stylebox("selected", "Tree", button_pressed_sb) - set_stylebox("selected_focus", "Tree", button_pressed_sb) - - # TreeContainer - - set_type_variation("TreeContainer", "PanelContainer") - - sb = base_sb.duplicate() - sb.set_corner_radius_all(0) - sb.bg_color = _get_primary_color(contrast, false) - set_stylebox("panel", "TreeContainer", sb) - - # OptionButton - - var option_button_sb = base_field_sb.duplicate() - option_button_sb.bg_color = _get_secondary_color(contrast) - - var option_button_hover_sb: StyleBoxFlat = button_sb.duplicate() - option_button_hover_sb.bg_color = _get_secondary_color(contrast + 0.05) - - var option_button_pressed_sb: StyleBoxFlat = button_sb.duplicate() - option_button_pressed_sb.bg_color = _get_secondary_color(contrast + 0.1) - - var option_button_disabled_sb: StyleBoxFlat = button_sb.duplicate() - option_button_disabled_sb.bg_color = _get_secondary_color(0.05) - - set_constant("arrow_margin", "OptionButton", base_spacing) - set_constant("h_separation", "OptionButton", base_spacing) - set_stylebox("disabled", "OptionButton", option_button_disabled_sb) - set_stylebox("disabled_mirrored", "OptionButton", option_button_disabled_sb) - set_stylebox("focus", "OptionButton", base_empty_sb) - set_stylebox("hover", "OptionButton", option_button_hover_sb) - set_stylebox("hover_mirrored", "OptionButton", option_button_hover_sb) - set_stylebox("hover_pressed", "OptionButton", option_button_pressed_sb) - set_stylebox("hover_pressed_mirrored", "OptionButton", option_button_pressed_sb) - set_stylebox("normal", "OptionButton", option_button_sb) - set_stylebox("normal_mirrored", "OptionButton", option_button_sb) - set_stylebox("pressed", "OptionButton", option_button_pressed_sb) - set_stylebox("pressed_mirrored", "OptionButton", option_button_pressed_sb) - - # OuterPanel - - set_type_variation("OuterPanel", "PanelContainer") - sb = base_sb.duplicate() - sb.bg_color = _get_primary_color(contrast, false) - sb.set_corner_radius_all(int(outer_radius)) - _set_border(sb, _get_color(base_border_color, base_border_color.a, false)) - set_stylebox("panel", "OuterPanel", sb) - - -func _get_primary_color(alpha: float = 1.0, transparent: bool = true) -> Color: - #return _get_color(secondary_color, alpha, transparent) - return _get_color(primary_color, alpha, transparent) - - -func _get_secondary_color(alpha: float = 1.0, transparent: bool = true) -> Color: - #return _get_color(primary_color, alpha, transparent) - return _get_color(secondary_color, alpha, transparent) - - -func _get_text_color(alpha: float = 1.0, transparent: bool = true) -> Color: - return _get_color(text_color, alpha, transparent) - - -func _get_color( - color: Color, alpha: float = 1.0, transparent: bool = true, blend_with: Color = background_color -) -> Color: - if transparent: - return Color(color, alpha) - return Color(blend_with).blend(Color(color, alpha)) - - -# Shorthand content margin setter -func _set_margin( - sb: StyleBox, left: float, top: float, right: float = left, bottom: float = top -) -> void: - sb.content_margin_left = left * scale - sb.content_margin_top = top * scale - sb.content_margin_right = right * scale - sb.content_margin_bottom = bottom * scale - - -# Shorthand border setter -func _set_border(sb: StyleBoxFlat, color: Color, width: float = 1, blend: bool = false) -> void: - sb.border_color = color - sb.border_blend = blend - sb.set_border_width_all(int(ceilf(width * scale))) diff --git a/ui/theme_default/theme_default.gd.uid b/ui/theme_default/theme_default.gd.uid deleted file mode 100644 index e8168ff0..00000000 --- a/ui/theme_default/theme_default.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://c2nmcbo0pbk5u diff --git a/ui/theme_default/theme_settings.gd b/ui/theme_default/theme_settings.gd new file mode 100644 index 00000000..074df23d --- /dev/null +++ b/ui/theme_default/theme_settings.gd @@ -0,0 +1,74 @@ +@abstract +class_name ThemeSettings extends RefCounted + +var text: Color = Color("e3e4eb") +var primary: Color = Color.from_hsv(0.667, 0.12, 0.14, 1.0) +var secondary: Color = Color.from_hsv(0.661, 0.15, 0.19, 1.0) +var graph_bg: Color = Color.from_hsv(0.656, 0.10, 0.10, 1.0) +var accent: Color = Color("af4548") +var warning: Color = Color("c42e40") + +# Semantic colors - derived from base colors for purposes +var surface: Color # Primary surface (panels, containers) +var surface_variant: Color # Secondary surface (inputs, fields) +var border: Color # Borders and separators +var text_secondary: Color # Secondary/dimmed text +var text_disabled: Color # Disabled text + +# Interactive state colors +var hover_overlay: Color # Overlay for hover states +var pressed_overlay: Color # Overlay for pressed states +var disabled_overlay: Color # Overlay for disabled states + +# UI element specific colors +var button_background: Color +var button_hover: Color +var button_pressed: Color +var input_background: Color +var panel_background: Color + + +func _init() -> void: + define_settings() + _calculate_semantic_colors() + + +@abstract func define_settings() -> void +@abstract func get_path() -> String + + +## Calculates semantic colors from base colors +func _calculate_semantic_colors() -> void: + surface = primary + surface_variant = secondary + + border = primary + + text_secondary = Color(text, 0.75) + text_disabled = Color(text, 0.35) + + hover_overlay = secondary.lightened(0.02) + pressed_overlay = secondary.lightened(0.05) + disabled_overlay = secondary.lightened(0.25) + + button_background = secondary + button_hover = secondary.lightened(0.02) + button_pressed = secondary.lightened(0.05) + + input_background = surface_variant + panel_background = surface + + +## Creates a lighter variant of a color +func lighten(color: Color, amount: float = 0.1) -> Color: + return color.lightened(amount) + + +## Creates a darker variant of a color +func darken(color: Color, amount: float = 0.1) -> Color: + return color.darkened(amount) + + +## Creates a color with adjusted alpha +func with_alpha(color: Color, alpha: float) -> Color: + return Color(color, alpha) diff --git a/ui/theme_default/theme_settings.gd.uid b/ui/theme_default/theme_settings.gd.uid new file mode 100644 index 00000000..a8f57f14 --- /dev/null +++ b/ui/theme_default/theme_settings.gd.uid @@ -0,0 +1 @@ +uid://dv5hxrp67n3tj diff --git a/ui/theme_default/theme_settings_dark.gd b/ui/theme_default/theme_settings_dark.gd new file mode 100644 index 00000000..5ca91ced --- /dev/null +++ b/ui/theme_default/theme_settings_dark.gd @@ -0,0 +1,13 @@ +@tool +class_name ThemeSettingsDark extends ThemeSettings + + +func define_settings() -> void: + text = Color("e3e4eb") + primary = Color.from_hsv(0.667, 0.12, 0.14, 1.0) + secondary = Color.from_hsv(0.661, 0.15, 0.19, 1.0) + graph_bg = Color.from_hsv(0.656, 0.10, 0.10, 1.0) + + +func get_path() -> String: + return "res://ui/theme_default/main.tres" diff --git a/ui/theme_default/theme_settings_dark.gd.uid b/ui/theme_default/theme_settings_dark.gd.uid new file mode 100644 index 00000000..bcca7b47 --- /dev/null +++ b/ui/theme_default/theme_settings_dark.gd.uid @@ -0,0 +1 @@ +uid://b4br1rxfd5hcv diff --git a/ui/theme_default/theme_settings_light.gd b/ui/theme_default/theme_settings_light.gd new file mode 100644 index 00000000..e81b105c --- /dev/null +++ b/ui/theme_default/theme_settings_light.gd @@ -0,0 +1,13 @@ +@tool +class_name ThemeSettingsLight extends ThemeSettings + + +func define_settings() -> void: + text = Color("1a1a1f") + primary = Color.from_hsv(0.646, 0.032, 0.988, 1.0) + secondary = Color.from_hsv(0.0, 0.0, 1.0, 1.0) + graph_bg = Color.from_hsv(0.633, 0.038, 0.971, 1.0) + + +func get_path() -> String: + return "res://ui/theme_default/main_light.tres" diff --git a/ui/theme_default/theme_settings_light.gd.uid b/ui/theme_default/theme_settings_light.gd.uid new file mode 100644 index 00000000..dece0bdc --- /dev/null +++ b/ui/theme_default/theme_settings_light.gd.uid @@ -0,0 +1 @@ +uid://dq34srl153iye diff --git a/ui/theme_default/theme_styles.gd b/ui/theme_default/theme_styles.gd new file mode 100644 index 00000000..1ea7d48b --- /dev/null +++ b/ui/theme_default/theme_styles.gd @@ -0,0 +1,71 @@ +@tool +class_name ThemeStyles extends RefCounted +## Utility class for creating common StyleBox objects with consistent parameters + +var settings: ThemeSettings +var base_spacing: int = 4 +var corner_radius: int = 3 +var border_width: int = 2 + + +func _init(color_settings: ThemeSettings) -> void: + settings = color_settings + + +## Creates a basic panel StyleBoxFlat +func create_panel(bg_color: Color, with_border: bool = false) -> StyleBoxFlat: + var style := StyleBoxFlat.new() + style.bg_color = bg_color + style.set_corner_radius_all(corner_radius) + style.set_content_margin_all(base_spacing) + + if with_border: + style.set_border_width_all(border_width) + style.border_color = settings.border + + return style + + +## Creates a button StyleBoxFlat +func create_button(bg_color: Color) -> StyleBoxFlat: + var style := StyleBoxFlat.new() + style.bg_color = bg_color + style.set_corner_radius_all(corner_radius) + style.content_margin_left = base_spacing * 2.0 + style.content_margin_right = base_spacing * 2.0 + style.content_margin_top = base_spacing + style.content_margin_bottom = base_spacing + return style + + +## Creates an input field StyleBoxFlat +func create_input(bg_color: Color) -> StyleBoxFlat: + var style := StyleBoxFlat.new() + style.bg_color = bg_color + style.set_corner_radius_all(corner_radius) + style.content_margin_left = base_spacing * 2.0 + style.content_margin_right = base_spacing * 2.0 + style.content_margin_top = base_spacing + style.content_margin_bottom = base_spacing + #style.set_border_width_all(border_width) + #style.border_color = settings.border + return style + + +## Creates an empty StyleBoxFlat (no background) +func create_empty() -> StyleBoxFlat: + var style := StyleBoxFlat.new() + style.draw_center = false + style.set_content_margin_all(base_spacing) + style.set_corner_radius_all(corner_radius) + return style + + +## Creates a separator StyleBoxLine +func create_separator(vertical: bool = false) -> StyleBoxLine: + var style := StyleBoxLine.new() + style.color = settings.border + style.vertical = vertical + style.grow_begin = 0 + style.grow_end = 0 + return style diff --git a/ui/theme_default/theme_styles.gd.uid b/ui/theme_default/theme_styles.gd.uid new file mode 100644 index 00000000..ec5696b3 --- /dev/null +++ b/ui/theme_default/theme_styles.gd.uid @@ -0,0 +1 @@ +uid://d13d6qa0uxb7m diff --git a/ui/theme_generator.gd b/ui/theme_generator.gd index 7ae79fb3..da6a792f 100644 --- a/ui/theme_generator.gd +++ b/ui/theme_generator.gd @@ -1,29 +1,24 @@ @tool extends EditorScript -var _save_path: String = "res://ui/theme_default/main.tres" - func _run() -> void: - var theme := MonologueTheme.new() - _update_existing_theme_instance(theme) - ResourceSaver.save(theme, _save_path) - print("Theme generated!") + var settings_dark = ThemeSettingsDark.new() + var theme_dark = ThemeBuilder.build_theme(settings_dark) + _update_existing_theme_instance(theme_dark, settings_dark.get_path()) + ResourceSaver.save(theme_dark, settings_dark.get_path()) + var settings_light = ThemeSettingsLight.new() + var theme_light = ThemeBuilder.build_theme(settings_light) + _update_existing_theme_instance(theme_light, settings_light.get_path()) + ResourceSaver.save(theme_light, settings_light.get_path()) -func _update_existing_theme_instance(new_theme: Theme): - # When the editor uses the generated theme file, it loads the resource into - # memory. This means that when the new theme is saved, the existing one in - # memory is not updated or invalidated until the editor is restarted, - # leaving the UI unaffected. - # To fix this issue, the cached theme resource in memory is fetched and - # mutated in-place (using the fact that when a resource is loaded, Godot uses - # the shared instance in memory instead of loading a new instance from disk). - if not ResourceLoader.exists(_save_path): +func _update_existing_theme_instance(new_theme: Theme, save_path: String): + if not ResourceLoader.exists(save_path): return - var existing_theme = load(_save_path) + var existing_theme = load(save_path) if not existing_theme is Theme: return diff --git a/unit/test_dropdown_field.gd b/unit/test_dropdown_field.gd new file mode 100644 index 00000000..90c6eaec --- /dev/null +++ b/unit/test_dropdown_field.gd @@ -0,0 +1,21 @@ +extends GdUnitTestSuite + + +func test_dropdown_field_exists(): + var descriptor = FieldBucket.get_descriptor("dropdown") + assert_object(descriptor).is_not_null() + assert_str(descriptor.name).is_equal("dropdown") + + +func test_sentence_node_speaker_is_dropdown(): + var node = auto_free(SentenceNode.new()) + var speaker_prop = node.get_property("speaker") + assert_object(speaker_prop).is_not_null() + assert_str(speaker_prop.type).is_equal("dropdown") + + +func test_dropdown_has_source_setting(): + var node = auto_free(SentenceNode.new()) + var speaker_prop = node.get_property("speaker") + var source = speaker_prop.get_settings_value("source", "") + assert_str(source).is_equal("characters") diff --git a/unit/test_dropdown_field.gd.uid b/unit/test_dropdown_field.gd.uid new file mode 100644 index 00000000..0a136b6e --- /dev/null +++ b/unit/test_dropdown_field.gd.uid @@ -0,0 +1 @@ +uid://bdrhu0w5g3ph diff --git a/unit/test_graph_edit_switcher.gd b/unit/test_graph_edit_switcher.gd deleted file mode 100644 index 4a626409..00000000 --- a/unit/test_graph_edit_switcher.gd +++ /dev/null @@ -1,143 +0,0 @@ -extends GdUnitTestSuite - -var switcher: GraphEditSwitcher - - -func before_test(): - switcher = auto_free(GraphEditSwitcher.new()) - switcher.graph_edits = auto_free(Control.new()) - switcher.graph_edits.add_child(auto_free(Control.new())) - switcher.tab_bar = auto_free(TabBar.new()) - switcher.tab_bar.add_tab("+") - switcher.side_panel = mock(SidePanel) - - -func test_add_root(): - var ge = mock(MonologueGraphEdit, CALL_REAL_FUNC) - switcher.graph_edits.add_child(ge) - switcher.tab_bar.add_tab("new") - switcher.tab_bar.current_tab = 1 - assert_object(ge.get_root_node()).is_null() - switcher.add_root() - assert_object(ge.get_root_node()).is_instanceof(RootNode) - # calling add_root() again should not increase child count - var child_count = ge.get_child_count() - switcher.add_root() - assert_int(ge.get_child_count()).is_equal(child_count) - - -func test_add_tab_first(): - switcher.add_tab("kitty.json") - assert_int(switcher.tab_bar.current_tab).is_equal(0) - assert_str(switcher.tab_bar.get_tab_title(0)).is_equal("kitty.json") - - -func test_add_tab_with_previous(): - switcher.tab_bar.remove_tab(0) - switcher.tab_bar.add_tab("zero") - switcher.tab_bar.add_tab("one") - switcher.tab_bar.add_tab("+") - switcher.add_tab("two") - assert_int(switcher.tab_bar.current_tab).is_equal(2) - assert_str(switcher.tab_bar.get_tab_title(2)).is_equal("two") - - -func test_connect_side_panel(): - var ge = mock(MonologueGraphEdit, CALL_REAL_FUNC) - switcher.connect_side_panel(ge) - var select = switcher.side_panel.on_graph_node_selected - assert_bool(ge.is_connected("node_selected", select)).is_true() - var deselect = switcher.side_panel.on_graph_node_deselected - assert_bool(ge.is_connected("node_deselected", deselect)).is_true() - var save = switcher.update_save_state - assert_bool(ge.undo_redo.is_connected("version_changed", save)).is_true() - - -func test_commit_side_panel(): - var node = mock(MonologueGraphNode) - switcher.commit_side_panel(node) - verify(switcher.side_panel, 1).refocus(node) - - -func test_get_current_graph_edit(): - switcher.tab_bar.add_tab("one") - switcher.tab_bar.add_tab("two") - var one = auto_free(Control.new()) - var two = auto_free(Control.new()) - switcher.graph_edits.add_child(one) - switcher.graph_edits.add_child(two) - switcher.tab_bar.current_tab = 2 - assert_object(switcher.current).is_same(two) - - -func test_is_file_opened_false(): - assert_bool(switcher.is_file_opened("kennel/doggy.json")).is_false() - - -func test_is_file_opened_true(): - var doggy = mock(MonologueGraphEdit) - doggy.file_path = "kennel/doggy.json" - switcher.graph_edits.add_child(doggy) - assert_bool(switcher.is_file_opened("kennel/doggy.json")).is_true() - - -func test_new_graph_edit(): - switcher.new_graph_edit() - var graph_edit = switcher.graph_edits.get_child(1) - var root = graph_edit.get_nodes()[0] - # check if RootNode was created in the new graph edit - assert_object(root).is_instanceof(RootNode) - graph_edit.free() - - -func test_on_tab_close_pressed_saved(): - var ge = mock(MonologueGraphEdit) - do_return(false).on(ge).is_unsaved() - switcher.graph_edits.add_child(ge) - var spy_switcher = spy(switcher) - spy_switcher._on_tab_close_pressed(1) - verify(spy_switcher, 1)._close_tab(ge, 1) - - -func test_on_tab_close_pressed_unsaved(): - var ge = mock(MonologueGraphEdit) - do_return(true).on(ge).is_unsaved() - switcher.graph_edits.add_child(ge) - switcher._on_tab_close_pressed(1) - - var save_prompt = null - for node in switcher.get_children(): - if node is PromptWindow: - save_prompt = node - break - assert_object(save_prompt).is_not_null() - save_prompt.free() - - -func test_show_current_config(): - var ge = mock(MonologueGraphEdit) - switcher.graph_edits.add_child(ge) - switcher.tab_bar.add_tab("ge") - switcher.tab_bar.current_tab = 1 - switcher.show_current_config() - verify(ge, 1).get_root_node() - - -func test_update_save_state_saved(): - var ge = mock(MonologueGraphEdit) - do_return(false).on(ge).is_unsaved() - switcher.graph_edits.add_child(ge) - switcher.tab_bar.add_tab("wassup*") - switcher.tab_bar.current_tab = 1 - switcher.update_save_state() - assert_str(switcher.tab_bar.get_tab_title(1)).is_equal("wassup") - - -func test_update_save_state_unsaved(): - var ge = mock(MonologueGraphEdit) - do_return(true).on(ge).is_unsaved() - switcher.graph_edits.add_child(ge) - switcher.tab_bar.add_tab("wassup") - switcher.tab_bar.current_tab = 1 - switcher.update_save_state() - assert_str(switcher.tab_bar.get_tab_title(1)).is_equal("wassup*") diff --git a/unit/test_graph_edit_switcher.gd.uid b/unit/test_graph_edit_switcher.gd.uid deleted file mode 100644 index 605c3bab..00000000 --- a/unit/test_graph_edit_switcher.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://c7ygpfi5gcrbq diff --git a/unit/test_list_field.gd b/unit/test_list_field.gd new file mode 100644 index 00000000..890aedb8 --- /dev/null +++ b/unit/test_list_field.gd @@ -0,0 +1,30 @@ +extends GdUnitTestSuite + + +func test_list_field_exists(): + var descriptor = FieldBucket.get_descriptor("list") + assert_object(descriptor).is_not_null() + assert_str(descriptor.name).is_equal("list") + + +func test_list_field_can_be_created(): + var field = FieldBucket.create_field("list") + assert_object(field).is_not_null() + + +func test_list_field_handles_empty_array(): + var field = auto_free(FieldBucket.create_field("list")) + field.set_value([]) + var result = field.get_value() + assert_array(result).is_empty() + + +func test_list_field_handles_array_with_items(): + var field = auto_free(FieldBucket.create_field("list")) + var test_data = [ + {"name": "Item 1", "value": "A"}, + {"name": "Item 2", "value": "B"} + ] + field.set_value(test_data) + var result = field.get_value() + assert_array(result).has_size(2) diff --git a/unit/test_list_field.gd.uid b/unit/test_list_field.gd.uid new file mode 100644 index 00000000..dbbe30ce --- /dev/null +++ b/unit/test_list_field.gd.uid @@ -0,0 +1 @@ +uid://bwv2jgot5amdx diff --git a/unit/test_node_title_property.gd b/unit/test_node_title_property.gd new file mode 100644 index 00000000..47df4463 --- /dev/null +++ b/unit/test_node_title_property.gd @@ -0,0 +1,51 @@ +extends GdUnitTestSuite + + +func test_sentence_node_main_property(): + var node = auto_free(SentenceNode.new()) + var main_prop = node.get_property("sentence") + assert_object(main_prop).is_not_null() + assert_str(main_prop.type).is_equal("context") + assert_bool(main_prop.get_settings_value("visible_in_graph")).is_true() + assert_bool(main_prop.get_settings_value("is_main_property")).is_true() + # SentenceNode main property should not be editable + assert_bool(main_prop.get_settings_value("editable")).is_false() + + +func test_text_node_main_property(): + var node = auto_free(TextNode.new()) + var main_prop = node.get_property("text") + assert_object(main_prop).is_not_null() + assert_str(main_prop.type).is_equal("text") + assert_bool(main_prop.get_settings_value("visible_in_graph")).is_true() + assert_bool(main_prop.get_settings_value("is_main_property")).is_true() + # TextNode main property should be editable + assert_bool(main_prop.get_settings_value("editable")).is_true() + + +func test_root_node_main_property(): + var node = auto_free(RootNode.new()) + var main_prop = node.get_property("root") + assert_object(main_prop).is_not_null() + assert_str(main_prop.type).is_equal("context") + assert_bool(main_prop.get_settings_value("visible_in_graph")).is_true() + assert_bool(main_prop.get_settings_value("is_main_property")).is_true() + # RootNode main property should not be editable + assert_bool(main_prop.get_settings_value("editable")).is_false() + + +func test_connection_tracking(): + var node = auto_free(SentenceNode.new()) + var main_prop = node.get_property("sentence") + + # Initially no connections + assert_bool(main_prop.is_port_connected()).is_false() + + # Add a connection + main_prop.add_connection_to("node2", "prop2", 0) + assert_bool(main_prop.is_port_connected()).is_true() + assert_int(main_prop.connected_to.size()).is_equal(1) + + # Remove connection + main_prop.remove_connection_to("node2", 0) + assert_bool(main_prop.is_port_connected()).is_false() diff --git a/unit/test_node_title_property.gd.uid b/unit/test_node_title_property.gd.uid new file mode 100644 index 00000000..92a0af11 --- /dev/null +++ b/unit/test_node_title_property.gd.uid @@ -0,0 +1 @@ +uid://d2g2xxgyv8lro diff --git a/unit/test_sentence_node.gd b/unit/test_sentence_node.gd index 5df700ba..2909ca75 100644 --- a/unit/test_sentence_node.gd +++ b/unit/test_sentence_node.gd @@ -1,6 +1,13 @@ extends GdUnitTestSuite +func test_title_property(): + var node = auto_free(SentenceNode.new()) + var title_prop = node.get_property("sentence") + assert_object(title_prop).is_not_null() + assert_str(title_prop.type).is_equal("context") + + func test_backwards_compatibility(): var node = auto_free(SentenceNode.new()) var ge = mock(MonologueGraphEdit, CALL_REAL_FUNC) diff --git a/unit/test_storyline_properties.gd b/unit/test_storyline_properties.gd new file mode 100644 index 00000000..c9ffaa59 --- /dev/null +++ b/unit/test_storyline_properties.gd @@ -0,0 +1,49 @@ +extends GdUnitTestSuite + + +func test_storyline_has_characters_property(): + var storyline = auto_free(StorylineDocument.new("Test Story")) + var characters_prop = storyline.get_property("characters") + assert_object(characters_prop).is_not_null() + assert_str(characters_prop.type).is_equal("list") + + +func test_storyline_has_variables_property(): + var storyline = auto_free(StorylineDocument.new("Test Story")) + var variables_prop = storyline.get_property("variables") + assert_object(variables_prop).is_not_null() + assert_str(variables_prop.type).is_equal("list") + + +func test_characters_property_has_schema(): + var storyline = auto_free(StorylineDocument.new("Test Story")) + var characters_prop = storyline.get_property("characters") + var schema = characters_prop.get_settings_value("data_schema", {}) + assert_bool(schema.has("name")).is_true() + assert_bool(schema.has("color")).is_true() + + +func test_variables_property_has_schema(): + var storyline = auto_free(StorylineDocument.new("Test Story")) + var variables_prop = storyline.get_property("variables") + var schema = variables_prop.get_settings_value("data_schema", {}) + assert_bool(schema.has("name")).is_true() + assert_bool(schema.has("value")).is_true() + + +func test_can_add_character_to_storyline(): + var storyline = auto_free(StorylineDocument.new("Test Story")) + var characters = [{"name": "Alice", "color": "#FF0000"}] + storyline.set_property_value("characters", characters) + var result = storyline.get_property_value("characters") + assert_array(result).has_size(1) + assert_str(result[0]["name"]).is_equal("Alice") + + +func test_can_add_variable_to_storyline(): + var storyline = auto_free(StorylineDocument.new("Test Story")) + var variables = [{"name": "score", "value": "0"}] + storyline.set_property_value("variables", variables) + var result = storyline.get_property_value("variables") + assert_array(result).has_size(1) + assert_str(result[0]["name"]).is_equal("score") diff --git a/unit/test_storyline_properties.gd.uid b/unit/test_storyline_properties.gd.uid new file mode 100644 index 00000000..df8087f5 --- /dev/null +++ b/unit/test_storyline_properties.gd.uid @@ -0,0 +1 @@ +uid://iqhw47jtls5m