diff options
154 files changed, 1132 insertions, 952 deletions
diff --git a/.github/workflows/linux_builds.yml b/.github/workflows/linux_builds.yml index 8a49959a30..f6d11e2efe 100644 --- a/.github/workflows/linux_builds.yml +++ b/.github/workflows/linux_builds.yml @@ -34,6 +34,7 @@ jobs: tests: true sconsflags: use_asan=yes use_ubsan=yes proj-test: true + godot-cpp-test: true bin: "./bin/godot.linuxbsd.tools.64s" # Skip 2GiB artifact speeding up action. artifact: false @@ -85,6 +86,15 @@ jobs: run: | ${{ matrix.bin }} --test + # Check class reference + - name: Check for class reference updates + if: ${{ matrix.doc-test }} + run: | + echo "Running --doctool to see if this changes the public API without updating the documentation." + echo -e "If a diff is shown, it means that your code/doc changes are incomplete and you should update the class reference with --doctool.\n\n" + ${{ matrix.bin }} --doctool --headless 2>&1 > /dev/null || true + git diff --color --exit-code && ! git ls-files --others --exclude-standard | sed -e 's/^/New doc file missing in PR: /' | grep 'xml$' + # Download, unzip and setup SwiftShader library [4466040] - name: Download SwiftShader if: ${{ matrix.tests }} @@ -95,15 +105,6 @@ jobs: curr="$(pwd)/libvk_swiftshader.so" sed -i "s|PATH_TO_CHANGE|$curr|" vk_swiftshader_icd.json - # Check class reference - - name: Check for class reference updates - if: ${{ matrix.doc-test }} - run: | - echo "Running --doctool to see if this changes the public API without updating the documentation." - echo -e "If a diff is shown, it means that your code/doc changes are incomplete and you should update the class reference with --doctool.\n\n" - VK_ICD_FILENAMES=$(pwd)/vk_swiftshader_icd.json DRI_PRIME=0 xvfb-run ${{ matrix.bin }} --doctool . 2>&1 > /dev/null || true - git diff --color --exit-code && ! git ls-files --others --exclude-standard | sed -e 's/^/New doc file missing in PR: /' | grep 'xml$' - # Download and extract zip archive with project, folder is renamed to be able to easy change used project - name: Download test project if: ${{ matrix.proj-test }} @@ -126,6 +127,46 @@ jobs: VK_ICD_FILENAMES=$(pwd)/vk_swiftshader_icd.json DRI_PRIME=0 xvfb-run ${{ matrix.bin }} 40 --audio-driver Dummy --path test_project 2>&1 | tee sanitizers_log.txt || true misc/scripts/check_ci_log.py sanitizers_log.txt + # Checkout godot-cpp + - name: Checkout godot-cpp + if: ${{ matrix.godot-cpp-test }} + uses: actions/checkout@v2 + with: + repository: godotengine/godot-cpp + submodules: 'recursive' + path: 'godot-cpp' + + # Check extension API + - name: Check for extension api updates + if: ${{ matrix.godot-cpp-test }} + run: | + echo "Running --dump-extension-api to create extensions api." + VK_ICD_FILENAMES=$(pwd)/vk_swiftshader_icd.json DRI_PRIME=0 xvfb-run ${{ matrix.bin }} --audio-driver Dummy --dump-extension-api 2>&1 > /dev/null || true + misc/scripts/compare_extension_api.py godot-cpp/godot-headers/extension_api.json extension_api.json + + # Copy new extension API files into place + - name: Copy new extension API files into place + if: ${{ matrix.godot-cpp-test }} + run: | + cp -f extension_api.json godot-cpp/godot-headers/ + cp -f core/extension/gdnative_interface.h godot-cpp/godot-headers/godot/ + + # Build godot-cpp library + - name: Build godot-cpp library + if: ${{ matrix.godot-cpp-test }} + run: | + cd godot-cpp + scons target=${{ matrix.target }} generate_bindings=yes -j2 + cd .. + + # Build godot-cpp test extension + - name: Build godot-cpp test extension + if: ${{ matrix.godot-cpp-test }} + run: | + cd godot-cpp/test + scons target=${{ matrix.target }} -j2 + cd ../.. + - name: Prepare artifact if: ${{ matrix.artifact }} run: | diff --git a/.gitignore b/.gitignore index 5b3414fe7e..5a8f6aec40 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,9 @@ # Documentation generated by doxygen or from classes.xml doc/_build/ +# Extension API dump +extension_api.json + # Javascript specific *.bc diff --git a/core/config/project_settings.cpp b/core/config/project_settings.cpp index 562cbbdd27..f37e7f5956 100644 --- a/core/config/project_settings.cpp +++ b/core/config/project_settings.cpp @@ -42,6 +42,8 @@ #include "core/os/os.h" #include "core/variant/variant_parser.h" +const String ProjectSettings::PROJECT_DATA_DIR_NAME_SUFFIX = "godot"; + ProjectSettings *ProjectSettings::singleton = nullptr; ProjectSettings *ProjectSettings::get_singleton() { @@ -521,7 +523,8 @@ Error ProjectSettings::setup(const String &p_path, const String &p_main_pack, bo } // Updating the default value after the project settings have loaded. - project_data_dir_name = GLOBAL_GET("application/config/project_data_dir_name"); + bool use_hidden_directory = GLOBAL_GET("application/config/use_hidden_project_data_directory"); + project_data_dir_name = (use_hidden_directory ? "." : "") + PROJECT_DATA_DIR_NAME_SUFFIX; // Using GLOBAL_GET on every block for compressing can be slow, so assigning here. Compression::zstd_long_distance_matching = GLOBAL_GET("compression/formats/zstd/long_distance_matching"); @@ -1094,7 +1097,7 @@ ProjectSettings::ProjectSettings() { custom_prop_info["application/run/main_scene"] = PropertyInfo(Variant::STRING, "application/run/main_scene", PROPERTY_HINT_FILE, "*.tscn,*.scn,*.res"); GLOBAL_DEF("application/run/disable_stdout", false); GLOBAL_DEF("application/run/disable_stderr", false); - project_data_dir_name = GLOBAL_DEF_RST("application/config/project_data_dir_name", ".godot"); + GLOBAL_DEF_RST("application/config/use_hidden_project_data_directory", true); GLOBAL_DEF("application/config/use_custom_user_dir", false); GLOBAL_DEF("application/config/custom_user_dir_name", ""); GLOBAL_DEF("application/config/project_settings_override", ""); diff --git a/core/config/project_settings.h b/core/config/project_settings.h index 82f04b94df..ca37401751 100644 --- a/core/config/project_settings.h +++ b/core/config/project_settings.h @@ -42,6 +42,7 @@ class ProjectSettings : public Object { public: typedef Map<String, Variant> CustomMap; + static const String PROJECT_DATA_DIR_NAME_SUFFIX; enum { //properties that are not for built in values begin from this value, so builtin ones are displayed first diff --git a/core/input/input.cpp b/core/input/input.cpp index 296aa1f071..c3b43a4274 100644 --- a/core/input/input.cpp +++ b/core/input/input.cpp @@ -133,6 +133,7 @@ void Input::_bind_methods() { ClassDB::bind_method(D_METHOD("set_custom_mouse_cursor", "image", "shape", "hotspot"), &Input::set_custom_mouse_cursor, DEFVAL(CURSOR_ARROW), DEFVAL(Vector2())); ClassDB::bind_method(D_METHOD("parse_input_event", "event"), &Input::parse_input_event); ClassDB::bind_method(D_METHOD("set_use_accumulated_input", "enable"), &Input::set_use_accumulated_input); + ClassDB::bind_method(D_METHOD("flush_buffered_events"), &Input::flush_buffered_events); BIND_ENUM_CONSTANT(MOUSE_MODE_VISIBLE); BIND_ENUM_CONSTANT(MOUSE_MODE_HIDDEN); diff --git a/core/input/input.h b/core/input/input.h index 6819fc8eb0..f63138a875 100644 --- a/core/input/input.h +++ b/core/input/input.h @@ -265,7 +265,6 @@ public: float get_joy_vibration_duration(int p_device); uint64_t get_joy_vibration_timestamp(int p_device); void joy_connection_changed(int p_idx, bool p_connected, String p_name, String p_guid = ""); - void parse_joypad_mapping(String p_mapping, bool p_update_existing); Vector3 get_gravity() const; Vector3 get_accelerometer() const; diff --git a/core/input/input_event.cpp b/core/input/input_event.cpp index 1d2b5f19ee..c6448b1e44 100644 --- a/core/input/input_event.cpp +++ b/core/input/input_event.cpp @@ -452,8 +452,13 @@ bool InputEventKey::is_match(const Ref<InputEvent> &p_event, bool p_exact_match) return false; } - return keycode == key->keycode && - (!p_exact_match || get_modifiers_mask() == key->get_modifiers_mask()); + if (keycode == 0) { + return physical_keycode == key->physical_keycode && + (!p_exact_match || get_modifiers_mask() == key->get_modifiers_mask()); + } else { + return keycode == key->keycode && + (!p_exact_match || get_modifiers_mask() == key->get_modifiers_mask()); + } } void InputEventKey::_bind_methods() { diff --git a/core/io/compression.h b/core/io/compression.h index cbfed74124..06f26876e5 100644 --- a/core/io/compression.h +++ b/core/io/compression.h @@ -54,8 +54,6 @@ public: static int get_max_compressed_buffer_size(int p_src_size, Mode p_mode = MODE_ZSTD); static int decompress(uint8_t *p_dst, int p_dst_max_size, const uint8_t *p_src, int p_src_size, Mode p_mode = MODE_ZSTD); static int decompress_dynamic(Vector<uint8_t> *p_dst_vect, int p_max_dst_size, const uint8_t *p_src, int p_src_size, Mode p_mode); - - Compression() {} }; #endif // COMPRESSION_H diff --git a/core/io/logger.h b/core/io/logger.h index f244f70e7e..48b073aa45 100644 --- a/core/io/logger.h +++ b/core/io/logger.h @@ -83,7 +83,6 @@ class RotatedFileLogger : public Logger { FileAccess *file = nullptr; - void rotate_file_without_closing(); void close_file(); void clear_old_backups(); void rotate_file(); diff --git a/core/math/convex_hull.cpp b/core/math/convex_hull.cpp index f67035c803..684814b1ae 100644 --- a/core/math/convex_hull.cpp +++ b/core/math/convex_hull.cpp @@ -594,8 +594,6 @@ private: IntermediateHull() { } - - void print(); }; enum Orientation { NONE, diff --git a/core/math/geometry_2d.h b/core/math/geometry_2d.h index 8e5830f9b3..6010159597 100644 --- a/core/math/geometry_2d.h +++ b/core/math/geometry_2d.h @@ -37,8 +37,6 @@ #include "core/templates/vector.h" class Geometry2D { - Geometry2D(); - public: static real_t get_closest_points_between_segments(const Vector2 &p1, const Vector2 &q1, const Vector2 &p2, const Vector2 &q2, Vector2 &c1, Vector2 &c2) { Vector2 d1 = q1 - p1; // Direction vector of segment S1. diff --git a/core/math/geometry_3d.h b/core/math/geometry_3d.h index 766689e222..6a59b34585 100644 --- a/core/math/geometry_3d.h +++ b/core/math/geometry_3d.h @@ -36,8 +36,6 @@ #include "core/templates/vector.h" class Geometry3D { - Geometry3D(); - public: static void get_closest_points_between_segments(const Vector3 &p1, const Vector3 &p2, const Vector3 &q1, const Vector3 &q2, Vector3 &c1, Vector3 &c2) { // Do the function 'd' as defined by pb. I think it's a dot product of some sort. diff --git a/core/os/memory.h b/core/os/memory.h index f67384a17e..ac56a12330 100644 --- a/core/os/memory.h +++ b/core/os/memory.h @@ -42,7 +42,6 @@ #endif class Memory { - Memory(); #ifdef DEBUG_ENABLED static SafeNumeric<uint64_t> mem_usage; static SafeNumeric<uint64_t> max_usage; diff --git a/core/string/ustring.cpp b/core/string/ustring.cpp index daeb7fbd17..397743fb6e 100644 --- a/core/string/ustring.cpp +++ b/core/string/ustring.cpp @@ -2137,7 +2137,7 @@ int64_t String::hex_to_int() const { s++; } - if (len > 2 && s[0] == '0' && s[1] == 'x') { + if (len > 2 && s[0] == '0' && lower_case(s[1]) == 'x') { s += 2; } @@ -2151,7 +2151,7 @@ int64_t String::hex_to_int() const { } else if (c >= 'a' && c <= 'f') { n = (c - 'a') + 10; } else { - return 0; + ERR_FAIL_COND_V_MSG(true, 0, "Invalid hexadecimal notation character \"" + chr(*s) + "\" in string \"" + *this + "\"."); } // Check for overflow/underflow, with special case to ensure INT64_MIN does not result in error bool overflow = ((hex > INT64_MAX / 16) && (sign == 1 || (sign == -1 && hex != (INT64_MAX >> 4) + 1))) || (sign == -1 && hex == (INT64_MAX >> 4) + 1 && c > '0'); @@ -2178,7 +2178,7 @@ int64_t String::bin_to_int() const { s++; } - if (len > 2 && s[0] == '0' && s[1] == 'b') { + if (len > 2 && s[0] == '0' && lower_case(s[1]) == 'b') { s += 2; } diff --git a/doc/classes/DisplayServer.xml b/doc/classes/DisplayServer.xml index 7a467c03c1..4b43286594 100644 --- a/doc/classes/DisplayServer.xml +++ b/doc/classes/DisplayServer.xml @@ -13,6 +13,13 @@ Returns the user's clipboard as a string if possible. </description> </method> + <method name="clipboard_get_primary" qualifiers="const"> + <return type="String" /> + <description> + Returns the user's primary clipboard as a string if possible. + [b]Note:[/b] This method is only implemented on Linux. + </description> + </method> <method name="clipboard_set"> <return type="void" /> <argument index="0" name="clipboard" type="String" /> @@ -20,6 +27,14 @@ Sets the user's clipboard content to the given string. </description> </method> + <method name="clipboard_set_primary"> + <return type="void" /> + <argument index="0" name="clipboard_primary" type="String" /> + <description> + Sets the user's primary clipboard content to the given string. + [b]Note:[/b] This method is only implemented on Linux. + </description> + </method> <method name="console_set_visible"> <return type="void" /> <argument index="0" name="console_visible" type="bool" /> diff --git a/doc/classes/EditorImportPlugin.xml b/doc/classes/EditorImportPlugin.xml index 6011a5411d..cb33f159ef 100644 --- a/doc/classes/EditorImportPlugin.xml +++ b/doc/classes/EditorImportPlugin.xml @@ -5,7 +5,7 @@ </brief_description> <description> [EditorImportPlugin]s provide a way to extend the editor's resource import functionality. Use them to import resources from custom files or to provide alternatives to the editor's existing importers. - EditorImportPlugins work by associating with specific file extensions and a resource type. See [method _get_recognized_extensions] and [method _get_resource_type]. They may optionally specify some import presets that affect the import process. EditorImportPlugins are responsible for creating the resources and saving them in the [code].godot/imported[/code] directory (see [member ProjectSettings.application/config/project_data_dir_name]). + EditorImportPlugins work by associating with specific file extensions and a resource type. See [method _get_recognized_extensions] and [method _get_resource_type]. They may optionally specify some import presets that affect the import process. EditorImportPlugins are responsible for creating the resources and saving them in the [code].godot/imported[/code] directory (see [member ProjectSettings.application/config/use_hidden_project_data_directory]). Below is an example EditorImportPlugin that imports a [Mesh] from a file with the extension ".special" or ".spec": [codeblocks] [gdscript] @@ -198,7 +198,7 @@ <method name="_get_save_extension" qualifiers="virtual const"> <return type="String" /> <description> - Gets the extension used to save this resource in the [code].godot/imported[/code] directory (see [member ProjectSettings.application/config/project_data_dir_name]). + Gets the extension used to save this resource in the [code].godot/imported[/code] directory (see [member ProjectSettings.application/config/use_hidden_project_data_directory]). </description> </method> <method name="_get_visible_name" qualifiers="virtual const"> diff --git a/doc/classes/EditorProperty.xml b/doc/classes/EditorProperty.xml index 6af6507606..5f342e6dc2 100644 --- a/doc/classes/EditorProperty.xml +++ b/doc/classes/EditorProperty.xml @@ -73,8 +73,8 @@ <member name="deletable" type="bool" setter="set_deletable" getter="is_deletable" default="false"> Used by the inspector, set to [code]true[/code] when the property can be deleted by the user. </member> - <member name="draw_red" type="bool" setter="set_draw_red" getter="is_draw_red" default="false"> - Used by the inspector, set to [code]true[/code] when the property must draw with error color. This is used for editable children's properties. + <member name="draw_warning" type="bool" setter="set_draw_warning" getter="is_draw_warning" default="false"> + Used by the inspector, set to [code]true[/code] when the property is drawn with the editor theme's warning color. This is used for editable children's properties. </member> <member name="keying" type="bool" setter="set_keying" getter="is_keying" default="false"> Used by the inspector, set to [code]true[/code] when the property can add keys for animation. diff --git a/doc/classes/Input.xml b/doc/classes/Input.xml index 88e4a67615..1fded42db2 100644 --- a/doc/classes/Input.xml +++ b/doc/classes/Input.xml @@ -37,6 +37,13 @@ Adds a new mapping entry (in SDL2 format) to the mapping database. Optionally update already connected devices. </description> </method> + <method name="flush_buffered_events"> + <return type="void" /> + <description> + Sends all input events which are in the current buffer to the game loop. These events may have been buffered as a result of accumulated input ([method set_use_accumulated_input]) or agile input flushing ([member ProjectSettings.input_devices/buffering/agile_event_flushing]). + The engine will already do this itself at key execution points (at least once per frame). However, this can be useful in advanced cases where you want precise control over the timing of event handling. + </description> + </method> <method name="get_accelerometer" qualifiers="const"> <return type="Vector3" /> <description> diff --git a/doc/classes/LineEdit.xml b/doc/classes/LineEdit.xml index 75f2d72396..a37bab9b11 100644 --- a/doc/classes/LineEdit.xml +++ b/doc/classes/LineEdit.xml @@ -222,6 +222,10 @@ [/csharp] [/codeblocks] </member> + <member name="middle_mouse_paste_enabled" type="bool" setter="set_middle_mouse_paste_enabled" getter="is_middle_mouse_paste_enabled" default="true"> + If [code]false[/code], using middle mouse button to paste clipboard will be disabled. + [b]Note:[/b] This method is only implemented on Linux. + </member> <member name="mouse_default_cursor_shape" type="int" setter="set_default_cursor_shape" getter="get_default_cursor_shape" override="true" enum="Control.CursorShape" default="1" /> <member name="placeholder_alpha" type="float" setter="set_placeholder_alpha" getter="get_placeholder_alpha" default="0.6"> Opacity of the [member placeholder_text]. From [code]0[/code] to [code]1[/code]. diff --git a/doc/classes/NavigationMesh.xml b/doc/classes/NavigationMesh.xml index e476949360..b100a20963 100644 --- a/doc/classes/NavigationMesh.xml +++ b/doc/classes/NavigationMesh.xml @@ -84,7 +84,7 @@ <member name="agent/max_slope" type="float" setter="set_agent_max_slope" getter="get_agent_max_slope" default="45.0"> The maximum slope that is considered walkable, in degrees. </member> - <member name="agent/radius" type="float" setter="set_agent_radius" getter="get_agent_radius" default="0.6"> + <member name="agent/radius" type="float" setter="set_agent_radius" getter="get_agent_radius" default="1.0"> The distance to erode/shrink the walkable area of the heightfield away from obstructions. [b]Note:[/b] While baking, this value will be rounded up to the nearest multiple of [member cell/size]. </member> diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml index 7b26da7162..c646380bee 100644 --- a/doc/classes/ProjectSettings.xml +++ b/doc/classes/ProjectSettings.xml @@ -221,11 +221,6 @@ The project's name. It is used both by the Project Manager and by exporters. The project name can be translated by translating its value in localization files. The window title will be set to match the project name automatically on startup. [b]Note:[/b] Changing this value will also change the user data folder's path if [member application/config/use_custom_user_dir] is [code]false[/code]. After renaming the project, you will no longer be able to access existing data in [code]user://[/code] unless you rename the old folder to match the new project name. See [url=https://docs.godotengine.org/en/latest/tutorials/io/data_paths.html]Data paths[/url] in the documentation for more information. </member> - <member name="application/config/project_data_dir_name" type="String" setter="" getter="" default="".godot""> - The project data directory is used for storing project-specific data (metadata, shader cache, etc.). - [b]Note:[/b] Restart the application after changing this setting. - [b]Note:[/b] Changing this value can help on platforms or with third-party tools where specific directory patterns are disallowed. Only modify this setting if you know that your environment requires it, as changing the default can impact compatibility with some external tools or plugins which expect the default [code].godot[/code] folder. - </member> <member name="application/config/project_settings_override" type="String" setter="" getter="" default=""""> Specifies a file to override project settings. For example: [code]user://custom_settings.cfg[/code]. See "Overriding" in the [ProjectSettings] class description at the top for more information. [b]Note:[/b] Regardless of this setting's value, [code]res://override.cfg[/code] will still be read to override the project settings. @@ -233,6 +228,12 @@ <member name="application/config/use_custom_user_dir" type="bool" setter="" getter="" default="false"> If [code]true[/code], the project will save user data to its own user directory (see [member application/config/custom_user_dir_name]). This setting is only effective on desktop platforms. A name must be set in the [member application/config/custom_user_dir_name] setting for this to take effect. If [code]false[/code], the project will save user data to [code](OS user data directory)/Godot/app_userdata/(project name)[/code]. </member> + <member name="application/config/use_hidden_project_data_directory" type="bool" setter="" getter="" default="true"> + If [code]true[/code], the project will use a hidden directory ([code].godot[/code]) for storing project-specific data (metadata, shader cache, etc.). + If [code]false[/code], a non-hidden directory ([code]godot[/code]) will be used instead. + [b]Note:[/b] Restart the application after changing this setting. + [b]Note:[/b] Changing this value can help on platforms or with third-party tools where hidden directory patterns are disallowed. Only modify this setting if you know that your environment requires it, as changing the default can impact compatibility with some external tools or plugins which expect the default [code].godot[/code] folder. + </member> <member name="application/config/windows_native_icon" type="String" setter="" getter="" default=""""> Icon set in [code].ico[/code] format used on Windows to set the game's icon. This is done automatically on start by calling [method DisplayServer.set_native_icon]. </member> @@ -1754,23 +1755,23 @@ </member> <member name="rendering/textures/vram_compression/import_bptc" type="bool" setter="" getter="" default="false"> If [code]true[/code], the texture importer will import VRAM-compressed textures using the BPTC algorithm. This texture compression algorithm is only supported on desktop platforms, and only when using the Vulkan renderer. - [b]Note:[/b] Changing this setting does [i]not[/i] impact textures that were already imported before. To make this setting apply to textures that were already imported, exit the editor, remove the [code].godot/imported/[/code] folder located inside the project folder then restart the editor (see [member application/config/project_data_dir_name]). + [b]Note:[/b] Changing this setting does [i]not[/i] impact textures that were already imported before. To make this setting apply to textures that were already imported, exit the editor, remove the [code].godot/imported/[/code] folder located inside the project folder then restart the editor (see [member application/config/use_hidden_project_data_directory]). </member> <member name="rendering/textures/vram_compression/import_etc" type="bool" setter="" getter="" default="false"> If [code]true[/code], the texture importer will import VRAM-compressed textures using the Ericsson Texture Compression algorithm. This algorithm doesn't support alpha channels in textures. - [b]Note:[/b] Changing this setting does [i]not[/i] impact textures that were already imported before. To make this setting apply to textures that were already imported, exit the editor, remove the [code].godot/imported/[/code] folder located inside the project folder then restart the editor (see [member application/config/project_data_dir_name]). + [b]Note:[/b] Changing this setting does [i]not[/i] impact textures that were already imported before. To make this setting apply to textures that were already imported, exit the editor, remove the [code].godot/imported/[/code] folder located inside the project folder then restart the editor (see [member application/config/use_hidden_project_data_directory]). </member> <member name="rendering/textures/vram_compression/import_etc2" type="bool" setter="" getter="" default="true"> If [code]true[/code], the texture importer will import VRAM-compressed textures using the Ericsson Texture Compression 2 algorithm. This texture compression algorithm is only supported when using the Vulkan renderer. - [b]Note:[/b] Changing this setting does [i]not[/i] impact textures that were already imported before. To make this setting apply to textures that were already imported, exit the editor, remove the [code].godot/imported/[/code] folder located inside the project folder then restart the editor (see [member application/config/project_data_dir_name]). + [b]Note:[/b] Changing this setting does [i]not[/i] impact textures that were already imported before. To make this setting apply to textures that were already imported, exit the editor, remove the [code].godot/imported/[/code] folder located inside the project folder then restart the editor (see [member application/config/use_hidden_project_data_directory]). </member> <member name="rendering/textures/vram_compression/import_pvrtc" type="bool" setter="" getter="" default="false"> If [code]true[/code], the texture importer will import VRAM-compressed textures using the PowerVR Texture Compression algorithm. This texture compression algorithm is only supported on iOS. - [b]Note:[/b] Changing this setting does [i]not[/i] impact textures that were already imported before. To make this setting apply to textures that were already imported, exit the editor, remove the [code].godot/imported/[/code] folder located inside the project folder then restart the editor (see [member application/config/project_data_dir_name]). + [b]Note:[/b] Changing this setting does [i]not[/i] impact textures that were already imported before. To make this setting apply to textures that were already imported, exit the editor, remove the [code].godot/imported/[/code] folder located inside the project folder then restart the editor (see [member application/config/use_hidden_project_data_directory]). </member> <member name="rendering/textures/vram_compression/import_s3tc" type="bool" setter="" getter="" default="true"> If [code]true[/code], the texture importer will import VRAM-compressed textures using the S3 Texture Compression algorithm. This algorithm is only supported on desktop platforms and consoles. - [b]Note:[/b] Changing this setting does [i]not[/i] impact textures that were already imported before. To make this setting apply to textures that were already imported, exit the editor, remove the [code].godot/imported/[/code] folder located inside the project folder then restart the editor (see [member application/config/project_data_dir_name]). + [b]Note:[/b] Changing this setting does [i]not[/i] impact textures that were already imported before. To make this setting apply to textures that were already imported, exit the editor, remove the [code].godot/imported/[/code] folder located inside the project folder then restart the editor (see [member application/config/use_hidden_project_data_directory]). </member> <member name="rendering/vulkan/descriptor_pools/max_descriptors_per_pool" type="int" setter="" getter="" default="64"> </member> diff --git a/doc/classes/SceneTreeTimer.xml b/doc/classes/SceneTreeTimer.xml index f97c5e42b5..b0509a322e 100644 --- a/doc/classes/SceneTreeTimer.xml +++ b/doc/classes/SceneTreeTimer.xml @@ -10,7 +10,7 @@ [gdscript] func some_function(): print("Timer started.") - yield(get_tree().create_timer(1.0), "timeout") + await get_tree().create_timer(1.0).timeout print("Timer ended.") [/gdscript] [csharp] diff --git a/doc/classes/String.xml b/doc/classes/String.xml index 10ce03c4b2..abb68e0d05 100644 --- a/doc/classes/String.xml +++ b/doc/classes/String.xml @@ -56,11 +56,11 @@ Converts a string containing a binary number into an integer. Binary strings can either be prefixed with [code]0b[/code] or not, and they can also start with a [code]-[/code] before the optional prefix. [codeblocks] [gdscript] - print("0x101".bin_to_int()) # Prints "5". + print("0b101".bin_to_int()) # Prints "5". print("101".bin_to_int()) # Prints "5". [/gdscript] [csharp] - GD.Print("0x101".BinToInt()); // Prints "5". + GD.Print("0b101".BinToInt()); // Prints "5". GD.Print("101".BinToInt()); // Prints "5". [/csharp] [/codeblocks] diff --git a/doc/classes/Tabs.xml b/doc/classes/TabBar.xml index ded4f0b32f..3ca124bb58 100644 --- a/doc/classes/Tabs.xml +++ b/doc/classes/TabBar.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Tabs" inherits="Control" version="4.0"> +<class name="TabBar" inherits="Control" version="4.0"> <brief_description> - Tabs control. + Tab bar control. </brief_description> <description> Simple tabs control, similar to [TabContainer] but is only in charge of drawing tabs, not interacting with children. @@ -114,7 +114,7 @@ <method name="get_tabs_rearrange_group" qualifiers="const"> <return type="int" /> <description> - Returns the [Tabs]' rearrange group ID. + Returns the [TabBar]'s rearrange group ID. </description> </method> <method name="move_tab"> @@ -192,7 +192,7 @@ <return type="void" /> <argument index="0" name="group_id" type="int" /> <description> - Defines the rearrange group ID. Choose for each [Tabs] the same value to dragging tabs between [Tabs]. Enable drag with [member drag_to_rearrange_enabled]. + Defines the rearrange group ID. Choose for each [TabBar] the same value to dragging tabs between [TabBar]. Enable drag with [member drag_to_rearrange_enabled]. </description> </method> </methods> @@ -209,10 +209,10 @@ <member name="scrolling_enabled" type="bool" setter="set_scrolling_enabled" getter="get_scrolling_enabled" default="true"> if [code]true[/code], the mouse's scroll wheel can be used to navigate the scroll view. </member> - <member name="tab_align" type="int" setter="set_tab_align" getter="get_tab_align" enum="Tabs.TabAlign" default="1"> + <member name="tab_align" type="int" setter="set_tab_align" getter="get_tab_align" enum="TabBar.TabAlign" default="1"> The alignment of all tabs. See [enum TabAlign] for details. </member> - <member name="tab_close_display_policy" type="int" setter="set_tab_close_display_policy" getter="get_tab_close_display_policy" enum="Tabs.CloseButtonDisplayPolicy" default="0"> + <member name="tab_close_display_policy" type="int" setter="set_tab_close_display_policy" getter="get_tab_close_display_policy" enum="TabBar.CloseButtonDisplayPolicy" default="0"> Sets when the close button will appear on the tabs. See [enum CloseButtonDisplayPolicy] for details. </member> </members> diff --git a/doc/classes/TextEdit.xml b/doc/classes/TextEdit.xml index a3914b58df..ba3394b54a 100644 --- a/doc/classes/TextEdit.xml +++ b/doc/classes/TextEdit.xml @@ -41,6 +41,13 @@ Override this method to define what happens when the user performs a paste operation. </description> </method> + <method name="_paste_primary_clipboard" qualifiers="virtual"> + <return type="void" /> + <description> + Override this method to define what happens when the user performs a paste operation with middle mouse button. + [b]Note:[/b] This method is only implemented on Linux. + </description> + </method> <method name="add_gutter"> <return type="void" /> <argument index="0" name="at" type="int" default="-1" /> @@ -937,6 +944,10 @@ <member name="language" type="String" setter="set_language" getter="get_language" default=""""> Language code used for line-breaking and text shaping algorithms, if left empty current locale is used instead. </member> + <member name="middle_mouse_paste_enabled" type="bool" setter="set_middle_mouse_paste_enabled" getter="is_middle_mouse_paste_enabled" default="true"> + If [code]false[/code], using middle mouse button to paste clipboard will be disabled. + [b]Note:[/b] This method is only implemented on Linux. + </member> <member name="minimap_draw" type="bool" setter="set_draw_minimap" getter="is_drawing_minimap" default="false"> If [code]true[/code], a minimap is shown, providing an outline of your source code. </member> diff --git a/doc/classes/TextParagraph.xml b/doc/classes/TextParagraph.xml index e06dfee698..5bd6b0572c 100644 --- a/doc/classes/TextParagraph.xml +++ b/doc/classes/TextParagraph.xml @@ -199,7 +199,7 @@ Returns width (for horizontal layout) or height (for vertical) of the line of text. </description> </method> - <method name="get_non_wraped_size" qualifiers="const"> + <method name="get_non_wrapped_size" qualifiers="const"> <return type="Vector2" /> <description> Returns the size of the bounding box of the paragraph, without line breaks. diff --git a/doc/classes/XRInterfaceExtension.xml b/doc/classes/XRInterfaceExtension.xml index 3b5d8e2f10..d2bb6aa59a 100644 --- a/doc/classes/XRInterfaceExtension.xml +++ b/doc/classes/XRInterfaceExtension.xml @@ -81,11 +81,6 @@ <description> </description> </method> - <method name="_get_tracking_status" qualifiers="virtual const"> - <return type="int" /> - <description> - </description> - </method> <method name="_get_transform_for_view" qualifiers="virtual"> <return type="Transform3D" /> <argument index="0" name="view" type="int" /> diff --git a/doc/translations/Makefile b/doc/translations/Makefile index ceee79ec95..ab08e107d0 100644 --- a/doc/translations/Makefile +++ b/doc/translations/Makefile @@ -21,3 +21,24 @@ merge: check: @for po in $(POFILES); do msgfmt -c $$po -o /dev/null; done + +# Generate completion ratio from statistics string such as: +# 2775 translated messages, 272 fuzzy translations, 151 untranslated messages. +# First number can be 0, second and third numbers are only present if non-zero. +include-list: + @list=""; \ + threshold=0.10; \ + for po in $(POFILES); do \ + res=`msgfmt --statistics $$po -o /dev/null 2>&1 | sed 's/[^0-9,]*//g'`; \ + complete=`cut -d',' -f1 <<< $$res`; \ + fuzzy_or_untranslated=`cut -d',' -f2 <<< $$res`; \ + untranslated_maybe=`cut -d',' -f3 <<< $$res`; \ + if [ -z "$$fuzzy_or_untranslated" ]; then fuzzy_or_untranslated=0; fi; \ + if [ -z "$$untranslated_maybe" ]; then untranslated_maybe=0; fi; \ + incomplete=`expr $$fuzzy_or_untranslated + $$untranslated_maybe`; \ + if `awk "BEGIN {exit !($$complete / ($$complete + $$incomplete) > $$threshold)}"`; then \ + lang=`basename $$po .po`; \ + list+="$$lang,"; \ + fi; \ + done; \ + echo $$list; diff --git a/drivers/vulkan/rendering_device_vulkan.cpp b/drivers/vulkan/rendering_device_vulkan.cpp index 8743135f89..e7ac447426 100644 --- a/drivers/vulkan/rendering_device_vulkan.cpp +++ b/drivers/vulkan/rendering_device_vulkan.cpp @@ -8913,6 +8913,8 @@ void RenderingDeviceVulkan::initialize(VulkanContext *p_context, bool p_local_de } } + // Note: If adding new project settings here, also duplicate their definition in + // rendering_server.cpp for headless doctool. staging_buffer_block_size = GLOBAL_DEF("rendering/vulkan/staging_buffer/block_size_kb", 256); staging_buffer_block_size = MAX(4, staging_buffer_block_size); staging_buffer_block_size *= 1024; //kb -> bytes diff --git a/editor/SCsub b/editor/SCsub index e8d417319a..6b18eeae93 100644 --- a/editor/SCsub +++ b/editor/SCsub @@ -5,7 +5,6 @@ Import("env") env.editor_sources = [] import os -import os.path import glob import editor_builders @@ -59,7 +58,7 @@ if env["tools"]: else: docs += Glob(d + "/*.xml") # Custom. - _make_doc_data_class_path(os.path.join(env.Dir("#").abspath, "editor")) + _make_doc_data_class_path(env.Dir("#editor").abspath) docs = sorted(docs) env.Depends("#editor/doc_data_compressed.gen.h", docs) @@ -69,10 +68,17 @@ if env["tools"]: env.Run(editor_builders.make_doc_header, "Generating documentation header."), ) - path = env.Dir(".").abspath + # Editor interface and class reference translations incur a significant size + # cost for the editor binary (see godot-proposals#3421). + # To limit it, we only include translations with a high enough completion + # ratio (30% for the editor UI, 10% for the class reference). + # Generated with `make include-list` for each resource. # Editor translations - tlist = glob.glob(path + "/translations/*.po") + to_include = ( + "ar,bg,bn,ca,cs,de,el,eo,es_AR,es,fi,fr,gl,he,hu,id,it,ja,ko,ms,nb,nl,pl,pt_BR,pt,ro,ru,sk,sv,th,tr,uk,vi,zh_CN,zh_TW" + ).split(",") + tlist = [env.Dir("#editor/translations").abspath + "/" + f + ".po" for f in to_include] env.Depends("#editor/editor_translations.gen.h", tlist) env.CommandNoCache( "#editor/editor_translations.gen.h", @@ -81,7 +87,8 @@ if env["tools"]: ) # Documentation translations - tlist = glob.glob(env.Dir("#doc").abspath + "/translations/*.po") + to_include = "es,fr,ja,zh_CN".split(",") + tlist = [env.Dir("#doc/translations").abspath + "/" + f + ".po" for f in to_include] env.Depends("#editor/doc_translations.gen.h", tlist) env.CommandNoCache( "#editor/doc_translations.gen.h", @@ -90,8 +97,8 @@ if env["tools"]: ) # Fonts - flist = glob.glob(path + "/../thirdparty/fonts/*.ttf") - flist.extend(glob.glob(path + "/../thirdparty/fonts/*.otf")) + flist = glob.glob(env.Dir("#thirdparty").abspath + "/fonts/*.ttf") + flist.extend(glob.glob(env.Dir("#thirdparty").abspath + "/fonts/*.otf")) flist.sort() env.Depends("#editor/builtin_fonts.gen.h", flist) env.CommandNoCache( diff --git a/editor/code_editor.h b/editor/code_editor.h index 3c52a0c6e8..6e3bd88112 100644 --- a/editor/code_editor.h +++ b/editor/code_editor.h @@ -53,7 +53,6 @@ public: void popup_find_line(CodeEdit *p_edit); int get_line() const; - void set_text_editor(CodeEdit *p_text_editor); GotoLineDialog(); }; @@ -101,7 +100,6 @@ class FindReplaceBar : public HBoxContainer { void _search_text_changed(const String &p_text); void _search_text_submitted(const String &p_text); void _replace_text_submitted(const String &p_text); - void _update_size(); protected: void _notification(int p_what); diff --git a/editor/editor_data.h b/editor/editor_data.h index 9184ddcf39..976d718b8e 100644 --- a/editor/editor_data.h +++ b/editor/editor_data.h @@ -135,8 +135,6 @@ private: Vector<Callable> undo_redo_callbacks; Map<StringName, Callable> move_element_functions; - void _cleanup_history(); - Vector<EditedScene> edited_scene; int current_edited_scene; diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp index 767856f939..3d6b523733 100644 --- a/editor/editor_file_system.cpp +++ b/editor/editor_file_system.cpp @@ -2163,7 +2163,8 @@ Error EditorFileSystem::_resource_import(const String &p_path) { } bool EditorFileSystem::_should_skip_directory(const String &p_path) { - if (p_path.begins_with(ProjectSettings::get_singleton()->get_project_data_path())) { + String project_data_path = ProjectSettings::get_singleton()->get_project_data_path(); + if (p_path == project_data_path || p_path.begins_with(project_data_path + "/")) { return true; } diff --git a/editor/editor_help.h b/editor/editor_help.h index 7a45b1abc1..46605b6763 100644 --- a/editor/editor_help.h +++ b/editor/editor_help.h @@ -57,7 +57,6 @@ class FindBar : public HBoxContainer { int results_count; - void _show_search(); void _hide_bar(); void _search_text_changed(const String &p_text); @@ -66,8 +65,6 @@ class FindBar : public HBoxContainer { void _update_results_count(); void _update_matches_label(); - void _update_size(); - protected: void _notification(int p_what); virtual void unhandled_input(const Ref<InputEvent> &p_event) override; diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp index 4d0f27c5d4..9f049a0e58 100644 --- a/editor/editor_inspector.cpp +++ b/editor/editor_inspector.cpp @@ -245,13 +245,15 @@ void EditorProperty::_notification(int p_what) { } Color color; - if (draw_red) { - color = get_theme_color(is_read_only() ? SNAME("readonly_error_color") : SNAME("error_color")); + if (draw_warning) { + color = get_theme_color(is_read_only() ? SNAME("readonly_warning_color") : SNAME("warning_color")); } else { color = get_theme_color(is_read_only() ? SNAME("readonly_color") : SNAME("property_color")); } if (label.find(".") != -1) { - color.a = 0.5; //this should be un-hacked honestly, as it's used for editor overrides + // FIXME: Move this to the project settings editor, as this is only used + // for project settings feature tag overrides. + color.a = 0.5; } int ofs = get_theme_constant(SNAME("font_offset")); @@ -625,8 +627,8 @@ bool EditorProperty::is_checked() const { return checked; } -void EditorProperty::set_draw_red(bool p_draw_red) { - draw_red = p_draw_red; +void EditorProperty::set_draw_warning(bool p_draw_warning) { + draw_warning = p_draw_warning; update(); } @@ -650,8 +652,8 @@ bool EditorProperty::is_keying() const { return keying; } -bool EditorProperty::is_draw_red() const { - return draw_red; +bool EditorProperty::is_draw_warning() const { + return draw_warning; } void EditorProperty::_focusable_focused(int p_index) { @@ -969,8 +971,8 @@ void EditorProperty::_bind_methods() { ClassDB::bind_method(D_METHOD("set_checked", "checked"), &EditorProperty::set_checked); ClassDB::bind_method(D_METHOD("is_checked"), &EditorProperty::is_checked); - ClassDB::bind_method(D_METHOD("set_draw_red", "draw_red"), &EditorProperty::set_draw_red); - ClassDB::bind_method(D_METHOD("is_draw_red"), &EditorProperty::is_draw_red); + ClassDB::bind_method(D_METHOD("set_draw_warning", "draw_warning"), &EditorProperty::set_draw_warning); + ClassDB::bind_method(D_METHOD("is_draw_warning"), &EditorProperty::is_draw_warning); ClassDB::bind_method(D_METHOD("set_keying", "keying"), &EditorProperty::set_keying); ClassDB::bind_method(D_METHOD("is_keying"), &EditorProperty::is_keying); @@ -993,7 +995,7 @@ void EditorProperty::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "read_only"), "set_read_only", "is_read_only"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "checkable"), "set_checkable", "is_checkable"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "checked"), "set_checked", "is_checked"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "draw_red"), "set_draw_red", "is_draw_red"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "draw_warning"), "set_draw_warning", "is_draw_warning"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "keying"), "set_keying", "is_keying"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "deletable"), "set_deletable", "is_deletable"); ADD_SIGNAL(MethodInfo("property_changed", PropertyInfo(Variant::STRING_NAME, "property"), PropertyInfo(Variant::NIL, "value", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NIL_IS_VARIANT))); @@ -1018,7 +1020,7 @@ EditorProperty::EditorProperty() { read_only = false; checkable = false; checked = false; - draw_red = false; + draw_warning = false; keying = false; deletable = false; keying_hover = false; @@ -2393,14 +2395,15 @@ void EditorInspector::update_tree() { valid_plugins.push_back(inspector_plugins[i]); } - // Decide if properties should be drawn in red. - bool draw_red = false; + // Decide if properties should be drawn with the warning color (yellow). + bool draw_warning = false; if (is_inside_tree()) { Node *nod = Object::cast_to<Node>(object); Node *es = EditorNode::get_singleton()->get_edited_scene(); if (nod && es != nod && nod->get_owner() != es) { - // Draw in red edited nodes that are not in the currently edited scene. - draw_red = true; + // Draw in warning color edited nodes that are not in the currently edited scene, + // as changes may be lost in the future. + draw_warning = true; } } @@ -2855,7 +2858,7 @@ void EditorInspector::update_tree() { editor_property_map[prop].push_back(ep); } } - ep->set_draw_red(draw_red); + ep->set_draw_warning(draw_warning); ep->set_use_folding(use_folding); ep->set_checkable(checkable); ep->set_checked(checked); diff --git a/editor/editor_inspector.h b/editor/editor_inspector.h index b71efe8f19..124ea31302 100644 --- a/editor/editor_inspector.h +++ b/editor/editor_inspector.h @@ -74,7 +74,7 @@ private: bool read_only; bool checkable; bool checked; - bool draw_red; + bool draw_warning; bool keying; bool deletable; @@ -96,8 +96,6 @@ private: bool draw_top_bg; void _ensure_popup(); - bool _is_property_different(const Variant &p_current, const Variant &p_orig); - bool _get_instantiated_node_original_property(const StringName &p_prop, Variant &value); void _focusable_focused(int p_index); bool selectable; @@ -150,8 +148,8 @@ public: void set_checked(bool p_checked); bool is_checked() const; - void set_draw_red(bool p_draw_red); - bool is_draw_red() const; + void set_draw_warning(bool p_draw_warning); + bool is_draw_warning() const; void set_keying(bool p_keying); bool is_keying() const; @@ -281,8 +279,6 @@ public: void unfold(); void fold(); - Object *get_edited_object(); - EditorInspectorSection(); ~EditorInspectorSection(); }; diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index ffcb75ba2c..891705da98 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -59,8 +59,8 @@ #include "scene/gui/panel.h" #include "scene/gui/panel_container.h" #include "scene/gui/split_container.h" +#include "scene/gui/tab_bar.h" #include "scene/gui/tab_container.h" -#include "scene/gui/tabs.h" #include "scene/gui/texture_progress_bar.h" #include "scene/main/window.h" #include "scene/resources/packed_scene.h" @@ -658,7 +658,7 @@ void EditorNode::_notification(int p_what) { } break; case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { - scene_tabs->set_tab_close_display_policy((bool(EDITOR_GET("interface/scene_tabs/always_show_close_button")) ? Tabs::CLOSE_BUTTON_SHOW_ALWAYS : Tabs::CLOSE_BUTTON_SHOW_ACTIVE_ONLY)); + scene_tabs->set_tab_close_display_policy((bool(EDITOR_GET("interface/scene_tabs/always_show_close_button")) ? TabBar::CLOSE_BUTTON_SHOW_ALWAYS : TabBar::CLOSE_BUTTON_SHOW_ACTIVE_ONLY)); theme = create_custom_theme(theme_base->get_theme()); theme_base->set_theme(theme); @@ -838,7 +838,7 @@ void EditorNode::_resources_changed(const Vector<String> &p_resources) { } if (res->get_import_path() != String()) { - //this is an imported resource, will be reloaded if reimported via the _resources_reimported() callback + // this is an imported resource, will be reloaded if reimported via the _resources_reimported() callback continue; } @@ -942,21 +942,21 @@ void EditorNode::_fs_changed() { } void EditorNode::_resources_reimported(const Vector<String> &p_resources) { - List<String> scenes; //will load later + List<String> scenes; // will load later int current_tab = scene_tabs->get_current_tab(); for (int i = 0; i < p_resources.size(); i++) { String file_type = ResourceLoader::get_resource_type(p_resources[i]); if (file_type == "PackedScene") { scenes.push_back(p_resources[i]); - //reload later if needed, first go with normal resources + // reload later if needed, first go with normal resources continue; } if (!ResourceCache::has(p_resources[i])) { - continue; //not loaded, no need to reload + continue; // not loaded, no need to reload } - //reload normally + // reload normally Resource *resource = ResourceCache::get(p_resources[i]); if (resource) { resource->reload_from_file(); @@ -1140,7 +1140,7 @@ Error EditorNode::load_resource(const String &p_resource, bool p_ignore_broken_d ERR_FAIL_COND_V(!res.is_valid(), ERR_CANT_OPEN); if (!p_ignore_broken_deps && dependency_errors.has(p_resource)) { - //current_option = -1; + // current_option = -1; Vector<String> errors; for (Set<String>::Element *E = dependency_errors[p_resource].front(); E; E = E->next()) { errors.push_back(E->get()); @@ -1216,7 +1216,7 @@ void EditorNode::save_resource_as(const Ref<Resource> &p_resource, const String List<String> preferred; for (const String &E : extensions) { if (p_resource->is_class("Script") && (E == "tres" || E == "res")) { - //this serves no purpose and confused people + // this serves no purpose and confused people continue; } file->add_filter("*." + E + " ; " + E.to_upper()); @@ -1325,7 +1325,7 @@ void EditorNode::_get_scene_metadata(const String &p_file) { Error err = cf->load(path); if (err != OK || !cf->has_section("editor_states")) { - return; //must not exist + return; // must not exist } List<String> esl; @@ -1349,7 +1349,7 @@ void EditorNode::_set_scene_metadata(const String &p_file, int p_idx) { return; } - scene->set_meta("__editor_run_settings__", Variant()); //clear it (no point in keeping it) + scene->set_meta("__editor_run_settings__", Variant()); // clear it (no point in keeping it) scene->set_meta("__editor_plugin_states__", Variant()); String path = EditorSettings::get_singleton()->get_project_settings_dir().plus_file(p_file.get_file() + "-editstate-" + p_file.md5_text() + ".cfg"); @@ -1392,10 +1392,10 @@ bool EditorNode::_find_and_save_resource(RES p_res, Map<RES, bool> &processed, i if (p_res->get_path().is_resource_file()) { if (changed || subchanged) { - //save + // save ResourceSaver::save(p_res->get_path(), p_res, flags); } - processed[p_res] = false; //because it's a file + processed[p_res] = false; // because it's a file return false; } else { processed[p_res] = changed; @@ -1493,7 +1493,7 @@ void EditorNode::_save_scene_with_preview(String p_file, int p_idx) { _find_node_types(editor_data.get_edited_scene_root(), c2d, c3d); save.step(TTR("Creating Thumbnail"), 1); - //current view? + // current view? Ref<Image> img; // If neither 3D or 2D nodes are present, make a 1x1 black texture. @@ -1546,12 +1546,12 @@ void EditorNode::_save_scene_with_preview(String p_file, int p_idx) { } img->convert(Image::FORMAT_RGB8); - //save thumbnail directly, as thumbnailer may not update due to actual scene not changing md5 + // save thumbnail directly, as thumbnailer may not update due to actual scene not changing md5 String temp_path = EditorPaths::get_singleton()->get_cache_dir(); String cache_base = ProjectSettings::get_singleton()->globalize_path(p_file).md5_text(); cache_base = temp_path.plus_file("resthumb-" + cache_base); - //does not have it, try to load a cached thumbnail + // does not have it, try to load a cached thumbnail String file = cache_base + ".png"; @@ -1599,7 +1599,7 @@ static bool _find_edited_resources(const Ref<Resource> &p_resource, Set<Ref<Reso if (res.is_null()) { continue; } - if (res->get_path().is_resource_file()) { //not a subresource, continue + if (res->get_path().is_resource_file()) { // not a subresource, continue continue; } if (_find_edited_resources(res, edited_resources)) { @@ -1612,7 +1612,7 @@ static bool _find_edited_resources(const Ref<Resource> &p_resource, Set<Ref<Reso } int EditorNode::_save_external_resources() { - //save external resources and its subresources if any was modified + // save external resources and its subresources if any was modified int flg = 0; if (EditorSettings::get_singleton()->get("filesystem/on_save/compress_binary_resources")) { @@ -1628,7 +1628,7 @@ int EditorNode::_save_external_resources() { if (!res->get_path().is_resource_file()) { continue; } - //not only check if this resource is edited, check contained subresources too + // not only check if this resource is edited, check contained subresources too if (_find_edited_resources(res, edited_subresources)) { ResourceSaver::save(res->get_path(), res, flg); saved++; @@ -1837,7 +1837,7 @@ void EditorNode::_dialog_action(String p_file) { case SETTINGS_PICK_MAIN_SCENE: { ProjectSettings::get_singleton()->set("application/run/main_scene", p_file); ProjectSettings::get_singleton()->save(); - //would be nice to show the project manager opened with the highlighted field.. + // would be nice to show the project manager opened with the highlighted field.. if (pick_main_scene->has_meta("from_native") && (bool)pick_main_scene->get_meta("from_native")) { run_native->resume_run_native(); @@ -1980,7 +1980,7 @@ void EditorNode::_dialog_action(String p_file) { } } break; - default: { //save scene? + default: { // save scene? if (file->get_file_mode() == EditorFileDialog::FILE_MODE_SAVE_FILE) { _save_scene_with_preview(p_file); @@ -2141,7 +2141,7 @@ void EditorNode::_edit_current() { bool is_resource = current_obj->is_class("Resource"); bool is_node = current_obj->is_class("Node"); - String editable_warning; //none by default + String editable_warning; // none by default if (is_resource) { Resource *current_res = Object::cast_to<Resource>(current_obj); @@ -2243,7 +2243,7 @@ void EditorNode::_edit_current() { for (; plugin_index < editor_table.size(); plugin_index++) { if (editor_table[plugin_index] == main_plugin) { if (!main_editor_buttons[plugin_index]->is_visible()) { - main_plugin = nullptr; //if button is not visible, then no plugin active + main_plugin = nullptr; // if button is not visible, then no plugin active } break; @@ -2329,7 +2329,7 @@ void EditorNode::_run(bool p_current, const String &p_custom) { } if (run_filename == "") { - //evidently, run the scene + // evidently, run the scene if (!ensure_main_scene(false)) { return; } @@ -2412,7 +2412,7 @@ void EditorNode::_android_build_source_selected(const String &p_file) { export_template_manager->install_android_template_from_file(p_file); } void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) { - if (!p_confirmed) { //this may be a hack.. + if (!p_confirmed) { // this may be a hack.. current_option = (MenuOptions)p_option; } @@ -2981,7 +2981,7 @@ int EditorNode::_next_unsaved_scene(bool p_valid_filename, int p_start) { void EditorNode::_exit_editor() { exiting = true; - resource_preview->stop(); //stop early to avoid crashes + resource_preview->stop(); // stop early to avoid crashes _save_docks(); // Dim the editor window while it's quitting to make it clearer that it's busy @@ -3087,7 +3087,7 @@ void EditorNode::_editor_select(int p_which) { ERR_FAIL_INDEX(p_which, editor_table.size()); - if (!main_editor_buttons[p_which]->is_visible()) { //button hidden, no editor + if (!main_editor_buttons[p_which]->is_visible()) { // button hidden, no editor return; } @@ -3229,7 +3229,7 @@ void EditorNode::set_addon_plugin_enabled(const String &p_addon, bool p_enabled, if (!p_enabled) { EditorPlugin *addon = plugin_addons[p_addon]; remove_editor_plugin(addon, p_config_changed); - memdelete(addon); //bye + memdelete(addon); // bye plugin_addons.erase(p_addon); _update_addon_config(); return; @@ -3321,10 +3321,10 @@ void EditorNode::_remove_edited_scene(bool p_change_tab) { void EditorNode::_remove_scene(int index, bool p_change_tab) { if (editor_data.get_edited_scene() == index) { - //Scene to remove is current scene + // Scene to remove is current scene _remove_edited_scene(p_change_tab); } else { - //Scene to remove is not active scene + // Scene to remove is not active scene editor_data.remove_scene(index); } } @@ -3338,7 +3338,7 @@ void EditorNode::set_edited_scene(Node *p_scene) { get_editor_data().set_edited_scene_root(p_scene); if (Object::cast_to<Popup>(p_scene)) { - Object::cast_to<Popup>(p_scene)->show(); //show popups + Object::cast_to<Popup>(p_scene)->show(); // show popups } scene_tree_dock->set_edited_scene(p_scene); if (get_tree()) { @@ -3374,7 +3374,7 @@ Dictionary EditorNode::_get_main_scene_state() { void EditorNode::_set_main_scene_state(Dictionary p_state, Node *p_for_scene) { if (get_edited_scene() != p_for_scene && p_for_scene != nullptr) { - return; //not for this scene + return; // not for this scene } changing_scene = false; @@ -3389,7 +3389,7 @@ void EditorNode::_set_main_scene_state(Dictionary p_state, Node *p_for_scene) { if (p_state.has("editor_index")) { int index = p_state["editor_index"]; - if (current < 2) { //if currently in spatial/2d, only switch to spatial/2d. if currently in script, stay there + if (current < 2) { // if currently in spatial/2d, only switch to spatial/2d. if currently in script, stay there if (index < 2 || !get_edited_scene()) { _editor_select(index); } @@ -3398,7 +3398,7 @@ void EditorNode::_set_main_scene_state(Dictionary p_state, Node *p_for_scene) { if (get_edited_scene()) { if (current < 2) { - //use heuristic instead + // use heuristic instead int n2d = 0, n3d = 0; _find_node_types(get_edited_scene(), n2d, n3d); if (n2d > n3d) { @@ -3420,7 +3420,7 @@ void EditorNode::_set_main_scene_state(Dictionary p_state, Node *p_for_scene) { scene_tree_dock->set_filter(p_state["node_filter"]); } - //this should only happen at the very end + // this should only happen at the very end EditorDebuggerNode::get_singleton()->update_live_edit_root(); ScriptEditor::get_singleton()->set_scene_root_script(editor_data.get_scene_root_script(editor_data.get_edited_scene())); @@ -3441,7 +3441,7 @@ void EditorNode::_clear_undo_history() { } void EditorNode::set_current_scene(int p_idx) { - //Save the folding in case the scene gets reloaded. + // Save the folding in case the scene gets reloaded. if (editor_data.get_scene_path(p_idx) != "" && editor_data.get_edited_scene_root(p_idx)) { editor_folding.save_scene_folding(editor_data.get_edited_scene_root(p_idx), editor_data.get_scene_path(p_idx)); } @@ -3469,7 +3469,7 @@ void EditorNode::set_current_scene(int p_idx) { Node *new_scene = editor_data.get_edited_scene_root(); if (Object::cast_to<Popup>(new_scene)) { - Object::cast_to<Popup>(new_scene)->show(); //show popups + Object::cast_to<Popup>(new_scene)->show(); // show popups } scene_tree_dock->set_edited_scene(new_scene); @@ -3488,7 +3488,7 @@ void EditorNode::set_current_scene(int p_idx) { _update_title(); - call_deferred(SNAME("_set_main_scene_state"), state, get_edited_scene()); //do after everything else is done setting up + call_deferred(SNAME("_set_main_scene_state"), state, get_edited_scene()); // do after everything else is done setting up } bool EditorNode::is_scene_open(const String &p_path) { @@ -3590,7 +3590,7 @@ Error EditorNode::load_scene(const String &p_scene, bool p_ignore_broken_deps, b return ERR_FILE_MISSING_DEPENDENCIES; } - dependency_errors.erase(lpath); //at least not self path + dependency_errors.erase(lpath); // at least not self path for (KeyValue<String, Set<String>> &E : dependency_errors) { String txt = vformat(TTR("Scene '%s' has broken dependencies:"), E.key) + "\n"; @@ -3601,7 +3601,7 @@ Error EditorNode::load_scene(const String &p_scene, bool p_ignore_broken_deps, b } if (ResourceCache::has(lpath)) { - //used from somewhere else? no problem! update state and replace sdata + // used from somewhere else? no problem! update state and replace sdata Ref<PackedScene> ps = Ref<PackedScene>(Object::cast_to<PackedScene>(ResourceCache::get(lpath))); if (ps.is_valid()) { ps->replace_state(sdata->get_state()); @@ -3610,7 +3610,7 @@ Error EditorNode::load_scene(const String &p_scene, bool p_ignore_broken_deps, b } } else { - sdata->set_path(lpath, true); //take over path + sdata->set_path(lpath, true); // take over path } Node *new_scene = sdata->instantiate(PackedScene::GEN_EDIT_STATE_MAIN); @@ -4224,7 +4224,7 @@ void EditorNode::_dock_make_float() { ERR_FAIL_COND(!dock); const Size2i borders = Size2i(4, 4) * EDSCALE; - Size2 dock_size = dock->get_size() + borders * 2; //remember size + Size2 dock_size = dock->get_size() + borders * 2; // remember size Point2 dock_screen_pos = dock->get_global_position() + get_tree()->get_root()->get_position() - borders; print_line("dock pos: " + dock->get_global_position() + " window pos: " + get_tree()->get_root()->get_position()); @@ -4464,7 +4464,7 @@ void EditorNode::_dock_select_draw() { void EditorNode::_save_docks() { if (waiting_for_first_scan) { - return; //scanning, do not touch docks + return; // scanning, do not touch docks } Ref<ConfigFile> config; config.instantiate(); @@ -4535,7 +4535,7 @@ void EditorNode::_load_docks() { config.instantiate(); Error err = config->load(EditorSettings::get_singleton()->get_project_settings_dir().plus_file("editor_layout.cfg")); if (err != OK) { - //no config + // no config if (overridden_default_layout >= 0) { _layout_menu_option(overridden_default_layout); } @@ -4648,7 +4648,7 @@ void EditorNode::_load_docks_from_config(Ref<ConfigFile> p_layout, const String for (int j = 0; j < names.size(); j++) { String name = names[j]; - //find it, in a horribly inefficient way + // find it, in a horribly inefficient way int atidx = -1; Control *node = nullptr; for (int k = 0; k < DOCK_SLOT_MAX; k++) { @@ -4662,7 +4662,7 @@ void EditorNode::_load_docks_from_config(Ref<ConfigFile> p_layout, const String atidx = k; break; } - if (atidx == -1) { //well, it's not anywhere + if (atidx == -1) { // well, it's not anywhere continue; } @@ -4778,7 +4778,7 @@ bool EditorNode::has_scenes_in_session() { } bool EditorNode::ensure_main_scene(bool p_from_native) { - pick_main_scene->set_meta("from_native", p_from_native); //whether from play button or native run + pick_main_scene->set_meta("from_native", p_from_native); // whether from play button or native run String main_scene = GLOBAL_DEF("application/run/main_scene", ""); if (main_scene == "") { @@ -4899,7 +4899,7 @@ void EditorNode::_update_layouts_menu() { config.instantiate(); Error err = config->load(EditorSettings::get_singleton()->get_editor_layouts_config()); if (err != OK) { - return; //no config + return; // no config } List<String> layouts; @@ -4940,7 +4940,7 @@ void EditorNode::_layout_menu_option(int p_id) { config.instantiate(); Error err = config->load(EditorSettings::get_singleton()->get_editor_layouts_config()); if (err != OK) { - return; //no config + return; // no config } _load_docks_from_config(config, editor_layouts->get_item_text(p_id)); @@ -5081,7 +5081,7 @@ void EditorNode::_scene_tab_changed(int p_tab) { bool unsaved = (saved_version != editor_data.get_undo_redo().get_version()); if (p_tab == editor_data.get_edited_scene()) { - return; //pointless + return; // pointless } uint64_t next_scene_version = editor_data.get_scene_version(p_tab); @@ -5284,11 +5284,11 @@ Variant EditorNode::drag_resource(const Ref<Resource> &p_res, Control *p_from) { Ref<Texture2D> preview; { - //todo make proper previews + // todo make proper previews Ref<ImageTexture> texture = gui_base->get_theme_icon(SNAME("FileBigThumb"), SNAME("EditorIcons")); Ref<Image> img = texture->get_image(); img = img->duplicate(); - img->resize(48, 48); //meh + img->resize(48, 48); // meh Ref<ImageTexture> resized_pic = Ref<ImageTexture>(memnew(ImageTexture)); resized_pic->create_from_image(img); preview = resized_pic; @@ -5306,7 +5306,7 @@ Variant EditorNode::drag_resource(const Ref<Resource> &p_res, Control *p_from) { drag_control->add_child(label); - p_from->set_drag_preview(drag_control); //wait until it enters scene + p_from->set_drag_preview(drag_control); // wait until it enters scene label->set_position(Point2((preview->get_width() - label->get_minimum_size().width) / 2, preview->get_height())); @@ -5360,7 +5360,7 @@ Variant EditorNode::drag_files_and_dirs(const Vector<String> &p_paths, Control * } vbox->add_child(label); } - p_from->set_drag_preview(vbox); //wait until it enters scene + p_from->set_drag_preview(vbox); // wait until it enters scene Dictionary drag_data; drag_data["type"] = has_folder ? "files_and_dirs" : "files"; @@ -5477,7 +5477,7 @@ void EditorNode::reload_scene(const String &p_path) { if (scene_idx == -1) { if (get_edited_scene()) { - //scene is not open, so at it might be instantiated. We'll refresh the whole scene later. + // scene is not open, so at it might be instantiated. We'll refresh the whole scene later. editor_data.get_undo_redo().clear_history(); } return; @@ -5488,17 +5488,17 @@ void EditorNode::reload_scene(const String &p_path) { _set_scene_metadata(p_path); } - //remove scene + // remove scene _remove_scene(scene_idx, false); - //reload scene + // reload scene load_scene(p_path, true, false, true, true); - //adjust index so tab is back a the previous position + // adjust index so tab is back a the previous position editor_data.move_edited_scene_to_index(scene_idx); get_undo_redo()->clear_history(); - //recover the tab + // recover the tab scene_tabs->set_current_tab(current_tab); } @@ -5598,7 +5598,7 @@ void EditorNode::_update_video_driver_color() { void EditorNode::_video_driver_selected(int p_which) { String driver = video_driver->get_item_metadata(p_which); - String current = ""; //OS::get_singleton()->get_video_driver_name(OS::get_singleton()->get_current_video_driver()); + String current = ""; // OS::get_singleton()->get_video_driver_name(OS::get_singleton()->get_current_video_driver()); if (driver == current) { return; @@ -5787,9 +5787,9 @@ EditorNode::EditorNode() { PhysicsServer2D::get_singleton()->set_active(false); // no physics by default if editor ScriptServer::set_scripting_enabled(false); // no scripting by default if editor - EditorHelp::generate_doc(); //before any editor classes are created + EditorHelp::generate_doc(); // before any editor classes are created SceneState::set_disable_placeholders(true); - ResourceLoader::clear_translation_remaps(); //no remaps using during editor + ResourceLoader::clear_translation_remaps(); // no remaps using during editor ResourceLoader::clear_path_remaps(); Input *id = Input::get_singleton(); @@ -5803,8 +5803,8 @@ EditorNode::EditorNode() { } if (!found_touchscreen && Input::get_singleton()) { - //only if no touchscreen ui hint, set emulation - id->set_emulate_touch_from_mouse(false); //just disable just in case + // only if no touchscreen ui hint, set emulation + id->set_emulate_touch_from_mouse(false); // just disable just in case } DisplayServer::get_singleton()->cursor_set_custom_image(RES()); } @@ -5871,7 +5871,7 @@ EditorNode::EditorNode() { ResourceLoader::set_error_notify_func(this, _load_error_notify); ResourceLoader::set_dependency_error_notify_func(this, _dependency_error_report); - { //register importers at the beginning, so dialogs are created with the right extensions + { // register importers at the beginning, so dialogs are created with the right extensions Ref<ResourceImporterTexture> import_texture; import_texture.instantiate(); ResourceFormatImporter::get_singleton()->add_importer(import_texture); @@ -5974,7 +5974,7 @@ EditorNode::EditorNode() { EditorFileSystem *efs = memnew(EditorFileSystem); add_child(efs); - //used for previews + // used for previews FileDialog::get_icon_func = _file_dialog_get_icon; FileDialog::register_func = _file_dialog_register; FileDialog::unregister_func = _file_dialog_unregister; @@ -5993,7 +5993,7 @@ EditorNode::EditorNode() { ClassDB::set_class_enabled("RootMotionView", true); - //defs here, use EDITOR_GET in logic + // defs here, use EDITOR_GET in logic EDITOR_DEF_RST("interface/scene_tabs/always_show_close_button", false); EDITOR_DEF_RST("interface/scene_tabs/resize_if_many_tabs", true); EDITOR_DEF_RST("interface/scene_tabs/minimum_width", 50); @@ -6217,13 +6217,13 @@ EditorNode::EditorNode() { tab_preview->set_position(Point2(2, 2) * EDSCALE); tab_preview_panel->add_child(tab_preview); - scene_tabs = memnew(Tabs); + scene_tabs = memnew(TabBar); scene_tabs->add_theme_style_override("tab_selected", gui_base->get_theme_stylebox(SNAME("SceneTabFG"), SNAME("EditorStyles"))); scene_tabs->add_theme_style_override("tab_unselected", gui_base->get_theme_stylebox(SNAME("SceneTabBG"), SNAME("EditorStyles"))); scene_tabs->set_select_with_rmb(true); scene_tabs->add_tab("unsaved"); - scene_tabs->set_tab_align(Tabs::ALIGN_LEFT); - scene_tabs->set_tab_close_display_policy((bool(EDITOR_DEF("interface/scene_tabs/always_show_close_button", false)) ? Tabs::CLOSE_BUTTON_SHOW_ALWAYS : Tabs::CLOSE_BUTTON_SHOW_ACTIVE_ONLY)); + scene_tabs->set_tab_align(TabBar::ALIGN_LEFT); + scene_tabs->set_tab_close_display_policy((bool(EDITOR_DEF("interface/scene_tabs/always_show_close_button", false)) ? TabBar::CLOSE_BUTTON_SHOW_ALWAYS : TabBar::CLOSE_BUTTON_SHOW_ACTIVE_ONLY)); scene_tabs->set_min_width(int(EDITOR_DEF("interface/scene_tabs/minimum_width", 50)) * EDSCALE); scene_tabs->set_drag_to_rearrange_enabled(true); scene_tabs->connect("tab_changed", callable_mp(this, &EditorNode::_scene_tab_changed)); @@ -6924,7 +6924,7 @@ EditorNode::EditorNode() { EditorAudioBuses *audio_bus_editor = EditorAudioBuses::register_editor(); - ScriptTextEditor::register_editor(); //register one for text scripts + ScriptTextEditor::register_editor(); // register one for text scripts TextEditor::register_editor(); if (StreamPeerSSL::is_available()) { @@ -6933,12 +6933,12 @@ EditorNode::EditorNode() { WARN_PRINT("Asset Library not available, as it requires SSL to work."); } - //add interface before adding plugins + // add interface before adding plugins editor_interface = memnew(EditorInterface); add_child(editor_interface); - //more visually meaningful to have this later + // more visually meaningful to have this later raise_bottom_panel_item(AnimationPlayerEditor::get_singleton()); add_editor_plugin(VersionControlEditorPlugin::get_singleton()); diff --git a/editor/editor_node.h b/editor/editor_node.h index 5c89823ad8..c64bcc0460 100644 --- a/editor/editor_node.h +++ b/editor/editor_node.h @@ -85,7 +85,7 @@ class ProjectSettingsEditor; class RunSettingsDialog; class ScriptCreateDialog; class TabContainer; -class Tabs; +class TabBar; class TextureProgressBar; class Button; class VSplitContainer; @@ -216,7 +216,7 @@ private: TOOL_MENU_BASE = 1000 }; - SubViewport *scene_root; //root of the scene being edited + SubViewport *scene_root; // root of the scene being edited PanelContainer *scene_root_parent; Control *theme_base; @@ -250,7 +250,7 @@ private: // Main tabs - Tabs *scene_tabs; + TabBar *scene_tabs; PopupMenu *scene_tabs_context_menu; Panel *tab_preview_panel; TextureRect *tab_preview; @@ -324,7 +324,7 @@ private: EditorSettingsDialog *settings_config_dialog; ProjectSettingsEditor *project_settings; - bool settings_changed = true; //make it update settings on first frame + bool settings_changed = true; // make it update settings on first frame void _update_from_settings(); PopupMenu *vcs_actions_menu; @@ -520,9 +520,6 @@ private: void _run(bool p_current = false, const String &p_custom = ""); void _run_native(const Ref<EditorExportPreset> &p_preset); - void _save_optimized(); - void _import_action(const String &p_action); - void _import(const String &p_file); void _add_to_recent_scenes(const String &p_scene); void _update_recent_scenes(); void _open_recent_scene(int p_idx); @@ -560,7 +557,6 @@ private: static void _editor_file_dialog_register(EditorFileDialog *p_dialog); static void _editor_file_dialog_unregister(EditorFileDialog *p_dialog); - void _cleanup_scene(); void _remove_edited_scene(bool p_change_tab = true); void _remove_scene(int index, bool p_change_tab = true); bool _find_and_save_resource(RES p_res, Map<RES, bool> &processed, int32_t flags); @@ -658,8 +654,6 @@ private: static int build_callback_count; static EditorBuildCallback build_callbacks[MAX_BUILD_CALLBACKS]; - void _license_tree_selected(); - void _update_update_spinner(); Vector<Ref<EditorResourceConversionPlugin>> resource_conversion_plugins; @@ -775,10 +769,9 @@ public: Node *get_edited_scene() { return editor_data.get_edited_scene_root(); } - SubViewport *get_scene_root() { return scene_root; } //root of the scene being edited + SubViewport *get_scene_root() { return scene_root; } // root of the scene being edited void fix_dependencies(const String &p_for_file); - void clear_scene() { _cleanup_scene(); } int new_scene(); Error load_scene(const String &p_scene, bool p_ignore_broken_deps = false, bool p_set_inherited = false, bool p_clear_errors = true, bool p_force_open_imported = false, bool p_silent_change_tab = false); Error load_resource(const String &p_resource, bool p_ignore_broken_deps = false); @@ -851,8 +844,6 @@ public: bool is_scene_in_use(const String &p_path); - void scan_import_changes(); - void save_layout(); void open_export_template_manager(); @@ -894,7 +885,6 @@ public: EditorNode(); ~EditorNode(); - void get_singleton(const char *arg1, bool arg2); void add_resource_conversion_plugin(const Ref<EditorResourceConversionPlugin> &p_plugin); void remove_resource_conversion_plugin(const Ref<EditorResourceConversionPlugin> &p_plugin); diff --git a/editor/editor_path.h b/editor/editor_path.h index cabfa931d6..07f8b7244e 100644 --- a/editor/editor_path.h +++ b/editor/editor_path.h @@ -47,7 +47,6 @@ class EditorPath : public Button { PopupMenu *sub_objects_menu; Vector<ObjectID> objects; - EditorPath(); void _show_popup(); void _id_pressed(int p_idx); diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp index 2d4db48f2a..fdcc0438ae 100644 --- a/editor/editor_themes.cpp +++ b/editor/editor_themes.cpp @@ -403,7 +403,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { float prev_icon_saturation = theme->has_color("icon_saturation", "Editor") ? theme->get_color("icon_saturation", "Editor").r : 1.0; - theme->set_color("icon_saturation", "Editor", Color(icon_saturation, icon_saturation, icon_saturation)); //can't save single float in theme, so using color + theme->set_color("icon_saturation", "Editor", Color(icon_saturation, icon_saturation, icon_saturation)); // can't save single float in theme, so using color theme->set_color("accent_color", "Editor", accent_color); theme->set_color("highlight_color", "Editor", highlight_color); theme->set_color("disabled_highlight_color", "Editor", disabled_highlight_color); @@ -431,7 +431,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { Color error_color = Color(1, 0.47, 0.42); Color property_color = font_color.lerp(Color(0.5, 0.5, 0.5), 0.5); Color readonly_color = property_color.lerp(dark_theme ? Color(0, 0, 0) : Color(1, 1, 1), 0.5); - Color readonly_error_color = error_color.lerp(dark_theme ? Color(0, 0, 0) : Color(1, 1, 1), 0.5); + Color readonly_warning_color = error_color.lerp(dark_theme ? Color(0, 0, 0) : Color(1, 1, 1), 0.5); if (!dark_theme) { // Darken some colors to be readable on a light background @@ -445,7 +445,6 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_color("error_color", "Editor", error_color); theme->set_color("property_color", "Editor", property_color); theme->set_color("readonly_color", "Editor", readonly_color); - theme->set_color("readonly_error_color", "EditorProperty", readonly_error_color); if (!dark_theme) { theme->set_color("vulkan_color", "Editor", Color::hex(0xad1128ff)); @@ -549,7 +548,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { Ref<StyleBoxEmpty> style_empty = make_empty_stylebox(default_margin_size, default_margin_size, default_margin_size, default_margin_size); - // Tabs + // TabBar Ref<StyleBoxFlat> style_tab_selected = style_widget->duplicate(); @@ -819,10 +818,10 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_stylebox("bg_selected", "EditorProperty", style_property_bg); theme->set_stylebox("bg", "EditorProperty", Ref<StyleBoxEmpty>(memnew(StyleBoxEmpty))); theme->set_constant("vseparation", "EditorProperty", (extra_spacing + default_margin_size) * EDSCALE); - theme->set_color("error_color", "EditorProperty", error_color); + theme->set_color("warning_color", "EditorProperty", warning_color); theme->set_color("property_color", "EditorProperty", property_color); theme->set_color("readonly_color", "EditorProperty", readonly_color); - theme->set_color("readonly_error_color", "EditorProperty", readonly_error_color); + theme->set_color("readonly_warning_color", "EditorProperty", readonly_warning_color); Color inspector_section_color = font_color.lerp(Color(0.5, 0.5, 0.5), 0.35); theme->set_color("font_color", "EditorInspectorSection", inspector_section_color); @@ -950,33 +949,33 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_constant("icon_margin", "ItemList", 6 * EDSCALE); theme->set_constant("line_separation", "ItemList", 3 * EDSCALE); - // Tabs & TabContainer + // TabBar & TabContainer theme->set_stylebox("tab_selected", "TabContainer", style_tab_selected); theme->set_stylebox("tab_unselected", "TabContainer", style_tab_unselected); theme->set_stylebox("tab_disabled", "TabContainer", style_tab_disabled); - theme->set_stylebox("tab_selected", "Tabs", style_tab_selected); - theme->set_stylebox("tab_unselected", "Tabs", style_tab_unselected); - theme->set_stylebox("tab_disabled", "Tabs", style_tab_disabled); + theme->set_stylebox("tab_selected", "TabBar", style_tab_selected); + theme->set_stylebox("tab_unselected", "TabBar", style_tab_unselected); + theme->set_stylebox("tab_disabled", "TabBar", style_tab_disabled); theme->set_color("font_selected_color", "TabContainer", font_color); theme->set_color("font_unselected_color", "TabContainer", font_disabled_color); - theme->set_color("font_selected_color", "Tabs", font_color); - theme->set_color("font_unselected_color", "Tabs", font_disabled_color); + theme->set_color("font_selected_color", "TabBar", font_color); + theme->set_color("font_unselected_color", "TabBar", font_disabled_color); theme->set_icon("menu", "TabContainer", theme->get_icon("GuiTabMenu", "EditorIcons")); theme->set_icon("menu_highlight", "TabContainer", theme->get_icon("GuiTabMenuHl", "EditorIcons")); theme->set_stylebox("SceneTabFG", "EditorStyles", style_tab_selected); theme->set_stylebox("SceneTabBG", "EditorStyles", style_tab_unselected); - theme->set_icon("close", "Tabs", theme->get_icon("GuiClose", "EditorIcons")); - theme->set_stylebox("close_bg_pressed", "Tabs", style_menu); - theme->set_stylebox("close_bg_highlight", "Tabs", style_menu); + theme->set_icon("close", "TabBar", theme->get_icon("GuiClose", "EditorIcons")); + theme->set_stylebox("close_bg_pressed", "TabBar", style_menu); + theme->set_stylebox("close_bg_highlight", "TabBar", style_menu); theme->set_icon("increment", "TabContainer", theme->get_icon("GuiScrollArrowRight", "EditorIcons")); theme->set_icon("decrement", "TabContainer", theme->get_icon("GuiScrollArrowLeft", "EditorIcons")); - theme->set_icon("increment", "Tabs", theme->get_icon("GuiScrollArrowRight", "EditorIcons")); - theme->set_icon("decrement", "Tabs", theme->get_icon("GuiScrollArrowLeft", "EditorIcons")); - theme->set_icon("increment_highlight", "Tabs", theme->get_icon("GuiScrollArrowRightHl", "EditorIcons")); - theme->set_icon("decrement_highlight", "Tabs", theme->get_icon("GuiScrollArrowLeftHl", "EditorIcons")); + theme->set_icon("increment", "TabBar", theme->get_icon("GuiScrollArrowRight", "EditorIcons")); + theme->set_icon("decrement", "TabBar", theme->get_icon("GuiScrollArrowLeft", "EditorIcons")); + theme->set_icon("increment_highlight", "TabBar", theme->get_icon("GuiScrollArrowRightHl", "EditorIcons")); + theme->set_icon("decrement_highlight", "TabBar", theme->get_icon("GuiScrollArrowLeftHl", "EditorIcons")); theme->set_icon("increment_highlight", "TabContainer", theme->get_icon("GuiScrollArrowRightHl", "EditorIcons")); theme->set_icon("decrement_highlight", "TabContainer", theme->get_icon("GuiScrollArrowLeftHl", "EditorIcons")); - theme->set_constant("hseparation", "Tabs", 4 * EDSCALE); + theme->set_constant("hseparation", "TabBar", 4 * EDSCALE); // Content of each tab Ref<StyleBoxFlat> style_content_panel = style_default->duplicate(); diff --git a/editor/editor_toaster.cpp b/editor/editor_toaster.cpp index 0d45a7f1d8..9de0ea40fe 100644 --- a/editor/editor_toaster.cpp +++ b/editor/editor_toaster.cpp @@ -35,7 +35,7 @@ #include "editor_toaster.h" -EditorToaster *EditorToaster::singleton; +EditorToaster *EditorToaster::singleton = nullptr; void EditorToaster::_notification(int p_what) { switch (p_what) { @@ -90,8 +90,10 @@ void EditorToaster::_notification(int p_what) { // Hide element if it is not visible anymore. if (modulate.a <= 0) { - element.key->hide(); - needs_update = true; + if (element.key->is_visible()) { + element.key->hide(); + needs_update = true; + } } } @@ -141,7 +143,7 @@ void EditorToaster::_notification(int p_what) { } void EditorToaster::_error_handler(void *p_self, const char *p_func, const char *p_file, int p_line, const char *p_error, const char *p_errorexp, bool p_editor_notify, ErrorHandlerType p_type) { - if (!EditorToaster::get_singleton()) { + if (!EditorToaster::get_singleton() || !EditorToaster::get_singleton()->is_inside_tree()) { return; } diff --git a/editor/filesystem_dock.h b/editor/filesystem_dock.h index 73bdd685b7..7c3851b94f 100644 --- a/editor/filesystem_dock.h +++ b/editor/filesystem_dock.h @@ -205,8 +205,6 @@ private: void _set_file_display(bool p_active); void _fs_changed(); - void _tree_toggle_collapsed(); - void _select_file(const String &p_path, bool p_select_in_favorites = false); void _tree_activate_file(); void _file_list_activate_file(int p_idx); @@ -228,8 +226,6 @@ private: void _file_removed(String p_file); void _folder_removed(String p_folder); - void _files_moved(String p_old_file, String p_new_file); - void _folder_moved(String p_old_folder, String p_new_folder); void _resource_created(); void _make_dir_confirm(); diff --git a/editor/find_in_files.cpp b/editor/find_in_files.cpp index b61f6e12eb..283496c0f1 100644 --- a/editor/find_in_files.cpp +++ b/editor/find_in_files.cpp @@ -235,7 +235,7 @@ void FindInFiles::_scan_dir(String path, PackedStringArray &out_folders) { // Ignore special dirs (such as .git and project data directory) String project_data_dir_name = ProjectSettings::get_singleton()->get_project_data_dir_name(); - if (file.begins_with(".") || file.begins_with(project_data_dir_name)) { + if (file.begins_with(".") || file == project_data_dir_name) { continue; } if (dir->current_is_hidden()) { diff --git a/editor/groups_editor.cpp b/editor/groups_editor.cpp index 113306fc8a..f01c7f50f7 100644 --- a/editor/groups_editor.cpp +++ b/editor/groups_editor.cpp @@ -204,7 +204,8 @@ void GroupDialog::_add_group(String p_name) { TreeItem *new_group = groups->create_item(groups_root); new_group->set_text(0, name); - new_group->add_button(0, groups->get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), 0); + new_group->add_button(0, groups->get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), DELETE_GROUP); + new_group->add_button(0, groups->get_theme_icon(SNAME("ActionCopy"), SNAME("EditorIcons")), COPY_GROUP); new_group->set_editable(0, true); new_group->select(0); groups->ensure_cursor_is_visible(); @@ -297,43 +298,50 @@ void GroupDialog::_load_groups(Node *p_current) { } } -void GroupDialog::_delete_group_pressed(Object *p_item, int p_column, int p_id) { +void GroupDialog::_modify_group_pressed(Object *p_item, int p_column, int p_id) { TreeItem *ti = Object::cast_to<TreeItem>(p_item); if (!ti) { return; } - String name = ti->get_text(0); + switch (p_id) { + case DELETE_GROUP: { + String name = ti->get_text(0); - undo_redo->create_action(TTR("Delete Group")); + undo_redo->create_action(TTR("Delete Group")); - List<Node *> nodes; - scene_tree->get_nodes_in_group(name, &nodes); - bool removed_all = true; - for (Node *E : nodes) { - if (_can_edit(E, name)) { - undo_redo->add_do_method(E, "remove_from_group", name); - undo_redo->add_undo_method(E, "add_to_group", name, true); - } else { - removed_all = false; - } - } + List<Node *> nodes; + scene_tree->get_nodes_in_group(name, &nodes); + bool removed_all = true; + for (Node *E : nodes) { + if (_can_edit(E, name)) { + undo_redo->add_do_method(E, "remove_from_group", name); + undo_redo->add_undo_method(E, "add_to_group", name, true); + } else { + removed_all = false; + } + } - if (removed_all) { - undo_redo->add_do_method(this, "_delete_group_item", name); - undo_redo->add_undo_method(this, "_add_group", name); - } + if (removed_all) { + undo_redo->add_do_method(this, "_delete_group_item", name); + undo_redo->add_undo_method(this, "_add_group", name); + } - undo_redo->add_do_method(this, "_group_selected"); - undo_redo->add_undo_method(this, "_group_selected"); - undo_redo->add_do_method(this, "emit_signal", "group_edited"); - undo_redo->add_undo_method(this, "emit_signal", "group_edited"); + undo_redo->add_do_method(this, "_group_selected"); + undo_redo->add_undo_method(this, "_group_selected"); + undo_redo->add_do_method(this, "emit_signal", "group_edited"); + undo_redo->add_undo_method(this, "emit_signal", "group_edited"); - // To force redraw of scene tree. - undo_redo->add_do_method(EditorNode::get_singleton()->get_scene_tree_dock()->get_tree_editor(), "update_tree"); - undo_redo->add_undo_method(EditorNode::get_singleton()->get_scene_tree_dock()->get_tree_editor(), "update_tree"); + // To force redraw of scene tree. + undo_redo->add_do_method(EditorNode::get_singleton()->get_scene_tree_dock()->get_tree_editor(), "update_tree"); + undo_redo->add_undo_method(EditorNode::get_singleton()->get_scene_tree_dock()->get_tree_editor(), "update_tree"); - undo_redo->commit_action(); + undo_redo->commit_action(); + } break; + case COPY_GROUP: { + DisplayServer::get_singleton()->clipboard_set(ti->get_text(p_column)); + } break; + } } void GroupDialog::_delete_group_item(const String &p_name) { @@ -437,7 +445,7 @@ GroupDialog::GroupDialog() { groups->set_v_size_flags(Control::SIZE_EXPAND_FILL); groups->add_theme_constant_override("draw_guides", 1); groups->connect("item_selected", callable_mp(this, &GroupDialog::_group_selected)); - groups->connect("button_pressed", callable_mp(this, &GroupDialog::_delete_group_pressed)); + groups->connect("button_pressed", callable_mp(this, &GroupDialog::_modify_group_pressed)); groups->connect("item_edited", callable_mp(this, &GroupDialog::_group_renamed)); HBoxContainer *chbc = memnew(HBoxContainer); @@ -582,7 +590,7 @@ void GroupsEditor::_add_group(const String &p_group) { group_name->clear(); } -void GroupsEditor::_remove_group(Object *p_item, int p_column, int p_id) { +void GroupsEditor::_modify_group(Object *p_item, int p_column, int p_id) { if (!node) { return; } @@ -591,21 +599,26 @@ void GroupsEditor::_remove_group(Object *p_item, int p_column, int p_id) { if (!ti) { return; } + switch (p_id) { + case DELETE_GROUP: { + String name = ti->get_text(0); + undo_redo->create_action(TTR("Remove from Group")); - String name = ti->get_text(0); - - undo_redo->create_action(TTR("Remove from Group")); - - undo_redo->add_do_method(node, "remove_from_group", name); - undo_redo->add_undo_method(node, "add_to_group", name, true); - undo_redo->add_do_method(this, "update_tree"); - undo_redo->add_undo_method(this, "update_tree"); + undo_redo->add_do_method(node, "remove_from_group", name); + undo_redo->add_undo_method(node, "add_to_group", name, true); + undo_redo->add_do_method(this, "update_tree"); + undo_redo->add_undo_method(this, "update_tree"); - // To force redraw of scene tree. - undo_redo->add_do_method(EditorNode::get_singleton()->get_scene_tree_dock()->get_tree_editor(), "update_tree"); - undo_redo->add_undo_method(EditorNode::get_singleton()->get_scene_tree_dock()->get_tree_editor(), "update_tree"); + // To force redraw of scene tree. + undo_redo->add_do_method(EditorNode::get_singleton()->get_scene_tree_dock()->get_tree_editor(), "update_tree"); + undo_redo->add_undo_method(EditorNode::get_singleton()->get_scene_tree_dock()->get_tree_editor(), "update_tree"); - undo_redo->commit_action(); + undo_redo->commit_action(); + } break; + case COPY_GROUP: { + DisplayServer::get_singleton()->clipboard_set(ti->get_text(p_column)); + } break; + } } struct _GroupInfoComparator { @@ -653,7 +666,8 @@ void GroupsEditor::update_tree() { TreeItem *item = tree->create_item(root); item->set_text(0, gi.name); if (can_be_deleted) { - item->add_button(0, get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), 0); + item->add_button(0, get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), DELETE_GROUP); + item->add_button(0, get_theme_icon(SNAME("ActionCopy"), SNAME("EditorIcons")), COPY_GROUP); } else { item->set_selectable(0, false); } @@ -706,7 +720,7 @@ GroupsEditor::GroupsEditor() { tree->set_hide_root(true); tree->set_v_size_flags(Control::SIZE_EXPAND_FILL); vbc->add_child(tree); - tree->connect("button_pressed", callable_mp(this, &GroupsEditor::_remove_group)); + tree->connect("button_pressed", callable_mp(this, &GroupsEditor::_modify_group)); tree->add_theme_constant_override("draw_guides", 1); add_theme_constant_override("separation", 3 * EDSCALE); } diff --git a/editor/groups_editor.h b/editor/groups_editor.h index 69f746801f..f0a5b4a794 100644 --- a/editor/groups_editor.h +++ b/editor/groups_editor.h @@ -82,7 +82,7 @@ class GroupDialog : public AcceptDialog { void _rename_group_item(const String &p_old_name, const String &p_new_name); void _add_group(String p_name); - void _delete_group_pressed(Object *p_item, int p_column, int p_id); + void _modify_group_pressed(Object *p_item, int p_column, int p_id); void _delete_group_item(const String &p_name); bool _can_edit(Node *p_node, String p_group); @@ -95,6 +95,11 @@ protected: static void _bind_methods(); public: + enum ModifyButton { + DELETE_GROUP, + COPY_GROUP, + }; + void edit(); void set_undo_redo(UndoRedo *p_undoredo) { undo_redo = p_undoredo; } @@ -116,8 +121,7 @@ class GroupsEditor : public VBoxContainer { void update_tree(); void _add_group(const String &p_group = ""); - void _remove_group(Object *p_item, int p_column, int p_id); - void _close(); + void _modify_group(Object *p_item, int p_column, int p_id); void _show_group_dialog(); @@ -125,6 +129,11 @@ protected: static void _bind_methods(); public: + enum ModifyButton { + DELETE_GROUP, + COPY_GROUP, + }; + void set_undo_redo(UndoRedo *p_undoredo) { undo_redo = p_undoredo; } void set_current(Node *p_node); diff --git a/editor/icons/Tabs.svg b/editor/icons/TabBar.svg index e20a1a0131..e20a1a0131 100644 --- a/editor/icons/Tabs.svg +++ b/editor/icons/TabBar.svg diff --git a/editor/import/resource_importer_layered_texture.h b/editor/import/resource_importer_layered_texture.h index 86e9c5bde8..7d8fb3cac5 100644 --- a/editor/import/resource_importer_layered_texture.h +++ b/editor/import/resource_importer_layered_texture.h @@ -91,8 +91,6 @@ public: virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr) override; - void update_imports(); - virtual bool are_import_settings_valid(const String &p_path) const override; virtual String get_import_settings_string() const override; diff --git a/editor/plugins/abstract_polygon_2d_editor.h b/editor/plugins/abstract_polygon_2d_editor.h index 4f9adfff25..5fea8b75d6 100644 --- a/editor/plugins/abstract_polygon_2d_editor.h +++ b/editor/plugins/abstract_polygon_2d_editor.h @@ -106,7 +106,6 @@ protected: void _wip_changed(); void _wip_close(); void _wip_cancel(); - bool _delete_point(const Vector2 &p_gpoint); void _notification(int p_what); void _node_removed(Node *p_node); diff --git a/editor/plugins/animation_blend_space_1d_editor.h b/editor/plugins/animation_blend_space_1d_editor.h index fe98a91ab3..503e066894 100644 --- a/editor/plugins/animation_blend_space_1d_editor.h +++ b/editor/plugins/animation_blend_space_1d_editor.h @@ -109,8 +109,6 @@ class AnimationNodeBlendSpace1DEditor : public AnimationTreeNodeEditorPlugin { void _edit_point_pos(double); void _open_editor(); - void _goto_parent(); - EditorFileDialog *open_file; Ref<AnimationNode> file_loaded; void _file_opened(const String &p_file); diff --git a/editor/plugins/animation_player_editor_plugin.h b/editor/plugins/animation_player_editor_plugin.h index eb8db2eaba..26bcff891d 100644 --- a/editor/plugins/animation_player_editor_plugin.h +++ b/editor/plugins/animation_player_editor_plugin.h @@ -187,7 +187,6 @@ class AnimationPlayerEditor : public VBoxContainer { void _scale_changed(const String &p_scale); void _save_animation(String p_file); void _load_animations(Vector<String> p_files); - void _seek_frame_changed(const String &p_frame); void _seek_value_changed(float p_value, bool p_set = false, bool p_timeline_only = false); void _blend_editor_next_changed(const int p_idx); @@ -217,7 +216,6 @@ class AnimationPlayerEditor : public VBoxContainer { void _pin_pressed(); - AnimationPlayerEditor(); ~AnimationPlayerEditor(); protected: diff --git a/editor/plugins/asset_library_editor_plugin.h b/editor/plugins/asset_library_editor_plugin.h index 286546f962..5fbf2833b2 100644 --- a/editor/plugins/asset_library_editor_plugin.h +++ b/editor/plugins/asset_library_editor_plugin.h @@ -285,7 +285,6 @@ class EditorAssetLibrary : public PanelContainer { void _search_text_submitted(const String &p_text = ""); void _api_request(const String &p_request, RequestType p_request_type, const String &p_arguments = ""); void _http_request_completed(int p_status, int p_code, const PackedStringArray &headers, const PackedByteArray &p_data); - void _http_download_completed(int p_status, int p_code, const PackedStringArray &headers, const PackedByteArray &p_data); void _filter_debounce_timer_timeout(); void _repository_changed(int p_repository_id); diff --git a/editor/plugins/canvas_item_editor_plugin.h b/editor/plugins/canvas_item_editor_plugin.h index 1965efbf30..286771ee08 100644 --- a/editor/plugins/canvas_item_editor_plugin.h +++ b/editor/plugins/canvas_item_editor_plugin.h @@ -421,8 +421,6 @@ private: CanvasItem *ref_item; - void _add_canvas_item(CanvasItem *p_canvas_item); - void _save_canvas_item_state(List<CanvasItem *> p_canvas_items, bool save_bones = false); void _restore_canvas_item_state(List<CanvasItem *> p_canvas_items, bool restore_bones = false); void _commit_canvas_item_state(List<CanvasItem *> p_canvas_items, String action_name, bool commit_bones = false); @@ -434,7 +432,6 @@ private: bool updating_scroll; void _update_scroll(real_t); void _update_scrollbars(); - void _append_canvas_item(CanvasItem *p_item); void _snap_changed(); void _selection_result_pressed(int); void _selection_menu_hide(); @@ -519,7 +516,6 @@ private: const Node *p_current); void _set_anchors_preset(Control::LayoutPreset p_preset); - void _set_offsets_preset(Control::LayoutPreset p_preset); void _set_anchors_and_offsets_preset(Control::LayoutPreset p_preset); void _set_anchors_and_offsets_to_keep_ratio(); @@ -551,15 +547,9 @@ protected: void _notification(int p_what); static void _bind_methods(); - void end_drag(); - void box_selection_start(Point2 &click); - bool box_selection_end(); HBoxContainer *get_panel_hb() { return hb; } - template <class P, class C> - void space_selected_items(); - static CanvasItemEditor *singleton; public: diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index 32a8bbf406..0096152cfe 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -2228,18 +2228,28 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { } if (ED_IS_SHORTCUT("spatial_editor/orbit_view_down", p_event)) { cursor.x_rot -= Math_PI / 12.0; + view_type = VIEW_TYPE_USER; + _update_name(); } if (ED_IS_SHORTCUT("spatial_editor/orbit_view_up", p_event)) { cursor.x_rot += Math_PI / 12.0; + view_type = VIEW_TYPE_USER; + _update_name(); } if (ED_IS_SHORTCUT("spatial_editor/orbit_view_right", p_event)) { cursor.y_rot -= Math_PI / 12.0; + view_type = VIEW_TYPE_USER; + _update_name(); } if (ED_IS_SHORTCUT("spatial_editor/orbit_view_left", p_event)) { cursor.y_rot += Math_PI / 12.0; + view_type = VIEW_TYPE_USER; + _update_name(); } if (ED_IS_SHORTCUT("spatial_editor/orbit_view_180", p_event)) { cursor.y_rot += Math_PI; + view_type = VIEW_TYPE_USER; + _update_name(); } if (ED_IS_SHORTCUT("spatial_editor/focus_origin", p_event)) { _menu_option(VIEW_CENTER_TO_ORIGIN); diff --git a/editor/plugins/node_3d_editor_plugin.h b/editor/plugins/node_3d_editor_plugin.h index 2d5aeaa981..5290a8804b 100644 --- a/editor/plugins/node_3d_editor_plugin.h +++ b/editor/plugins/node_3d_editor_plugin.h @@ -677,8 +677,6 @@ private: void _register_all_gizmos(); - Node3DEditor(); - void _selection_changed(); void _refresh_menu_icons(); diff --git a/editor/plugins/resource_preloader_editor_plugin.h b/editor/plugins/resource_preloader_editor_plugin.h index 04ab458eb5..943765d4e0 100644 --- a/editor/plugins/resource_preloader_editor_plugin.h +++ b/editor/plugins/resource_preloader_editor_plugin.h @@ -59,7 +59,6 @@ class ResourcePreloaderEditor : public PanelContainer { ResourcePreloader *preloader; void _load_pressed(); - void _load_scene_pressed(); void _files_load_request(const Vector<String> &p_paths); void _paste_pressed(); void _remove_resource(const String &p_to_remove); diff --git a/editor/plugins/script_editor_plugin.h b/editor/plugins/script_editor_plugin.h index 8caebc1c8c..2b0bdfd109 100644 --- a/editor/plugins/script_editor_plugin.h +++ b/editor/plugins/script_editor_plugin.h @@ -371,14 +371,11 @@ class ScriptEditor : public PanelContainer { bool use_space_indentation; bool convert_indent_on_save; - void _trim_trailing_whitespace(TextEdit *tx); - void _goto_script_line2(int p_line); void _goto_script_line(REF p_script, int p_line); void _set_execution(REF p_script, int p_line); void _clear_execution(REF p_script); void _breaked(bool p_breaked, bool p_can_debug); - void _update_window_menu(); void _script_created(Ref<Script> p_script); void _set_breakpoint(REF p_scrpt, int p_line, bool p_enabled); void _clear_breakpoints(); @@ -430,7 +427,6 @@ class ScriptEditor : public PanelContainer { void _make_script_list_context_menu(); void _help_search(String p_text); - void _help_index(String p_text); void _history_forward(); void _history_back(); diff --git a/editor/plugins/sprite_frames_editor_plugin.h b/editor/plugins/sprite_frames_editor_plugin.h index 5e3b2fb8c1..9732384000 100644 --- a/editor/plugins/sprite_frames_editor_plugin.h +++ b/editor/plugins/sprite_frames_editor_plugin.h @@ -100,7 +100,6 @@ class SpriteFramesEditor : public HSplitContainer { float min_sheet_zoom; void _load_pressed(); - void _load_scene_pressed(); void _file_load_request(const Vector<String> &p_path, int p_at_pos = -1); void _copy_pressed(); void _paste_pressed(); @@ -128,7 +127,6 @@ class SpriteFramesEditor : public HSplitContainer { UndoRedo *undo_redo; - bool _is_drop_valid(const Dictionary &p_drag_data, const Dictionary &p_item_data) const; Variant get_drag_data_fw(const Point2 &p_point, Control *p_from); bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const; void drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from); diff --git a/editor/plugins/theme_editor_plugin.cpp b/editor/plugins/theme_editor_plugin.cpp index 19e1b40a0d..127219546d 100644 --- a/editor/plugins/theme_editor_plugin.cpp +++ b/editor/plugins/theme_editor_plugin.cpp @@ -3204,7 +3204,7 @@ void ThemeEditor::_add_preview_tab(ThemeEditorPreview *p_preview_tab, const Stri preview_tabs->add_tab(p_preview_name, p_icon); preview_tabs_content->add_child(p_preview_tab); - preview_tabs->set_tab_right_button(preview_tabs->get_tab_count() - 1, EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("close"), SNAME("Tabs"))); + preview_tabs->set_tab_right_button(preview_tabs->get_tab_count() - 1, EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("close"), SNAME("TabBar"))); p_preview_tab->connect("control_picked", callable_mp(this, &ThemeEditor::_preview_control_picked)); preview_tabs->set_current_tab(preview_tabs->get_tab_count() - 1); @@ -3328,8 +3328,8 @@ ThemeEditor::ThemeEditor() { preview_tabs_content->set_draw_behind_parent(true); preview_tabs_vb->add_child(preview_tabs_content); - preview_tabs = memnew(Tabs); - preview_tabs->set_tab_align(Tabs::ALIGN_LEFT); + preview_tabs = memnew(TabBar); + preview_tabs->set_tab_align(TabBar::ALIGN_LEFT); preview_tabs->set_h_size_flags(SIZE_EXPAND_FILL); preview_tabbar_hb->add_child(preview_tabs); preview_tabs->connect("tab_changed", callable_mp(this, &ThemeEditor::_change_preview_tab)); diff --git a/editor/plugins/theme_editor_plugin.h b/editor/plugins/theme_editor_plugin.h index 5b0357e3f8..b6becbb1c7 100644 --- a/editor/plugins/theme_editor_plugin.h +++ b/editor/plugins/theme_editor_plugin.h @@ -34,7 +34,7 @@ #include "scene/gui/margin_container.h" #include "scene/gui/option_button.h" #include "scene/gui/scroll_container.h" -#include "scene/gui/tabs.h" +#include "scene/gui/tab_bar.h" #include "scene/gui/texture_rect.h" #include "scene/resources/theme.h" #include "theme_editor_preview.h" @@ -347,7 +347,6 @@ class ThemeTypeEditor : public MarginContainer { void _update_type_items(); void _list_type_selected(int p_index); - void _select_type(String p_type_name); void _add_type_button_cbk(); void _add_default_type_items(); @@ -391,7 +390,7 @@ class ThemeEditor : public VBoxContainer { Ref<Theme> theme; - Tabs *preview_tabs; + TabBar *preview_tabs; PanelContainer *preview_tabs_content; Button *add_preview_button; EditorFileDialog *preview_scene_dialog; diff --git a/editor/plugins/tiles/tile_map_editor.cpp b/editor/plugins/tiles/tile_map_editor.cpp index 5df4f40b55..5dfa44a353 100644 --- a/editor/plugins/tiles/tile_map_editor.cpp +++ b/editor/plugins/tiles/tile_map_editor.cpp @@ -194,7 +194,7 @@ void TileMapEditorTilesPlugin::_update_tile_set_sources_list() { } // Synchronize - TilesEditor::get_singleton()->set_sources_lists_current(sources_list->get_current()); + TilesEditorPlugin::get_singleton()->set_sources_lists_current(sources_list->get_current()); } void TileMapEditorTilesPlugin::_update_source_display() { @@ -304,7 +304,7 @@ void TileMapEditorTilesPlugin::_update_patterns_list() { for (int i = 0; i < tile_set->get_patterns_count(); i++) { int id = patterns_item_list->add_item(""); patterns_item_list->set_item_metadata(id, tile_set->get_pattern(i)); - TilesEditor::get_singleton()->queue_pattern_preview(tile_set, tile_set->get_pattern(i), callable_mp(this, &TileMapEditorTilesPlugin::_pattern_preview_done)); + TilesEditorPlugin::get_singleton()->queue_pattern_preview(tile_set, tile_set->get_pattern(i), callable_mp(this, &TileMapEditorTilesPlugin::_pattern_preview_done)); } // Update the label visibility. @@ -336,7 +336,7 @@ void TileMapEditorTilesPlugin::_update_atlas_view() { ERR_FAIL_COND(!atlas_source); tile_atlas_view->set_atlas_source(*tile_map->get_tileset(), atlas_source, source_id); - TilesEditor::get_singleton()->synchronize_atlas_view(tile_atlas_view); + TilesEditorPlugin::get_singleton()->synchronize_atlas_view(tile_atlas_view); tile_atlas_control->update(); } @@ -2116,8 +2116,8 @@ TileMapEditorTilesPlugin::TileMapEditorTilesPlugin() { sources_list->set_texture_filter(CanvasItem::TEXTURE_FILTER_NEAREST); sources_list->connect("item_selected", callable_mp(this, &TileMapEditorTilesPlugin::_update_fix_selected_and_hovered).unbind(1)); sources_list->connect("item_selected", callable_mp(this, &TileMapEditorTilesPlugin::_update_source_display).unbind(1)); - sources_list->connect("item_selected", callable_mp(TilesEditor::get_singleton(), &TilesEditor::set_sources_lists_current)); - sources_list->connect("visibility_changed", callable_mp(TilesEditor::get_singleton(), &TilesEditor::synchronize_sources_list), varray(sources_list)); + sources_list->connect("item_selected", callable_mp(TilesEditorPlugin::get_singleton(), &TilesEditorPlugin::set_sources_lists_current)); + sources_list->connect("visibility_changed", callable_mp(TilesEditorPlugin::get_singleton(), &TilesEditorPlugin::synchronize_sources_list), varray(sources_list)); atlas_sources_split_container->add_child(sources_list); // Tile atlas source. @@ -2126,7 +2126,7 @@ TileMapEditorTilesPlugin::TileMapEditorTilesPlugin() { tile_atlas_view->set_v_size_flags(Control::SIZE_EXPAND_FILL); tile_atlas_view->set_texture_grid_visible(false); tile_atlas_view->set_tile_shape_grid_visible(false); - tile_atlas_view->connect("transform_changed", callable_mp(TilesEditor::get_singleton(), &TilesEditor::set_atlas_view_transform)); + tile_atlas_view->connect("transform_changed", callable_mp(TilesEditorPlugin::get_singleton(), &TilesEditorPlugin::set_atlas_view_transform)); atlas_sources_split_container->add_child(tile_atlas_view); tile_atlas_control = memnew(Control); @@ -4049,8 +4049,8 @@ TileMapEditor::TileMapEditor() { tile_map_editor_plugins.push_back(memnew(TileMapEditorTilesPlugin)); tile_map_editor_plugins.push_back(memnew(TileMapEditorTerrainsPlugin)); - // Tabs. - tabs_bar = memnew(Tabs); + // TabBar. + tabs_bar = memnew(TabBar); tabs_bar->set_clip_tabs(false); for (int plugin_index = 0; plugin_index < tile_map_editor_plugins.size(); plugin_index++) { Vector<TileMapEditorPlugin::TabData> tabs_vector = tile_map_editor_plugins[plugin_index]->get_tabs(); @@ -4065,6 +4065,7 @@ TileMapEditor::TileMapEditor() { // --- TileMap toolbar --- tile_map_toolbar = memnew(HBoxContainer); tile_map_toolbar->set_h_size_flags(SIZE_EXPAND_FILL); + add_child(tile_map_toolbar); // Tabs. tile_map_toolbar->add_child(tabs_bar); diff --git a/editor/plugins/tiles/tile_map_editor.h b/editor/plugins/tiles/tile_map_editor.h index 54bac160a3..1f1a560113 100644 --- a/editor/plugins/tiles/tile_map_editor.h +++ b/editor/plugins/tiles/tile_map_editor.h @@ -38,7 +38,7 @@ #include "editor/editor_node.h" #include "scene/2d/tile_map.h" #include "scene/gui/box_container.h" -#include "scene/gui/tabs.h" +#include "scene/gui/tab_bar.h" class TileMapEditorPlugin : public Object { public: @@ -351,7 +351,7 @@ private: // Bottom panel. Label *missing_tileset_label; - Tabs *tabs_bar; + TabBar *tabs_bar; LocalVector<TileMapEditorPlugin::TabData> tabs_data; LocalVector<TileMapEditorPlugin *> tabs_plugins; void _update_bottom_panel(); @@ -380,7 +380,6 @@ public: void forward_canvas_draw_over_viewport(Control *p_overlay); void edit(TileMap *p_tile_map); - Control *get_toolbar() { return tile_map_toolbar; }; TileMapEditor(); ~TileMapEditor(); diff --git a/editor/plugins/tiles/tile_set_atlas_source_editor.cpp b/editor/plugins/tiles/tile_set_atlas_source_editor.cpp index 157d28da4f..c8892bceaa 100644 --- a/editor/plugins/tiles/tile_set_atlas_source_editor.cpp +++ b/editor/plugins/tiles/tile_set_atlas_source_editor.cpp @@ -924,7 +924,7 @@ void TileSetAtlasSourceEditor::_update_atlas_view() { tile_atlas_view->update(); // Synchronize atlas view. - TilesEditor::get_singleton()->synchronize_atlas_view(tile_atlas_view); + TilesEditorPlugin::get_singleton()->synchronize_atlas_view(tile_atlas_view); } void TileSetAtlasSourceEditor::_update_toolbar() { @@ -2476,7 +2476,7 @@ TileSetAtlasSourceEditor::TileSetAtlasSourceEditor() { tile_atlas_view = memnew(TileAtlasView); tile_atlas_view->set_h_size_flags(SIZE_EXPAND_FILL); tile_atlas_view->set_v_size_flags(SIZE_EXPAND_FILL); - tile_atlas_view->connect("transform_changed", callable_mp(TilesEditor::get_singleton(), &TilesEditor::set_atlas_view_transform)); + tile_atlas_view->connect("transform_changed", callable_mp(TilesEditorPlugin::get_singleton(), &TilesEditorPlugin::set_atlas_view_transform)); tile_atlas_view->connect("transform_changed", callable_mp(this, &TileSetAtlasSourceEditor::_tile_atlas_view_transform_changed).unbind(2)); right_panel->add_child(tile_atlas_view); diff --git a/editor/plugins/tiles/tile_set_editor.cpp b/editor/plugins/tiles/tile_set_editor.cpp index 44f5ba29de..0fbb9a98c7 100644 --- a/editor/plugins/tiles/tile_set_editor.cpp +++ b/editor/plugins/tiles/tile_set_editor.cpp @@ -209,7 +209,7 @@ void TileSetEditor::_update_sources_list(int force_selected_id) { _source_selected(sources_list->get_current()); // Synchronize the lists. - TilesEditor::get_singleton()->set_sources_lists_current(sources_list->get_current()); + TilesEditorPlugin::get_singleton()->set_sources_lists_current(sources_list->get_current()); } void TileSetEditor::_source_selected(int p_source_index) { @@ -370,7 +370,7 @@ void TileSetEditor::_update_patterns_list() { for (int i = 0; i < tile_set->get_patterns_count(); i++) { int id = patterns_item_list->add_item(""); patterns_item_list->set_item_metadata(id, tile_set->get_pattern(i)); - TilesEditor::get_singleton()->queue_pattern_preview(tile_set, tile_set->get_pattern(i), callable_mp(this, &TileSetEditor::_pattern_preview_done)); + TilesEditorPlugin::get_singleton()->queue_pattern_preview(tile_set, tile_set->get_pattern(i), callable_mp(this, &TileSetEditor::_pattern_preview_done)); } // Update the label visibility. @@ -642,8 +642,8 @@ TileSetEditor::TileSetEditor() { set_process_internal(true); - // Tabs. - tabs_bar = memnew(Tabs); + // TabBar. + tabs_bar = memnew(TabBar); tabs_bar->set_clip_tabs(false); tabs_bar->add_tab(TTR("Tiles")); tabs_bar->add_tab(TTR("Patterns")); @@ -652,6 +652,7 @@ TileSetEditor::TileSetEditor() { tile_set_toolbar = memnew(HBoxContainer); tile_set_toolbar->set_h_size_flags(SIZE_EXPAND_FILL); tile_set_toolbar->add_child(tabs_bar); + add_child(tile_set_toolbar); //// Tiles //// // Split container. @@ -674,8 +675,8 @@ TileSetEditor::TileSetEditor() { sources_list->set_h_size_flags(SIZE_EXPAND_FILL); sources_list->set_v_size_flags(SIZE_EXPAND_FILL); sources_list->connect("item_selected", callable_mp(this, &TileSetEditor::_source_selected)); - sources_list->connect("item_selected", callable_mp(TilesEditor::get_singleton(), &TilesEditor::set_sources_lists_current)); - sources_list->connect("visibility_changed", callable_mp(TilesEditor::get_singleton(), &TilesEditor::synchronize_sources_list), varray(sources_list)); + sources_list->connect("item_selected", callable_mp(TilesEditorPlugin::get_singleton(), &TilesEditorPlugin::set_sources_lists_current)); + sources_list->connect("visibility_changed", callable_mp(TilesEditorPlugin::get_singleton(), &TilesEditorPlugin::synchronize_sources_list), varray(sources_list)); sources_list->set_texture_filter(CanvasItem::TEXTURE_FILTER_NEAREST); sources_list->set_drag_forwarding(this); split_container_left_side->add_child(sources_list); diff --git a/editor/plugins/tiles/tile_set_editor.h b/editor/plugins/tiles/tile_set_editor.h index 1f26560588..cda38760cf 100644 --- a/editor/plugins/tiles/tile_set_editor.h +++ b/editor/plugins/tiles/tile_set_editor.h @@ -48,9 +48,9 @@ private: bool tile_set_changed_needs_update = false; HSplitContainer *split_container; - // Tabs. + // TabBar. HBoxContainer *tile_set_toolbar; - Tabs *tabs_bar; + TabBar *tabs_bar; // Tiles. Label *no_source_selected_label; @@ -97,7 +97,6 @@ public: _FORCE_INLINE_ static TileSetEditor *get_singleton() { return singleton; } void edit(Ref<TileSet> p_tile_set); - Control *get_toolbar() { return tile_set_toolbar; }; void drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from); bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const; diff --git a/editor/plugins/tiles/tiles_editor_plugin.cpp b/editor/plugins/tiles/tiles_editor_plugin.cpp index cc1b80fa8e..f1918073fb 100644 --- a/editor/plugins/tiles/tiles_editor_plugin.cpp +++ b/editor/plugins/tiles/tiles_editor_plugin.cpp @@ -45,37 +45,18 @@ #include "tile_set_editor.h" -TilesEditor *TilesEditor::singleton = nullptr; +TilesEditorPlugin *TilesEditorPlugin::singleton = nullptr; -void TilesEditor::_notification(int p_what) { - switch (p_what) { - case NOTIFICATION_ENTER_TREE: - case NOTIFICATION_THEME_CHANGED: { - tileset_tilemap_switch_button->set_icon(get_theme_icon(SNAME("TileSet"), SNAME("EditorIcons"))); - } break; - case NOTIFICATION_INTERNAL_PROCESS: { - if (tile_map_changed_needs_update) { - TileMap *tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id)); - if (tile_map) { - tile_set = tile_map->get_tileset(); - } - _update_switch_button(); - _update_editors(); - } - } break; - } -} - -void TilesEditor::_pattern_preview_done(const Variant &p_udata) { +void TilesEditorPlugin::_pattern_preview_done(const Variant &p_udata) { pattern_preview_done.set(); } -void TilesEditor::_thread_func(void *ud) { - TilesEditor *te = (TilesEditor *)ud; +void TilesEditorPlugin::_thread_func(void *ud) { + TilesEditorPlugin *te = (TilesEditorPlugin *)ud; te->_thread(); } -void TilesEditor::_thread() { +void TilesEditorPlugin::_thread() { pattern_thread_exited.clear(); while (!pattern_thread_exit.is_set()) { pattern_preview_sem.wait(); @@ -132,7 +113,7 @@ void TilesEditor::_thread() { EditorNode::get_singleton()->add_child(viewport); pattern_preview_done.clear(); - RS::get_singleton()->request_frame_drawn_callback(const_cast<TilesEditor *>(this), "_pattern_preview_done", Variant()); + RS::get_singleton()->request_frame_drawn_callback(const_cast<TilesEditorPlugin *>(this), "_pattern_preview_done", Variant()); while (!pattern_preview_done.is_set()) { OS::get_singleton()->delay_usec(10); @@ -159,65 +140,73 @@ void TilesEditor::_thread() { pattern_thread_exited.set(); } -void TilesEditor::_tile_map_changed() { +void TilesEditorPlugin::_tile_map_changed() { tile_map_changed_needs_update = true; } -void TilesEditor::_update_switch_button() { - // Force the buttons status if needed. +void TilesEditorPlugin::_update_editors() { + // If tile_map is not edited, we change the edited only if we are not editing a tile_set. + tileset_editor->edit(tile_set); TileMap *tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id)); - if (tile_map && !tile_set.is_valid()) { - tileset_tilemap_switch_button->set_pressed(false); - } else if (!tile_map && tile_set.is_valid()) { - tileset_tilemap_switch_button->set_pressed(true); + if (tile_map) { + tilemap_editor->edit(tile_map); + } else { + tilemap_editor->edit(nullptr); } + + // Update the viewport. + CanvasItemEditor::get_singleton()->update_viewport(); } -void TilesEditor::_update_editors() { - // Set editors visibility. - tilemap_toolbar->set_visible(!tileset_tilemap_switch_button->is_pressed()); - tilemap_editor->set_visible(!tileset_tilemap_switch_button->is_pressed()); - tileset_toolbar->set_visible(tileset_tilemap_switch_button->is_pressed()); - tileset_editor->set_visible(tileset_tilemap_switch_button->is_pressed()); - - // Enable/disable the switch button. - if (!tileset_tilemap_switch_button->is_pressed()) { - if (!tile_set.is_valid()) { - tileset_tilemap_switch_button->set_disabled(true); - tileset_tilemap_switch_button->set_tooltip(TTR("This TileMap has no assigned TileSet, assign a TileSet to this TileMap to edit it.")); - } else { - tileset_tilemap_switch_button->set_disabled(false); - tileset_tilemap_switch_button->set_tooltip(TTR("Switch between TileSet/TileMap editor.")); - } - } else { +void TilesEditorPlugin::_notification(int p_what) { + switch (p_what) { + case NOTIFICATION_INTERNAL_PROCESS: { + if (tile_map_changed_needs_update) { + TileMap *tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id)); + if (tile_map) { + tile_set = tile_map->get_tileset(); + } + _update_editors(); + tile_map_changed_needs_update = false; + } + } break; + } +} + +void TilesEditorPlugin::make_visible(bool p_visible) { + if (p_visible) { + // Disable and hide invalid editors. TileMap *tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id)); - if (!tile_map) { - tileset_tilemap_switch_button->set_disabled(true); - tileset_tilemap_switch_button->set_tooltip(TTR("You are editing a TileSet resource. Select a TileMap node to paint.")); + tileset_editor_button->set_visible(tile_set.is_valid()); + tilemap_editor_button->set_visible(tile_map); + if (tile_map) { + editor_node->make_bottom_panel_item_visible(tilemap_editor); } else { - tileset_tilemap_switch_button->set_disabled(false); - tileset_tilemap_switch_button->set_tooltip(TTR("Switch between TileSet/TileMap editor.")); + editor_node->make_bottom_panel_item_visible(tileset_editor); } - } - // If tile_map is not edited, we change the edited only if we are not editing a tile_set. - TileMap *tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id)); - if (tile_map) { - tilemap_editor->edit(tile_map); } else { - tilemap_editor->edit(nullptr); + tileset_editor_button->hide(); + tilemap_editor_button->hide(); + editor_node->hide_bottom_panel(); } - tileset_editor->edit(tile_set); +} - // Update the viewport - CanvasItemEditor::get_singleton()->update_viewport(); +void TilesEditorPlugin::queue_pattern_preview(Ref<TileSet> p_tile_set, Ref<TileMapPattern> p_pattern, Callable p_callback) { + ERR_FAIL_COND(!p_tile_set.is_valid()); + ERR_FAIL_COND(!p_pattern.is_valid()); + { + MutexLock lock(pattern_preview_mutex); + pattern_preview_queue.push_back({ p_tile_set, p_pattern, p_callback }); + } + pattern_preview_sem.post(); } -void TilesEditor::set_sources_lists_current(int p_current) { +void TilesEditorPlugin::set_sources_lists_current(int p_current) { atlas_sources_lists_current = p_current; } -void TilesEditor::synchronize_sources_list(Object *p_current) { +void TilesEditorPlugin::synchronize_sources_list(Object *p_current) { ItemList *item_list = Object::cast_to<ItemList>(p_current); ERR_FAIL_COND(!item_list); @@ -231,12 +220,12 @@ void TilesEditor::synchronize_sources_list(Object *p_current) { } } -void TilesEditor::set_atlas_view_transform(float p_zoom, Vector2 p_scroll) { +void TilesEditorPlugin::set_atlas_view_transform(float p_zoom, Vector2 p_scroll) { atlas_view_zoom = p_zoom; atlas_view_scroll = p_scroll; } -void TilesEditor::synchronize_atlas_view(Object *p_current) { +void TilesEditorPlugin::synchronize_atlas_view(Object *p_current) { TileAtlasView *tile_atlas_view = Object::cast_to<TileAtlasView>(p_current); ERR_FAIL_COND(!tile_atlas_view); @@ -245,21 +234,11 @@ void TilesEditor::synchronize_atlas_view(Object *p_current) { } } -void TilesEditor::queue_pattern_preview(Ref<TileSet> p_tile_set, Ref<TileMapPattern> p_pattern, Callable p_callback) { - ERR_FAIL_COND(!p_tile_set.is_valid()); - ERR_FAIL_COND(!p_pattern.is_valid()); - { - MutexLock lock(pattern_preview_mutex); - pattern_preview_queue.push_back({ p_tile_set, p_pattern, p_callback }); - } - pattern_preview_sem.post(); -} - -void TilesEditor::edit(Object *p_object) { +void TilesEditorPlugin::edit(Object *p_object) { // Disconnect to changes. TileMap *tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id)); if (tile_map) { - tile_map->disconnect("changed", callable_mp(this, &TilesEditor::_tile_map_changed)); + tile_map->disconnect("changed", callable_mp(this, &TilesEditorPlugin::_tile_map_changed)); } // Update edited objects. @@ -269,84 +248,72 @@ void TilesEditor::edit(Object *p_object) { tile_map_id = p_object->get_instance_id(); tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id)); tile_set = tile_map->get_tileset(); + editor_node->make_bottom_panel_item_visible(tilemap_editor); } else if (p_object->is_class("TileSet")) { tile_set = Ref<TileSet>(p_object); if (tile_map) { - if (tile_map->get_tileset() != tile_set) { + if (tile_map->get_tileset() != tile_set || !tile_map->is_inside_tree()) { tile_map = nullptr; + tile_map_id = ObjectID(); } } - } - - // Update pressed status button. - if (p_object->is_class("TileMap")) { - tileset_tilemap_switch_button->set_pressed(false); - } else if (p_object->is_class("TileSet")) { - tileset_tilemap_switch_button->set_pressed(true); + editor_node->make_bottom_panel_item_visible(tileset_editor); } } // Update the editors. - _update_switch_button(); _update_editors(); // Add change listener. if (tile_map) { - tile_map->connect("changed", callable_mp(this, &TilesEditor::_tile_map_changed)); + tile_map->connect("changed", callable_mp(this, &TilesEditorPlugin::_tile_map_changed)); } } -void TilesEditor::_bind_methods() { - ClassDB::bind_method(D_METHOD("_pattern_preview_done", "pattern"), &TilesEditor::_pattern_preview_done); +bool TilesEditorPlugin::handles(Object *p_object) const { + return p_object->is_class("TileMap") || p_object->is_class("TileSet"); +} + +void TilesEditorPlugin::_bind_methods() { + ClassDB::bind_method(D_METHOD("_pattern_preview_done", "pattern"), &TilesEditorPlugin::_pattern_preview_done); } -TilesEditor::TilesEditor(EditorNode *p_editor) { +TilesEditorPlugin::TilesEditorPlugin(EditorNode *p_node) { set_process_internal(true); // Update the singleton. singleton = this; - // Toolbar. - HBoxContainer *toolbar = memnew(HBoxContainer); - toolbar->set_h_size_flags(SIZE_EXPAND_FILL); - add_child(toolbar); - - // Switch button. - tileset_tilemap_switch_button = memnew(Button); - tileset_tilemap_switch_button->set_flat(true); - tileset_tilemap_switch_button->set_toggle_mode(true); - tileset_tilemap_switch_button->connect("toggled", callable_mp(this, &TilesEditor::_update_editors).unbind(1)); - toolbar->add_child(tileset_tilemap_switch_button); - - // Tilemap editor. - tilemap_editor = memnew(TileMapEditor); - tilemap_editor->set_h_size_flags(SIZE_EXPAND_FILL); - tilemap_editor->set_v_size_flags(SIZE_EXPAND_FILL); - tilemap_editor->hide(); - add_child(tilemap_editor); - - tilemap_toolbar = tilemap_editor->get_toolbar(); - toolbar->add_child(tilemap_toolbar); + editor_node = p_node; // Tileset editor. tileset_editor = memnew(TileSetEditor); - tileset_editor->set_h_size_flags(SIZE_EXPAND_FILL); - tileset_editor->set_v_size_flags(SIZE_EXPAND_FILL); + tileset_editor->set_h_size_flags(Control::SIZE_EXPAND_FILL); + tileset_editor->set_v_size_flags(Control::SIZE_EXPAND_FILL); + tileset_editor->set_custom_minimum_size(Size2(0, 200) * EDSCALE); tileset_editor->hide(); - add_child(tileset_editor); - tileset_toolbar = tileset_editor->get_toolbar(); - toolbar->add_child(tileset_toolbar); + // Tilemap editor. + tilemap_editor = memnew(TileMapEditor); + tilemap_editor->set_h_size_flags(Control::SIZE_EXPAND_FILL); + tilemap_editor->set_v_size_flags(Control::SIZE_EXPAND_FILL); + tilemap_editor->set_custom_minimum_size(Size2(0, 200) * EDSCALE); + tilemap_editor->hide(); // Pattern preview generation thread. pattern_preview_thread.start(_thread_func, this); + // Bottom buttons. + tileset_editor_button = p_node->add_bottom_panel_item(TTR("TileSet"), tileset_editor); + tileset_editor_button->hide(); + tilemap_editor_button = p_node->add_bottom_panel_item(TTR("TileMap"), tilemap_editor); + tilemap_editor_button->hide(); + // Initialization. - _update_switch_button(); _update_editors(); } -TilesEditor::~TilesEditor() { +TilesEditorPlugin::~TilesEditorPlugin() { if (pattern_preview_thread.is_started()) { pattern_thread_exit.set(); pattern_preview_sem.post(); @@ -357,40 +324,3 @@ TilesEditor::~TilesEditor() { pattern_preview_thread.wait_to_finish(); } } - -/////////////////////////////////////////////////////////////// - -void TilesEditorPlugin::_notification(int p_what) { -} - -void TilesEditorPlugin::make_visible(bool p_visible) { - if (p_visible) { - tiles_editor_button->show(); - editor_node->make_bottom_panel_item_visible(tiles_editor); - } else { - editor_node->hide_bottom_panel(); - tiles_editor_button->hide(); - } -} - -void TilesEditorPlugin::edit(Object *p_object) { - tiles_editor->edit(p_object); -} - -bool TilesEditorPlugin::handles(Object *p_object) const { - return p_object->is_class("TileMap") || p_object->is_class("TileSet"); -} - -TilesEditorPlugin::TilesEditorPlugin(EditorNode *p_node) { - editor_node = p_node; - - tiles_editor = memnew(TilesEditor(p_node)); - tiles_editor->set_custom_minimum_size(Size2(0, 200) * EDSCALE); - tiles_editor->hide(); - - tiles_editor_button = p_node->add_bottom_panel_item(TTR("Tiles"), tiles_editor); - tiles_editor_button->hide(); -} - -TilesEditorPlugin::~TilesEditorPlugin() { -} diff --git a/editor/plugins/tiles/tiles_editor_plugin.h b/editor/plugins/tiles/tiles_editor_plugin.h index c77fd76d1c..dd52bdc31a 100644 --- a/editor/plugins/tiles/tiles_editor_plugin.h +++ b/editor/plugins/tiles/tiles_editor_plugin.h @@ -38,25 +38,24 @@ #include "tile_map_editor.h" #include "tile_set_editor.h" -class TilesEditor : public VBoxContainer { - GDCLASS(TilesEditor, VBoxContainer); +class TilesEditorPlugin : public EditorPlugin { + GDCLASS(TilesEditorPlugin, EditorPlugin); - static TilesEditor *singleton; + static TilesEditorPlugin *singleton; private: + EditorNode *editor_node; + bool tile_map_changed_needs_update = false; ObjectID tile_map_id; Ref<TileSet> tile_set; - Button *tileset_tilemap_switch_button; - - Control *tilemap_toolbar; + Button *tilemap_editor_button; TileMapEditor *tilemap_editor; - Control *tileset_toolbar; + Button *tileset_editor_button; TileSetEditor *tileset_editor; - void _update_switch_button(); void _update_editors(); // For synchronization. @@ -64,6 +63,8 @@ private: float atlas_view_zoom = 1.0; Vector2 atlas_view_scroll = Vector2(); + void _tile_map_changed(); + // Patterns preview generation. struct QueueItem { Ref<TileSet> tile_set; @@ -81,17 +82,18 @@ private: static void _thread_func(void *ud); void _thread(); - void _tile_map_changed(); - protected: void _notification(int p_what); static void _bind_methods(); public: - _FORCE_INLINE_ static TilesEditor *get_singleton() { return singleton; } + _FORCE_INLINE_ static TilesEditorPlugin *get_singleton() { return singleton; } + + virtual bool forward_canvas_gui_input(const Ref<InputEvent> &p_event) override { return tilemap_editor->forward_canvas_gui_input(p_event); } + virtual void forward_canvas_draw_over_viewport(Control *p_overlay) override { tilemap_editor->forward_canvas_draw_over_viewport(p_overlay); } - bool forward_canvas_gui_input(const Ref<InputEvent> &p_event) { return tilemap_editor->forward_canvas_gui_input(p_event); } - void forward_canvas_draw_over_viewport(Control *p_overlay) { tilemap_editor->forward_canvas_draw_over_viewport(p_overlay); } + // Pattern preview API. + void queue_pattern_preview(Ref<TileSet> p_tile_set, Ref<TileMapPattern> p_pattern, Callable p_callback); // To synchronize the atlas sources lists. void set_sources_lists_current(int p_current); @@ -100,30 +102,6 @@ public: void set_atlas_view_transform(float p_zoom, Vector2 p_scroll); void synchronize_atlas_view(Object *p_current); - // Pattern preview API. - void queue_pattern_preview(Ref<TileSet> p_tile_set, Ref<TileMapPattern> p_pattern, Callable p_callback); - - void edit(Object *p_object); - - TilesEditor(EditorNode *p_editor); - ~TilesEditor(); -}; - -class TilesEditorPlugin : public EditorPlugin { - GDCLASS(TilesEditorPlugin, EditorPlugin); - -private: - EditorNode *editor_node; - TilesEditor *tiles_editor; - Button *tiles_editor_button; - -protected: - void _notification(int p_what); - -public: - virtual bool forward_canvas_gui_input(const Ref<InputEvent> &p_event) override { return tiles_editor->forward_canvas_gui_input(p_event); } - virtual void forward_canvas_draw_over_viewport(Control *p_overlay) override { tiles_editor->forward_canvas_draw_over_viewport(p_overlay); } - virtual void edit(Object *p_object) override; virtual bool handles(Object *p_object) const override; virtual void make_visible(bool p_visible) override; diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp index 0a067dfc17..09ca1f7608 100644 --- a/editor/plugins/visual_shader_editor_plugin.cpp +++ b/editor/plugins/visual_shader_editor_plugin.cpp @@ -31,6 +31,7 @@ #include "visual_shader_editor_plugin.h" #include "core/config/project_settings.h" +#include "core/core_string_names.h" #include "core/input/input.h" #include "core/io/resource_loader.h" #include "core/math/math_defs.h" @@ -212,19 +213,27 @@ void VisualShaderGraphPlugin::set_uniform_name(VisualShader::Type p_type, int p_ void VisualShaderGraphPlugin::update_curve(int p_node_id) { if (links.has(p_node_id) && links[p_node_id].curve_editors[0]) { - if (((VisualShaderNodeCurveTexture *)links[p_node_id].visual_node)->get_texture().is_valid()) { - links[p_node_id].curve_editors[0]->set_curve(((VisualShaderNodeCurveTexture *)links[p_node_id].visual_node)->get_texture()->get_curve()); + Ref<VisualShaderNodeCurveTexture> tex = Object::cast_to<VisualShaderNodeCurveTexture>(links[p_node_id].visual_node); + ERR_FAIL_COND(!tex.is_valid()); + + if (tex->get_texture().is_valid()) { + links[p_node_id].curve_editors[0]->set_curve(tex->get_texture()->get_curve()); } + tex->emit_signal(CoreStringNames::get_singleton()->changed); } } void VisualShaderGraphPlugin::update_curve_xyz(int p_node_id) { if (links.has(p_node_id) && links[p_node_id].curve_editors[0] && links[p_node_id].curve_editors[1] && links[p_node_id].curve_editors[2]) { - if (((VisualShaderNodeCurveXYZTexture *)links[p_node_id].visual_node)->get_texture().is_valid()) { - links[p_node_id].curve_editors[0]->set_curve(((VisualShaderNodeCurveXYZTexture *)links[p_node_id].visual_node)->get_texture()->get_curve_x()); - links[p_node_id].curve_editors[1]->set_curve(((VisualShaderNodeCurveXYZTexture *)links[p_node_id].visual_node)->get_texture()->get_curve_y()); - links[p_node_id].curve_editors[2]->set_curve(((VisualShaderNodeCurveXYZTexture *)links[p_node_id].visual_node)->get_texture()->get_curve_z()); + Ref<VisualShaderNodeCurveXYZTexture> tex = Object::cast_to<VisualShaderNodeCurveXYZTexture>(links[p_node_id].visual_node); + ERR_FAIL_COND(!tex.is_valid()); + + if (tex->get_texture().is_valid()) { + links[p_node_id].curve_editors[0]->set_curve(tex->get_texture()->get_curve_x()); + links[p_node_id].curve_editors[1]->set_curve(tex->get_texture()->get_curve_y()); + links[p_node_id].curve_editors[2]->set_curve(tex->get_texture()->get_curve_z()); } + tex->emit_signal(CoreStringNames::get_singleton()->changed); } } diff --git a/editor/plugins/visual_shader_editor_plugin.h b/editor/plugins/visual_shader_editor_plugin.h index 9f24c5af72..5788959a77 100644 --- a/editor/plugins/visual_shader_editor_plugin.h +++ b/editor/plugins/visual_shader_editor_plugin.h @@ -335,8 +335,6 @@ class VisualShaderEditor : public VBoxContainer { void _delete_node_request(int p_type, int p_node); void _delete_nodes_request(); - void _removed_from_graph(); - void _node_changed(int p_id); void _edit_port_default_input(Object *p_button, int p_node, int p_port); diff --git a/editor/project_settings_editor.h b/editor/project_settings_editor.h index eb6c300d5b..f90db02c46 100644 --- a/editor/project_settings_editor.h +++ b/editor/project_settings_editor.h @@ -100,8 +100,6 @@ class ProjectSettingsEditor : public AcceptDialog { void _action_reordered(const String &p_action_name, const String &p_relative_to, bool p_before); void _update_action_map_editor(); - ProjectSettingsEditor(); - protected: void _notification(int p_what); static void _bind_methods(); diff --git a/editor/reparent_dialog.h b/editor/reparent_dialog.h index 5c3a65a522..3fcdda7bed 100644 --- a/editor/reparent_dialog.h +++ b/editor/reparent_dialog.h @@ -46,7 +46,6 @@ class ReparentDialog : public ConfirmationDialog { SceneTreeEditor *tree; CheckBox *keep_transform; - void update_tree(); void _reparent(); void _cancel(); @@ -56,7 +55,6 @@ protected: public: void set_current(const Set<Node *> &p_selection); - String get_selected_type(); ReparentDialog(); ~ReparentDialog(); diff --git a/editor/scene_tree_dock.h b/editor/scene_tree_dock.h index 255e026887..66000602fa 100644 --- a/editor/scene_tree_dock.h +++ b/editor/scene_tree_dock.h @@ -246,8 +246,6 @@ class SceneTreeDock : public VBoxContainer { void _perform_instantiate_scenes(const Vector<String> &p_files, Node *parent, int p_pos); void _replace_with_branch_scene(const String &p_file, Node *base); - void _file_selected(String p_file); - void _remote_tree_selected(); void _local_tree_selected(); diff --git a/editor/scene_tree_editor.h b/editor/scene_tree_editor.h index 4acd5d8486..b4c40ab17a 100644 --- a/editor/scene_tree_editor.h +++ b/editor/scene_tree_editor.h @@ -114,8 +114,6 @@ class SceneTreeEditor : public Control { void _node_visibility_changed(Node *p_node); void _update_visibility_color(Node *p_node, TreeItem *p_item); - void _node_replace_owner(Node *p_base, Node *p_node, Node *p_root); - void _selection_changed(); Node *get_scene_node(); @@ -173,7 +171,6 @@ class SceneTreeDialog : public ConfirmationDialog { //Button *cancel; LineEdit *filter; - void update_tree(); void _select(); void _cancel(); void _filter_changed(const String &p_filter); diff --git a/editor/translations/Makefile b/editor/translations/Makefile index 1843114f06..82b3d49c59 100644 --- a/editor/translations/Makefile +++ b/editor/translations/Makefile @@ -18,3 +18,24 @@ merge: check: @for po in $(POFILES); do msgfmt -c $$po -o /dev/null; done + +# Generate completion ratio from statistics string such as: +# 2775 translated messages, 272 fuzzy translations, 151 untranslated messages. +# First number can be 0, second and third numbers are only present if non-zero. +include-list: + @list=""; \ + threshold=0.30; \ + for po in $(POFILES); do \ + res=`msgfmt --statistics $$po -o /dev/null 2>&1 | sed 's/[^0-9,]*//g'`; \ + complete=`cut -d',' -f1 <<< $$res`; \ + fuzzy_or_untranslated=`cut -d',' -f2 <<< $$res`; \ + untranslated_maybe=`cut -d',' -f3 <<< $$res`; \ + if [ -z "$$fuzzy_or_untranslated" ]; then fuzzy_or_untranslated=0; fi; \ + if [ -z "$$untranslated_maybe" ]; then untranslated_maybe=0; fi; \ + incomplete=`expr $$fuzzy_or_untranslated + $$untranslated_maybe`; \ + if `awk "BEGIN {exit !($$complete / ($$complete + $$incomplete) > $$threshold)}"`; then \ + lang=`basename $$po .po`; \ + list+="$$lang,"; \ + fi; \ + done; \ + echo $$list; diff --git a/main/main.cpp b/main/main.cpp index a07533180a..d4a6216e35 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -376,7 +376,9 @@ void Main::print_help(const char *p_binary) { OS::get_singleton()->print(" --doctool [<path>] Dump the engine API reference to the given <path> (defaults to current dir) in XML format, merging if existing files are found.\n"); OS::get_singleton()->print(" --no-docbase Disallow dumping the base types (used with --doctool).\n"); OS::get_singleton()->print(" --build-solutions Build the scripting solutions (e.g. for C# projects). Implies --editor and requires a valid project to edit.\n"); + OS::get_singleton()->print(" --dump-extension-api Generate JSON dump of the Godot API for GDExtension bindings named 'extension_api.json' in the current folder.\n"); #ifdef DEBUG_METHODS_ENABLED + // TODO: Should be removed together with nativescript eventually. OS::get_singleton()->print(" --gdnative-generate-json-api <path> Generate JSON dump of the Godot API for GDNative bindings and save it on the file specified in <path>.\n"); OS::get_singleton()->print(" --gdnative-generate-json-builtin-api <path> Generate JSON dump of the Godot API of the builtin Variant types and utility functions for GDNative bindings and save it on the file specified in <path>.\n"); #endif @@ -901,20 +903,24 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph auto_build_solutions = true; editor = true; cmdline_tool = true; - +#ifdef DEBUG_METHODS_ENABLED } else if (I->get() == "--gdnative-generate-json-api" || I->get() == "--gdnative-generate-json-builtin-api") { // Register as an editor instance to use low-end fallback if relevant. editor = true; cmdline_tool = true; - - // We still pass it to the main arguments since the argument handling itself is not done in this function + // We still pass it to the main arguments since the argument handling itself is not done in this function, + // it's done in nativescript init code. main_args.push_back(I->get()); +#endif } else if (I->get() == "--dump-extension-api") { // Register as an editor instance to use low-end fallback if relevant. editor = true; cmdline_tool = true; dump_extension_api = true; - print_line("dump extension?"); + print_line("Dumping Extension API"); + // Hack. Not needed but otherwise we end up detecting that this should + // run the project instead of a cmdline tool. + // Needs full refactoring to fix properly. main_args.push_back(I->get()); } else if (I->get() == "--export" || I->get() == "--export-debug" || I->get() == "--export-pack") { // Export project @@ -1341,8 +1347,9 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph display_driver_idx = 0; } - if (audio_driver == "") { // specified in project.godot - audio_driver = GLOBAL_DEF_RST_NOVAL("audio/driver/driver", AudioDriverManager::get_driver(0)->get_name()); + GLOBAL_DEF_RST_NOVAL("audio/driver/driver", AudioDriverManager::get_driver(0)->get_name()); + if (audio_driver == "") { // Specified in project.godot. + audio_driver = GLOBAL_GET("audio/driver/driver"); } for (int i = 0; i < AudioDriverManager::get_driver_count(); i++) { @@ -2065,6 +2072,8 @@ bool Main::start() { if (check_only) { if (!script_res->is_valid()) { OS::get_singleton()->set_exit_code(EXIT_FAILURE); + } else { + OS::get_singleton()->set_exit_code(EXIT_SUCCESS); } return false; } @@ -2137,7 +2146,7 @@ bool Main::start() { } #endif - bool embed_subwindows = GLOBAL_DEF("display/window/subwindows/embed_subwindows", false); + bool embed_subwindows = GLOBAL_DEF("display/window/subwindows/embed_subwindows", true); if (OS::get_singleton()->is_single_window() || (!project_manager && !editor && embed_subwindows)) { sml->get_root()->set_embed_subwindows_hint(true); diff --git a/misc/dist/html/editor.html b/misc/dist/html/editor.html index 2cae215951..69e267f665 100644 --- a/misc/dist/html/editor.html +++ b/misc/dist/html/editor.html @@ -14,7 +14,7 @@ <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" /> <meta name="msapplication-starturl" content="/latest" /> <meta property="og:site_name" content="Godot Engine Web Editor" /> - <meta property="og:url" name="twitter:url" content="https://editor.godotengine.org/releases/latest/" /> + <meta property="og:url" name="twitter:url" content="https://editor.godotengine.org/releases/latest/" /> <meta property="og:title" name="twitter:title" content="Free and open source 2D and 3D game engine" /> <meta property="og:description" name="twitter:description" content="Use the Godot Engine editor directly in your web browser, without having to install anything." /> <meta property="og:image" name="twitter:image" content="https://godotengine.org/themes/godotengine/assets/og_image.png" /> @@ -269,11 +269,6 @@ <div id="tabs"> <div id="tab-loader"> <div style="color: #e0e0e0;" id="persistence"> - <label for="videoMode" style="display: none;">Select video driver:</label><br /> - <select id="videoMode" style="display: none;"> - <option value="GLES2" selected="selected">WebGL</option> - <option value="GLES3">WebGL 2</option> - </select> <br /> <img src="logo.svg" alt="Godot Engine logo" width="1024" height="414" style="width: auto; height: auto; max-width: 85%; max-height: 250px" /> <br /> @@ -283,6 +278,14 @@ <br /> <br /> <br /> + <label for="videoMode" style="margin-right: 1rem">Video driver:</label> + <select id="videoMode"> + <option value="" selected="selected">Auto</option> + <option value="GLES2">WebGL</option> + <option value="GLES3">WebGL 2</option> + </select> + <br /> + <br /> <label for="zip-file" style="margin-right: 1rem">Preload project ZIP:</label> <input id="zip-file" type="file" name="files" style="margin-bottom: 1rem"/> <br /> <a href="demo.zip">(Try this for example)</a> @@ -348,7 +351,7 @@ var game = null; var setStatusMode; var setStatusNotice; - var video_driver = "GLES2"; + var video_driver = ""; function clearPersistence() { function deleteDB(path) { @@ -479,6 +482,15 @@ animationCallbacks.push(adjustCanvasDimensions); adjustCanvasDimensions(); + function replaceCanvas(from) { + const out = document.createElement("canvas"); + out.id = from.id; + out.tabIndex = from.tabIndex; + from.parentNode.replaceChild(out, from); + lastScale = 0; + return out; + } + setStatusMode = function setStatusMode(mode) { if (statusMode === mode || !initializing) return; @@ -534,6 +546,7 @@ 'canvas': gameCanvas, 'canvasResizePolicy': 1, 'onExit': function () { + gameCanvas = replaceCanvas(gameCanvas); setGameTabEnabled(false); showTab('editor'); game = null; @@ -548,7 +561,7 @@ const is_editor = args.filter(function(v) { return v == '--editor' || v == '-e' }).length != 0; const is_project_manager = args.filter(function(v) { return v == '--project-manager' }).length != 0; const is_game = !is_editor && !is_project_manager; - if (is_project_manager) { + if (video_driver) { args.push('--video-driver', video_driver); } if (is_game) { @@ -561,7 +574,7 @@ showTab('game'); game.init().then(function() { requestAnimationFrame(function() { - game.start({'args': args}).then(function() { + game.start({'args': args, 'canvas': gameCanvas}).then(function() { gameCanvas.focus(); }); }); @@ -576,7 +589,7 @@ showTab('loader'); setLoaderEnabled(true); }; - editor.start({'args': args, 'persistentDrops': is_project_manager}); + editor.start({'args': args, 'persistentDrops': is_project_manager, 'canvas': editorCanvas}); }); }, 0); OnEditorExit = null; @@ -603,6 +616,7 @@ 'canvas': editorCanvas, 'canvasResizePolicy': 0, 'onExit': function() { + editorCanvas = replaceCanvas(editorCanvas); if (OnEditorExit) { OnEditorExit(); } @@ -634,10 +648,14 @@ } catch(e) { // File exists } - //selectVideoMode(); + selectVideoMode(); showTab('editor'); setLoaderEnabled(false); - editor.start({'args': ['--project-manager', '--video-driver', video_driver], 'persistentDrops': true}).then(function() { + const args = ['--project-manager']; + if (video_driver) { + args.push('--video-driver', video_driver); + } + editor.start({'args': args, 'persistentDrops': true}).then(function() { setStatusMode('hidden'); initializing = false; }); diff --git a/misc/scripts/compare_extension_api.py b/misc/scripts/compare_extension_api.py new file mode 100755 index 0000000000..f96db4278c --- /dev/null +++ b/misc/scripts/compare_extension_api.py @@ -0,0 +1,11 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import sys + +# TODO: +# Add a process that compares the original godot-cpp/godot-headers/extension_api.json with the new extension_api.json (both passed as arguments) and reports any API calls that have been removed. +# If we only have additions or no changes to the file, we pass +# For now we deem this too early because the API isn't stable enough yet. + +sys.exit(0) diff --git a/modules/bullet/area_bullet.h b/modules/bullet/area_bullet.h index 7cf666c119..c8b516c951 100644 --- a/modules/bullet/area_bullet.h +++ b/modules/bullet/area_bullet.h @@ -145,7 +145,6 @@ public: virtual void dispatch_callbacks(); void call_event(CollisionObjectBullet *p_otherObject, PhysicsServer3D::AreaBodyStatus p_status); - void set_on_state_change(ObjectID p_id, const StringName &p_method, const Variant &p_udata = Variant()); void scratch(); void clear_overlaps(bool p_notify); diff --git a/modules/bullet/soft_body_bullet.cpp b/modules/bullet/soft_body_bullet.cpp index 81b832fb42..3a2370ff31 100644 --- a/modules/bullet/soft_body_bullet.cpp +++ b/modules/bullet/soft_body_bullet.cpp @@ -116,6 +116,7 @@ void SoftBodyBullet::set_soft_mesh(RID p_mesh) { } Array arrays = RenderingServer::get_singleton()->mesh_surface_get_arrays(soft_mesh, 0); + ERR_FAIL_COND(arrays.is_empty()); bool success = set_trimesh_body_shape(arrays[RS::ARRAY_INDEX], arrays[RS::ARRAY_VERTEX]); if (!success) { diff --git a/modules/gdnative/nativescript/nativescript.cpp b/modules/gdnative/nativescript/nativescript.cpp index fb46bafb3c..368eb67fa6 100644 --- a/modules/gdnative/nativescript/nativescript.cpp +++ b/modules/gdnative/nativescript/nativescript.cpp @@ -1139,15 +1139,12 @@ void NativeScriptLanguage::profiling_start() { MutexLock lock(mutex); profile_data.clear(); - profiling = true; #endif } void NativeScriptLanguage::profiling_stop() { #ifdef DEBUG_ENABLED MutexLock lock(mutex); - - profiling = false; #endif } diff --git a/modules/gdnative/nativescript/nativescript.h b/modules/gdnative/nativescript/nativescript.h index a7647e8c59..2364c6c0f6 100644 --- a/modules/gdnative/nativescript/nativescript.h +++ b/modules/gdnative/nativescript/nativescript.h @@ -269,7 +269,6 @@ private: }; Map<StringName, ProfileData> profile_data; - bool profiling = false; public: // These two maps must only be touched on the main thread @@ -295,8 +294,6 @@ public: return singleton; } - void _hacky_api_anchor(); - _FORCE_INLINE_ void set_language_index(int p_idx) { lang_idx = p_idx; } #ifndef NO_THREADS diff --git a/modules/gdnative/pluginscript/pluginscript_instance.h b/modules/gdnative/pluginscript/pluginscript_instance.h index bdae265db2..81e711bafc 100644 --- a/modules/gdnative/pluginscript/pluginscript_instance.h +++ b/modules/gdnative/pluginscript/pluginscript_instance.h @@ -69,8 +69,6 @@ public: virtual ScriptLanguage *get_language(); - void set_path(const String &p_path); - virtual const Vector<Multiplayer::RPCConfig> get_rpc_methods() const; virtual void refcount_incremented(); diff --git a/modules/gdscript/language_server/gdscript_language_server.h b/modules/gdscript/language_server/gdscript_language_server.h index 85a44a8cc1..f1413f0133 100644 --- a/modules/gdscript/language_server/gdscript_language_server.h +++ b/modules/gdscript/language_server/gdscript_language_server.h @@ -50,10 +50,8 @@ class GDScriptLanguageServer : public EditorPlugin { private: void _notification(int p_what); - void _iteration(); public: - Error parse_script_file(const String &p_path); GDScriptLanguageServer(); void start(); void stop(); diff --git a/modules/gltf/gltf_document.h b/modules/gltf/gltf_document.h index a1d82a4649..f2f0b439a5 100644 --- a/modules/gltf/gltf_document.h +++ b/modules/gltf/gltf_document.h @@ -269,8 +269,6 @@ private: Error _reparent_non_joint_skeleton_subtrees( Ref<GLTFState> state, Ref<GLTFSkeleton> skeleton, const Vector<GLTFNodeIndex> &non_joints); - Error _reparent_to_fake_joint(Ref<GLTFState> state, Ref<GLTFSkeleton> skeleton, - const GLTFNodeIndex node_index); Error _determine_skeleton_roots(Ref<GLTFState> state, const GLTFSkeletonIndex skel_i); Error _create_skeletons(Ref<GLTFState> state); diff --git a/modules/mbedtls/packet_peer_mbed_dtls.h b/modules/mbedtls/packet_peer_mbed_dtls.h index 6554c74a21..92e6ab88c4 100644 --- a/modules/mbedtls/packet_peer_mbed_dtls.h +++ b/modules/mbedtls/packet_peer_mbed_dtls.h @@ -59,8 +59,6 @@ protected: Ref<SSLContextMbedTLS> ssl_ctx; mbedtls_timing_delay_context timer; - static void _bind_methods(); - Error _do_handshake(); int _set_cookie(); diff --git a/modules/mbedtls/ssl_context_mbedtls.h b/modules/mbedtls/ssl_context_mbedtls.h index 1b55a54a10..5692dec1b6 100644 --- a/modules/mbedtls/ssl_context_mbedtls.h +++ b/modules/mbedtls/ssl_context_mbedtls.h @@ -67,8 +67,6 @@ class SSLContextMbedTLS : public RefCounted { protected: bool inited = false; - static PackedByteArray _read_file(String p_path); - public: static void print_mbedtls_error(int p_ret); diff --git a/modules/mbedtls/stream_peer_mbedtls.h b/modules/mbedtls/stream_peer_mbedtls.h index b89d7fb238..407479e3cc 100644 --- a/modules/mbedtls/stream_peer_mbedtls.h +++ b/modules/mbedtls/stream_peer_mbedtls.h @@ -50,8 +50,6 @@ private: protected: Ref<SSLContextMbedTLS> ssl_ctx; - static void _bind_methods(); - Error _do_handshake(); public: diff --git a/modules/mono/editor/GodotTools/GodotTools.IdeMessaging/Client.cs b/modules/mono/editor/GodotTools/GodotTools.IdeMessaging/Client.cs index 1d7bfaf0a4..bc09e1ebf9 100644 --- a/modules/mono/editor/GodotTools/GodotTools.IdeMessaging/Client.cs +++ b/modules/mono/editor/GodotTools/GodotTools.IdeMessaging/Client.cs @@ -121,15 +121,20 @@ namespace GodotTools.IdeMessaging this.messageHandler = messageHandler; this.logger = logger; - // TODO: Need to fetch the project data dir name from ProjectSettings instead of defaulting to ".godot" string projectMetadataDir = Path.Combine(godotProjectDir, ".godot", "mono", "metadata"); + // FileSystemWatcher requires an existing directory + if (!Directory.Exists(projectMetadataDir)) { + // Check if the non hidden version exists + string nonHiddenProjectMetadataDir = Path.Combine(godotProjectDir, "godot", "mono", "metadata"); + if (Directory.Exists(nonHiddenProjectMetadataDir)) { + projectMetadataDir = nonHiddenProjectMetadataDir; + } else { + Directory.CreateDirectory(projectMetadataDir); + } + } MetaFilePath = Path.Combine(projectMetadataDir, GodotIdeMetadata.DefaultFileName); - // FileSystemWatcher requires an existing directory - if (!Directory.Exists(projectMetadataDir)) - Directory.CreateDirectory(projectMetadataDir); - fsWatcher = new FileSystemWatcher(projectMetadataDir, GodotIdeMetadata.DefaultFileName); } diff --git a/modules/mono/mono_gd/gd_mono_utils.cpp b/modules/mono/mono_gd/gd_mono_utils.cpp index 13939bd014..09aa9ad948 100644 --- a/modules/mono/mono_gd/gd_mono_utils.cpp +++ b/modules/mono/mono_gd/gd_mono_utils.cpp @@ -450,7 +450,7 @@ void debug_send_unhandled_exception_error(MonoException *p_exc) { int line = si.size() ? si[0].line : __LINE__; String error_msg = "Unhandled exception"; - EngineDebugger::get_script_debugger()->send_error(func, file, line, error_msg, exc_msg, ERR_HANDLER_ERROR, si); + EngineDebugger::get_script_debugger()->send_error(func, file, line, error_msg, exc_msg, true, ERR_HANDLER_ERROR, si); #endif } diff --git a/modules/navigation/navigation_mesh_generator.cpp b/modules/navigation/navigation_mesh_generator.cpp index bb6bc578a4..8fd3a13e1f 100644 --- a/modules/navigation/navigation_mesh_generator.cpp +++ b/modules/navigation/navigation_mesh_generator.cpp @@ -489,7 +489,7 @@ NavigationMeshGenerator::~NavigationMeshGenerator() { } void NavigationMeshGenerator::bake(Ref<NavigationMesh> p_nav_mesh, Node *p_node) { - ERR_FAIL_COND(!p_nav_mesh.is_valid()); + ERR_FAIL_COND_MSG(!p_nav_mesh.is_valid(), "Invalid navigation mesh."); #ifdef TOOLS_ENABLED EditorProgress *ep(nullptr); diff --git a/modules/visual_script/visual_script_nodes.h b/modules/visual_script/visual_script_nodes.h index bf2d8e9683..78881f0a53 100644 --- a/modules/visual_script/visual_script_nodes.h +++ b/modules/visual_script/visual_script_nodes.h @@ -90,12 +90,6 @@ public: void set_stack_size(int p_size); int get_stack_size() const; - void set_return_type_enabled(bool p_returns); - bool is_return_type_enabled() const; - - void set_return_type(Variant::Type p_type); - Variant::Type get_return_type() const; - void set_rpc_mode(Multiplayer::RPCMode p_mode); Multiplayer::RPCMode get_rpc_mode() const; diff --git a/platform/android/audio_driver_opensl.h b/platform/android/audio_driver_opensl.h index e3efaddba2..fcc2513f3f 100644 --- a/platform/android/audio_driver_opensl.h +++ b/platform/android/audio_driver_opensl.h @@ -59,7 +59,6 @@ class AudioDriverOpenSL : public AudioDriver { SLObjectItf sl; SLEngineItf EngineItf; SLObjectItf OutputMix; - SLVolumeItf volumeItf; SLObjectItf player; SLObjectItf recorder; SLAndroidSimpleBufferQueueItf bufferQueueItf; @@ -68,7 +67,6 @@ class AudioDriverOpenSL : public AudioDriver { SLDataFormat_PCM pcm; SLDataSink audioSink; SLDataLocator_OutputMix locator_outputmix; - SLBufferQueueState state; static AudioDriverOpenSL *s_ad; @@ -89,8 +87,6 @@ class AudioDriverOpenSL : public AudioDriver { virtual Error capture_init_device(); public: - void set_singleton(); - virtual const char *get_name() const; virtual Error init(); diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp index 034885aa32..94ca51f75a 100644 --- a/platform/android/os_android.cpp +++ b/platform/android/os_android.cpp @@ -263,7 +263,6 @@ Size2i OS_Android::get_display_size() const { void OS_Android::set_context_is_16_bits(bool p_is_16) { #if defined(OPENGL_ENABLED) - //use_16bits_fbo = p_is_16; //if (rasterizer) // rasterizer->set_force_16_bits_fbo(p_is_16); #endif @@ -325,7 +324,6 @@ OS_Android::OS_Android(GodotJavaWrapper *p_godot_java, GodotIOJavaWrapper *p_god #if defined(OPENGL_ENABLED) gl_extensions = nullptr; use_gl2 = false; - use_16bits_fbo = false; #endif #if defined(VULKAN_ENABLED) diff --git a/platform/android/os_android.h b/platform/android/os_android.h index ce8083388f..9bb37325cf 100644 --- a/platform/android/os_android.h +++ b/platform/android/os_android.h @@ -48,7 +48,6 @@ private: bool use_apk_expansion; #if defined(OPENGL_ENABLED) - bool use_16bits_fbo; const char *gl_extensions; #endif diff --git a/platform/linuxbsd/display_server_x11.cpp b/platform/linuxbsd/display_server_x11.cpp index f2cd336b39..c0e5aac938 100644 --- a/platform/linuxbsd/display_server_x11.cpp +++ b/platform/linuxbsd/display_server_x11.cpp @@ -406,6 +406,20 @@ void DisplayServerX11::clipboard_set(const String &p_text) { XSetSelectionOwner(x11_display, XInternAtom(x11_display, "CLIPBOARD", 0), windows[MAIN_WINDOW_ID].x11_window, CurrentTime); } +void DisplayServerX11::clipboard_set_primary(const String &p_text) { + _THREAD_SAFE_METHOD_ + if (!p_text.is_empty()) { + { + // The clipboard content can be accessed while polling for events. + MutexLock mutex_lock(events_mutex); + internal_clipboard_primary = p_text; + } + + XSetSelectionOwner(x11_display, XA_PRIMARY, windows[MAIN_WINDOW_ID].x11_window, CurrentTime); + XSetSelectionOwner(x11_display, XInternAtom(x11_display, "PRIMARY", 0), windows[MAIN_WINDOW_ID].x11_window, CurrentTime); + } +} + Bool DisplayServerX11::_predicate_clipboard_selection(Display *display, XEvent *event, XPointer arg) { if (event->type == SelectionNotify && event->xselection.requestor == *(Window *)arg) { return True; @@ -427,7 +441,12 @@ String DisplayServerX11::_clipboard_get_impl(Atom p_source, Window x11_window, A Window selection_owner = XGetSelectionOwner(x11_display, p_source); if (selection_owner == x11_window) { - return internal_clipboard; + static const char *target_type = "PRIMARY"; + if (p_source != None && String(XGetAtomName(x11_display, p_source)) == target_type) { + return internal_clipboard_primary; + } else { + return internal_clipboard; + } } if (selection_owner != None) { @@ -580,6 +599,19 @@ String DisplayServerX11::clipboard_get() const { return ret; } +String DisplayServerX11::clipboard_get_primary() const { + _THREAD_SAFE_METHOD_ + + String ret; + ret = _clipboard_get(XInternAtom(x11_display, "PRIMARY", 0), windows[MAIN_WINDOW_ID].x11_window); + + if (ret.is_empty()) { + ret = _clipboard_get(XA_PRIMARY, windows[MAIN_WINDOW_ID].x11_window); + } + + return ret; +} + Bool DisplayServerX11::_predicate_clipboard_save_targets(Display *display, XEvent *event, XPointer arg) { if (event->xany.window == *(Window *)arg) { return (event->type == SelectionRequest) || @@ -2417,7 +2449,7 @@ void DisplayServerX11::_handle_key_event(WindowID p_window, XKeyEvent *p_event, Input::get_singleton()->parse_input_event(k); } -Atom DisplayServerX11::_process_selection_request_target(Atom p_target, Window p_requestor, Atom p_property) const { +Atom DisplayServerX11::_process_selection_request_target(Atom p_target, Window p_requestor, Atom p_property, Atom p_selection) const { if (p_target == XInternAtom(x11_display, "TARGETS", 0)) { // Request to list all supported targets. Atom data[9]; @@ -2459,7 +2491,13 @@ Atom DisplayServerX11::_process_selection_request_target(Atom p_target, Window p p_target == XInternAtom(x11_display, "text/plain", 0)) { // Directly using internal clipboard because we know our window // is the owner during a selection request. - CharString clip = internal_clipboard.utf8(); + CharString clip; + static const char *target_type = "PRIMARY"; + if (p_selection != None && String(XGetAtomName(x11_display, p_selection)) == target_type) { + clip = internal_clipboard_primary.utf8(); + } else { + clip = internal_clipboard.utf8(); + } XChangeProperty(x11_display, p_requestor, p_property, @@ -2497,7 +2535,7 @@ void DisplayServerX11::_handle_selection_request_event(XSelectionRequestEvent *p for (uint64_t i = 0; i < len; i += 2) { Atom target = targets[i]; Atom &property = targets[i + 1]; - property = _process_selection_request_target(target, p_event->requestor, property); + property = _process_selection_request_target(target, p_event->requestor, property, p_event->selection); } XChangeProperty(x11_display, @@ -2515,7 +2553,7 @@ void DisplayServerX11::_handle_selection_request_event(XSelectionRequestEvent *p } } else { // Request for target conversion. - respond.xselection.property = _process_selection_request_target(p_event->target, p_event->requestor, p_event->property); + respond.xselection.property = _process_selection_request_target(p_event->target, p_event->requestor, p_event->property, p_event->selection); } respond.xselection.type = SelectionNotify; diff --git a/platform/linuxbsd/display_server_x11.h b/platform/linuxbsd/display_server_x11.h index 1887c7105b..ded481f613 100644 --- a/platform/linuxbsd/display_server_x11.h +++ b/platform/linuxbsd/display_server_x11.h @@ -155,6 +155,7 @@ class DisplayServerX11 : public DisplayServer { WindowID _create_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect); String internal_clipboard; + String internal_clipboard_primary; Window xdnd_source_window; ::Display *x11_display; char *xmbstring; @@ -205,7 +206,7 @@ class DisplayServerX11 : public DisplayServer { void _handle_key_event(WindowID p_window, XKeyEvent *p_event, LocalVector<XEvent> &p_events, uint32_t &p_event_index, bool p_echo = false); - Atom _process_selection_request_target(Atom p_target, Window p_requestor, Atom p_property) const; + Atom _process_selection_request_target(Atom p_target, Window p_requestor, Atom p_property, Atom p_selection) const; void _handle_selection_request_event(XSelectionRequestEvent *p_event) const; String _clipboard_get_impl(Atom p_source, Window x11_window, Atom target) const; @@ -290,6 +291,8 @@ public: virtual void clipboard_set(const String &p_text) override; virtual String clipboard_get() const override; + virtual void clipboard_set_primary(const String &p_text) override; + virtual String clipboard_get_primary() const override; virtual int get_screen_count() const override; virtual Point2i screen_get_position(int p_screen = SCREEN_OF_MAIN_WINDOW) const override; diff --git a/platform/osx/joypad_osx.h b/platform/osx/joypad_osx.h index c060c3d523..3048ecf39e 100644 --- a/platform/osx/joypad_osx.h +++ b/platform/osx/joypad_osx.h @@ -106,7 +106,6 @@ private: int get_joy_ref(IOHIDDeviceRef p_device) const; void poll_joypads() const; - void setup_joypad_objects(); void config_hid_manager(CFArrayRef p_matching_array) const; void joypad_vibration_start(int p_id, float p_magnitude, float p_duration, uint64_t p_timestamp); diff --git a/platform/uwp/os_uwp.h b/platform/uwp/os_uwp.h index 7945f409a1..9398573ee1 100644 --- a/platform/uwp/os_uwp.h +++ b/platform/uwp/os_uwp.h @@ -117,11 +117,6 @@ private: Windows::System::Display::DisplayRequest ^ display_request; - void _post_dpad(DWORD p_dpad, int p_device, bool p_pressed); - - void _drag_event(int idx, UINT uMsg, WPARAM wParam, LPARAM lParam); - void _touch_event(int idx, UINT uMsg, WPARAM wParam, LPARAM lParam); - ref class ManagedType { public: property bool alert_close_handle; diff --git a/scene/2d/audio_listener_2d.h b/scene/2d/audio_listener_2d.h index 875887acc6..454053bc4a 100644 --- a/scene/2d/audio_listener_2d.h +++ b/scene/2d/audio_listener_2d.h @@ -43,8 +43,6 @@ private: friend class Viewport; protected: - void _update_listener(); - bool _set(const StringName &p_name, const Variant &p_value); bool _get(const StringName &p_name, Variant &r_ret) const; void _get_property_list(List<PropertyInfo> *p_list) const; diff --git a/scene/2d/collision_object_2d.cpp b/scene/2d/collision_object_2d.cpp index 6916f832d0..28facd09ce 100644 --- a/scene/2d/collision_object_2d.cpp +++ b/scene/2d/collision_object_2d.cpp @@ -454,7 +454,7 @@ void CollisionObject2D::shape_owner_clear_shapes(uint32_t p_owner) { } uint32_t CollisionObject2D::shape_find_owner(int p_shape_index) const { - ERR_FAIL_INDEX_V(p_shape_index, total_subshapes, 0); + ERR_FAIL_INDEX_V(p_shape_index, total_subshapes, UINT32_MAX); for (const KeyValue<uint32_t, ShapeData> &E : shapes) { for (int i = 0; i < E.value.shapes.size(); i++) { @@ -465,7 +465,7 @@ uint32_t CollisionObject2D::shape_find_owner(int p_shape_index) const { } //in theory it should be unreachable - return 0; + ERR_FAIL_V_MSG(UINT32_MAX, "Can't find owner for shape index " + itos(p_shape_index) + "."); } void CollisionObject2D::set_pickable(bool p_enabled) { diff --git a/scene/2d/cpu_particles_2d.h b/scene/2d/cpu_particles_2d.h index 4990d443e3..391f51224e 100644 --- a/scene/2d/cpu_particles_2d.h +++ b/scene/2d/cpu_particles_2d.h @@ -201,7 +201,6 @@ public: void set_explosiveness_ratio(real_t p_ratio); void set_randomness_ratio(real_t p_ratio); void set_lifetime_randomness(double p_random); - void set_visibility_aabb(const Rect2 &p_aabb); void set_use_local_coordinates(bool p_enable); void set_speed_scale(double p_scale); @@ -213,7 +212,6 @@ public: real_t get_explosiveness_ratio() const; real_t get_randomness_ratio() const; double get_lifetime_randomness() const; - Rect2 get_visibility_aabb() const; bool get_use_local_coordinates() const; double get_speed_scale() const; @@ -226,9 +224,6 @@ public: void set_draw_order(DrawOrder p_order); DrawOrder get_draw_order() const; - void set_draw_passes(int p_count); - int get_draw_passes() const; - void set_texture(const Ref<Texture2D> &p_texture); Ref<Texture2D> get_texture() const; @@ -264,7 +259,6 @@ public: void set_emission_points(const Vector<Vector2> &p_points); void set_emission_normals(const Vector<Vector2> &p_normals); void set_emission_colors(const Vector<Color> &p_colors); - void set_emission_point_count(int p_count); void set_scale_curve_x(Ref<Curve> p_scale_curve); void set_scale_curve_y(Ref<Curve> p_scale_curve); void set_split_scale(bool p_split_scale); @@ -275,7 +269,6 @@ public: Vector<Vector2> get_emission_points() const; Vector<Vector2> get_emission_normals() const; Vector<Color> get_emission_colors() const; - int get_emission_point_count() const; Ref<Curve> get_scale_curve_x() const; Ref<Curve> get_scale_curve_y() const; bool get_split_scale(); diff --git a/scene/2d/gpu_particles_2d.cpp b/scene/2d/gpu_particles_2d.cpp index 3637594e1b..6950fefdbe 100644 --- a/scene/2d/gpu_particles_2d.cpp +++ b/scene/2d/gpu_particles_2d.cpp @@ -532,6 +532,7 @@ void GPUParticles2D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_trail_section_subdivisions"), &GPUParticles2D::get_trail_section_subdivisions); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "emitting"), "set_emitting", "is_emitting"); + ADD_PROPERTY_DEFAULT("emitting", true); // Workaround for doctool in headless mode, as dummy rasterizer always returns false. ADD_PROPERTY(PropertyInfo(Variant::INT, "amount", PROPERTY_HINT_RANGE, "1,1000000,1,exp"), "set_amount", "get_amount"); ADD_GROUP("Time", ""); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "lifetime", PROPERTY_HINT_RANGE, "0.01,600.0,0.01,or_greater"), "set_lifetime", "get_lifetime"); diff --git a/scene/2d/mesh_instance_2d.cpp b/scene/2d/mesh_instance_2d.cpp index 15008390b7..58bff97da9 100644 --- a/scene/2d/mesh_instance_2d.cpp +++ b/scene/2d/mesh_instance_2d.cpp @@ -96,6 +96,10 @@ Rect2 MeshInstance2D::_edit_get_rect() const { return Node2D::_edit_get_rect(); } + +bool MeshInstance2D::_edit_use_rect() const { + return mesh.is_valid(); +} #endif MeshInstance2D::MeshInstance2D() { diff --git a/scene/2d/mesh_instance_2d.h b/scene/2d/mesh_instance_2d.h index adfda4cf7f..f94d53da7d 100644 --- a/scene/2d/mesh_instance_2d.h +++ b/scene/2d/mesh_instance_2d.h @@ -48,6 +48,7 @@ protected: public: #ifdef TOOLS_ENABLED virtual Rect2 _edit_get_rect() const override; + virtual bool _edit_use_rect() const override; #endif void set_mesh(const Ref<Mesh> &p_mesh); diff --git a/scene/2d/navigation_agent_2d.cpp b/scene/2d/navigation_agent_2d.cpp index 2f00978123..7faa964407 100644 --- a/scene/2d/navigation_agent_2d.cpp +++ b/scene/2d/navigation_agent_2d.cpp @@ -184,7 +184,7 @@ Vector2 NavigationAgent2D::get_target_location() const { Vector2 NavigationAgent2D::get_next_location() { update_navigation(); if (navigation_path.size() == 0) { - ERR_FAIL_COND_V(agent_parent == nullptr, Vector2()); + ERR_FAIL_COND_V_MSG(agent_parent == nullptr, Vector2(), "The agent has no parent."); return agent_parent->get_global_position(); } else { return navigation_path[nav_path_index]; @@ -192,7 +192,7 @@ Vector2 NavigationAgent2D::get_next_location() { } real_t NavigationAgent2D::distance_to_target() const { - ERR_FAIL_COND_V(agent_parent == nullptr, 0.0); + ERR_FAIL_COND_V_MSG(agent_parent == nullptr, 0.0, "The agent has no parent."); return agent_parent->get_global_position().distance_to(target_location); } diff --git a/scene/3d/audio_listener_3d.h b/scene/3d/audio_listener_3d.h index 492cacb0e9..31de3b4fb1 100644 --- a/scene/3d/audio_listener_3d.h +++ b/scene/3d/audio_listener_3d.h @@ -63,9 +63,6 @@ public: virtual Transform3D get_listener_transform() const; - void set_visible_layers(uint32_t p_layers); - uint32_t get_visible_layers() const; - AudioListener3D(); ~AudioListener3D(); }; diff --git a/scene/3d/collision_object_3d.cpp b/scene/3d/collision_object_3d.cpp index 814ed5c2a7..fd891a5e13 100644 --- a/scene/3d/collision_object_3d.cpp +++ b/scene/3d/collision_object_3d.cpp @@ -648,7 +648,7 @@ void CollisionObject3D::shape_owner_clear_shapes(uint32_t p_owner) { } uint32_t CollisionObject3D::shape_find_owner(int p_shape_index) const { - ERR_FAIL_INDEX_V(p_shape_index, total_subshapes, 0); + ERR_FAIL_INDEX_V(p_shape_index, total_subshapes, UINT32_MAX); for (const KeyValue<uint32_t, ShapeData> &E : shapes) { for (int i = 0; i < E.value.shapes.size(); i++) { @@ -659,7 +659,7 @@ uint32_t CollisionObject3D::shape_find_owner(int p_shape_index) const { } //in theory it should be unreachable - return 0; + ERR_FAIL_V_MSG(UINT32_MAX, "Can't find owner for shape index " + itos(p_shape_index) + "."); } CollisionObject3D::CollisionObject3D(RID p_rid, bool p_area) { diff --git a/scene/3d/cpu_particles_3d.h b/scene/3d/cpu_particles_3d.h index 160814ead4..aca7328a27 100644 --- a/scene/3d/cpu_particles_3d.h +++ b/scene/3d/cpu_particles_3d.h @@ -209,7 +209,6 @@ public: void set_explosiveness_ratio(real_t p_ratio); void set_randomness_ratio(real_t p_ratio); void set_lifetime_randomness(double p_random); - void set_visibility_aabb(const AABB &p_aabb); void set_use_local_coordinates(bool p_enable); void set_speed_scale(double p_scale); @@ -221,7 +220,6 @@ public: real_t get_explosiveness_ratio() const; real_t get_randomness_ratio() const; double get_lifetime_randomness() const; - AABB get_visibility_aabb() const; bool get_use_local_coordinates() const; double get_speed_scale() const; @@ -234,9 +232,6 @@ public: void set_draw_order(DrawOrder p_order); DrawOrder get_draw_order() const; - void set_draw_passes(int p_count); - int get_draw_passes() const; - void set_mesh(const Ref<Mesh> &p_mesh); Ref<Mesh> get_mesh() const; @@ -275,7 +270,6 @@ public: void set_emission_points(const Vector<Vector3> &p_points); void set_emission_normals(const Vector<Vector3> &p_normals); void set_emission_colors(const Vector<Color> &p_colors); - void set_emission_point_count(int p_count); void set_emission_ring_axis(Vector3 p_axis); void set_emission_ring_height(real_t p_height); void set_emission_ring_radius(real_t p_radius); @@ -291,7 +285,6 @@ public: Vector<Vector3> get_emission_points() const; Vector<Vector3> get_emission_normals() const; Vector<Color> get_emission_colors() const; - int get_emission_point_count() const; Vector3 get_emission_ring_axis() const; real_t get_emission_ring_height() const; real_t get_emission_ring_radius() const; diff --git a/scene/3d/gpu_particles_3d.cpp b/scene/3d/gpu_particles_3d.cpp index 32a62d8c7e..ea6242b669 100644 --- a/scene/3d/gpu_particles_3d.cpp +++ b/scene/3d/gpu_particles_3d.cpp @@ -562,6 +562,7 @@ void GPUParticles3D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_transform_align"), &GPUParticles3D::get_transform_align); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "emitting"), "set_emitting", "is_emitting"); + ADD_PROPERTY_DEFAULT("emitting", true); // Workaround for doctool in headless mode, as dummy rasterizer always returns false. ADD_PROPERTY(PropertyInfo(Variant::INT, "amount", PROPERTY_HINT_RANGE, "1,1000000,1,exp"), "set_amount", "get_amount"); ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "sub_emitter", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "GPUParticles3D"), "set_sub_emitter", "get_sub_emitter"); ADD_GROUP("Time", ""); diff --git a/scene/3d/navigation_agent_3d.cpp b/scene/3d/navigation_agent_3d.cpp index c2d5c757db..1bc7d20c19 100644 --- a/scene/3d/navigation_agent_3d.cpp +++ b/scene/3d/navigation_agent_3d.cpp @@ -192,7 +192,7 @@ Vector3 NavigationAgent3D::get_target_location() const { Vector3 NavigationAgent3D::get_next_location() { update_navigation(); if (navigation_path.size() == 0) { - ERR_FAIL_COND_V(agent_parent == nullptr, Vector3()); + ERR_FAIL_COND_V_MSG(agent_parent == nullptr, Vector3(), "The agent has no parent."); return agent_parent->get_global_transform().origin; } else { return navigation_path[nav_path_index] - Vector3(0, navigation_height_offset, 0); @@ -200,7 +200,7 @@ Vector3 NavigationAgent3D::get_next_location() { } real_t NavigationAgent3D::distance_to_target() const { - ERR_FAIL_COND_V(agent_parent == nullptr, 0.0); + ERR_FAIL_COND_V_MSG(agent_parent == nullptr, 0.0, "The agent has no parent."); return agent_parent->get_global_transform().origin.distance_to(target_location); } diff --git a/scene/3d/navigation_region_3d.cpp b/scene/3d/navigation_region_3d.cpp index 8a51a259f7..473368cf69 100644 --- a/scene/3d/navigation_region_3d.cpp +++ b/scene/3d/navigation_region_3d.cpp @@ -162,7 +162,7 @@ void _bake_navigation_mesh(void *p_user_data) { } void NavigationRegion3D::bake_navigation_mesh() { - ERR_FAIL_COND(bake_thread.is_started()); + ERR_FAIL_COND_MSG(bake_thread.is_started(), "Unable to start another bake request. The navigation mesh bake thread is already baking a navigation mesh."); BakeThreadsArgs *args = memnew(BakeThreadsArgs); args->nav_region = this; diff --git a/scene/3d/node_3d.cpp b/scene/3d/node_3d.cpp index c96204cf60..5293dd3f0a 100644 --- a/scene/3d/node_3d.cpp +++ b/scene/3d/node_3d.cpp @@ -484,14 +484,14 @@ void Node3D::_update_gizmos() { #endif } -#ifdef TOOLS_ENABLED void Node3D::set_disable_gizmos(bool p_enabled) { +#ifdef TOOLS_ENABLED data.gizmos_disabled = p_enabled; if (!p_enabled) { clear_gizmos(); } -} #endif +} void Node3D::set_disable_scale(bool p_enabled) { data.disable_scale = p_enabled; diff --git a/scene/3d/soft_dynamic_body_3d.cpp b/scene/3d/soft_dynamic_body_3d.cpp index 9fceb21790..903eedb58b 100644 --- a/scene/3d/soft_dynamic_body_3d.cpp +++ b/scene/3d/soft_dynamic_body_3d.cpp @@ -250,7 +250,7 @@ void SoftDynamicBody3D::_notification(int p_what) { RID space = get_world_3d()->get_space(); PhysicsServer3D::get_singleton()->soft_body_set_space(physics_rid, space); - prepare_physics_server(); + _prepare_physics_server(); } break; case NOTIFICATION_READY: { @@ -284,13 +284,13 @@ void SoftDynamicBody3D::_notification(int p_what) { case NOTIFICATION_DISABLED: { if (is_inside_tree() && (disable_mode == DISABLE_MODE_REMOVE)) { - prepare_physics_server(); + _prepare_physics_server(); } } break; case NOTIFICATION_ENABLED: { if (is_inside_tree() && (disable_mode == DISABLE_MODE_REMOVE)) { - prepare_physics_server(); + _prepare_physics_server(); } } break; @@ -378,7 +378,7 @@ void SoftDynamicBody3D::_bind_methods() { TypedArray<String> SoftDynamicBody3D::get_configuration_warnings() const { TypedArray<String> warnings = Node::get_configuration_warnings(); - if (get_mesh().is_null()) { + if (mesh.is_null()) { warnings.push_back(TTR("This body will be ignored until you set a mesh.")); } @@ -407,11 +407,17 @@ void SoftDynamicBody3D::_update_physics_server() { } void SoftDynamicBody3D::_draw_soft_mesh() { - if (get_mesh().is_null()) { + if (mesh.is_null()) { return; } - const RID mesh_rid = get_mesh()->get_rid(); + RID mesh_rid = mesh->get_rid(); + if (owned_mesh != mesh_rid) { + _become_mesh_owner(); + mesh_rid = mesh->get_rid(); + PhysicsServer3D::get_singleton()->soft_body_set_mesh(physics_rid, mesh_rid); + } + if (!rendering_server_handler.is_ready(mesh_rid)) { rendering_server_handler.prepare(mesh_rid, 0); @@ -430,11 +436,11 @@ void SoftDynamicBody3D::_draw_soft_mesh() { rendering_server_handler.commit_changes(); } -void SoftDynamicBody3D::prepare_physics_server() { +void SoftDynamicBody3D::_prepare_physics_server() { #ifdef TOOLS_ENABLED if (Engine::get_singleton()->is_editor_hint()) { - if (get_mesh().is_valid()) { - PhysicsServer3D::get_singleton()->soft_body_set_mesh(physics_rid, get_mesh()->get_rid()); + if (mesh.is_valid()) { + PhysicsServer3D::get_singleton()->soft_body_set_mesh(physics_rid, mesh->get_rid()); } else { PhysicsServer3D::get_singleton()->soft_body_set_mesh(physics_rid, RID()); } @@ -443,9 +449,13 @@ void SoftDynamicBody3D::prepare_physics_server() { } #endif - if (get_mesh().is_valid() && (is_enabled() || (disable_mode != DISABLE_MODE_REMOVE))) { - become_mesh_owner(); - PhysicsServer3D::get_singleton()->soft_body_set_mesh(physics_rid, get_mesh()->get_rid()); + if (mesh.is_valid() && (is_enabled() || (disable_mode != DISABLE_MODE_REMOVE))) { + RID mesh_rid = mesh->get_rid(); + if (owned_mesh != mesh_rid) { + _become_mesh_owner(); + mesh_rid = mesh->get_rid(); + } + PhysicsServer3D::get_singleton()->soft_body_set_mesh(physics_rid, mesh_rid); RS::get_singleton()->connect("frame_pre_draw", callable_mp(this, &SoftDynamicBody3D::_draw_soft_mesh)); } else { PhysicsServer3D::get_singleton()->soft_body_set_mesh(physics_rid, RID()); @@ -455,38 +465,32 @@ void SoftDynamicBody3D::prepare_physics_server() { } } -void SoftDynamicBody3D::become_mesh_owner() { - if (mesh.is_null()) { - return; - } +void SoftDynamicBody3D::_become_mesh_owner() { + Vector<Ref<Material>> copy_materials; + copy_materials.append_array(surface_override_materials); - if (!mesh_owner) { - mesh_owner = true; + ERR_FAIL_COND(!mesh->get_surface_count()); - Vector<Ref<Material>> copy_materials; - copy_materials.append_array(surface_override_materials); + // Get current mesh array and create new mesh array with necessary flag for SoftDynamicBody + Array surface_arrays = mesh->surface_get_arrays(0); + Array surface_blend_arrays = mesh->surface_get_blend_shape_arrays(0); + Dictionary surface_lods = mesh->surface_get_lods(0); + uint32_t surface_format = mesh->surface_get_format(0); - ERR_FAIL_COND(!mesh->get_surface_count()); + surface_format |= Mesh::ARRAY_FLAG_USE_DYNAMIC_UPDATE; - // Get current mesh array and create new mesh array with necessary flag for SoftDynamicBody - Array surface_arrays = mesh->surface_get_arrays(0); - Array surface_blend_arrays = mesh->surface_get_blend_shape_arrays(0); - Dictionary surface_lods = mesh->surface_get_lods(0); - uint32_t surface_format = mesh->surface_get_format(0); + Ref<ArrayMesh> soft_mesh; + soft_mesh.instantiate(); + soft_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, surface_arrays, surface_blend_arrays, surface_lods, surface_format); + soft_mesh->surface_set_material(0, mesh->surface_get_material(0)); - surface_format |= Mesh::ARRAY_FLAG_USE_DYNAMIC_UPDATE; + set_mesh(soft_mesh); - Ref<ArrayMesh> soft_mesh; - soft_mesh.instantiate(); - soft_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, surface_arrays, surface_blend_arrays, surface_lods, surface_format); - soft_mesh->surface_set_material(0, mesh->surface_get_material(0)); - - set_mesh(soft_mesh); - - for (int i = copy_materials.size() - 1; 0 <= i; --i) { - set_surface_override_material(i, copy_materials[i]); - } + for (int i = copy_materials.size() - 1; 0 <= i; --i) { + set_surface_override_material(i, copy_materials[i]); } + + owned_mesh = soft_mesh->get_rid(); } void SoftDynamicBody3D::set_collision_mask(uint32_t p_mask) { @@ -548,16 +552,10 @@ void SoftDynamicBody3D::set_disable_mode(DisableMode p_mode) { return; } - bool inside_tree = is_inside_tree(); - - if (inside_tree && (disable_mode == DISABLE_MODE_REMOVE)) { - prepare_physics_server(); - } - disable_mode = p_mode; - if (inside_tree && (disable_mode == DISABLE_MODE_REMOVE)) { - prepare_physics_server(); + if (mesh.is_valid() && is_inside_tree() && !is_enabled()) { + _prepare_physics_server(); } } diff --git a/scene/3d/soft_dynamic_body_3d.h b/scene/3d/soft_dynamic_body_3d.h index 5e7fbfe29e..57e116aa05 100644 --- a/scene/3d/soft_dynamic_body_3d.h +++ b/scene/3d/soft_dynamic_body_3d.h @@ -90,7 +90,7 @@ private: DisableMode disable_mode = DISABLE_MODE_REMOVE; - bool mesh_owner = false; + RID owned_mesh; uint32_t collision_mask = 1; uint32_t collision_layer = 1; NodePath parent_collision_ignore; @@ -106,6 +106,12 @@ private: void _update_pickable(); + void _update_physics_server(); + void _draw_soft_mesh(); + + void _prepare_physics_server(); + void _become_mesh_owner(); + protected: bool _set(const StringName &p_name, const Variant &p_value); bool _get(const StringName &p_name, Variant &r_ret) const; @@ -120,14 +126,7 @@ protected: TypedArray<String> get_configuration_warnings() const override; -protected: - void _update_physics_server(); - void _draw_soft_mesh(); - public: - void prepare_physics_server(); - void become_mesh_owner(); - RID get_physics_rid() const { return physics_rid; } void set_collision_mask(uint32_t p_mask); diff --git a/scene/3d/sprite_3d.h b/scene/3d/sprite_3d.h index 90c2a309e1..61448c0e32 100644 --- a/scene/3d/sprite_3d.h +++ b/scene/3d/sprite_3d.h @@ -118,12 +118,6 @@ public: void set_flip_v(bool p_flip); bool is_flipped_v() const; - void set_region_enabled(bool p_region); - bool is_region_enabled() const; - - void set_region_rect(const Rect2 &p_region_rect); - Rect2 get_region_rect() const; - void set_modulate(const Color &p_color); Color get_modulate() const; diff --git a/scene/animation/animation_player.h b/scene/animation/animation_player.h index 21e309efe0..d9d88b5510 100644 --- a/scene/animation/animation_player.h +++ b/scene/animation/animation_player.h @@ -301,7 +301,6 @@ public: void set_current_animation(const String &p_anim); String get_assigned_animation() const; void set_assigned_animation(const String &p_anim); - void stop_all(); void set_active(bool p_active); bool is_active() const; bool is_valid() const; diff --git a/scene/animation/animation_tree.h b/scene/animation/animation_tree.h index 21b49937a7..5abea39d20 100644 --- a/scene/animation/animation_tree.h +++ b/scene/animation/animation_tree.h @@ -57,8 +57,6 @@ public: Vector<Input> inputs; - real_t process_input(int p_input, real_t p_time, bool p_seek, real_t p_blend); - friend class AnimationTree; struct AnimationState { @@ -85,7 +83,6 @@ public: State *state = nullptr; real_t _pre_process(const StringName &p_base_path, AnimationNode *p_parent, State *p_state, real_t p_time, bool p_seek, const Vector<StringName> &p_connections); - void _pre_update_animations(HashMap<NodePath, int> *track_map); //all this is temporary StringName base_path; @@ -110,8 +107,6 @@ protected: void _validate_property(PropertyInfo &property) const override; - void _set_parent(Object *p_parent); - GDVIRTUAL0RC(Dictionary, _get_child_nodes) GDVIRTUAL0RC(Array, _get_parameter_list) GDVIRTUAL1RC(Ref<AnimationNode>, _get_child_by_name, StringName) @@ -265,7 +260,6 @@ private: AnimationNode::State state; bool cache_valid = false; void _node_removed(Node *p_node); - void _caches_cleared(); void _clear_caches(); bool _update_caches(AnimationPlayer *player); diff --git a/scene/gui/control.h b/scene/gui/control.h index b551a2e299..02ab336ef0 100644 --- a/scene/gui/control.h +++ b/scene/gui/control.h @@ -233,9 +233,6 @@ private: static constexpr unsigned properties_managed_by_container_count = 11; static String properties_managed_by_container[properties_managed_by_container_count]; - // used internally - Control *_find_control_at_pos(CanvasItem *p_node, const Point2 &p_pos, const Transform2D &p_xform, Transform2D &r_inv_xform); - void _window_find_focus_neighbor(const Vector2 &p_dir, Node *p_at, const Point2 *p_points, real_t p_min, real_t &r_closest_dist, Control **r_closest); Control *_get_focus_neighbor(Side p_side, int p_count = 0); @@ -250,7 +247,6 @@ private: void _update_minimum_size(); void _clear_size_warning(); - void _update_scroll(); void _compute_offsets(Rect2 p_rect, const real_t p_anchors[4], real_t (&r_offsets)[4]); void _compute_anchors(Rect2 p_rect, const real_t p_offsets[4], real_t (&r_anchors)[4]); diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp index 54e7d8f960..99c5e3bf0c 100644 --- a/scene/gui/line_edit.cpp +++ b/scene/gui/line_edit.cpp @@ -235,6 +235,25 @@ void LineEdit::gui_input(const Ref<InputEvent> &p_event) { return; } + if (is_middle_mouse_paste_enabled() && b->is_pressed() && b->get_button_index() == MOUSE_BUTTON_MIDDLE && is_editable()) { + String paste_buffer = DisplayServer::get_singleton()->clipboard_get_primary().strip_escapes(); + + deselect(); + set_caret_at_pixel_pos(b->get_position().x); + if (!paste_buffer.is_empty()) { + insert_text_at_caret(paste_buffer); + + if (!text_changed_dirty) { + if (is_inside_tree()) { + MessageQueue::get_singleton()->push_call(this, "_text_changed"); + } + text_changed_dirty = true; + } + } + grab_focus(); + return; + } + if (b->get_button_index() != MOUSE_BUTTON_LEFT) { return; } @@ -271,6 +290,9 @@ void LineEdit::gui_input(const Ref<InputEvent> &p_event) { selection.double_click = true; last_dblclk = 0; caret_column = selection.begin; + if (!pass) { + DisplayServer::get_singleton()->clipboard_set_primary(text); + } } else if (b->is_double_click()) { // Double-click select word. last_dblclk = OS::get_singleton()->get_ticks_msec(); @@ -286,6 +308,9 @@ void LineEdit::gui_input(const Ref<InputEvent> &p_event) { break; } } + if (!pass) { + DisplayServer::get_singleton()->clipboard_set_primary(text.substr(selection.begin, selection.end - selection.begin)); + } } } @@ -303,6 +328,9 @@ void LineEdit::gui_input(const Ref<InputEvent> &p_event) { update(); } else { + if (selection.enabled && !pass && b->get_button_index() == MOUSE_BUTTON_LEFT) { + DisplayServer::get_singleton()->clipboard_set_primary(text.substr(selection.begin, selection.end - selection.begin)); + } if (!text.is_empty() && is_editable() && clear_button_enabled) { bool press_attempt = clear_button_status.press_attempt; clear_button_status.press_attempt = false; @@ -1890,6 +1918,14 @@ bool LineEdit::is_virtual_keyboard_enabled() const { return virtual_keyboard_enabled; } +void LineEdit::set_middle_mouse_paste_enabled(bool p_enabled) { + middle_mouse_paste_enabled = p_enabled; +} + +bool LineEdit::is_middle_mouse_paste_enabled() const { + return middle_mouse_paste_enabled; +} + void LineEdit::set_selecting_enabled(bool p_enabled) { selecting_enabled = p_enabled; @@ -2156,6 +2192,8 @@ void LineEdit::_bind_methods() { ClassDB::bind_method(D_METHOD("is_clear_button_enabled"), &LineEdit::is_clear_button_enabled); ClassDB::bind_method(D_METHOD("set_shortcut_keys_enabled", "enable"), &LineEdit::set_shortcut_keys_enabled); ClassDB::bind_method(D_METHOD("is_shortcut_keys_enabled"), &LineEdit::is_shortcut_keys_enabled); + ClassDB::bind_method(D_METHOD("set_middle_mouse_paste_enabled", "enable"), &LineEdit::set_middle_mouse_paste_enabled); + ClassDB::bind_method(D_METHOD("is_middle_mouse_paste_enabled"), &LineEdit::is_middle_mouse_paste_enabled); ClassDB::bind_method(D_METHOD("set_selecting_enabled", "enable"), &LineEdit::set_selecting_enabled); ClassDB::bind_method(D_METHOD("is_selecting_enabled"), &LineEdit::is_selecting_enabled); ClassDB::bind_method(D_METHOD("set_right_icon", "icon"), &LineEdit::set_right_icon); @@ -2211,6 +2249,7 @@ void LineEdit::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "virtual_keyboard_enabled"), "set_virtual_keyboard_enabled", "is_virtual_keyboard_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "clear_button_enabled"), "set_clear_button_enabled", "is_clear_button_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shortcut_keys_enabled"), "set_shortcut_keys_enabled", "is_shortcut_keys_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "middle_mouse_paste_enabled"), "set_middle_mouse_paste_enabled", "is_middle_mouse_paste_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "selecting_enabled"), "set_selecting_enabled", "is_selecting_enabled"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "right_icon", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_right_icon", "get_right_icon"); ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,Left-to-Right,Right-to-Left,Inherited"), "set_text_direction", "get_text_direction"); @@ -2237,33 +2276,33 @@ void LineEdit::_ensure_menu() { menu_dir = memnew(PopupMenu); menu_dir->set_name("DirMenu"); - menu_dir->add_radio_check_item(RTR("Same as layout direction"), MENU_DIR_INHERITED); - menu_dir->add_radio_check_item(RTR("Auto-detect direction"), MENU_DIR_AUTO); - menu_dir->add_radio_check_item(RTR("Left-to-right"), MENU_DIR_LTR); - menu_dir->add_radio_check_item(RTR("Right-to-left"), MENU_DIR_RTL); - menu->add_child(menu_dir); + menu_dir->add_radio_check_item(RTR("Same as Layout Direction"), MENU_DIR_INHERITED); + menu_dir->add_radio_check_item(RTR("Auto-Detect Direction"), MENU_DIR_AUTO); + menu_dir->add_radio_check_item(RTR("Left-to-Right"), MENU_DIR_LTR); + menu_dir->add_radio_check_item(RTR("Right-to-Left"), MENU_DIR_RTL); + menu->add_child(menu_dir, false, INTERNAL_MODE_FRONT); menu_ctl = memnew(PopupMenu); menu_ctl->set_name("CTLMenu"); - menu_ctl->add_item(RTR("Left-to-right mark (LRM)"), MENU_INSERT_LRM); - menu_ctl->add_item(RTR("Right-to-left mark (RLM)"), MENU_INSERT_RLM); - menu_ctl->add_item(RTR("Start of left-to-right embedding (LRE)"), MENU_INSERT_LRE); - menu_ctl->add_item(RTR("Start of right-to-left embedding (RLE)"), MENU_INSERT_RLE); - menu_ctl->add_item(RTR("Start of left-to-right override (LRO)"), MENU_INSERT_LRO); - menu_ctl->add_item(RTR("Start of right-to-left override (RLO)"), MENU_INSERT_RLO); - menu_ctl->add_item(RTR("Pop direction formatting (PDF)"), MENU_INSERT_PDF); + menu_ctl->add_item(RTR("Left-to-Right Mark (LRM)"), MENU_INSERT_LRM); + menu_ctl->add_item(RTR("Right-to-Left Mark (RLM)"), MENU_INSERT_RLM); + menu_ctl->add_item(RTR("Start of Left-to-Right Embedding (LRE)"), MENU_INSERT_LRE); + menu_ctl->add_item(RTR("Start of Right-to-Left Embedding (RLE)"), MENU_INSERT_RLE); + menu_ctl->add_item(RTR("Start of Left-to-Right Override (LRO)"), MENU_INSERT_LRO); + menu_ctl->add_item(RTR("Start of Right-to-Left Override (RLO)"), MENU_INSERT_RLO); + menu_ctl->add_item(RTR("Pop Direction Formatting (PDF)"), MENU_INSERT_PDF); menu_ctl->add_separator(); - menu_ctl->add_item(RTR("Arabic letter mark (ALM)"), MENU_INSERT_ALM); - menu_ctl->add_item(RTR("Left-to-right isolate (LRI)"), MENU_INSERT_LRI); - menu_ctl->add_item(RTR("Right-to-left isolate (RLI)"), MENU_INSERT_RLI); - menu_ctl->add_item(RTR("First strong isolate (FSI)"), MENU_INSERT_FSI); - menu_ctl->add_item(RTR("Pop direction isolate (PDI)"), MENU_INSERT_PDI); + menu_ctl->add_item(RTR("Arabic Letter Mark (ALM)"), MENU_INSERT_ALM); + menu_ctl->add_item(RTR("Left-to-Right Isolate (LRI)"), MENU_INSERT_LRI); + menu_ctl->add_item(RTR("Right-to-Left Isolate (RLI)"), MENU_INSERT_RLI); + menu_ctl->add_item(RTR("First Strong Isolate (FSI)"), MENU_INSERT_FSI); + menu_ctl->add_item(RTR("Pop Direction Isolate (PDI)"), MENU_INSERT_PDI); menu_ctl->add_separator(); - menu_ctl->add_item(RTR("Zero width joiner (ZWJ)"), MENU_INSERT_ZWJ); - menu_ctl->add_item(RTR("Zero width non-joiner (ZWNJ)"), MENU_INSERT_ZWNJ); - menu_ctl->add_item(RTR("Word joiner (WJ)"), MENU_INSERT_WJ); - menu_ctl->add_item(RTR("Soft hyphen (SHY)"), MENU_INSERT_SHY); - menu->add_child(menu_ctl); + menu_ctl->add_item(RTR("Zero-Width Joiner (ZWJ)"), MENU_INSERT_ZWJ); + menu_ctl->add_item(RTR("Zero-Width Non-Joiner (ZWNJ)"), MENU_INSERT_ZWNJ); + menu_ctl->add_item(RTR("Word Joiner (WJ)"), MENU_INSERT_WJ); + menu_ctl->add_item(RTR("Soft Hyphen (SHY)"), MENU_INSERT_SHY); + menu->add_child(menu_ctl, false, INTERNAL_MODE_FRONT); menu->connect("id_pressed", callable_mp(this, &LineEdit::menu_option)); menu_dir->connect("id_pressed", callable_mp(this, &LineEdit::menu_option)); @@ -2290,12 +2329,12 @@ void LineEdit::_ensure_menu() { menu->add_item(RTR("Redo"), MENU_REDO, is_shortcut_keys_enabled() ? _get_menu_action_accelerator("ui_redo") : 0); } menu->add_separator(); - menu->add_submenu_item(RTR("Text writing direction"), "DirMenu"); + menu->add_submenu_item(RTR("Text Writing Direction"), "DirMenu"); menu->add_separator(); - menu->add_check_item(RTR("Display control characters"), MENU_DISPLAY_UCC); + menu->add_check_item(RTR("Display Control Characters"), MENU_DISPLAY_UCC); menu->set_item_checked(menu->get_item_index(MENU_DISPLAY_UCC), draw_control_chars); if (editable) { - menu->add_submenu_item(RTR("Insert control character"), "CTLMenu"); + menu->add_submenu_item(RTR("Insert Control Character"), "CTLMenu"); } menu_dir->set_item_checked(menu_dir->get_item_index(MENU_DIR_INHERITED), text_direction == TEXT_DIRECTION_INHERITED); menu_dir->set_item_checked(menu_dir->get_item_index(MENU_DIR_AUTO), text_direction == TEXT_DIRECTION_AUTO); diff --git a/scene/gui/line_edit.h b/scene/gui/line_edit.h index 923024dd56..94179ce05b 100644 --- a/scene/gui/line_edit.h +++ b/scene/gui/line_edit.h @@ -126,6 +126,8 @@ private: bool virtual_keyboard_enabled = true; + bool middle_mouse_paste_enabled = true; + Ref<Texture2D> right_icon; struct Selection { @@ -187,7 +189,6 @@ private: void _toggle_draw_caret(); void clear_internal(); - void changed_internal(); void _editor_settings_changed(); @@ -318,6 +319,9 @@ public: void set_virtual_keyboard_enabled(bool p_enable); bool is_virtual_keyboard_enabled() const; + void set_middle_mouse_paste_enabled(bool p_enabled); + bool is_middle_mouse_paste_enabled() const; + void set_selecting_enabled(bool p_enabled); bool is_selecting_enabled() const; diff --git a/scene/gui/popup.h b/scene/gui/popup.h index c7090e7231..8458a75eef 100644 --- a/scene/gui/popup.h +++ b/scene/gui/popup.h @@ -80,7 +80,6 @@ protected: virtual Size2 _get_contents_minimum_size() const override; public: - void set_child_rect(Control *p_child); PopupPanel(); }; diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index 4588966d88..bc6552c208 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -486,7 +486,7 @@ void RichTextLabel::_shape_line(ItemFrame *p_frame, int p_line, const Ref<Font> remaining_characters -= cell_ch; table->columns.write[column].min_width = MAX(table->columns[column].min_width, ceil(frame->lines[i].text_buf->get_size().x)); - table->columns.write[column].max_width = MAX(table->columns[column].max_width, ceil(frame->lines[i].text_buf->get_non_wraped_size().x)); + table->columns.write[column].max_width = MAX(table->columns[column].max_width, ceil(frame->lines[i].text_buf->get_non_wrapped_size().x)); } idx++; } @@ -1596,12 +1596,16 @@ void RichTextLabel::gui_input(const Ref<InputEvent> &p_event) { selection.to_char = words[i + 1]; selection.active = true; + DisplayServer::get_singleton()->clipboard_set_primary(get_selected_text()); update(); break; } } } } else if (!b->is_pressed()) { + if (selection.enabled) { + DisplayServer::get_singleton()->clipboard_set_primary(get_selected_text()); + } selection.click_item = nullptr; if (!b->is_double_click() && !scroll_updated) { @@ -1719,6 +1723,7 @@ void RichTextLabel::gui_input(const Ref<InputEvent> &p_event) { swap = true; } else if (selection.from_char == selection.to_char) { selection.active = false; + update(); return; } } diff --git a/scene/gui/tabs.cpp b/scene/gui/tab_bar.cpp index 0755a79eee..78b58c773a 100644 --- a/scene/gui/tabs.cpp +++ b/scene/gui/tab_bar.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* tabs.cpp */ +/* tab_bar.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,7 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "tabs.h" +#include "tab_bar.h" #include "core/object/message_queue.h" #include "core/string/translation.h" @@ -37,7 +37,7 @@ #include "scene/gui/label.h" #include "scene/gui/texture_rect.h" -Size2 Tabs::get_minimum_size() const { +Size2 TabBar::get_minimum_size() const { Ref<StyleBox> tab_unselected = get_theme_stylebox(SNAME("tab_unselected")); Ref<StyleBox> tab_selected = get_theme_stylebox(SNAME("tab_selected")); Ref<StyleBox> tab_disabled = get_theme_stylebox(SNAME("tab_disabled")); @@ -90,7 +90,7 @@ Size2 Tabs::get_minimum_size() const { return ms; } -void Tabs::gui_input(const Ref<InputEvent> &p_event) { +void TabBar::gui_input(const Ref<InputEvent> &p_event) { ERR_FAIL_COND(p_event.is_null()); Ref<InputEventMouseMotion> mm = p_event; @@ -164,7 +164,7 @@ void Tabs::gui_input(const Ref<InputEvent> &p_event) { if (rb_pressing && !mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_LEFT) { if (rb_hover != -1) { - //pressed + // pressed emit_signal(SNAME("tab_rmb_clicked"), rb_hover); } @@ -174,7 +174,7 @@ void Tabs::gui_input(const Ref<InputEvent> &p_event) { if (cb_pressing && !mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_LEFT) { if (cb_hover != -1) { - //pressed + // pressed emit_signal(SNAME("tab_closed"), cb_hover); } @@ -222,6 +222,11 @@ void Tabs::gui_input(const Ref<InputEvent> &p_event) { } } + if (max_drawn_tab <= 0) { + // Return early if there are no actual tabs to handle input for. + return; + } + int found = -1; for (int i = offset; i <= max_drawn_tab; i++) { if (tabs[i].rb_rect.has_point(pos)) { @@ -252,7 +257,7 @@ void Tabs::gui_input(const Ref<InputEvent> &p_event) { } } -void Tabs::_shape(int p_tab) { +void TabBar::_shape(int p_tab) { Ref<Font> font = get_theme_font(SNAME("font")); int font_size = get_theme_font_size(SNAME("font_size")); @@ -268,7 +273,7 @@ void Tabs::_shape(int p_tab) { tabs.write[p_tab].text_buf->add_string(tabs.write[p_tab].xl_text, font, font_size, tabs[p_tab].opentype_features, (tabs[p_tab].language != "") ? tabs[p_tab].language : TranslationServer::get_singleton()->get_tool_locale()); } -void Tabs::_notification(int p_what) { +void TabBar::_notification(int p_what) { switch (p_what) { case NOTIFICATION_LAYOUT_DIRECTION_CHANGED: { _update_cache(); @@ -505,11 +510,11 @@ void Tabs::_notification(int p_what) { } } -int Tabs::get_tab_count() const { +int TabBar::get_tab_count() const { return tabs.size(); } -void Tabs::set_current_tab(int p_current) { +void TabBar::set_current_tab(int p_current) { if (current == p_current) { return; } @@ -524,27 +529,27 @@ void Tabs::set_current_tab(int p_current) { emit_signal(SNAME("tab_changed"), p_current); } -int Tabs::get_current_tab() const { +int TabBar::get_current_tab() const { return current; } -int Tabs::get_previous_tab() const { +int TabBar::get_previous_tab() const { return previous; } -int Tabs::get_hovered_tab() const { +int TabBar::get_hovered_tab() const { return hover; } -int Tabs::get_tab_offset() const { +int TabBar::get_tab_offset() const { return offset; } -bool Tabs::get_offset_buttons_visible() const { +bool TabBar::get_offset_buttons_visible() const { return buttons_visible; } -void Tabs::set_tab_title(int p_tab, const String &p_title) { +void TabBar::set_tab_title(int p_tab, const String &p_title) { ERR_FAIL_INDEX(p_tab, tabs.size()); tabs.write[p_tab].text = p_title; _shape(p_tab); @@ -552,12 +557,12 @@ void Tabs::set_tab_title(int p_tab, const String &p_title) { minimum_size_changed(); } -String Tabs::get_tab_title(int p_tab) const { +String TabBar::get_tab_title(int p_tab) const { ERR_FAIL_INDEX_V(p_tab, tabs.size(), ""); return tabs[p_tab].text; } -void Tabs::set_tab_text_direction(int p_tab, Control::TextDirection p_text_direction) { +void TabBar::set_tab_text_direction(int p_tab, Control::TextDirection p_text_direction) { ERR_FAIL_INDEX(p_tab, tabs.size()); ERR_FAIL_COND((int)p_text_direction < -1 || (int)p_text_direction > 3); if (tabs[p_tab].text_direction != p_text_direction) { @@ -567,19 +572,19 @@ void Tabs::set_tab_text_direction(int p_tab, Control::TextDirection p_text_direc } } -Control::TextDirection Tabs::get_tab_text_direction(int p_tab) const { +Control::TextDirection TabBar::get_tab_text_direction(int p_tab) const { ERR_FAIL_INDEX_V(p_tab, tabs.size(), Control::TEXT_DIRECTION_INHERITED); return tabs[p_tab].text_direction; } -void Tabs::clear_tab_opentype_features(int p_tab) { +void TabBar::clear_tab_opentype_features(int p_tab) { ERR_FAIL_INDEX(p_tab, tabs.size()); tabs.write[p_tab].opentype_features.clear(); _shape(p_tab); update(); } -void Tabs::set_tab_opentype_feature(int p_tab, const String &p_name, int p_value) { +void TabBar::set_tab_opentype_feature(int p_tab, const String &p_name, int p_value) { ERR_FAIL_INDEX(p_tab, tabs.size()); int32_t tag = TS->name_to_tag(p_name); if (!tabs[p_tab].opentype_features.has(tag) || (int)tabs[p_tab].opentype_features[tag] != p_value) { @@ -589,7 +594,7 @@ void Tabs::set_tab_opentype_feature(int p_tab, const String &p_name, int p_value } } -int Tabs::get_tab_opentype_feature(int p_tab, const String &p_name) const { +int TabBar::get_tab_opentype_feature(int p_tab, const String &p_name) const { ERR_FAIL_INDEX_V(p_tab, tabs.size(), -1); int32_t tag = TS->name_to_tag(p_name); if (!tabs[p_tab].opentype_features.has(tag)) { @@ -598,7 +603,7 @@ int Tabs::get_tab_opentype_feature(int p_tab, const String &p_name) const { return tabs[p_tab].opentype_features[tag]; } -void Tabs::set_tab_language(int p_tab, const String &p_language) { +void TabBar::set_tab_language(int p_tab, const String &p_language) { ERR_FAIL_INDEX(p_tab, tabs.size()); if (tabs[p_tab].language != p_language) { tabs.write[p_tab].language = p_language; @@ -607,35 +612,35 @@ void Tabs::set_tab_language(int p_tab, const String &p_language) { } } -String Tabs::get_tab_language(int p_tab) const { +String TabBar::get_tab_language(int p_tab) const { ERR_FAIL_INDEX_V(p_tab, tabs.size(), ""); return tabs[p_tab].language; } -void Tabs::set_tab_icon(int p_tab, const Ref<Texture2D> &p_icon) { +void TabBar::set_tab_icon(int p_tab, const Ref<Texture2D> &p_icon) { ERR_FAIL_INDEX(p_tab, tabs.size()); tabs.write[p_tab].icon = p_icon; update(); minimum_size_changed(); } -Ref<Texture2D> Tabs::get_tab_icon(int p_tab) const { +Ref<Texture2D> TabBar::get_tab_icon(int p_tab) const { ERR_FAIL_INDEX_V(p_tab, tabs.size(), Ref<Texture2D>()); return tabs[p_tab].icon; } -void Tabs::set_tab_disabled(int p_tab, bool p_disabled) { +void TabBar::set_tab_disabled(int p_tab, bool p_disabled) { ERR_FAIL_INDEX(p_tab, tabs.size()); tabs.write[p_tab].disabled = p_disabled; update(); } -bool Tabs::get_tab_disabled(int p_tab) const { +bool TabBar::get_tab_disabled(int p_tab) const { ERR_FAIL_INDEX_V(p_tab, tabs.size(), false); return tabs[p_tab].disabled; } -void Tabs::set_tab_right_button(int p_tab, const Ref<Texture2D> &p_right_button) { +void TabBar::set_tab_right_button(int p_tab, const Ref<Texture2D> &p_right_button) { ERR_FAIL_INDEX(p_tab, tabs.size()); tabs.write[p_tab].right_button = p_right_button; _update_cache(); @@ -643,12 +648,12 @@ void Tabs::set_tab_right_button(int p_tab, const Ref<Texture2D> &p_right_button) minimum_size_changed(); } -Ref<Texture2D> Tabs::get_tab_right_button(int p_tab) const { +Ref<Texture2D> TabBar::get_tab_right_button(int p_tab) const { ERR_FAIL_INDEX_V(p_tab, tabs.size(), Ref<Texture2D>()); return tabs[p_tab].right_button; } -void Tabs::_update_hover() { +void TabBar::_update_hover() { if (!is_inside_tree()) { return; } @@ -685,7 +690,7 @@ void Tabs::_update_hover() { } } -void Tabs::_update_cache() { +void TabBar::_update_cache() { Ref<StyleBox> tab_disabled = get_theme_stylebox(SNAME("tab_disabled")); Ref<StyleBox> tab_unselected = get_theme_stylebox(SNAME("tab_unselected")); Ref<StyleBox> tab_selected = get_theme_stylebox(SNAME("tab_selected")); @@ -748,7 +753,7 @@ void Tabs::_update_cache() { } } -void Tabs::_on_mouse_exited() { +void TabBar::_on_mouse_exited() { rb_hover = -1; cb_hover = -1; hover = -1; @@ -756,7 +761,7 @@ void Tabs::_on_mouse_exited() { update(); } -void Tabs::add_tab(const String &p_str, const Ref<Texture2D> &p_icon) { +void TabBar::add_tab(const String &p_str, const Ref<Texture2D> &p_icon) { Tab t; t.text = p_str; t.xl_text = atr(p_str); @@ -775,7 +780,7 @@ void Tabs::add_tab(const String &p_str, const Ref<Texture2D> &p_icon) { minimum_size_changed(); } -void Tabs::clear_tabs() { +void TabBar::clear_tabs() { tabs.clear(); current = 0; previous = 0; @@ -783,7 +788,7 @@ void Tabs::clear_tabs() { update(); } -void Tabs::remove_tab(int p_idx) { +void TabBar::remove_tab(int p_idx) { ERR_FAIL_INDEX(p_idx, tabs.size()); tabs.remove(p_idx); if (current >= p_idx) { @@ -805,7 +810,7 @@ void Tabs::remove_tab(int p_idx) { _ensure_no_over_offset(); } -Variant Tabs::get_drag_data(const Point2 &p_point) { +Variant TabBar::get_drag_data(const Point2 &p_point) { if (!drag_to_rearrange_enabled) { return Variant(); } @@ -839,7 +844,7 @@ Variant Tabs::get_drag_data(const Point2 &p_point) { return drag_data; } -bool Tabs::can_drop_data(const Point2 &p_point, const Variant &p_data) const { +bool TabBar::can_drop_data(const Point2 &p_point, const Variant &p_data) const { if (!drag_to_rearrange_enabled) { return false; } @@ -855,9 +860,9 @@ bool Tabs::can_drop_data(const Point2 &p_point, const Variant &p_data) const { if (from_path == to_path) { return true; } else if (get_tabs_rearrange_group() != -1) { - // drag and drop between other Tabs + // drag and drop between other TabBars Node *from_node = get_node(from_path); - Tabs *from_tabs = Object::cast_to<Tabs>(from_node); + TabBar *from_tabs = Object::cast_to<TabBar>(from_node); if (from_tabs && from_tabs->get_tabs_rearrange_group() == get_tabs_rearrange_group()) { return true; } @@ -866,7 +871,7 @@ bool Tabs::can_drop_data(const Point2 &p_point, const Variant &p_data) const { return false; } -void Tabs::drop_data(const Point2 &p_point, const Variant &p_data) { +void TabBar::drop_data(const Point2 &p_point, const Variant &p_data) { if (!drag_to_rearrange_enabled) { return; } @@ -892,7 +897,7 @@ void Tabs::drop_data(const Point2 &p_point, const Variant &p_data) { } else if (get_tabs_rearrange_group() != -1) { // drag and drop between Tabs Node *from_node = get_node(from_path); - Tabs *from_tabs = Object::cast_to<Tabs>(from_node); + TabBar *from_tabs = Object::cast_to<TabBar>(from_node); if (from_tabs && from_tabs->get_tabs_rearrange_group() == get_tabs_rearrange_group()) { if (tab_from_id >= from_tabs->get_tab_count()) { return; @@ -912,7 +917,7 @@ void Tabs::drop_data(const Point2 &p_point, const Variant &p_data) { update(); } -int Tabs::get_tab_idx_at_point(const Point2 &p_point) const { +int TabBar::get_tab_idx_at_point(const Point2 &p_point) const { int hover_now = -1; for (int i = offset; i <= max_drawn_tab; i++) { Rect2 rect = get_tab_rect(i); @@ -924,17 +929,17 @@ int Tabs::get_tab_idx_at_point(const Point2 &p_point) const { return hover_now; } -void Tabs::set_tab_align(TabAlign p_align) { +void TabBar::set_tab_align(TabAlign p_align) { ERR_FAIL_INDEX(p_align, ALIGN_MAX); tab_align = p_align; update(); } -Tabs::TabAlign Tabs::get_tab_align() const { +TabBar::TabAlign TabBar::get_tab_align() const { return tab_align; } -void Tabs::set_clip_tabs(bool p_clip_tabs) { +void TabBar::set_clip_tabs(bool p_clip_tabs) { if (clip_tabs == p_clip_tabs) { return; } @@ -943,11 +948,11 @@ void Tabs::set_clip_tabs(bool p_clip_tabs) { minimum_size_changed(); } -bool Tabs::get_clip_tabs() const { +bool TabBar::get_clip_tabs() const { return clip_tabs; } -void Tabs::move_tab(int from, int to) { +void TabBar::move_tab(int from, int to) { if (from == to) { return; } @@ -963,7 +968,7 @@ void Tabs::move_tab(int from, int to) { update(); } -int Tabs::get_tab_width(int p_idx) const { +int TabBar::get_tab_width(int p_idx) const { ERR_FAIL_INDEX_V(p_idx, tabs.size(), 0); Ref<StyleBox> tab_unselected = get_theme_stylebox(SNAME("tab_unselected")); @@ -1005,7 +1010,7 @@ int Tabs::get_tab_width(int p_idx) const { return x; } -void Tabs::_ensure_no_over_offset() { +void TabBar::_ensure_no_over_offset() { if (!is_inside_tree()) { return; } @@ -1031,7 +1036,7 @@ void Tabs::_ensure_no_over_offset() { } } -void Tabs::ensure_tab_visible(int p_idx) { +void TabBar::ensure_tab_visible(int p_idx) { if (!is_inside_tree()) { return; } @@ -1068,7 +1073,7 @@ void Tabs::ensure_tab_visible(int p_idx) { } } -Rect2 Tabs::get_tab_rect(int p_tab) const { +Rect2 TabBar::get_tab_rect(int p_tab) const { ERR_FAIL_INDEX_V(p_tab, tabs.size(), Rect2()); if (is_layout_rtl()) { return Rect2(get_size().width - tabs[p_tab].ofs_cache - tabs[p_tab].size_cache, 0, tabs[p_tab].size_cache, get_size().height); @@ -1077,93 +1082,93 @@ Rect2 Tabs::get_tab_rect(int p_tab) const { } } -void Tabs::set_tab_close_display_policy(CloseButtonDisplayPolicy p_policy) { +void TabBar::set_tab_close_display_policy(CloseButtonDisplayPolicy p_policy) { ERR_FAIL_INDEX(p_policy, CLOSE_BUTTON_MAX); cb_displaypolicy = p_policy; update(); } -Tabs::CloseButtonDisplayPolicy Tabs::get_tab_close_display_policy() const { +TabBar::CloseButtonDisplayPolicy TabBar::get_tab_close_display_policy() const { return cb_displaypolicy; } -void Tabs::set_min_width(int p_width) { +void TabBar::set_min_width(int p_width) { min_width = p_width; } -void Tabs::set_scrolling_enabled(bool p_enabled) { +void TabBar::set_scrolling_enabled(bool p_enabled) { scrolling_enabled = p_enabled; } -bool Tabs::get_scrolling_enabled() const { +bool TabBar::get_scrolling_enabled() const { return scrolling_enabled; } -void Tabs::set_drag_to_rearrange_enabled(bool p_enabled) { +void TabBar::set_drag_to_rearrange_enabled(bool p_enabled) { drag_to_rearrange_enabled = p_enabled; } -bool Tabs::get_drag_to_rearrange_enabled() const { +bool TabBar::get_drag_to_rearrange_enabled() const { return drag_to_rearrange_enabled; } -void Tabs::set_tabs_rearrange_group(int p_group_id) { +void TabBar::set_tabs_rearrange_group(int p_group_id) { tabs_rearrange_group = p_group_id; } -int Tabs::get_tabs_rearrange_group() const { +int TabBar::get_tabs_rearrange_group() const { return tabs_rearrange_group; } -void Tabs::set_select_with_rmb(bool p_enabled) { +void TabBar::set_select_with_rmb(bool p_enabled) { select_with_rmb = p_enabled; } -bool Tabs::get_select_with_rmb() const { +bool TabBar::get_select_with_rmb() const { return select_with_rmb; } -void Tabs::_bind_methods() { - ClassDB::bind_method(D_METHOD("_update_hover"), &Tabs::_update_hover); - ClassDB::bind_method(D_METHOD("get_tab_count"), &Tabs::get_tab_count); - ClassDB::bind_method(D_METHOD("set_current_tab", "tab_idx"), &Tabs::set_current_tab); - ClassDB::bind_method(D_METHOD("get_current_tab"), &Tabs::get_current_tab); - ClassDB::bind_method(D_METHOD("get_previous_tab"), &Tabs::get_previous_tab); - ClassDB::bind_method(D_METHOD("set_tab_title", "tab_idx", "title"), &Tabs::set_tab_title); - ClassDB::bind_method(D_METHOD("get_tab_title", "tab_idx"), &Tabs::get_tab_title); - ClassDB::bind_method(D_METHOD("set_tab_text_direction", "tab_idx", "direction"), &Tabs::set_tab_text_direction); - ClassDB::bind_method(D_METHOD("get_tab_text_direction", "tab_idx"), &Tabs::get_tab_text_direction); - ClassDB::bind_method(D_METHOD("set_tab_opentype_feature", "tab_idx", "tag", "values"), &Tabs::set_tab_opentype_feature); - ClassDB::bind_method(D_METHOD("get_tab_opentype_feature", "tab_idx", "tag"), &Tabs::get_tab_opentype_feature); - ClassDB::bind_method(D_METHOD("clear_tab_opentype_features", "tab_idx"), &Tabs::clear_tab_opentype_features); - ClassDB::bind_method(D_METHOD("set_tab_language", "tab_idx", "language"), &Tabs::set_tab_language); - ClassDB::bind_method(D_METHOD("get_tab_language", "tab_idx"), &Tabs::get_tab_language); - ClassDB::bind_method(D_METHOD("set_tab_icon", "tab_idx", "icon"), &Tabs::set_tab_icon); - ClassDB::bind_method(D_METHOD("get_tab_icon", "tab_idx"), &Tabs::get_tab_icon); - ClassDB::bind_method(D_METHOD("set_tab_disabled", "tab_idx", "disabled"), &Tabs::set_tab_disabled); - ClassDB::bind_method(D_METHOD("get_tab_disabled", "tab_idx"), &Tabs::get_tab_disabled); - ClassDB::bind_method(D_METHOD("remove_tab", "tab_idx"), &Tabs::remove_tab); - ClassDB::bind_method(D_METHOD("add_tab", "title", "icon"), &Tabs::add_tab, DEFVAL(""), DEFVAL(Ref<Texture2D>())); - ClassDB::bind_method(D_METHOD("set_tab_align", "align"), &Tabs::set_tab_align); - ClassDB::bind_method(D_METHOD("get_tab_align"), &Tabs::get_tab_align); - ClassDB::bind_method(D_METHOD("set_clip_tabs", "clip_tabs"), &Tabs::set_clip_tabs); - ClassDB::bind_method(D_METHOD("get_clip_tabs"), &Tabs::get_clip_tabs); - ClassDB::bind_method(D_METHOD("get_tab_offset"), &Tabs::get_tab_offset); - ClassDB::bind_method(D_METHOD("get_offset_buttons_visible"), &Tabs::get_offset_buttons_visible); - ClassDB::bind_method(D_METHOD("ensure_tab_visible", "idx"), &Tabs::ensure_tab_visible); - ClassDB::bind_method(D_METHOD("get_tab_rect", "tab_idx"), &Tabs::get_tab_rect); - ClassDB::bind_method(D_METHOD("move_tab", "from", "to"), &Tabs::move_tab); - ClassDB::bind_method(D_METHOD("set_tab_close_display_policy", "policy"), &Tabs::set_tab_close_display_policy); - ClassDB::bind_method(D_METHOD("get_tab_close_display_policy"), &Tabs::get_tab_close_display_policy); - ClassDB::bind_method(D_METHOD("set_scrolling_enabled", "enabled"), &Tabs::set_scrolling_enabled); - ClassDB::bind_method(D_METHOD("get_scrolling_enabled"), &Tabs::get_scrolling_enabled); - ClassDB::bind_method(D_METHOD("set_drag_to_rearrange_enabled", "enabled"), &Tabs::set_drag_to_rearrange_enabled); - ClassDB::bind_method(D_METHOD("get_drag_to_rearrange_enabled"), &Tabs::get_drag_to_rearrange_enabled); - ClassDB::bind_method(D_METHOD("set_tabs_rearrange_group", "group_id"), &Tabs::set_tabs_rearrange_group); - ClassDB::bind_method(D_METHOD("get_tabs_rearrange_group"), &Tabs::get_tabs_rearrange_group); - - ClassDB::bind_method(D_METHOD("set_select_with_rmb", "enabled"), &Tabs::set_select_with_rmb); - ClassDB::bind_method(D_METHOD("get_select_with_rmb"), &Tabs::get_select_with_rmb); +void TabBar::_bind_methods() { + ClassDB::bind_method(D_METHOD("_update_hover"), &TabBar::_update_hover); + ClassDB::bind_method(D_METHOD("get_tab_count"), &TabBar::get_tab_count); + ClassDB::bind_method(D_METHOD("set_current_tab", "tab_idx"), &TabBar::set_current_tab); + ClassDB::bind_method(D_METHOD("get_current_tab"), &TabBar::get_current_tab); + ClassDB::bind_method(D_METHOD("get_previous_tab"), &TabBar::get_previous_tab); + ClassDB::bind_method(D_METHOD("set_tab_title", "tab_idx", "title"), &TabBar::set_tab_title); + ClassDB::bind_method(D_METHOD("get_tab_title", "tab_idx"), &TabBar::get_tab_title); + ClassDB::bind_method(D_METHOD("set_tab_text_direction", "tab_idx", "direction"), &TabBar::set_tab_text_direction); + ClassDB::bind_method(D_METHOD("get_tab_text_direction", "tab_idx"), &TabBar::get_tab_text_direction); + ClassDB::bind_method(D_METHOD("set_tab_opentype_feature", "tab_idx", "tag", "values"), &TabBar::set_tab_opentype_feature); + ClassDB::bind_method(D_METHOD("get_tab_opentype_feature", "tab_idx", "tag"), &TabBar::get_tab_opentype_feature); + ClassDB::bind_method(D_METHOD("clear_tab_opentype_features", "tab_idx"), &TabBar::clear_tab_opentype_features); + ClassDB::bind_method(D_METHOD("set_tab_language", "tab_idx", "language"), &TabBar::set_tab_language); + ClassDB::bind_method(D_METHOD("get_tab_language", "tab_idx"), &TabBar::get_tab_language); + ClassDB::bind_method(D_METHOD("set_tab_icon", "tab_idx", "icon"), &TabBar::set_tab_icon); + ClassDB::bind_method(D_METHOD("get_tab_icon", "tab_idx"), &TabBar::get_tab_icon); + ClassDB::bind_method(D_METHOD("set_tab_disabled", "tab_idx", "disabled"), &TabBar::set_tab_disabled); + ClassDB::bind_method(D_METHOD("get_tab_disabled", "tab_idx"), &TabBar::get_tab_disabled); + ClassDB::bind_method(D_METHOD("remove_tab", "tab_idx"), &TabBar::remove_tab); + ClassDB::bind_method(D_METHOD("add_tab", "title", "icon"), &TabBar::add_tab, DEFVAL(""), DEFVAL(Ref<Texture2D>())); + ClassDB::bind_method(D_METHOD("set_tab_align", "align"), &TabBar::set_tab_align); + ClassDB::bind_method(D_METHOD("get_tab_align"), &TabBar::get_tab_align); + ClassDB::bind_method(D_METHOD("set_clip_tabs", "clip_tabs"), &TabBar::set_clip_tabs); + ClassDB::bind_method(D_METHOD("get_clip_tabs"), &TabBar::get_clip_tabs); + ClassDB::bind_method(D_METHOD("get_tab_offset"), &TabBar::get_tab_offset); + ClassDB::bind_method(D_METHOD("get_offset_buttons_visible"), &TabBar::get_offset_buttons_visible); + ClassDB::bind_method(D_METHOD("ensure_tab_visible", "idx"), &TabBar::ensure_tab_visible); + ClassDB::bind_method(D_METHOD("get_tab_rect", "tab_idx"), &TabBar::get_tab_rect); + ClassDB::bind_method(D_METHOD("move_tab", "from", "to"), &TabBar::move_tab); + ClassDB::bind_method(D_METHOD("set_tab_close_display_policy", "policy"), &TabBar::set_tab_close_display_policy); + ClassDB::bind_method(D_METHOD("get_tab_close_display_policy"), &TabBar::get_tab_close_display_policy); + ClassDB::bind_method(D_METHOD("set_scrolling_enabled", "enabled"), &TabBar::set_scrolling_enabled); + ClassDB::bind_method(D_METHOD("get_scrolling_enabled"), &TabBar::get_scrolling_enabled); + ClassDB::bind_method(D_METHOD("set_drag_to_rearrange_enabled", "enabled"), &TabBar::set_drag_to_rearrange_enabled); + ClassDB::bind_method(D_METHOD("get_drag_to_rearrange_enabled"), &TabBar::get_drag_to_rearrange_enabled); + ClassDB::bind_method(D_METHOD("set_tabs_rearrange_group", "group_id"), &TabBar::set_tabs_rearrange_group); + ClassDB::bind_method(D_METHOD("get_tabs_rearrange_group"), &TabBar::get_tabs_rearrange_group); + + ClassDB::bind_method(D_METHOD("set_select_with_rmb", "enabled"), &TabBar::set_select_with_rmb); + ClassDB::bind_method(D_METHOD("get_select_with_rmb"), &TabBar::get_select_with_rmb); ADD_SIGNAL(MethodInfo("tab_changed", PropertyInfo(Variant::INT, "tab"))); ADD_SIGNAL(MethodInfo("tab_rmb_clicked", PropertyInfo(Variant::INT, "tab"))); @@ -1190,6 +1195,6 @@ void Tabs::_bind_methods() { BIND_ENUM_CONSTANT(CLOSE_BUTTON_MAX); } -Tabs::Tabs() { - connect("mouse_exited", callable_mp(this, &Tabs::_on_mouse_exited)); +TabBar::TabBar() { + connect("mouse_exited", callable_mp(this, &TabBar::_on_mouse_exited)); } diff --git a/scene/gui/tabs.h b/scene/gui/tab_bar.h index b044453803..411a62b1d9 100644 --- a/scene/gui/tabs.h +++ b/scene/gui/tab_bar.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* tabs.h */ +/* tab_bar.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,14 +28,14 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef TABS_H -#define TABS_H +#ifndef TAB_BAR_H +#define TAB_BAR_H #include "scene/gui/control.h" #include "scene/resources/text_line.h" -class Tabs : public Control { - GDCLASS(Tabs, Control); +class TabBar : public Control { + GDCLASS(TabBar, Control); public: enum TabAlign { @@ -83,7 +83,6 @@ private: Vector<Tab> tabs; int current = 0; int previous = 0; - int _get_top_margin() const; TabAlign tab_align = ALIGN_CENTER; bool clip_tabs = true; int rb_hover = -1; @@ -187,10 +186,10 @@ public: Rect2 get_tab_rect(int p_tab) const; Size2 get_minimum_size() const override; - Tabs(); + TabBar(); }; -VARIANT_ENUM_CAST(Tabs::TabAlign); -VARIANT_ENUM_CAST(Tabs::CloseButtonDisplayPolicy); +VARIANT_ENUM_CAST(TabBar::TabAlign); +VARIANT_ENUM_CAST(TabBar::CloseButtonDisplayPolicy); -#endif // TABS_H +#endif // TAB_BAR_H diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index f03eebd543..a1d66d8544 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -1534,6 +1534,10 @@ void TextEdit::gui_input(const Ref<InputEvent> &p_gui_input) { update(); } + if (is_middle_mouse_paste_enabled() && mb->get_button_index() == MOUSE_BUTTON_MIDDLE) { + paste_primary_clipboard(); + } + if (mb->get_button_index() == MOUSE_BUTTON_RIGHT && context_menu_enabled) { _reset_caret_blink_timer(); @@ -1571,6 +1575,7 @@ void TextEdit::gui_input(const Ref<InputEvent> &p_gui_input) { dragging_selection = false; can_drag_minimap = false; click_select_held->stop(); + DisplayServer::get_singleton()->clipboard_set_primary(get_selected_text()); } // Notify to show soft keyboard. @@ -2596,6 +2601,14 @@ bool TextEdit::is_virtual_keyboard_enabled() const { return virtual_keyboard_enabled; } +void TextEdit::set_middle_mouse_paste_enabled(bool p_enabled) { + middle_mouse_paste_enabled = p_enabled; +} + +bool TextEdit::is_middle_mouse_paste_enabled() const { + return middle_mouse_paste_enabled; +} + // Text manipulation void TextEdit::clear() { setting_text = true; @@ -2915,6 +2928,13 @@ void TextEdit::paste() { _paste_internal(); } +void TextEdit::paste_primary_clipboard() { + if (GDVIRTUAL_CALL(_paste_primary_clipboard)) { + return; + } + _paste_primary_clipboard_internal(); +} + // Context menu. PopupMenu *TextEdit::get_menu() const { const_cast<TextEdit *>(this)->_generate_context_menu(); @@ -4039,7 +4059,7 @@ int TextEdit::get_visible_line_count() const { } int TextEdit::get_total_visible_line_count() const { - /* Returns the total number of (lines + wraped - hidden). */ + /* Returns the total number of (lines + wrapped - hidden). */ if (!_is_hiding_enabled() && get_line_wrapping_mode() == LineWrappingMode::LINE_WRAPPING_NONE) { return text.size(); } @@ -4536,6 +4556,9 @@ void TextEdit::_bind_methods() { ClassDB::bind_method(D_METHOD("set_virtual_keyboard_enabled", "enabled"), &TextEdit::set_virtual_keyboard_enabled); ClassDB::bind_method(D_METHOD("is_virtual_keyboard_enabled"), &TextEdit::is_virtual_keyboard_enabled); + ClassDB::bind_method(D_METHOD("set_middle_mouse_paste_enabled", "enabled"), &TextEdit::set_middle_mouse_paste_enabled); + ClassDB::bind_method(D_METHOD("is_middle_mouse_paste_enabled"), &TextEdit::is_middle_mouse_paste_enabled); + // Text manipulation ClassDB::bind_method(D_METHOD("clear"), &TextEdit::clear); @@ -4575,6 +4598,7 @@ void TextEdit::_bind_methods() { GDVIRTUAL_BIND(_cut) GDVIRTUAL_BIND(_copy) GDVIRTUAL_BIND(_paste) + GDVIRTUAL_BIND(_paste_primary_clipboard) // Context Menu BIND_ENUM_CONSTANT(MENU_CUT); @@ -4850,6 +4874,7 @@ void TextEdit::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shortcut_keys_enabled"), "set_shortcut_keys_enabled", "is_shortcut_keys_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "selecting_enabled"), "set_selecting_enabled", "is_selecting_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "virtual_keyboard_enabled"), "set_virtual_keyboard_enabled", "is_virtual_keyboard_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "middle_mouse_paste_enabled"), "set_middle_mouse_paste_enabled", "is_middle_mouse_paste_enabled"); ADD_PROPERTY(PropertyInfo(Variant::INT, "wrap_mode", PROPERTY_HINT_ENUM, "None,Boundary"), "set_line_wrapping_mode", "get_line_wrapping_mode"); @@ -5141,6 +5166,24 @@ void TextEdit::_paste_internal() { end_complex_operation(); } +void TextEdit::_paste_primary_clipboard_internal() { + if (!is_editable()) { + return; + } + + String paste_buffer = DisplayServer::get_singleton()->clipboard_get_primary(); + + Point2i pos = get_line_column_at_pos(get_local_mouse_pos()); + deselect(); + set_caret_line(pos.y, true, false); + set_caret_column(pos.x); + if (!paste_buffer.is_empty()) { + insert_text_at_caret(paste_buffer); + } + + grab_focus(); +} + /* Text. */ // Context menu. void TextEdit::_generate_context_menu() { @@ -5150,32 +5193,32 @@ void TextEdit::_generate_context_menu() { menu_dir = memnew(PopupMenu); menu_dir->set_name("DirMenu"); - menu_dir->add_radio_check_item(RTR("Same as layout direction"), MENU_DIR_INHERITED); - menu_dir->add_radio_check_item(RTR("Auto-detect direction"), MENU_DIR_AUTO); - menu_dir->add_radio_check_item(RTR("Left-to-right"), MENU_DIR_LTR); - menu_dir->add_radio_check_item(RTR("Right-to-left"), MENU_DIR_RTL); + menu_dir->add_radio_check_item(RTR("Same as Layout Direction"), MENU_DIR_INHERITED); + menu_dir->add_radio_check_item(RTR("Auto-Detect Direction"), MENU_DIR_AUTO); + menu_dir->add_radio_check_item(RTR("Left-to-Right"), MENU_DIR_LTR); + menu_dir->add_radio_check_item(RTR("Right-to-Left"), MENU_DIR_RTL); menu->add_child(menu_dir, false, INTERNAL_MODE_FRONT); menu_ctl = memnew(PopupMenu); menu_ctl->set_name("CTLMenu"); - menu_ctl->add_item(RTR("Left-to-right mark (LRM)"), MENU_INSERT_LRM); - menu_ctl->add_item(RTR("Right-to-left mark (RLM)"), MENU_INSERT_RLM); - menu_ctl->add_item(RTR("Start of left-to-right embedding (LRE)"), MENU_INSERT_LRE); - menu_ctl->add_item(RTR("Start of right-to-left embedding (RLE)"), MENU_INSERT_RLE); - menu_ctl->add_item(RTR("Start of left-to-right override (LRO)"), MENU_INSERT_LRO); - menu_ctl->add_item(RTR("Start of right-to-left override (RLO)"), MENU_INSERT_RLO); - menu_ctl->add_item(RTR("Pop direction formatting (PDF)"), MENU_INSERT_PDF); + menu_ctl->add_item(RTR("Left-to-Right Mark (LRM)"), MENU_INSERT_LRM); + menu_ctl->add_item(RTR("Right-to-Left Mark (RLM)"), MENU_INSERT_RLM); + menu_ctl->add_item(RTR("Start of Left-to-Right Embedding (LRE)"), MENU_INSERT_LRE); + menu_ctl->add_item(RTR("Start of Right-to-Left Embedding (RLE)"), MENU_INSERT_RLE); + menu_ctl->add_item(RTR("Start of Left-to-Right Override (LRO)"), MENU_INSERT_LRO); + menu_ctl->add_item(RTR("Start of Right-to-Left Override (RLO)"), MENU_INSERT_RLO); + menu_ctl->add_item(RTR("Pop Direction Formatting (PDF)"), MENU_INSERT_PDF); menu_ctl->add_separator(); - menu_ctl->add_item(RTR("Arabic letter mark (ALM)"), MENU_INSERT_ALM); - menu_ctl->add_item(RTR("Left-to-right isolate (LRI)"), MENU_INSERT_LRI); - menu_ctl->add_item(RTR("Right-to-left isolate (RLI)"), MENU_INSERT_RLI); - menu_ctl->add_item(RTR("First strong isolate (FSI)"), MENU_INSERT_FSI); - menu_ctl->add_item(RTR("Pop direction isolate (PDI)"), MENU_INSERT_PDI); + menu_ctl->add_item(RTR("Arabic Letter Mark (ALM)"), MENU_INSERT_ALM); + menu_ctl->add_item(RTR("Left-to-Right Isolate (LRI)"), MENU_INSERT_LRI); + menu_ctl->add_item(RTR("Right-to-Left Isolate (RLI)"), MENU_INSERT_RLI); + menu_ctl->add_item(RTR("First Strong Isolate (FSI)"), MENU_INSERT_FSI); + menu_ctl->add_item(RTR("Pop Direction Isolate (PDI)"), MENU_INSERT_PDI); menu_ctl->add_separator(); - menu_ctl->add_item(RTR("Zero width joiner (ZWJ)"), MENU_INSERT_ZWJ); - menu_ctl->add_item(RTR("Zero width non-joiner (ZWNJ)"), MENU_INSERT_ZWNJ); - menu_ctl->add_item(RTR("Word joiner (WJ)"), MENU_INSERT_WJ); - menu_ctl->add_item(RTR("Soft hyphen (SHY)"), MENU_INSERT_SHY); + menu_ctl->add_item(RTR("Zero-Width Joiner (ZWJ)"), MENU_INSERT_ZWJ); + menu_ctl->add_item(RTR("Zero-Width Non-Joiner (ZWNJ)"), MENU_INSERT_ZWNJ); + menu_ctl->add_item(RTR("Word Joiner (WJ)"), MENU_INSERT_WJ); + menu_ctl->add_item(RTR("Soft Hyphen (SHY)"), MENU_INSERT_SHY); menu->add_child(menu_ctl, false, INTERNAL_MODE_FRONT); menu->connect("id_pressed", callable_mp(this, &TextEdit::menu_option)); @@ -5203,12 +5246,12 @@ void TextEdit::_generate_context_menu() { menu->add_item(RTR("Redo"), MENU_REDO, is_shortcut_keys_enabled() ? _get_menu_action_accelerator("ui_redo") : 0); } menu->add_separator(); - menu->add_submenu_item(RTR("Text writing direction"), "DirMenu"); + menu->add_submenu_item(RTR("Text Writing Direction"), "DirMenu"); menu->add_separator(); - menu->add_check_item(RTR("Display control characters"), MENU_DISPLAY_UCC); + menu->add_check_item(RTR("Display Control Characters"), MENU_DISPLAY_UCC); menu->set_item_checked(menu->get_item_index(MENU_DISPLAY_UCC), draw_control_chars); if (editable) { - menu->add_submenu_item(RTR("Insert control character"), "CTLMenu"); + menu->add_submenu_item(RTR("Insert Control Character"), "CTLMenu"); } menu_dir->set_item_checked(menu_dir->get_item_index(MENU_DIR_INHERITED), text_direction == TEXT_DIRECTION_INHERITED); menu_dir->set_item_checked(menu_dir->get_item_index(MENU_DIR_AUTO), text_direction == TEXT_DIRECTION_AUTO); @@ -5477,6 +5520,8 @@ void TextEdit::_update_selection_mode_word() { } } + DisplayServer::get_singleton()->clipboard_set_primary(get_selected_text()); + update(); click_select_held->start(); @@ -5504,6 +5549,8 @@ void TextEdit::_update_selection_mode_line() { set_caret_column(0); select(selection.selecting_line, selection.selecting_column, line, col); + DisplayServer::get_singleton()->clipboard_set_primary(get_selected_text()); + update(); click_select_held->start(); diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h index 16c1ee9ff9..8823e44c0d 100644 --- a/scene/gui/text_edit.h +++ b/scene/gui/text_edit.h @@ -269,6 +269,7 @@ private: bool context_menu_enabled = true; bool shortcut_keys_enabled = true; bool virtual_keyboard_enabled = true; + bool middle_mouse_paste_enabled = true; // Overridable actions String cut_copy_line = ""; @@ -586,12 +587,14 @@ protected: virtual void _cut_internal(); virtual void _copy_internal(); virtual void _paste_internal(); + virtual void _paste_primary_clipboard_internal(); GDVIRTUAL1(_handle_unicode_input, int) GDVIRTUAL0(_backspace) GDVIRTUAL0(_cut) GDVIRTUAL0(_copy) GDVIRTUAL0(_paste) + GDVIRTUAL0(_paste_primary_clipboard) public: /* General overrides. */ @@ -640,6 +643,9 @@ public: void set_virtual_keyboard_enabled(bool p_enabled); bool is_virtual_keyboard_enabled() const; + void set_middle_mouse_paste_enabled(bool p_enabled); + bool is_middle_mouse_paste_enabled() const; + // Text manipulation void clear(); @@ -674,6 +680,7 @@ public: void cut(); void copy(); void paste(); + void paste_primary_clipboard(); // Context menu. PopupMenu *get_menu() const; diff --git a/scene/main/canvas_layer.cpp b/scene/main/canvas_layer.cpp index 4540e42b4c..26bff4494b 100644 --- a/scene/main/canvas_layer.cpp +++ b/scene/main/canvas_layer.cpp @@ -128,7 +128,7 @@ void CanvasLayer::_notification(int p_what) { } else { vp = Node::get_viewport(); } - ERR_FAIL_COND(!vp); + ERR_FAIL_NULL_MSG(vp, "Viewport is not initialized."); vp->_canvas_layer_add(this); viewport = vp->get_viewport_rid(); @@ -140,6 +140,8 @@ void CanvasLayer::_notification(int p_what) { } break; case NOTIFICATION_EXIT_TREE: { + ERR_FAIL_NULL_MSG(vp, "Viewport is not initialized."); + vp->_canvas_layer_remove(this); RenderingServer::get_singleton()->viewport_remove_canvas(viewport, canvas); viewport = RID(); @@ -160,6 +162,8 @@ Size2 CanvasLayer::get_viewport_size() const { return Size2(1, 1); } + ERR_FAIL_NULL_V_MSG(vp, Size2(1, 1), "Viewport is not initialized."); + Rect2 r = vp->get_visible_rect(); return r.size; } @@ -169,7 +173,7 @@ RID CanvasLayer::get_viewport() const { } void CanvasLayer::set_custom_viewport(Node *p_viewport) { - ERR_FAIL_NULL(p_viewport); + ERR_FAIL_NULL_MSG(p_viewport, "Cannot set viewport to nullptr."); if (is_inside_tree()) { vp->_canvas_layer_remove(this); RenderingServer::get_singleton()->viewport_remove_canvas(viewport, canvas); diff --git a/scene/main/scene_tree.h b/scene/main/scene_tree.h index 19331c1906..7a4f9f9c52 100644 --- a/scene/main/scene_tree.h +++ b/scene/main/scene_tree.h @@ -136,7 +136,6 @@ private: void _flush_ugc(); _FORCE_INLINE_ void _update_group_order(Group &g, bool p_use_priority = false); - void _update_listener(); Array _get_nodes_in_group(const StringName &p_group); @@ -265,9 +264,6 @@ public: void set_pause(bool p_enabled); bool is_paused() const; - void set_camera(const RID &p_camera); - RID get_camera() const; - #ifdef DEBUG_ENABLED void set_debug_collisions_hint(bool p_enabled); bool is_debugging_collisions_hint() const; diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 0e62e6e30a..3280190250 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -2192,7 +2192,10 @@ void Viewport::_drop_physics_mouseover(bool p_paused_only) { if (physics_object_over.is_valid()) { CollisionObject3D *co = Object::cast_to<CollisionObject3D>(ObjectDB::get_instance(physics_object_over)); if (co) { - if (!(p_paused_only && co->can_process())) { + if (!co->is_inside_tree()) { + physics_object_over = ObjectID(); + physics_object_capture = ObjectID(); + } else if (!(p_paused_only && co->can_process())) { co->_mouse_exit(); physics_object_over = ObjectID(); physics_object_capture = ObjectID(); @@ -2213,7 +2216,7 @@ void Viewport::_cleanup_mouseover_colliders(bool p_clean_all_frames, bool p_paus Object *o = ObjectDB::get_instance(E->key()); if (o) { CollisionObject2D *co = Object::cast_to<CollisionObject2D>(o); - if (co) { + if (co && co->is_inside_tree()) { if (p_clean_all_frames && p_paused_only && co->can_process()) { continue; } @@ -2239,7 +2242,7 @@ void Viewport::_cleanup_mouseover_colliders(bool p_clean_all_frames, bool p_paus Object *o = ObjectDB::get_instance(E->key().first); if (o) { CollisionObject2D *co = Object::cast_to<CollisionObject2D>(o); - if (co) { + if (co && co->is_inside_tree()) { if (p_clean_all_frames && p_paused_only && co->can_process()) { continue; } diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index 61c25ae9db..33e0e2cad7 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -115,8 +115,8 @@ #include "scene/gui/spin_box.h" #include "scene/gui/split_container.h" #include "scene/gui/subviewport_container.h" +#include "scene/gui/tab_bar.h" #include "scene/gui/tab_container.h" -#include "scene/gui/tabs.h" #include "scene/gui/text_edit.h" #include "scene/gui/texture_button.h" #include "scene/gui/texture_progress_bar.h" @@ -262,7 +262,7 @@ static Ref<ResourceFormatLoaderShader> resource_loader_shader; void register_scene_types() { SceneStringNames::create(); - OS::get_singleton()->yield(); //may take time to init + OS::get_singleton()->yield(); // may take time to init Node::init_node_hrcr(); @@ -287,7 +287,7 @@ void register_scene_types() { resource_loader_shader.instantiate(); ResourceLoader::add_resource_format_loader(resource_loader_shader, true); - OS::get_singleton()->yield(); //may take time to init + OS::get_singleton()->yield(); // may take time to init GDREGISTER_CLASS(Object); @@ -309,7 +309,7 @@ void register_scene_types() { GDREGISTER_CLASS(ButtonGroup); GDREGISTER_VIRTUAL_CLASS(BaseButton); - OS::get_singleton()->yield(); //may take time to init + OS::get_singleton()->yield(); // may take time to init GDREGISTER_CLASS(Control); GDREGISTER_CLASS(Button); @@ -330,7 +330,7 @@ void register_scene_types() { GDREGISTER_CLASS(Panel); GDREGISTER_VIRTUAL_CLASS(Range); - OS::get_singleton()->yield(); //may take time to init + OS::get_singleton()->yield(); // may take time to init GDREGISTER_CLASS(TextureRect); GDREGISTER_CLASS(ColorRect); @@ -338,7 +338,7 @@ void register_scene_types() { GDREGISTER_CLASS(ReferenceRect); GDREGISTER_CLASS(AspectRatioContainer); GDREGISTER_CLASS(TabContainer); - GDREGISTER_CLASS(Tabs); + GDREGISTER_CLASS(TabBar); GDREGISTER_VIRTUAL_CLASS(Separator); GDREGISTER_CLASS(HSeparator); GDREGISTER_CLASS(VSeparator); @@ -352,7 +352,7 @@ void register_scene_types() { GDREGISTER_CLASS(ScrollContainer); GDREGISTER_CLASS(PanelContainer); - OS::get_singleton()->yield(); //may take time to init + OS::get_singleton()->yield(); // may take time to init GDREGISTER_CLASS(TextureProgressBar); GDREGISTER_CLASS(ItemList); @@ -391,7 +391,7 @@ void register_scene_types() { GDREGISTER_CLASS(GraphNode); GDREGISTER_CLASS(GraphEdit); - OS::get_singleton()->yield(); //may take time to init + OS::get_singleton()->yield(); // may take time to init bool swap_cancel_ok = false; if (DisplayServer::get_singleton()) { @@ -431,9 +431,9 @@ void register_scene_types() { GDREGISTER_CLASS(AnimationNodeTimeSeek); GDREGISTER_CLASS(AnimationNodeTransition); - GDREGISTER_CLASS(ShaderGlobalsOverride); //can be used in any shader + GDREGISTER_CLASS(ShaderGlobalsOverride); // can be used in any shader - OS::get_singleton()->yield(); //may take time to init + OS::get_singleton()->yield(); // may take time to init /* REGISTER 3D */ @@ -486,9 +486,9 @@ void register_scene_types() { GDREGISTER_CLASS(Position3D); GDREGISTER_CLASS(RootMotionView); - ClassDB::set_class_enabled("RootMotionView", false); //disabled by default, enabled by editor + ClassDB::set_class_enabled("RootMotionView", false); // disabled by default, enabled by editor - OS::get_singleton()->yield(); //may take time to init + OS::get_singleton()->yield(); // may take time to init GDREGISTER_VIRTUAL_CLASS(CollisionObject3D); GDREGISTER_VIRTUAL_CLASS(PhysicsBody3D); @@ -533,7 +533,7 @@ void register_scene_types() { GDREGISTER_CLASS(NavigationAgent3D); GDREGISTER_CLASS(NavigationObstacle3D); - OS::get_singleton()->yield(); //may take time to init + OS::get_singleton()->yield(); // may take time to init #endif /* REGISTER SHADER */ @@ -673,7 +673,7 @@ void register_scene_types() { GDREGISTER_CLASS(OccluderPolygon2D); GDREGISTER_CLASS(BackBufferCopy); - OS::get_singleton()->yield(); //may take time to init + OS::get_singleton()->yield(); // may take time to init GDREGISTER_CLASS(Camera2D); GDREGISTER_CLASS(AudioListener2D); @@ -705,7 +705,7 @@ void register_scene_types() { GDREGISTER_CLASS(PhysicalBone2D); GDREGISTER_CLASS(SkeletonModification2DPhysicalBones); - OS::get_singleton()->yield(); //may take time to init + OS::get_singleton()->yield(); // may take time to init /* REGISTER RESOURCES */ @@ -746,7 +746,7 @@ void register_scene_types() { GDREGISTER_CLASS(MeshLibrary); - OS::get_singleton()->yield(); //may take time to init + OS::get_singleton()->yield(); // may take time to init GDREGISTER_VIRTUAL_CLASS(Shape3D); GDREGISTER_CLASS(SeparationRayShape3D); @@ -768,7 +768,7 @@ void register_scene_types() { ClassDB::register_class<SkeletonModification3DTwoBoneIK>(); ClassDB::register_class<SkeletonModification3DStackHolder>(); - OS::get_singleton()->yield(); //may take time to init + OS::get_singleton()->yield(); // may take time to init GDREGISTER_CLASS(VelocityTracker3D); #endif @@ -823,7 +823,7 @@ void register_scene_types() { GDREGISTER_CLASS(BitMap); GDREGISTER_CLASS(Gradient); - OS::get_singleton()->yield(); //may take time to init + OS::get_singleton()->yield(); // may take time to init GDREGISTER_CLASS(AudioStreamPlayer); GDREGISTER_CLASS(AudioStreamPlayer2D); @@ -833,7 +833,7 @@ void register_scene_types() { GDREGISTER_VIRTUAL_CLASS(VideoStream); GDREGISTER_CLASS(AudioStreamSample); - OS::get_singleton()->yield(); //may take time to init + OS::get_singleton()->yield(); // may take time to init GDREGISTER_VIRTUAL_CLASS(Shape2D); GDREGISTER_CLASS(WorldBoundaryShape2D); @@ -854,13 +854,13 @@ void register_scene_types() { GDREGISTER_CLASS(NavigationAgent2D); GDREGISTER_CLASS(NavigationObstacle2D); - OS::get_singleton()->yield(); //may take time to init + OS::get_singleton()->yield(); // may take time to init GDREGISTER_VIRTUAL_CLASS(SceneState); GDREGISTER_CLASS(PackedScene); GDREGISTER_CLASS(SceneTree); - GDREGISTER_VIRTUAL_CLASS(SceneTreeTimer); //sorry, you can't create it + GDREGISTER_VIRTUAL_CLASS(SceneTreeTimer); // sorry, you can't create it #ifndef DISABLE_DEPRECATED // Dropped in 4.0, near approximation. @@ -1008,7 +1008,7 @@ void register_scene_types() { #endif /* DISABLE_DEPRECATED */ - OS::get_singleton()->yield(); //may take time to init + OS::get_singleton()->yield(); // may take time to init for (int i = 0; i < 20; i++) { GLOBAL_DEF_BASIC(vformat("layer_names/2d_render/layer_%d", i + 1), ""); @@ -1086,7 +1086,7 @@ void unregister_scene_types() { ResourceLoader::remove_resource_format_loader(resource_loader_shader); resource_loader_shader.unref(); - //StandardMaterial3D is not initialised when 3D is disabled, so it shouldn't be cleaned up either + // StandardMaterial3D is not initialised when 3D is disabled, so it shouldn't be cleaned up either #ifndef _3D_DISABLED BaseMaterial3D::finish_shaders(); #endif // _3D_DISABLED diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp index 54bb7a82cf..9fdfd493c1 100644 --- a/scene/resources/default_theme/default_theme.cpp +++ b/scene/resources/default_theme/default_theme.cpp @@ -785,30 +785,30 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_constant("icon_separation", "TabContainer", 4 * scale); theme->set_constant("outline_size", "TabContainer", 0); - // Tabs - - theme->set_stylebox("tab_selected", "Tabs", sb_expand(make_stylebox(tab_current_png, 4, 3, 4, 1, 16, 3, 16, 2), 2, 2, 2, 2)); - theme->set_stylebox("tab_unselected", "Tabs", sb_expand(make_stylebox(tab_behind_png, 5, 4, 5, 1, 16, 5, 16, 2), 3, 3, 3, 3)); - theme->set_stylebox("tab_disabled", "Tabs", sb_expand(make_stylebox(tab_disabled_png, 5, 5, 5, 1, 16, 6, 16, 4), 3, 0, 3, 3)); - theme->set_stylebox("close_bg_pressed", "Tabs", make_stylebox(button_pressed_png, 4, 4, 4, 4)); - theme->set_stylebox("close_bg_highlight", "Tabs", make_stylebox(button_normal_png, 4, 4, 4, 4)); - - theme->set_icon("increment", "Tabs", make_icon(scroll_button_right_png)); - theme->set_icon("increment_highlight", "Tabs", make_icon(scroll_button_right_hl_png)); - theme->set_icon("decrement", "Tabs", make_icon(scroll_button_left_png)); - theme->set_icon("decrement_highlight", "Tabs", make_icon(scroll_button_left_hl_png)); - theme->set_icon("close", "Tabs", make_icon(tab_close_png)); - - theme->set_font("font", "Tabs", Ref<Font>()); - theme->set_font_size("font_size", "Tabs", -1); - - theme->set_color("font_selected_color", "Tabs", control_font_hover_color); - theme->set_color("font_unselected_color", "Tabs", control_font_low_color); - theme->set_color("font_disabled_color", "Tabs", control_font_disabled_color); - theme->set_color("font_outline_color", "Tabs", Color(1, 1, 1)); - - theme->set_constant("hseparation", "Tabs", 4 * scale); - theme->set_constant("outline_size", "Tabs", 0); + // TabBar + + theme->set_stylebox("tab_selected", "TabBar", sb_expand(make_stylebox(tab_current_png, 4, 3, 4, 1, 16, 3, 16, 2), 2, 2, 2, 2)); + theme->set_stylebox("tab_unselected", "TabBar", sb_expand(make_stylebox(tab_behind_png, 5, 4, 5, 1, 16, 5, 16, 2), 3, 3, 3, 3)); + theme->set_stylebox("tab_disabled", "TabBar", sb_expand(make_stylebox(tab_disabled_png, 5, 5, 5, 1, 16, 6, 16, 4), 3, 0, 3, 3)); + theme->set_stylebox("close_bg_pressed", "TabBar", make_stylebox(button_pressed_png, 4, 4, 4, 4)); + theme->set_stylebox("close_bg_highlight", "TabBar", make_stylebox(button_normal_png, 4, 4, 4, 4)); + + theme->set_icon("increment", "TabBar", make_icon(scroll_button_right_png)); + theme->set_icon("increment_highlight", "TabBar", make_icon(scroll_button_right_hl_png)); + theme->set_icon("decrement", "TabBar", make_icon(scroll_button_left_png)); + theme->set_icon("decrement_highlight", "TabBar", make_icon(scroll_button_left_hl_png)); + theme->set_icon("close", "TabBar", make_icon(tab_close_png)); + + theme->set_font("font", "TabBar", Ref<Font>()); + theme->set_font_size("font_size", "TabBar", -1); + + theme->set_color("font_selected_color", "TabBar", control_font_hover_color); + theme->set_color("font_unselected_color", "TabBar", control_font_low_color); + theme->set_color("font_disabled_color", "TabBar", control_font_disabled_color); + theme->set_color("font_outline_color", "TabBar", Color(1, 1, 1)); + + theme->set_constant("hseparation", "TabBar", 4 * scale); + theme->set_constant("outline_size", "TabBar", 0); // Separators diff --git a/scene/resources/mesh.h b/scene/resources/mesh.h index 8d5571d67c..a95b4d4a5e 100644 --- a/scene/resources/mesh.h +++ b/scene/resources/mesh.h @@ -278,7 +278,6 @@ public: int surface_get_array_index_len(int p_idx) const override; uint32_t surface_get_format(int p_idx) const override; PrimitiveType surface_get_primitive_type(int p_idx) const override; - bool surface_is_alpha_sorting_enabled(int p_idx) const; virtual void surface_set_material(int p_idx, const Ref<Material> &p_material) override; virtual Ref<Material> surface_get_material(int p_idx) const override; diff --git a/scene/resources/navigation_mesh.h b/scene/resources/navigation_mesh.h index 1cdf7a07ed..009239838f 100644 --- a/scene/resources/navigation_mesh.h +++ b/scene/resources/navigation_mesh.h @@ -85,7 +85,7 @@ protected: float cell_size = 0.3f; float cell_height = 0.2f; float agent_height = 2.0f; - float agent_radius = 0.6f; + float agent_radius = 1.0f; float agent_max_climb = 0.9f; float agent_max_slope = 45.0f; float region_min_size = 8.0f; diff --git a/scene/resources/shape_2d.h b/scene/resources/shape_2d.h index 14bdd60e4b..7c5d1344e8 100644 --- a/scene/resources/shape_2d.h +++ b/scene/resources/shape_2d.h @@ -64,7 +64,6 @@ public: static bool is_collision_outline_enabled(); - Shape2D(); ~Shape2D(); }; diff --git a/scene/resources/text_paragraph.cpp b/scene/resources/text_paragraph.cpp index b2e18e2451..fae1de94d3 100644 --- a/scene/resources/text_paragraph.cpp +++ b/scene/resources/text_paragraph.cpp @@ -84,7 +84,7 @@ void TextParagraph::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "width"), "set_width", "get_width"); - ClassDB::bind_method(D_METHOD("get_non_wraped_size"), &TextParagraph::get_non_wraped_size); + ClassDB::bind_method(D_METHOD("get_non_wrapped_size"), &TextParagraph::get_non_wrapped_size); ClassDB::bind_method(D_METHOD("get_size"), &TextParagraph::get_size); ClassDB::bind_method(D_METHOD("get_rid"), &TextParagraph::get_rid); @@ -417,7 +417,7 @@ float TextParagraph::get_width() const { return width; } -Size2 TextParagraph::get_non_wraped_size() const { +Size2 TextParagraph::get_non_wrapped_size() const { const_cast<TextParagraph *>(this)->_shape_lines(); if (TS->shaped_text_get_orientation(rid) == TextServer::ORIENTATION_HORIZONTAL) { return Size2(TS->shaped_text_get_size(rid).x, TS->shaped_text_get_size(rid).y + spacing_top + spacing_bottom); diff --git a/scene/resources/text_paragraph.h b/scene/resources/text_paragraph.h index 69c50559df..701c9a17cd 100644 --- a/scene/resources/text_paragraph.h +++ b/scene/resources/text_paragraph.h @@ -120,7 +120,7 @@ public: void set_max_lines_visible(int p_lines); int get_max_lines_visible() const; - Size2 get_non_wraped_size() const; + Size2 get_non_wrapped_size() const; Size2 get_size() const; diff --git a/servers/audio/effects/audio_effect_limiter.h b/servers/audio/effects/audio_effect_limiter.h index d5def670a4..398613aa44 100644 --- a/servers/audio/effects/audio_effect_limiter.h +++ b/servers/audio/effects/audio_effect_limiter.h @@ -72,8 +72,6 @@ public: float get_soft_clip_ratio() const; Ref<AudioEffectInstance> instantiate() override; - void set_volume_db(float p_volume); - float get_volume_db() const; AudioEffectLimiter(); }; diff --git a/servers/audio/effects/audio_effect_record.h b/servers/audio/effects/audio_effect_record.h index 1a89821f80..6e862b1377 100644 --- a/servers/audio/effects/audio_effect_record.h +++ b/servers/audio/effects/audio_effect_record.h @@ -93,7 +93,6 @@ class AudioEffectRecord : public AudioEffect { protected: static void _bind_methods(); - static void debug(uint64_t time_diff, int p_frame_count); public: Ref<AudioEffectInstance> instantiate() override; diff --git a/servers/audio/effects/audio_effect_reverb.h b/servers/audio/effects/audio_effect_reverb.h index d01d1120bd..eaa66352f6 100644 --- a/servers/audio/effects/audio_effect_reverb.h +++ b/servers/audio/effects/audio_effect_reverb.h @@ -90,8 +90,6 @@ public: float get_hpf() const; Ref<AudioEffectInstance> instantiate() override; - void set_volume_db(float p_volume); - float get_volume_db() const; AudioEffectReverb(); }; diff --git a/servers/display_server.cpp b/servers/display_server.cpp index 3897e5e7c2..a6101530c8 100644 --- a/servers/display_server.cpp +++ b/servers/display_server.cpp @@ -159,6 +159,14 @@ String DisplayServer::clipboard_get() const { ERR_FAIL_V_MSG(String(), "Clipboard is not supported by this display server."); } +void DisplayServer::clipboard_set_primary(const String &p_text) { + WARN_PRINT("Primary clipboard is not supported by this display server."); +} + +String DisplayServer::clipboard_get_primary() const { + ERR_FAIL_V_MSG(String(), "Primary clipboard is not supported by this display server."); +} + void DisplayServer::screen_set_orientation(ScreenOrientation p_orientation, int p_screen) { WARN_PRINT("Orientation not supported by this display server."); } @@ -360,6 +368,8 @@ void DisplayServer::_bind_methods() { ClassDB::bind_method(D_METHOD("clipboard_set", "clipboard"), &DisplayServer::clipboard_set); ClassDB::bind_method(D_METHOD("clipboard_get"), &DisplayServer::clipboard_get); + ClassDB::bind_method(D_METHOD("clipboard_set_primary", "clipboard_primary"), &DisplayServer::clipboard_set_primary); + ClassDB::bind_method(D_METHOD("clipboard_get_primary"), &DisplayServer::clipboard_get_primary); ClassDB::bind_method(D_METHOD("get_screen_count"), &DisplayServer::get_screen_count); ClassDB::bind_method(D_METHOD("screen_get_position", "screen"), &DisplayServer::screen_get_position, DEFVAL(SCREEN_OF_MAIN_WINDOW)); diff --git a/servers/display_server.h b/servers/display_server.h index f411a72aa3..8af7946a1e 100644 --- a/servers/display_server.h +++ b/servers/display_server.h @@ -161,6 +161,8 @@ public: virtual void clipboard_set(const String &p_text); virtual String clipboard_get() const; + virtual void clipboard_set_primary(const String &p_text); + virtual String clipboard_get_primary() const; enum { SCREEN_OF_MAIN_WINDOW = -1 diff --git a/servers/physics_2d/godot_body_2d.cpp b/servers/physics_2d/godot_body_2d.cpp index b0885a1f7b..a18c748e1d 100644 --- a/servers/physics_2d/godot_body_2d.cpp +++ b/servers/physics_2d/godot_body_2d.cpp @@ -119,6 +119,8 @@ void GodotBody2D::update_mass_properties() { } break; } + + _update_transform_dependent(); } void GodotBody2D::reset_mass_properties() { @@ -179,7 +181,8 @@ void GodotBody2D::set_param(PhysicsServer2D::BodyParameter p_param, const Varian } break; case PhysicsServer2D::BODY_PARAM_CENTER_OF_MASS: { calculate_center_of_mass = false; - center_of_mass = p_value; + center_of_mass_local = p_value; + _update_transform_dependent(); } break; case PhysicsServer2D::BODY_PARAM_GRAVITY_SCALE: { gravity_scale = p_value; @@ -273,6 +276,7 @@ PhysicsServer2D::BodyMode GodotBody2D::get_mode() const { void GodotBody2D::_shapes_changed() { _mass_properties_changed(); + wakeup(); wakeup_neighbours(); } @@ -301,6 +305,7 @@ void GodotBody2D::set_state(PhysicsServer2D::BodyState p_state, const Variant &p } _set_transform(t); _set_inv_transform(get_transform().inverse()); + _update_transform_dependent(); } wakeup(); @@ -400,6 +405,10 @@ void GodotBody2D::_compute_area_gravity_and_damping(const GodotArea2D *p_area) { area_angular_damp += p_area->get_angular_damp(); } +void GodotBody2D::_update_transform_dependent() { + center_of_mass = get_transform().basis_xform(center_of_mass_local); +} + void GodotBody2D::integrate_forces(real_t p_step) { if (mode == PhysicsServer2D::BODY_MODE_STATIC) { return; @@ -568,6 +577,8 @@ void GodotBody2D::integrate_velocities(real_t p_step) { if (continuous_cd_mode != PhysicsServer2D::CCD_MODE_DISABLED) { new_transform = get_transform(); } + + _update_transform_dependent(); } void GodotBody2D::wakeup_neighbours() { diff --git a/servers/physics_2d/godot_body_2d.h b/servers/physics_2d/godot_body_2d.h index c4f3578f1b..5fce362fa7 100644 --- a/servers/physics_2d/godot_body_2d.h +++ b/servers/physics_2d/godot_body_2d.h @@ -66,6 +66,7 @@ class GodotBody2D : public GodotCollisionObject2D { real_t inertia = 0.0; real_t _inv_inertia = 0.0; + Vector2 center_of_mass_local; Vector2 center_of_mass; bool calculate_inertia = true; @@ -139,7 +140,9 @@ class GodotBody2D : public GodotCollisionObject2D { uint64_t island_step = 0; - _FORCE_INLINE_ void _compute_area_gravity_and_damping(const GodotArea2D *p_area); + void _compute_area_gravity_and_damping(const GodotArea2D *p_area); + + void _update_transform_dependent(); friend class GodotPhysicsDirectBodyState2D; // i give up, too many functions to expose diff --git a/servers/physics_3d/godot_body_3d.cpp b/servers/physics_3d/godot_body_3d.cpp index 6df6a0c45b..02929eeaed 100644 --- a/servers/physics_3d/godot_body_3d.cpp +++ b/servers/physics_3d/godot_body_3d.cpp @@ -40,7 +40,7 @@ void GodotBody3D::_mass_properties_changed() { } } -void GodotBody3D::_update_transform_dependant() { +void GodotBody3D::_update_transform_dependent() { center_of_mass = get_transform().basis.xform(center_of_mass_local); principal_inertia_axes = get_transform().basis * principal_inertia_axes_local; @@ -161,7 +161,7 @@ void GodotBody3D::update_mass_properties() { } break; } - _update_transform_dependant(); + _update_transform_dependent(); } void GodotBody3D::reset_mass_properties() { @@ -217,14 +217,14 @@ void GodotBody3D::set_param(PhysicsServer3D::BodyParameter p_param, const Varian if (mode == PhysicsServer3D::BODY_MODE_DYNAMIC) { principal_inertia_axes_local = Basis(); _inv_inertia = inertia.inverse(); - _update_transform_dependant(); + _update_transform_dependent(); } } } break; case PhysicsServer3D::BODY_PARAM_CENTER_OF_MASS: { calculate_center_of_mass = false; center_of_mass_local = p_value; - _update_transform_dependant(); + _update_transform_dependent(); } break; case PhysicsServer3D::BODY_PARAM_GRAVITY_SCALE: { gravity_scale = p_value; @@ -295,7 +295,7 @@ void GodotBody3D::set_mode(PhysicsServer3D::BodyMode p_mode) { if (mode == PhysicsServer3D::BODY_MODE_KINEMATIC && prev != mode) { first_time_kinematic = true; } - _update_transform_dependant(); + _update_transform_dependent(); } break; case PhysicsServer3D::BODY_MODE_DYNAMIC: { @@ -303,7 +303,7 @@ void GodotBody3D::set_mode(PhysicsServer3D::BodyMode p_mode) { if (!calculate_inertia) { principal_inertia_axes_local = Basis(); _inv_inertia = inertia.inverse(); - _update_transform_dependant(); + _update_transform_dependent(); } _mass_properties_changed(); _set_static(false); @@ -314,7 +314,7 @@ void GodotBody3D::set_mode(PhysicsServer3D::BodyMode p_mode) { _inv_mass = mass > 0 ? (1.0 / mass) : 0; _inv_inertia = Vector3(); angular_velocity = Vector3(); - _update_transform_dependant(); + _update_transform_dependent(); _set_static(false); set_active(true); } @@ -327,6 +327,8 @@ PhysicsServer3D::BodyMode GodotBody3D::get_mode() const { void GodotBody3D::_shapes_changed() { _mass_properties_changed(); + wakeup(); + wakeup_neighbours(); } void GodotBody3D::set_state(PhysicsServer3D::BodyState p_state, const Variant &p_variant) { @@ -355,6 +357,7 @@ void GodotBody3D::set_state(PhysicsServer3D::BodyState p_state, const Variant &p } _set_transform(t); _set_inv_transform(get_transform().inverse()); + _update_transform_dependent(); } wakeup(); @@ -651,7 +654,7 @@ void GodotBody3D::integrate_velocities(real_t p_step) { _set_transform(transform); _set_inv_transform(get_transform().inverse()); - _update_transform_dependant(); + _update_transform_dependent(); } void GodotBody3D::wakeup_neighbours() { diff --git a/servers/physics_3d/godot_body_3d.h b/servers/physics_3d/godot_body_3d.h index 1151a22c96..5acdab9d13 100644 --- a/servers/physics_3d/godot_body_3d.h +++ b/servers/physics_3d/godot_body_3d.h @@ -135,9 +135,9 @@ class GodotBody3D : public GodotCollisionObject3D { uint64_t island_step = 0; - _FORCE_INLINE_ void _compute_area_gravity_and_damping(const GodotArea3D *p_area); + void _compute_area_gravity_and_damping(const GodotArea3D *p_area); - _FORCE_INLINE_ void _update_transform_dependant(); + void _update_transform_dependent(); friend class GodotPhysicsDirectBodyState3D; // i give up, too many functions to expose diff --git a/servers/physics_3d/godot_physics_server_3d.cpp b/servers/physics_3d/godot_physics_server_3d.cpp index 34b56e733e..79a2e0b0ea 100644 --- a/servers/physics_3d/godot_physics_server_3d.cpp +++ b/servers/physics_3d/godot_physics_server_3d.cpp @@ -584,7 +584,6 @@ void GodotPhysicsServer3D::body_set_collision_layer(RID p_body, uint32_t p_layer ERR_FAIL_COND(!body); body->set_collision_layer(p_layer); - body->wakeup(); } uint32_t GodotPhysicsServer3D::body_get_collision_layer(RID p_body) const { @@ -599,7 +598,6 @@ void GodotPhysicsServer3D::body_set_collision_mask(RID p_body, uint32_t p_mask) ERR_FAIL_COND(!body); body->set_collision_mask(p_mask); - body->wakeup(); } uint32_t GodotPhysicsServer3D::body_get_collision_mask(RID p_body) const { diff --git a/servers/physics_3d/godot_soft_body_3d.cpp b/servers/physics_3d/godot_soft_body_3d.cpp index d15235d27c..f214e3603a 100644 --- a/servers/physics_3d/godot_soft_body_3d.cpp +++ b/servers/physics_3d/godot_soft_body_3d.cpp @@ -139,6 +139,7 @@ void GodotSoftBody3D::set_mesh(RID p_mesh) { } Array arrays = RenderingServer::get_singleton()->mesh_surface_get_arrays(soft_mesh, 0); + ERR_FAIL_COND(arrays.is_empty()); bool success = create_from_trimesh(arrays[RenderingServer::ARRAY_INDEX], arrays[RenderingServer::ARRAY_VERTEX]); if (!success) { diff --git a/servers/physics_server_2d_wrap_mt.h b/servers/physics_server_2d_wrap_mt.h index 927ef5d57c..4a2f07ab1e 100644 --- a/servers/physics_server_2d_wrap_mt.h +++ b/servers/physics_server_2d_wrap_mt.h @@ -59,9 +59,7 @@ class PhysicsServer2DWrapMT : public PhysicsServer2D { bool create_thread = false; Semaphore step_sem; - int step_pending = 0; void thread_step(real_t p_delta); - void thread_flush(); void thread_exit(); diff --git a/servers/physics_server_3d_wrap_mt.h b/servers/physics_server_3d_wrap_mt.h index bf936fd0fc..4c88ef2642 100644 --- a/servers/physics_server_3d_wrap_mt.h +++ b/servers/physics_server_3d_wrap_mt.h @@ -58,9 +58,7 @@ class PhysicsServer3DWrapMT : public PhysicsServer3D { bool create_thread = false; Semaphore step_sem; - int step_pending = 0; void thread_step(real_t p_delta); - void thread_flush(); void thread_exit(); diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp index 6b84ab908d..0deb822e86 100644 --- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp +++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp @@ -328,6 +328,8 @@ void RenderForwardClustered::_render_list_template(RenderingDevice::DrawListID p push_constant.uv_offset = 0; } + bool should_request_redraw = false; + for (uint32_t i = p_from_element; i < p_to_element; i++) { const GeometryInstanceSurfaceDataCache *surf = p_params->elements[i]; const RenderElementInfo &element_info = p_params->element_info[i]; @@ -365,6 +367,11 @@ void RenderForwardClustered::_render_list_template(RenderingDevice::DrawListID p continue; } + //request a redraw if one of the shaders uses TIME + if (shader->uses_time) { + should_request_redraw = true; + } + //find cull variant SceneShaderForwardClustered::ShaderData::CullVariant cull_variant; @@ -500,6 +507,11 @@ void RenderForwardClustered::_render_list_template(RenderingDevice::DrawListID p RD::get_singleton()->draw_list_draw(draw_list, index_array_rd.is_valid(), instance_count); i += element_info.repeat - 1; //skip equal elements } + + // Make the actual redraw request + if (should_request_redraw) { + RenderingServerDefault::redraw_request(); + } } void RenderForwardClustered::_render_list(RenderingDevice::DrawListID p_draw_list, RenderingDevice::FramebufferFormatID p_framebuffer_Format, RenderListParameters *p_params, uint32_t p_from_element, uint32_t p_to_element) { diff --git a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp index a1c3481ed6..d05cfdc386 100644 --- a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp +++ b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp @@ -657,6 +657,10 @@ void SceneShaderForwardClustered::init(RendererStorageRD *p_storage, const Strin actions.render_mode_defines["specular_schlick_ggx"] = "#define SPECULAR_BLINN\n"; } + actions.custom_samplers["SCREEN_TEXTURE"] = "material_samplers[3]"; // linear filter with mipmaps + actions.custom_samplers["DEPTH_TEXTURE"] = "material_samplers[3]"; + actions.custom_samplers["NORMAL_ROUGHNESS_TEXTURE"] = "material_samplers[1]"; // linear filter + actions.render_mode_defines["specular_blinn"] = "#define SPECULAR_BLINN\n"; actions.render_mode_defines["specular_phong"] = "#define SPECULAR_PHONG\n"; actions.render_mode_defines["specular_toon"] = "#define SPECULAR_TOON\n"; diff --git a/servers/rendering/renderer_rd/renderer_storage_rd.cpp b/servers/rendering/renderer_rd/renderer_storage_rd.cpp index a7bfea455d..3e68a2b622 100644 --- a/servers/rendering/renderer_rd/renderer_storage_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_storage_rd.cpp @@ -2672,9 +2672,11 @@ void RendererStorageRD::MaterialData::update_textures(const Map<StringName, Vari if (uniform_array_size > 0) { if (textures.size() < uniform_array_size) { const Map<StringName, RID>::Element *W = p_default_textures.find(uniform_name); - if (W) { - for (int j = textures.size(); j < uniform_array_size; j++) { + for (int j = textures.size(); j < uniform_array_size; j++) { + if (W) { textures.push_back(W->get()); + } else { + textures.push_back(RID()); } } } diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp index 9c38bf7606..53f2d96f52 100644 --- a/servers/rendering/shader_language.cpp +++ b/servers/rendering/shader_language.cpp @@ -2763,6 +2763,7 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const FunctionI bool is_const = false; ConstantNode::Value value; + value.sint = -1; _find_identifier(p_block, false, p_function_info, vn->name, nullptr, nullptr, &is_const, nullptr, nullptr, &value); if (!is_const || value.sint < min || value.sint > max) { diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp index 21f81af725..039dbc71e3 100644 --- a/servers/rendering_server.cpp +++ b/servers/rendering_server.cpp @@ -2811,6 +2811,12 @@ RenderingServer::RenderingServer() { PropertyInfo(Variant::INT, "rendering/vulkan/rendering/back_end", PROPERTY_HINT_ENUM, "Forward Clustered (Supports Desktop Only),Forward Mobile (Supports Desktop and Mobile)")); + // Already defined in RenderingDeviceVulkan::initialize which runs before this code. + // We re-define them here just for doctool's sake. Make sure to keep default values in sync. + GLOBAL_DEF("rendering/vulkan/staging_buffer/block_size_kb", 256); + GLOBAL_DEF("rendering/vulkan/staging_buffer/max_size_mb", 128); + GLOBAL_DEF("rendering/vulkan/staging_buffer/texture_upload_region_size_px", 64); + GLOBAL_DEF("rendering/vulkan/descriptor_pools/max_descriptors_per_pool", 64); GLOBAL_DEF("rendering/3d/viewport/scale", 1.0); ProjectSettings::get_singleton()->set_custom_property_info("rendering/3d/viewport/scale", diff --git a/servers/xr/xr_interface_extension.cpp b/servers/xr/xr_interface_extension.cpp index 341ba32245..80576ac607 100644 --- a/servers/xr/xr_interface_extension.cpp +++ b/servers/xr/xr_interface_extension.cpp @@ -41,8 +41,6 @@ void XRInterfaceExtension::_bind_methods() { GDVIRTUAL_BIND(_initialize); GDVIRTUAL_BIND(_uninitialize); - GDVIRTUAL_BIND(_get_tracking_status); - GDVIRTUAL_BIND(_supports_play_area_mode, "mode"); GDVIRTUAL_BIND(_get_play_area_mode); GDVIRTUAL_BIND(_set_play_area_mode, "mode"); |