summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/classes/EditorInterface.xml38
-rw-r--r--doc/classes/EditorPlugin.xml2
-rw-r--r--doc/classes/EditorSettings.xml2
-rw-r--r--drivers/alsa/audio_driver_alsa.cpp12
-rw-r--r--drivers/pulseaudio/audio_driver_pulseaudio.cpp12
-rw-r--r--drivers/wasapi/audio_driver_wasapi.cpp7
-rw-r--r--editor/editor_interface.cpp437
-rw-r--r--editor/editor_interface.h143
-rw-r--r--editor/editor_node.cpp6
-rw-r--r--editor/editor_node.h2
-rw-r--r--editor/editor_paths.cpp4
-rw-r--r--editor/editor_plugin.cpp360
-rw-r--r--editor/editor_plugin.h83
-rw-r--r--editor/editor_properties_array_dict.cpp3
-rw-r--r--editor/editor_run_script.cpp1
-rw-r--r--editor/editor_run_script.h4
-rw-r--r--editor/gui/scene_tree_editor.h3
-rw-r--r--editor/import/resource_importer_imagefont.cpp2
-rw-r--r--editor/plugins/canvas_item_editor_plugin.h1
-rw-r--r--editor/plugins/control_editor_plugin.h1
-rw-r--r--editor/plugins/curve_editor_plugin.cpp3
-rw-r--r--editor/plugins/gpu_particles_collision_sdf_editor_plugin.cpp3
-rw-r--r--editor/plugins/mesh_library_editor_plugin.cpp1
-rw-r--r--editor/plugins/node_3d_editor_plugin.h1
-rw-r--r--editor/plugins/resource_preloader_editor_plugin.cpp1
-rw-r--r--editor/plugins/tiles/tiles_editor_plugin.cpp3
-rw-r--r--editor/plugins/voxel_gi_editor_plugin.cpp3
-rw-r--r--editor/register_editor_types.cpp5
-rw-r--r--editor/scene_tree_dock.h3
-rw-r--r--modules/multiplayer/editor/multiplayer_editor_plugin.cpp3
-rw-r--r--platform/linuxbsd/freedesktop_portal_desktop.cpp11
-rw-r--r--platform/linuxbsd/freedesktop_screensaver.cpp11
-rw-r--r--platform/linuxbsd/joypad_linux.cpp8
-rw-r--r--platform/linuxbsd/os_linuxbsd.cpp10
-rw-r--r--platform/linuxbsd/tts_linux.cpp5
-rw-r--r--platform/linuxbsd/x11/display_server_x11.cpp99
-rw-r--r--platform/linuxbsd/x11/display_server_x11.h3
-rw-r--r--platform/windows/crash_handler_windows.cpp3
-rw-r--r--platform/windows/detect.py6
-rw-r--r--platform/windows/display_server_windows.cpp1
-rw-r--r--platform/windows/os_windows.cpp107
-rw-r--r--platform/windows/tts_windows.cpp3
-rw-r--r--scene/2d/physics_body_2d.cpp2
-rw-r--r--scene/3d/physics_body_3d.cpp4
44 files changed, 908 insertions, 514 deletions
diff --git a/doc/classes/EditorInterface.xml b/doc/classes/EditorInterface.xml
index 48939db1f7..74825493a1 100644
--- a/doc/classes/EditorInterface.xml
+++ b/doc/classes/EditorInterface.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="EditorInterface" inherits="Node" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
+<class name="EditorInterface" inherits="Object" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
Godot editor's interface.
</brief_description>
@@ -34,7 +34,7 @@
Edits the given [Script]. The line and column on which to open the script can also be specified. The script will be open with the user-configured editor for the script's language which may be an external editor.
</description>
</method>
- <method name="get_base_control">
+ <method name="get_base_control" qualifiers="const">
<return type="Control" />
<description>
Returns the main container of Godot editor's window. For example, you can use it to retrieve the size of the container and place your controls accordingly.
@@ -60,20 +60,20 @@
Returns the current path being viewed in the [FileSystemDock].
</description>
</method>
- <method name="get_edited_scene_root">
+ <method name="get_edited_scene_root" qualifiers="const">
<return type="Node" />
<description>
Returns the edited (current) scene's root [Node].
</description>
</method>
- <method name="get_editor_main_screen">
+ <method name="get_editor_main_screen" qualifiers="const">
<return type="VBoxContainer" />
<description>
Returns the editor control responsible for main screen plugins and tools. Use it with plugins that implement [method EditorPlugin._has_main_screen].
[b]Warning:[/b] Removing and freeing this node will render a part of the editor useless and may cause a crash.
</description>
</method>
- <method name="get_editor_paths">
+ <method name="get_editor_paths" qualifiers="const">
<return type="EditorPaths" />
<description>
Returns the [EditorPaths] singleton.
@@ -86,13 +86,13 @@
[b]Note:[/b] This value is set via the [code]interface/editor/display_scale[/code] and [code]interface/editor/custom_display_scale[/code] editor settings. Editor must be restarted for changes to be properly applied.
</description>
</method>
- <method name="get_editor_settings">
+ <method name="get_editor_settings" qualifiers="const">
<return type="EditorSettings" />
<description>
Returns the editor's [EditorSettings] instance.
</description>
</method>
- <method name="get_file_system_dock">
+ <method name="get_file_system_dock" qualifiers="const">
<return type="FileSystemDock" />
<description>
Returns the editor's [FileSystemDock] instance.
@@ -118,19 +118,19 @@
Returns the name of the scene that is being played. If no scene is currently being played, returns an empty string.
</description>
</method>
- <method name="get_resource_filesystem">
+ <method name="get_resource_filesystem" qualifiers="const">
<return type="EditorFileSystem" />
<description>
Returns the editor's [EditorFileSystem] instance.
</description>
</method>
- <method name="get_resource_previewer">
+ <method name="get_resource_previewer" qualifiers="const">
<return type="EditorResourcePreview" />
<description>
Returns the editor's [EditorResourcePreview] instance.
</description>
</method>
- <method name="get_script_editor">
+ <method name="get_script_editor" qualifiers="const">
<return type="ScriptEditor" />
<description>
Returns the editor's [ScriptEditor] instance.
@@ -143,7 +143,7 @@
Returns an array containing the paths of the currently selected files (and directories) in the [FileSystemDock].
</description>
</method>
- <method name="get_selection">
+ <method name="get_selection" qualifiers="const">
<return type="EditorSelection" />
<description>
Returns the editor's [EditorSelection] instance.
@@ -158,12 +158,6 @@
Shows the given property on the given [param object] in the editor's Inspector dock. If [param inspector_only] is [code]true[/code], plugins will not attempt to edit [param object].
</description>
</method>
- <method name="is_movie_maker_enabled" qualifiers="const">
- <return type="bool" />
- <description>
- Returns [code]true[/code] if Movie Maker mode is enabled in the editor. See also [method set_movie_maker_enabled]. See [MovieWriter] for more information.
- </description>
- </method>
<method name="is_playing_scene" qualifiers="const">
<return type="bool" />
<description>
@@ -253,13 +247,6 @@
Sets the editor's current main screen to the one specified in [param name]. [param name] must match the text of the tab in question exactly ([code]2D[/code], [code]3D[/code], [code]Script[/code], [code]AssetLib[/code]).
</description>
</method>
- <method name="set_movie_maker_enabled">
- <return type="void" />
- <param index="0" name="enabled" type="bool" />
- <description>
- Sets whether Movie Maker mode is enabled in the editor. See also [method is_movie_maker_enabled]. See [MovieWriter] for more information.
- </description>
- </method>
<method name="set_plugin_enabled">
<return type="void" />
<param index="0" name="plugin" type="String" />
@@ -279,5 +266,8 @@
<member name="distraction_free_mode" type="bool" setter="set_distraction_free_mode" getter="is_distraction_free_mode_enabled">
If [code]true[/code], enables distraction-free mode which hides side docks to increase the space available for the main view.
</member>
+ <member name="movie_maker_enabled" type="bool" setter="set_movie_maker_enabled" getter="is_movie_maker_enabled">
+ If [code]true[/code], the Movie Maker mode is enabled in the editor. See [MovieWriter] for more information.
+ </member>
</members>
</class>
diff --git a/doc/classes/EditorPlugin.xml b/doc/classes/EditorPlugin.xml
index a8ee5cdc19..1f3f028bbe 100644
--- a/doc/classes/EditorPlugin.xml
+++ b/doc/classes/EditorPlugin.xml
@@ -532,7 +532,7 @@
<method name="get_editor_interface">
<return type="EditorInterface" />
<description>
- Returns the [EditorInterface] object that gives you control over Godot editor's window and its functionalities.
+ Returns the [EditorInterface] singleton. It provides access to some parts of the editor GUI as well as various inner states and tools.
</description>
</method>
<method name="get_export_as_menu">
diff --git a/doc/classes/EditorSettings.xml b/doc/classes/EditorSettings.xml
index 996af71c3b..85d5f7dd55 100644
--- a/doc/classes/EditorSettings.xml
+++ b/doc/classes/EditorSettings.xml
@@ -9,7 +9,7 @@
Accessing the settings can be done using the following methods, such as:
[codeblocks]
[gdscript]
- var settings = EditorInterface.get_editor_settings()
+ var settings = get_editor_interface().get_editor_settings()
# `settings.set("some/property", 10)` also works as this class overrides `_set()` internally.
settings.set_setting("some/property", 10)
# `settings.get("some/property")` also works as this class overrides `_get()` internally.
diff --git a/drivers/alsa/audio_driver_alsa.cpp b/drivers/alsa/audio_driver_alsa.cpp
index 689f76389b..6095fef035 100644
--- a/drivers/alsa/audio_driver_alsa.cpp
+++ b/drivers/alsa/audio_driver_alsa.cpp
@@ -169,6 +169,18 @@ Error AudioDriverALSA::init() {
return ERR_CANT_OPEN;
}
#endif
+ bool ver_ok = false;
+ String version = String::utf8(snd_asoundlib_version());
+ Vector<String> ver_parts = version.split(".");
+ if (ver_parts.size() >= 2) {
+ ver_ok = ((ver_parts[0].to_int() == 1 && ver_parts[1].to_int() >= 1)) || (ver_parts[0].to_int() > 1); // 1.1.0
+ }
+ print_verbose(vformat("ALSA %s detected.", version));
+ if (!ver_ok) {
+ print_verbose("Unsupported ALSA library version!");
+ return ERR_CANT_OPEN;
+ }
+
active.clear();
exit_thread.clear();
diff --git a/drivers/pulseaudio/audio_driver_pulseaudio.cpp b/drivers/pulseaudio/audio_driver_pulseaudio.cpp
index 797ffd67fe..9ae74a8906 100644
--- a/drivers/pulseaudio/audio_driver_pulseaudio.cpp
+++ b/drivers/pulseaudio/audio_driver_pulseaudio.cpp
@@ -290,6 +290,18 @@ Error AudioDriverPulseAudio::init() {
return ERR_CANT_OPEN;
}
#endif
+ bool ver_ok = false;
+ String version = String::utf8(pa_get_library_version());
+ Vector<String> ver_parts = version.split(".");
+ if (ver_parts.size() >= 2) {
+ ver_ok = (ver_parts[0].to_int() >= 8); // 8.0.0
+ }
+ print_verbose(vformat("PulseAudio %s detected.", version));
+ if (!ver_ok) {
+ print_verbose("Unsupported PulseAudio library version!");
+ return ERR_CANT_OPEN;
+ }
+
active.clear();
exit_thread.clear();
diff --git a/drivers/wasapi/audio_driver_wasapi.cpp b/drivers/wasapi/audio_driver_wasapi.cpp
index 72ec0c19ab..805528b8c7 100644
--- a/drivers/wasapi/audio_driver_wasapi.cpp
+++ b/drivers/wasapi/audio_driver_wasapi.cpp
@@ -206,8 +206,6 @@ Error AudioDriverWASAPI::audio_device_init(AudioDeviceWASAPI *p_device, bool p_i
IMMDeviceEnumerator *enumerator = nullptr;
IMMDevice *output_device = nullptr;
- CoInitialize(nullptr);
-
HRESULT hr = CoCreateInstance(CLSID_MMDeviceEnumerator, nullptr, CLSCTX_ALL, IID_IMMDeviceEnumerator, (void **)&enumerator);
ERR_FAIL_COND_V(hr != S_OK, ERR_CANT_OPEN);
@@ -582,8 +580,6 @@ PackedStringArray AudioDriverWASAPI::audio_device_get_list(bool p_input) {
list.push_back(String("Default"));
- CoInitialize(nullptr);
-
HRESULT hr = CoCreateInstance(CLSID_MMDeviceEnumerator, nullptr, CLSCTX_ALL, IID_IMMDeviceEnumerator, (void **)&enumerator);
ERR_FAIL_COND_V(hr != S_OK, PackedStringArray());
@@ -702,6 +698,8 @@ void AudioDriverWASAPI::write_sample(WORD format_tag, int bits_per_sample, BYTE
}
void AudioDriverWASAPI::thread_func(void *p_udata) {
+ CoInitializeEx(nullptr, COINIT_MULTITHREADED);
+
AudioDriverWASAPI *ad = static_cast<AudioDriverWASAPI *>(p_udata);
uint32_t avail_frames = 0;
uint32_t write_ofs = 0;
@@ -908,6 +906,7 @@ void AudioDriverWASAPI::thread_func(void *p_udata) {
OS::get_singleton()->delay_usec(1000);
}
}
+ CoUninitialize();
}
void AudioDriverWASAPI::start() {
diff --git a/editor/editor_interface.cpp b/editor/editor_interface.cpp
new file mode 100644
index 0000000000..99803fd82d
--- /dev/null
+++ b/editor/editor_interface.cpp
@@ -0,0 +1,437 @@
+/**************************************************************************/
+/* editor_interface.cpp */
+/**************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/**************************************************************************/
+/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/**************************************************************************/
+
+#include "editor_interface.h"
+
+#include "editor/editor_command_palette.h"
+#include "editor/editor_node.h"
+#include "editor/editor_paths.h"
+#include "editor/editor_resource_preview.h"
+#include "editor/editor_scale.h"
+#include "editor/editor_settings.h"
+#include "editor/filesystem_dock.h"
+#include "editor/inspector_dock.h"
+#include "main/main.h"
+#include "scene/gui/box_container.h"
+#include "scene/gui/control.h"
+
+EditorInterface *EditorInterface::singleton = nullptr;
+
+void EditorInterface::restart_editor(bool p_save) {
+ if (p_save) {
+ EditorNode::get_singleton()->save_all_scenes();
+ }
+ EditorNode::get_singleton()->restart_editor();
+}
+
+// Editor tools.
+
+EditorCommandPalette *EditorInterface::get_command_palette() const {
+ return EditorCommandPalette::get_singleton();
+}
+
+EditorFileSystem *EditorInterface::get_resource_file_system() const {
+ return EditorFileSystem::get_singleton();
+}
+
+EditorPaths *EditorInterface::get_editor_paths() const {
+ return EditorPaths::get_singleton();
+}
+
+EditorResourcePreview *EditorInterface::get_resource_previewer() const {
+ return EditorResourcePreview::get_singleton();
+}
+
+EditorSelection *EditorInterface::get_selection() const {
+ return EditorNode::get_singleton()->get_editor_selection();
+}
+
+Ref<EditorSettings> EditorInterface::get_editor_settings() const {
+ return EditorSettings::get_singleton();
+}
+
+TypedArray<Texture2D> EditorInterface::_make_mesh_previews(const TypedArray<Mesh> &p_meshes, int p_preview_size) {
+ Vector<Ref<Mesh>> meshes;
+
+ for (int i = 0; i < p_meshes.size(); i++) {
+ meshes.push_back(p_meshes[i]);
+ }
+
+ Vector<Ref<Texture2D>> textures = make_mesh_previews(meshes, nullptr, p_preview_size);
+ TypedArray<Texture2D> ret;
+ for (int i = 0; i < textures.size(); i++) {
+ ret.push_back(textures[i]);
+ }
+
+ return ret;
+}
+
+Vector<Ref<Texture2D>> EditorInterface::make_mesh_previews(const Vector<Ref<Mesh>> &p_meshes, Vector<Transform3D> *p_transforms, int p_preview_size) {
+ int size = p_preview_size;
+
+ RID scenario = RS::get_singleton()->scenario_create();
+
+ RID viewport = RS::get_singleton()->viewport_create();
+ RS::get_singleton()->viewport_set_update_mode(viewport, RS::VIEWPORT_UPDATE_ALWAYS);
+ RS::get_singleton()->viewport_set_scenario(viewport, scenario);
+ RS::get_singleton()->viewport_set_size(viewport, size, size);
+ RS::get_singleton()->viewport_set_transparent_background(viewport, true);
+ RS::get_singleton()->viewport_set_active(viewport, true);
+ RID viewport_texture = RS::get_singleton()->viewport_get_texture(viewport);
+
+ RID camera = RS::get_singleton()->camera_create();
+ RS::get_singleton()->viewport_attach_camera(viewport, camera);
+
+ RID light = RS::get_singleton()->directional_light_create();
+ RID light_instance = RS::get_singleton()->instance_create2(light, scenario);
+
+ RID light2 = RS::get_singleton()->directional_light_create();
+ RS::get_singleton()->light_set_color(light2, Color(0.7, 0.7, 0.7));
+ RID light_instance2 = RS::get_singleton()->instance_create2(light2, scenario);
+
+ EditorProgress ep("mlib", TTR("Creating Mesh Previews"), p_meshes.size());
+
+ Vector<Ref<Texture2D>> textures;
+
+ for (int i = 0; i < p_meshes.size(); i++) {
+ Ref<Mesh> mesh = p_meshes[i];
+ if (!mesh.is_valid()) {
+ textures.push_back(Ref<Texture2D>());
+ continue;
+ }
+
+ Transform3D mesh_xform;
+ if (p_transforms != nullptr) {
+ mesh_xform = (*p_transforms)[i];
+ }
+
+ RID inst = RS::get_singleton()->instance_create2(mesh->get_rid(), scenario);
+ RS::get_singleton()->instance_set_transform(inst, mesh_xform);
+
+ AABB aabb = mesh->get_aabb();
+ Vector3 ofs = aabb.get_center();
+ aabb.position -= ofs;
+ Transform3D xform;
+ xform.basis = Basis().rotated(Vector3(0, 1, 0), -Math_PI / 6);
+ xform.basis = Basis().rotated(Vector3(1, 0, 0), Math_PI / 6) * xform.basis;
+ AABB rot_aabb = xform.xform(aabb);
+ float m = MAX(rot_aabb.size.x, rot_aabb.size.y) * 0.5;
+ if (m == 0) {
+ textures.push_back(Ref<Texture2D>());
+ continue;
+ }
+ xform.origin = -xform.basis.xform(ofs); //-ofs*m;
+ xform.origin.z -= rot_aabb.size.z * 2;
+ xform.invert();
+ xform = mesh_xform * xform;
+
+ RS::get_singleton()->camera_set_transform(camera, xform * Transform3D(Basis(), Vector3(0, 0, 3)));
+ RS::get_singleton()->camera_set_orthogonal(camera, m * 2, 0.01, 1000.0);
+
+ RS::get_singleton()->instance_set_transform(light_instance, xform * Transform3D().looking_at(Vector3(-2, -1, -1), Vector3(0, 1, 0)));
+ RS::get_singleton()->instance_set_transform(light_instance2, xform * Transform3D().looking_at(Vector3(+1, -1, -2), Vector3(0, 1, 0)));
+
+ ep.step(TTR("Thumbnail..."), i);
+ DisplayServer::get_singleton()->process_events();
+ Main::iteration();
+ Main::iteration();
+ Ref<Image> img = RS::get_singleton()->texture_2d_get(viewport_texture);
+ ERR_CONTINUE(!img.is_valid() || img->is_empty());
+ Ref<ImageTexture> it = ImageTexture::create_from_image(img);
+
+ RS::get_singleton()->free(inst);
+
+ textures.push_back(it);
+ }
+
+ RS::get_singleton()->free(viewport);
+ RS::get_singleton()->free(light);
+ RS::get_singleton()->free(light_instance);
+ RS::get_singleton()->free(light2);
+ RS::get_singleton()->free(light_instance2);
+ RS::get_singleton()->free(camera);
+ RS::get_singleton()->free(scenario);
+
+ return textures;
+}
+
+void EditorInterface::set_plugin_enabled(const String &p_plugin, bool p_enabled) {
+ EditorNode::get_singleton()->set_addon_plugin_enabled(p_plugin, p_enabled, true);
+}
+
+bool EditorInterface::is_plugin_enabled(const String &p_plugin) const {
+ return EditorNode::get_singleton()->is_addon_plugin_enabled(p_plugin);
+}
+
+// Editor GUI.
+
+Control *EditorInterface::get_base_control() const {
+ return EditorNode::get_singleton()->get_gui_base();
+}
+
+VBoxContainer *EditorInterface::get_editor_main_screen() const {
+ return EditorNode::get_singleton()->get_main_screen_control();
+}
+
+ScriptEditor *EditorInterface::get_script_editor() const {
+ return ScriptEditor::get_singleton();
+}
+
+void EditorInterface::set_main_screen_editor(const String &p_name) {
+ EditorNode::get_singleton()->select_editor_by_name(p_name);
+}
+
+void EditorInterface::set_distraction_free_mode(bool p_enter) {
+ EditorNode::get_singleton()->set_distraction_free_mode(p_enter);
+}
+
+bool EditorInterface::is_distraction_free_mode_enabled() const {
+ return EditorNode::get_singleton()->is_distraction_free_mode_enabled();
+}
+
+float EditorInterface::get_editor_scale() const {
+ return EDSCALE;
+}
+
+// Editor docks.
+
+FileSystemDock *EditorInterface::get_file_system_dock() const {
+ return FileSystemDock::get_singleton();
+}
+
+void EditorInterface::select_file(const String &p_file) {
+ FileSystemDock::get_singleton()->select_file(p_file);
+}
+
+Vector<String> EditorInterface::get_selected_paths() const {
+ return FileSystemDock::get_singleton()->get_selected_paths();
+}
+
+String EditorInterface::get_current_path() const {
+ return FileSystemDock::get_singleton()->get_current_path();
+}
+
+String EditorInterface::get_current_directory() const {
+ return FileSystemDock::get_singleton()->get_current_directory();
+}
+
+EditorInspector *EditorInterface::get_inspector() const {
+ return InspectorDock::get_inspector_singleton();
+}
+
+// Object/Resource/Node editing.
+
+void EditorInterface::inspect_object(Object *p_obj, const String &p_for_property, bool p_inspector_only) {
+ EditorNode::get_singleton()->push_item(p_obj, p_for_property, p_inspector_only);
+}
+
+void EditorInterface::edit_resource(const Ref<Resource> &p_resource) {
+ EditorNode::get_singleton()->edit_resource(p_resource);
+}
+
+void EditorInterface::edit_node(Node *p_node) {
+ EditorNode::get_singleton()->edit_node(p_node);
+}
+
+void EditorInterface::edit_script(const Ref<Script> &p_script, int p_line, int p_col, bool p_grab_focus) {
+ ScriptEditor::get_singleton()->edit(p_script, p_line, p_col, p_grab_focus);
+}
+
+void EditorInterface::open_scene_from_path(const String &scene_path) {
+ if (EditorNode::get_singleton()->is_changing_scene()) {
+ return;
+ }
+
+ EditorNode::get_singleton()->open_request(scene_path);
+}
+
+void EditorInterface::reload_scene_from_path(const String &scene_path) {
+ if (EditorNode::get_singleton()->is_changing_scene()) {
+ return;
+ }
+
+ EditorNode::get_singleton()->reload_scene(scene_path);
+}
+
+Node *EditorInterface::get_edited_scene_root() const {
+ return EditorNode::get_singleton()->get_edited_scene();
+}
+
+PackedStringArray EditorInterface::get_open_scenes() const {
+ PackedStringArray ret;
+ Vector<EditorData::EditedScene> scenes = EditorNode::get_editor_data().get_edited_scenes();
+
+ int scns_amount = scenes.size();
+ for (int idx_scn = 0; idx_scn < scns_amount; idx_scn++) {
+ if (scenes[idx_scn].root == nullptr) {
+ continue;
+ }
+ ret.push_back(scenes[idx_scn].root->get_scene_file_path());
+ }
+ return ret;
+}
+
+Error EditorInterface::save_scene() {
+ if (!get_edited_scene_root()) {
+ return ERR_CANT_CREATE;
+ }
+ if (get_edited_scene_root()->get_scene_file_path().is_empty()) {
+ return ERR_CANT_CREATE;
+ }
+
+ save_scene_as(get_edited_scene_root()->get_scene_file_path());
+ return OK;
+}
+
+void EditorInterface::save_scene_as(const String &p_scene, bool p_with_preview) {
+ EditorNode::get_singleton()->save_scene_to_path(p_scene, p_with_preview);
+}
+
+// Scene playback.
+
+void EditorInterface::play_main_scene() {
+ EditorNode::get_singleton()->run_play();
+}
+
+void EditorInterface::play_current_scene() {
+ EditorNode::get_singleton()->run_play_current();
+}
+
+void EditorInterface::play_custom_scene(const String &scene_path) {
+ EditorNode::get_singleton()->run_play_custom(scene_path);
+}
+
+void EditorInterface::stop_playing_scene() {
+ EditorNode::get_singleton()->run_stop();
+}
+
+bool EditorInterface::is_playing_scene() const {
+ return EditorNode::get_singleton()->is_run_playing();
+}
+
+String EditorInterface::get_playing_scene() const {
+ return EditorNode::get_singleton()->get_run_playing_scene();
+}
+
+void EditorInterface::set_movie_maker_enabled(bool p_enabled) {
+ EditorNode::get_singleton()->set_movie_maker_enabled(p_enabled);
+}
+
+bool EditorInterface::is_movie_maker_enabled() const {
+ return EditorNode::get_singleton()->is_movie_maker_enabled();
+}
+
+// Base.
+
+void EditorInterface::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("restart_editor", "save"), &EditorInterface::restart_editor, DEFVAL(true));
+
+ // Editor tools.
+
+ ClassDB::bind_method(D_METHOD("get_command_palette"), &EditorInterface::get_command_palette);
+ ClassDB::bind_method(D_METHOD("get_resource_filesystem"), &EditorInterface::get_resource_file_system);
+ ClassDB::bind_method(D_METHOD("get_editor_paths"), &EditorInterface::get_editor_paths);
+ ClassDB::bind_method(D_METHOD("get_resource_previewer"), &EditorInterface::get_resource_previewer);
+ ClassDB::bind_method(D_METHOD("get_selection"), &EditorInterface::get_selection);
+ ClassDB::bind_method(D_METHOD("get_editor_settings"), &EditorInterface::get_editor_settings);
+
+ ClassDB::bind_method(D_METHOD("make_mesh_previews", "meshes", "preview_size"), &EditorInterface::_make_mesh_previews);
+
+ ClassDB::bind_method(D_METHOD("set_plugin_enabled", "plugin", "enabled"), &EditorInterface::set_plugin_enabled);
+ ClassDB::bind_method(D_METHOD("is_plugin_enabled", "plugin"), &EditorInterface::is_plugin_enabled);
+
+ // Editor GUI.
+
+ ClassDB::bind_method(D_METHOD("get_base_control"), &EditorInterface::get_base_control);
+ ClassDB::bind_method(D_METHOD("get_editor_main_screen"), &EditorInterface::get_editor_main_screen);
+ ClassDB::bind_method(D_METHOD("get_script_editor"), &EditorInterface::get_script_editor);
+
+ ClassDB::bind_method(D_METHOD("set_main_screen_editor", "name"), &EditorInterface::set_main_screen_editor);
+ ClassDB::bind_method(D_METHOD("set_distraction_free_mode", "enter"), &EditorInterface::set_distraction_free_mode);
+ ClassDB::bind_method(D_METHOD("is_distraction_free_mode_enabled"), &EditorInterface::is_distraction_free_mode_enabled);
+
+ ClassDB::bind_method(D_METHOD("get_editor_scale"), &EditorInterface::get_editor_scale);
+
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "distraction_free_mode"), "set_distraction_free_mode", "is_distraction_free_mode_enabled");
+
+ // Editor docks.
+
+ ClassDB::bind_method(D_METHOD("get_file_system_dock"), &EditorInterface::get_file_system_dock);
+ ClassDB::bind_method(D_METHOD("select_file", "file"), &EditorInterface::select_file);
+ ClassDB::bind_method(D_METHOD("get_selected_paths"), &EditorInterface::get_selected_paths);
+ ClassDB::bind_method(D_METHOD("get_current_path"), &EditorInterface::get_current_path);
+ ClassDB::bind_method(D_METHOD("get_current_directory"), &EditorInterface::get_current_directory);
+
+ ClassDB::bind_method(D_METHOD("get_inspector"), &EditorInterface::get_inspector);
+
+ // Object/Resource/Node editing.
+
+ ClassDB::bind_method(D_METHOD("inspect_object", "object", "for_property", "inspector_only"), &EditorInterface::inspect_object, DEFVAL(String()), DEFVAL(false));
+
+ ClassDB::bind_method(D_METHOD("edit_resource", "resource"), &EditorInterface::edit_resource);
+ ClassDB::bind_method(D_METHOD("edit_node", "node"), &EditorInterface::edit_node);
+ ClassDB::bind_method(D_METHOD("edit_script", "script", "line", "column", "grab_focus"), &EditorInterface::edit_script, DEFVAL(-1), DEFVAL(0), DEFVAL(true));
+ ClassDB::bind_method(D_METHOD("open_scene_from_path", "scene_filepath"), &EditorInterface::open_scene_from_path);
+ ClassDB::bind_method(D_METHOD("reload_scene_from_path", "scene_filepath"), &EditorInterface::reload_scene_from_path);
+
+ ClassDB::bind_method(D_METHOD("get_open_scenes"), &EditorInterface::get_open_scenes);
+ ClassDB::bind_method(D_METHOD("get_edited_scene_root"), &EditorInterface::get_edited_scene_root);
+
+ ClassDB::bind_method(D_METHOD("save_scene"), &EditorInterface::save_scene);
+ ClassDB::bind_method(D_METHOD("save_scene_as", "path", "with_preview"), &EditorInterface::save_scene_as, DEFVAL(true));
+
+ // Scene playback.
+
+ ClassDB::bind_method(D_METHOD("play_main_scene"), &EditorInterface::play_main_scene);
+ ClassDB::bind_method(D_METHOD("play_current_scene"), &EditorInterface::play_current_scene);
+ ClassDB::bind_method(D_METHOD("play_custom_scene", "scene_filepath"), &EditorInterface::play_custom_scene);
+ ClassDB::bind_method(D_METHOD("stop_playing_scene"), &EditorInterface::stop_playing_scene);
+ ClassDB::bind_method(D_METHOD("is_playing_scene"), &EditorInterface::is_playing_scene);
+ ClassDB::bind_method(D_METHOD("get_playing_scene"), &EditorInterface::get_playing_scene);
+
+ ClassDB::bind_method(D_METHOD("set_movie_maker_enabled", "enabled"), &EditorInterface::set_movie_maker_enabled);
+ ClassDB::bind_method(D_METHOD("is_movie_maker_enabled"), &EditorInterface::is_movie_maker_enabled);
+
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "movie_maker_enabled"), "set_movie_maker_enabled", "is_movie_maker_enabled");
+}
+
+void EditorInterface::create() {
+ memnew(EditorInterface);
+}
+
+void EditorInterface::free() {
+ ERR_FAIL_COND(singleton == nullptr);
+ memdelete(singleton);
+}
+
+EditorInterface::EditorInterface() {
+ ERR_FAIL_COND(singleton != nullptr);
+ singleton = this;
+}
diff --git a/editor/editor_interface.h b/editor/editor_interface.h
new file mode 100644
index 0000000000..9a64969e88
--- /dev/null
+++ b/editor/editor_interface.h
@@ -0,0 +1,143 @@
+/**************************************************************************/
+/* editor_interface.h */
+/**************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/**************************************************************************/
+/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/**************************************************************************/
+
+#ifndef EDITOR_INTERFACE_H
+#define EDITOR_INTERFACE_H
+
+#include "core/io/resource.h"
+#include "core/object/class_db.h"
+#include "core/object/object.h"
+#include "core/object/script_language.h"
+
+class Control;
+class EditorCommandPalette;
+class EditorFileSystem;
+class EditorInspector;
+class EditorPaths;
+class EditorResourcePreview;
+class EditorSelection;
+class EditorSettings;
+class FileSystemDock;
+class Mesh;
+class Node;
+class ScriptEditor;
+class Texture2D;
+class VBoxContainer;
+
+class EditorInterface : public Object {
+ GDCLASS(EditorInterface, Object);
+
+ static EditorInterface *singleton;
+
+ // Editor tools.
+
+ TypedArray<Texture2D> _make_mesh_previews(const TypedArray<Mesh> &p_meshes, int p_preview_size);
+
+protected:
+ static void _bind_methods();
+
+public:
+ static EditorInterface *get_singleton() { return singleton; }
+
+ void restart_editor(bool p_save = true);
+
+ // Editor tools.
+
+ EditorCommandPalette *get_command_palette() const;
+ EditorFileSystem *get_resource_file_system() const;
+ EditorPaths *get_editor_paths() const;
+ EditorResourcePreview *get_resource_previewer() const;
+ EditorSelection *get_selection() const;
+ Ref<EditorSettings> get_editor_settings() const;
+
+ Vector<Ref<Texture2D>> make_mesh_previews(const Vector<Ref<Mesh>> &p_meshes, Vector<Transform3D> *p_transforms, int p_preview_size);
+
+ void set_plugin_enabled(const String &p_plugin, bool p_enabled);
+ bool is_plugin_enabled(const String &p_plugin) const;
+
+ // Editor GUI.
+
+ Control *get_base_control() const;
+ VBoxContainer *get_editor_main_screen() const;
+ ScriptEditor *get_script_editor() const;
+
+ void set_main_screen_editor(const String &p_name);
+ void set_distraction_free_mode(bool p_enter);
+ bool is_distraction_free_mode_enabled() const;
+
+ float get_editor_scale() const;
+
+ // Editor docks.
+
+ FileSystemDock *get_file_system_dock() const;
+ void select_file(const String &p_file);
+ Vector<String> get_selected_paths() const;
+ String get_current_path() const;
+ String get_current_directory() const;
+
+ EditorInspector *get_inspector() const;
+
+ // Object/Resource/Node editing.
+
+ void inspect_object(Object *p_obj, const String &p_for_property = String(), bool p_inspector_only = false);
+
+ void edit_resource(const Ref<Resource> &p_resource);
+ void edit_node(Node *p_node);
+ void edit_script(const Ref<Script> &p_script, int p_line = -1, int p_col = 0, bool p_grab_focus = true);
+ void open_scene_from_path(const String &scene_path);
+ void reload_scene_from_path(const String &scene_path);
+
+ PackedStringArray get_open_scenes() const;
+ Node *get_edited_scene_root() const;
+
+ Error save_scene();
+ void save_scene_as(const String &p_scene, bool p_with_preview = true);
+
+ // Scene playback.
+
+ void play_main_scene();
+ void play_current_scene();
+ void play_custom_scene(const String &scene_path);
+ void stop_playing_scene();
+ bool is_playing_scene() const;
+ String get_playing_scene() const;
+
+ void set_movie_maker_enabled(bool p_enabled);
+ bool is_movie_maker_enabled() const;
+
+ // Base.
+
+ static void create();
+ static void free();
+
+ EditorInterface();
+};
+
+#endif // EDITOR_INTERFACE_H
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index 057f8e4ce4..f2f1285799 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -75,6 +75,7 @@
#include "editor/editor_folding.h"
#include "editor/editor_help.h"
#include "editor/editor_inspector.h"
+#include "editor/editor_interface.h"
#include "editor/editor_layouts_dialog.h"
#include "editor/editor_log.h"
#include "editor/editor_native_shader_source_visualizer.h"
@@ -7901,11 +7902,6 @@ EditorNode::EditorNode() {
print_verbose("Asset Library not available (due to using Web editor, or SSL support disabled).");
}
- // Add interface before adding plugins.
-
- editor_interface = memnew(EditorInterface);
- add_child(editor_interface);
-
// More visually meaningful to have this later.
raise_bottom_panel_item(AnimationPlayerEditor::get_singleton());
diff --git a/editor/editor_node.h b/editor/editor_node.h
index 8f17932cb0..831e2989f5 100644
--- a/editor/editor_node.h
+++ b/editor/editor_node.h
@@ -65,6 +65,7 @@ class TabContainer;
class TextureRect;
class TextureProgressBar;
class Tree;
+class VBoxContainer;
class VSplitContainer;
class Window;
@@ -269,7 +270,6 @@ private:
EditorCommandPalette *command_palette = nullptr;
EditorExport *editor_export = nullptr;
- EditorInterface *editor_interface = nullptr;
EditorLog *log = nullptr;
EditorNativeShaderSourceVisualizer *native_shader_source_visualizer = nullptr;
EditorPlugin *editor_plugin_screen = nullptr;
diff --git a/editor/editor_paths.cpp b/editor/editor_paths.cpp
index d5ba841801..610f66cff9 100644
--- a/editor/editor_paths.cpp
+++ b/editor/editor_paths.cpp
@@ -91,8 +91,7 @@ String EditorPaths::get_feature_profiles_dir() const {
}
void EditorPaths::create() {
- ERR_FAIL_COND(singleton != nullptr);
- memnew(EditorPaths());
+ memnew(EditorPaths);
}
void EditorPaths::free() {
@@ -111,6 +110,7 @@ void EditorPaths::_bind_methods() {
}
EditorPaths::EditorPaths() {
+ ERR_FAIL_COND(singleton != nullptr);
singleton = this;
project_data_dir = ProjectSettings::get_singleton()->get_project_data_path();
diff --git a/editor/editor_plugin.cpp b/editor/editor_plugin.cpp
index 9281965e6f..8ac5e77d35 100644
--- a/editor/editor_plugin.cpp
+++ b/editor/editor_plugin.cpp
@@ -31,15 +31,13 @@
#include "editor_plugin.h"
#include "editor/debugger/editor_debugger_node.h"
-#include "editor/editor_command_palette.h"
+#include "editor/editor_file_system.h"
+#include "editor/editor_inspector.h"
+#include "editor/editor_interface.h"
#include "editor/editor_node.h"
-#include "editor/editor_paths.h"
-#include "editor/editor_resource_preview.h"
-#include "editor/editor_settings.h"
#include "editor/editor_translation_parser.h"
#include "editor/editor_undo_redo_manager.h"
#include "editor/export/editor_export.h"
-#include "editor/filesystem_dock.h"
#include "editor/gui/editor_title_bar.h"
#include "editor/import/editor_import_plugin.h"
#include "editor/import/resource_importer_scene.h"
@@ -51,362 +49,10 @@
#include "editor/plugins/script_editor_plugin.h"
#include "editor/project_settings_editor.h"
#include "editor/scene_tree_dock.h"
-#include "main/main.h"
#include "scene/3d/camera_3d.h"
#include "scene/gui/popup_menu.h"
#include "servers/rendering_server.h"
-TypedArray<Texture2D> EditorInterface::_make_mesh_previews(const TypedArray<Mesh> &p_meshes, int p_preview_size) {
- Vector<Ref<Mesh>> meshes;
-
- for (int i = 0; i < p_meshes.size(); i++) {
- meshes.push_back(p_meshes[i]);
- }
-
- Vector<Ref<Texture2D>> textures = make_mesh_previews(meshes, nullptr, p_preview_size);
- TypedArray<Texture2D> ret;
- for (int i = 0; i < textures.size(); i++) {
- ret.push_back(textures[i]);
- }
-
- return ret;
-}
-
-Vector<Ref<Texture2D>> EditorInterface::make_mesh_previews(const Vector<Ref<Mesh>> &p_meshes, Vector<Transform3D> *p_transforms, int p_preview_size) {
- int size = p_preview_size;
-
- RID scenario = RS::get_singleton()->scenario_create();
-
- RID viewport = RS::get_singleton()->viewport_create();
- RS::get_singleton()->viewport_set_update_mode(viewport, RS::VIEWPORT_UPDATE_ALWAYS);
- RS::get_singleton()->viewport_set_scenario(viewport, scenario);
- RS::get_singleton()->viewport_set_size(viewport, size, size);
- RS::get_singleton()->viewport_set_transparent_background(viewport, true);
- RS::get_singleton()->viewport_set_active(viewport, true);
- RID viewport_texture = RS::get_singleton()->viewport_get_texture(viewport);
-
- RID camera = RS::get_singleton()->camera_create();
- RS::get_singleton()->viewport_attach_camera(viewport, camera);
-
- RID light = RS::get_singleton()->directional_light_create();
- RID light_instance = RS::get_singleton()->instance_create2(light, scenario);
-
- RID light2 = RS::get_singleton()->directional_light_create();
- RS::get_singleton()->light_set_color(light2, Color(0.7, 0.7, 0.7));
- RID light_instance2 = RS::get_singleton()->instance_create2(light2, scenario);
-
- EditorProgress ep("mlib", TTR("Creating Mesh Previews"), p_meshes.size());
-
- Vector<Ref<Texture2D>> textures;
-
- for (int i = 0; i < p_meshes.size(); i++) {
- Ref<Mesh> mesh = p_meshes[i];
- if (!mesh.is_valid()) {
- textures.push_back(Ref<Texture2D>());
- continue;
- }
-
- Transform3D mesh_xform;
- if (p_transforms != nullptr) {
- mesh_xform = (*p_transforms)[i];
- }
-
- RID inst = RS::get_singleton()->instance_create2(mesh->get_rid(), scenario);
- RS::get_singleton()->instance_set_transform(inst, mesh_xform);
-
- AABB aabb = mesh->get_aabb();
- Vector3 ofs = aabb.get_center();
- aabb.position -= ofs;
- Transform3D xform;
- xform.basis = Basis().rotated(Vector3(0, 1, 0), -Math_PI / 6);
- xform.basis = Basis().rotated(Vector3(1, 0, 0), Math_PI / 6) * xform.basis;
- AABB rot_aabb = xform.xform(aabb);
- float m = MAX(rot_aabb.size.x, rot_aabb.size.y) * 0.5;
- if (m == 0) {
- textures.push_back(Ref<Texture2D>());
- continue;
- }
- xform.origin = -xform.basis.xform(ofs); //-ofs*m;
- xform.origin.z -= rot_aabb.size.z * 2;
- xform.invert();
- xform = mesh_xform * xform;
-
- RS::get_singleton()->camera_set_transform(camera, xform * Transform3D(Basis(), Vector3(0, 0, 3)));
- RS::get_singleton()->camera_set_orthogonal(camera, m * 2, 0.01, 1000.0);
-
- RS::get_singleton()->instance_set_transform(light_instance, xform * Transform3D().looking_at(Vector3(-2, -1, -1), Vector3(0, 1, 0)));
- RS::get_singleton()->instance_set_transform(light_instance2, xform * Transform3D().looking_at(Vector3(+1, -1, -2), Vector3(0, 1, 0)));
-
- ep.step(TTR("Thumbnail..."), i);
- DisplayServer::get_singleton()->process_events();
- Main::iteration();
- Main::iteration();
- Ref<Image> img = RS::get_singleton()->texture_2d_get(viewport_texture);
- ERR_CONTINUE(!img.is_valid() || img->is_empty());
- Ref<ImageTexture> it = ImageTexture::create_from_image(img);
-
- RS::get_singleton()->free(inst);
-
- textures.push_back(it);
- }
-
- RS::get_singleton()->free(viewport);
- RS::get_singleton()->free(light);
- RS::get_singleton()->free(light_instance);
- RS::get_singleton()->free(light2);
- RS::get_singleton()->free(light_instance2);
- RS::get_singleton()->free(camera);
- RS::get_singleton()->free(scenario);
-
- return textures;
-}
-
-void EditorInterface::set_main_screen_editor(const String &p_name) {
- EditorNode::get_singleton()->select_editor_by_name(p_name);
-}
-
-VBoxContainer *EditorInterface::get_editor_main_screen() {
- return EditorNode::get_singleton()->get_main_screen_control();
-}
-
-void EditorInterface::edit_resource(const Ref<Resource> &p_resource) {
- EditorNode::get_singleton()->edit_resource(p_resource);
-}
-
-void EditorInterface::edit_node(Node *p_node) {
- EditorNode::get_singleton()->edit_node(p_node);
-}
-
-void EditorInterface::edit_script(const Ref<Script> &p_script, int p_line, int p_col, bool p_grab_focus) {
- ScriptEditor::get_singleton()->edit(p_script, p_line, p_col, p_grab_focus);
-}
-
-void EditorInterface::open_scene_from_path(const String &scene_path) {
- if (EditorNode::get_singleton()->is_changing_scene()) {
- return;
- }
-
- EditorNode::get_singleton()->open_request(scene_path);
-}
-
-void EditorInterface::reload_scene_from_path(const String &scene_path) {
- if (EditorNode::get_singleton()->is_changing_scene()) {
- return;
- }
-
- EditorNode::get_singleton()->reload_scene(scene_path);
-}
-
-void EditorInterface::play_main_scene() {
- EditorNode::get_singleton()->run_play();
-}
-
-void EditorInterface::play_current_scene() {
- EditorNode::get_singleton()->run_play_current();
-}
-
-void EditorInterface::play_custom_scene(const String &scene_path) {
- EditorNode::get_singleton()->run_play_custom(scene_path);
-}
-
-void EditorInterface::stop_playing_scene() {
- EditorNode::get_singleton()->run_stop();
-}
-
-bool EditorInterface::is_playing_scene() const {
- return EditorNode::get_singleton()->is_run_playing();
-}
-
-String EditorInterface::get_playing_scene() const {
- return EditorNode::get_singleton()->get_run_playing_scene();
-}
-
-Node *EditorInterface::get_edited_scene_root() {
- return EditorNode::get_singleton()->get_edited_scene();
-}
-
-PackedStringArray EditorInterface::get_open_scenes() const {
- PackedStringArray ret;
- Vector<EditorData::EditedScene> scenes = EditorNode::get_editor_data().get_edited_scenes();
-
- int scns_amount = scenes.size();
- for (int idx_scn = 0; idx_scn < scns_amount; idx_scn++) {
- if (scenes[idx_scn].root == nullptr) {
- continue;
- }
- ret.push_back(scenes[idx_scn].root->get_scene_file_path());
- }
- return ret;
-}
-
-ScriptEditor *EditorInterface::get_script_editor() {
- return ScriptEditor::get_singleton();
-}
-
-void EditorInterface::select_file(const String &p_file) {
- FileSystemDock::get_singleton()->select_file(p_file);
-}
-
-Vector<String> EditorInterface::get_selected_paths() const {
- return FileSystemDock::get_singleton()->get_selected_paths();
-}
-
-String EditorInterface::get_current_path() const {
- return FileSystemDock::get_singleton()->get_current_path();
-}
-
-String EditorInterface::get_current_directory() const {
- return FileSystemDock::get_singleton()->get_current_directory();
-}
-
-void EditorInterface::inspect_object(Object *p_obj, const String &p_for_property, bool p_inspector_only) {
- EditorNode::get_singleton()->push_item(p_obj, p_for_property, p_inspector_only);
-}
-
-EditorFileSystem *EditorInterface::get_resource_file_system() {
- return EditorFileSystem::get_singleton();
-}
-
-FileSystemDock *EditorInterface::get_file_system_dock() {
- return FileSystemDock::get_singleton();
-}
-
-EditorSelection *EditorInterface::get_selection() {
- return EditorNode::get_singleton()->get_editor_selection();
-}
-
-Ref<EditorSettings> EditorInterface::get_editor_settings() {
- return EditorSettings::get_singleton();
-}
-EditorPaths *EditorInterface::get_editor_paths() {
- return EditorPaths::get_singleton();
-}
-
-EditorResourcePreview *EditorInterface::get_resource_previewer() {
- return EditorResourcePreview::get_singleton();
-}
-
-Control *EditorInterface::get_base_control() {
- return EditorNode::get_singleton()->get_gui_base();
-}
-
-float EditorInterface::get_editor_scale() const {
- return EDSCALE;
-}
-
-void EditorInterface::set_plugin_enabled(const String &p_plugin, bool p_enabled) {
- EditorNode::get_singleton()->set_addon_plugin_enabled(p_plugin, p_enabled, true);
-}
-
-bool EditorInterface::is_plugin_enabled(const String &p_plugin) const {
- return EditorNode::get_singleton()->is_addon_plugin_enabled(p_plugin);
-}
-
-void EditorInterface::set_movie_maker_enabled(bool p_enabled) {
- EditorNode::get_singleton()->set_movie_maker_enabled(p_enabled);
-}
-
-bool EditorInterface::is_movie_maker_enabled() const {
- return EditorNode::get_singleton()->is_movie_maker_enabled();
-}
-
-EditorInspector *EditorInterface::get_inspector() const {
- return InspectorDock::get_inspector_singleton();
-}
-
-Error EditorInterface::save_scene() {
- if (!get_edited_scene_root()) {
- return ERR_CANT_CREATE;
- }
- if (get_edited_scene_root()->get_scene_file_path().is_empty()) {
- return ERR_CANT_CREATE;
- }
-
- save_scene_as(get_edited_scene_root()->get_scene_file_path());
- return OK;
-}
-
-void EditorInterface::save_scene_as(const String &p_scene, bool p_with_preview) {
- EditorNode::get_singleton()->save_scene_to_path(p_scene, p_with_preview);
-}
-
-void EditorInterface::set_distraction_free_mode(bool p_enter) {
- EditorNode::get_singleton()->set_distraction_free_mode(p_enter);
-}
-
-void EditorInterface::restart_editor(bool p_save) {
- if (p_save) {
- EditorNode::get_singleton()->save_all_scenes();
- }
- EditorNode::get_singleton()->restart_editor();
-}
-
-bool EditorInterface::is_distraction_free_mode_enabled() const {
- return EditorNode::get_singleton()->is_distraction_free_mode_enabled();
-}
-
-EditorCommandPalette *EditorInterface::get_command_palette() const {
- return EditorCommandPalette::get_singleton();
-}
-
-EditorInterface *EditorInterface::singleton = nullptr;
-
-void EditorInterface::_bind_methods() {
- ClassDB::bind_method(D_METHOD("inspect_object", "object", "for_property", "inspector_only"), &EditorInterface::inspect_object, DEFVAL(String()), DEFVAL(false));
- ClassDB::bind_method(D_METHOD("get_selection"), &EditorInterface::get_selection);
- ClassDB::bind_method(D_METHOD("get_editor_settings"), &EditorInterface::get_editor_settings);
- ClassDB::bind_method(D_METHOD("get_script_editor"), &EditorInterface::get_script_editor);
- ClassDB::bind_method(D_METHOD("get_base_control"), &EditorInterface::get_base_control);
- ClassDB::bind_method(D_METHOD("get_editor_scale"), &EditorInterface::get_editor_scale);
- ClassDB::bind_method(D_METHOD("edit_resource", "resource"), &EditorInterface::edit_resource);
- ClassDB::bind_method(D_METHOD("edit_node", "node"), &EditorInterface::edit_node);
- ClassDB::bind_method(D_METHOD("edit_script", "script", "line", "column", "grab_focus"), &EditorInterface::edit_script, DEFVAL(-1), DEFVAL(0), DEFVAL(true));
- ClassDB::bind_method(D_METHOD("open_scene_from_path", "scene_filepath"), &EditorInterface::open_scene_from_path);
- ClassDB::bind_method(D_METHOD("reload_scene_from_path", "scene_filepath"), &EditorInterface::reload_scene_from_path);
- ClassDB::bind_method(D_METHOD("play_main_scene"), &EditorInterface::play_main_scene);
- ClassDB::bind_method(D_METHOD("play_current_scene"), &EditorInterface::play_current_scene);
- ClassDB::bind_method(D_METHOD("play_custom_scene", "scene_filepath"), &EditorInterface::play_custom_scene);
- ClassDB::bind_method(D_METHOD("stop_playing_scene"), &EditorInterface::stop_playing_scene);
- ClassDB::bind_method(D_METHOD("is_playing_scene"), &EditorInterface::is_playing_scene);
- ClassDB::bind_method(D_METHOD("get_playing_scene"), &EditorInterface::get_playing_scene);
- ClassDB::bind_method(D_METHOD("get_open_scenes"), &EditorInterface::get_open_scenes);
- ClassDB::bind_method(D_METHOD("get_edited_scene_root"), &EditorInterface::get_edited_scene_root);
- ClassDB::bind_method(D_METHOD("get_resource_previewer"), &EditorInterface::get_resource_previewer);
- ClassDB::bind_method(D_METHOD("get_resource_filesystem"), &EditorInterface::get_resource_file_system);
- ClassDB::bind_method(D_METHOD("get_editor_main_screen"), &EditorInterface::get_editor_main_screen);
- ClassDB::bind_method(D_METHOD("make_mesh_previews", "meshes", "preview_size"), &EditorInterface::_make_mesh_previews);
- ClassDB::bind_method(D_METHOD("select_file", "file"), &EditorInterface::select_file);
- ClassDB::bind_method(D_METHOD("get_selected_paths"), &EditorInterface::get_selected_paths);
- ClassDB::bind_method(D_METHOD("get_current_path"), &EditorInterface::get_current_path);
- ClassDB::bind_method(D_METHOD("get_current_directory"), &EditorInterface::get_current_directory);
- ClassDB::bind_method(D_METHOD("get_file_system_dock"), &EditorInterface::get_file_system_dock);
- ClassDB::bind_method(D_METHOD("get_editor_paths"), &EditorInterface::get_editor_paths);
- ClassDB::bind_method(D_METHOD("get_command_palette"), &EditorInterface::get_command_palette);
-
- ClassDB::bind_method(D_METHOD("set_plugin_enabled", "plugin", "enabled"), &EditorInterface::set_plugin_enabled);
- ClassDB::bind_method(D_METHOD("is_plugin_enabled", "plugin"), &EditorInterface::is_plugin_enabled);
-
- ClassDB::bind_method(D_METHOD("set_movie_maker_enabled", "enabled"), &EditorInterface::set_movie_maker_enabled);
- ClassDB::bind_method(D_METHOD("is_movie_maker_enabled"), &EditorInterface::is_movie_maker_enabled);
-
- ClassDB::bind_method(D_METHOD("get_inspector"), &EditorInterface::get_inspector);
-
- ClassDB::bind_method(D_METHOD("save_scene"), &EditorInterface::save_scene);
- ClassDB::bind_method(D_METHOD("save_scene_as", "path", "with_preview"), &EditorInterface::save_scene_as, DEFVAL(true));
- ClassDB::bind_method(D_METHOD("restart_editor", "save"), &EditorInterface::restart_editor, DEFVAL(true));
-
- ClassDB::bind_method(D_METHOD("set_main_screen_editor", "name"), &EditorInterface::set_main_screen_editor);
- ClassDB::bind_method(D_METHOD("set_distraction_free_mode", "enter"), &EditorInterface::set_distraction_free_mode);
- ClassDB::bind_method(D_METHOD("is_distraction_free_mode_enabled"), &EditorInterface::is_distraction_free_mode_enabled);
-
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "distraction_free_mode"), "set_distraction_free_mode", "is_distraction_free_mode_enabled");
-}
-
-EditorInterface::EditorInterface() {
- singleton = this;
-}
-
-///////////////////////////////////////////
void EditorPlugin::add_custom_type(const String &p_type, const String &p_base, const Ref<Script> &p_script, const Ref<Texture2D> &p_icon) {
EditorNode::get_editor_data().add_custom_type(p_type, p_base, p_script, p_icon);
}
diff --git a/editor/editor_plugin.h b/editor/editor_plugin.h
index 74f46b2d0b..69789a4d4f 100644
--- a/editor/editor_plugin.h
+++ b/editor/editor_plugin.h
@@ -38,101 +38,20 @@
class Node3D;
class Button;
class PopupMenu;
-class EditorCommandPalette;
class EditorDebuggerPlugin;
class EditorExport;
class EditorExportPlugin;
-class EditorFileSystem;
class EditorImportPlugin;
-class EditorInspector;
class EditorInspectorPlugin;
+class EditorInterface;
class EditorNode3DGizmoPlugin;
-class EditorPaths;
class EditorResourceConversionPlugin;
-class EditorResourcePreview;
class EditorSceneFormatImporter;
class EditorScenePostImportPlugin;
-class EditorSelection;
-class EditorSettings;
class EditorToolAddons;
class EditorTranslationParserPlugin;
class EditorUndoRedoManager;
-class FileSystemDock;
class ScriptCreateDialog;
-class ScriptEditor;
-class VBoxContainer;
-
-class EditorInterface : public Node {
- GDCLASS(EditorInterface, Node);
-
-protected:
- static void _bind_methods();
- static EditorInterface *singleton;
-
- TypedArray<Texture2D> _make_mesh_previews(const TypedArray<Mesh> &p_meshes, int p_preview_size);
-
-public:
- static EditorInterface *get_singleton() { return singleton; }
-
- VBoxContainer *get_editor_main_screen();
- void edit_resource(const Ref<Resource> &p_resource);
- void edit_node(Node *p_node);
- void edit_script(const Ref<Script> &p_script, int p_line = -1, int p_col = 0, bool p_grab_focus = true);
- void open_scene_from_path(const String &scene_path);
- void reload_scene_from_path(const String &scene_path);
-
- void play_main_scene();
- void play_current_scene();
- void play_custom_scene(const String &scene_path);
- void stop_playing_scene();
- bool is_playing_scene() const;
- String get_playing_scene() const;
-
- Node *get_edited_scene_root();
- PackedStringArray get_open_scenes() const;
- ScriptEditor *get_script_editor();
-
- EditorCommandPalette *get_command_palette() const;
-
- void select_file(const String &p_file);
- Vector<String> get_selected_paths() const;
- String get_current_path() const;
- String get_current_directory() const;
-
- void inspect_object(Object *p_obj, const String &p_for_property = String(), bool p_inspector_only = false);
-
- EditorSelection *get_selection();
- //EditorImportExport *get_import_export();
- Ref<EditorSettings> get_editor_settings();
- EditorPaths *get_editor_paths();
- EditorResourcePreview *get_resource_previewer();
- EditorFileSystem *get_resource_file_system();
-
- FileSystemDock *get_file_system_dock();
-
- Control *get_base_control();
- float get_editor_scale() const;
-
- void set_plugin_enabled(const String &p_plugin, bool p_enabled);
- bool is_plugin_enabled(const String &p_plugin) const;
-
- void set_movie_maker_enabled(bool p_enabled);
- bool is_movie_maker_enabled() const;
-
- EditorInspector *get_inspector() const;
-
- Error save_scene();
- void save_scene_as(const String &p_scene, bool p_with_preview = true);
- void restart_editor(bool p_save = true);
-
- Vector<Ref<Texture2D>> make_mesh_previews(const Vector<Ref<Mesh>> &p_meshes, Vector<Transform3D> *p_transforms, int p_preview_size);
-
- void set_main_screen_editor(const String &p_name);
- void set_distraction_free_mode(bool p_enter);
- bool is_distraction_free_mode_enabled() const;
-
- EditorInterface();
-};
class EditorPlugin : public Node {
GDCLASS(EditorPlugin, Node);
diff --git a/editor/editor_properties_array_dict.cpp b/editor/editor_properties_array_dict.cpp
index be66fbafac..bb0434a1bf 100644
--- a/editor/editor_properties_array_dict.cpp
+++ b/editor/editor_properties_array_dict.cpp
@@ -203,8 +203,7 @@ void EditorPropertyArray::_property_changed(const String &p_property, Variant p_
index = p_property.get_slice("/", 1).to_int();
}
- Array array;
- array.assign(object->get_array().duplicate());
+ Variant array = object->get_array().duplicate();
array.set(index, p_value);
object->set_array(array);
emit_changed(get_edited_property(), array, "", true);
diff --git a/editor/editor_run_script.cpp b/editor/editor_run_script.cpp
index c87947d96b..a459943656 100644
--- a/editor/editor_run_script.cpp
+++ b/editor/editor_run_script.cpp
@@ -30,6 +30,7 @@
#include "editor_run_script.h"
+#include "editor/editor_interface.h"
#include "editor/editor_node.h"
void EditorScript::add_root_node(Node *p_node) {
diff --git a/editor/editor_run_script.h b/editor/editor_run_script.h
index ea2fb1fd77..8284d59110 100644
--- a/editor/editor_run_script.h
+++ b/editor/editor_run_script.h
@@ -31,9 +31,11 @@
#ifndef EDITOR_RUN_SCRIPT_H
#define EDITOR_RUN_SCRIPT_H
+#include "core/object/gdvirtual.gen.inc"
#include "core/object/ref_counted.h"
-#include "editor/editor_plugin.h"
+#include "core/object/script_language.h"
+class EditorInterface;
class EditorNode;
class EditorScript : public RefCounted {
diff --git a/editor/gui/scene_tree_editor.h b/editor/gui/scene_tree_editor.h
index 6a3213f8e4..20cc62d675 100644
--- a/editor/gui/scene_tree_editor.h
+++ b/editor/gui/scene_tree_editor.h
@@ -31,10 +31,11 @@
#ifndef SCENE_TREE_EDITOR_H
#define SCENE_TREE_EDITOR_H
-#include "editor/editor_data.h"
#include "scene/gui/dialogs.h"
#include "scene/gui/tree.h"
+class EditorSelection;
+
class SceneTreeEditor : public Control {
GDCLASS(SceneTreeEditor, Control);
diff --git a/editor/import/resource_importer_imagefont.cpp b/editor/import/resource_importer_imagefont.cpp
index e6ba84294a..cbd00f0f6b 100644
--- a/editor/import/resource_importer_imagefont.cpp
+++ b/editor/import/resource_importer_imagefont.cpp
@@ -151,7 +151,7 @@ Error ResourceImporterImageFont::import(const String &p_source_file, const Strin
int x = pos % columns;
int y = pos / columns;
font->set_glyph_advance(0, chr_height, idx, Vector2(chr_width, 0));
- font->set_glyph_offset(0, Vector2i(chr_height, 0), idx, Vector2(0, -0.5 * chr_height));
+ font->set_glyph_offset(0, Vector2i(chr_height, 0), idx, Vector2i(0, -0.5 * chr_height));
font->set_glyph_size(0, Vector2i(chr_height, 0), idx, Vector2(chr_width, chr_height));
font->set_glyph_uv_rect(0, Vector2i(chr_height, 0), idx, Rect2(img_margin.position.x + chr_cell_width * x + char_margin.position.x, img_margin.position.y + chr_cell_height * y + char_margin.position.y, chr_width, chr_height));
font->set_glyph_texture_idx(0, Vector2i(chr_height, 0), idx, 0);
diff --git a/editor/plugins/canvas_item_editor_plugin.h b/editor/plugins/canvas_item_editor_plugin.h
index e5f9b7b567..6d8c6842b2 100644
--- a/editor/plugins/canvas_item_editor_plugin.h
+++ b/editor/plugins/canvas_item_editor_plugin.h
@@ -40,6 +40,7 @@ class CanvasItemEditorViewport;
class ConfirmationDialog;
class EditorData;
class EditorZoomWidget;
+class EditorSelection;
class HScrollBar;
class HSplitContainer;
class MenuButton;
diff --git a/editor/plugins/control_editor_plugin.h b/editor/plugins/control_editor_plugin.h
index 19e004a390..4a411c0241 100644
--- a/editor/plugins/control_editor_plugin.h
+++ b/editor/plugins/control_editor_plugin.h
@@ -45,6 +45,7 @@
#include "scene/gui/separator.h"
#include "scene/gui/texture_rect.h"
+class EditorSelection;
class GridContainer;
// Inspector controls.
diff --git a/editor/plugins/curve_editor_plugin.cpp b/editor/plugins/curve_editor_plugin.cpp
index 20710bac19..a7ec4bfe33 100644
--- a/editor/plugins/curve_editor_plugin.cpp
+++ b/editor/plugins/curve_editor_plugin.cpp
@@ -34,6 +34,7 @@
#include "core/core_string_names.h"
#include "core/input/input.h"
#include "core/os/keyboard.h"
+#include "editor/editor_interface.h"
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
@@ -780,7 +781,7 @@ CurveEditorPlugin::CurveEditorPlugin() {
curve_plugin.instantiate();
EditorInspector::add_inspector_plugin(curve_plugin);
- get_editor_interface()->get_resource_previewer()->add_preview_generator(memnew(CurvePreviewGenerator));
+ EditorInterface::get_singleton()->get_resource_previewer()->add_preview_generator(memnew(CurvePreviewGenerator));
}
//-----------------------------------
diff --git a/editor/plugins/gpu_particles_collision_sdf_editor_plugin.cpp b/editor/plugins/gpu_particles_collision_sdf_editor_plugin.cpp
index abecba144c..9582f0caa5 100644
--- a/editor/plugins/gpu_particles_collision_sdf_editor_plugin.cpp
+++ b/editor/plugins/gpu_particles_collision_sdf_editor_plugin.cpp
@@ -30,6 +30,7 @@
#include "gpu_particles_collision_sdf_editor_plugin.h"
+#include "editor/editor_interface.h"
#include "editor/editor_node.h"
#include "editor/gui/editor_file_dialog.h"
@@ -193,7 +194,7 @@ GPUParticlesCollisionSDF3DEditorPlugin::GPUParticlesCollisionSDF3DEditorPlugin()
probe_file->set_file_mode(EditorFileDialog::FILE_MODE_SAVE_FILE);
probe_file->add_filter("*.exr");
probe_file->connect("file_selected", callable_mp(this, &GPUParticlesCollisionSDF3DEditorPlugin::_sdf_save_path_and_bake));
- get_editor_interface()->get_base_control()->add_child(probe_file);
+ EditorInterface::get_singleton()->get_base_control()->add_child(probe_file);
probe_file->set_title(TTR("Select path for SDF Texture"));
GPUParticlesCollisionSDF3D::bake_begin_function = bake_func_begin;
diff --git a/editor/plugins/mesh_library_editor_plugin.cpp b/editor/plugins/mesh_library_editor_plugin.cpp
index 3959ed2976..7bee4d01ee 100644
--- a/editor/plugins/mesh_library_editor_plugin.cpp
+++ b/editor/plugins/mesh_library_editor_plugin.cpp
@@ -30,6 +30,7 @@
#include "mesh_library_editor_plugin.h"
+#include "editor/editor_interface.h"
#include "editor/editor_node.h"
#include "editor/editor_settings.h"
#include "editor/gui/editor_file_dialog.h"
diff --git a/editor/plugins/node_3d_editor_plugin.h b/editor/plugins/node_3d_editor_plugin.h
index c4193f0420..c4e1070d84 100644
--- a/editor/plugins/node_3d_editor_plugin.h
+++ b/editor/plugins/node_3d_editor_plugin.h
@@ -44,6 +44,7 @@ class ColorPickerButton;
class ConfirmationDialog;
class DirectionalLight3D;
class EditorData;
+class EditorSelection;
class EditorSpinSlider;
class HSplitContainer;
class LineEdit;
diff --git a/editor/plugins/resource_preloader_editor_plugin.cpp b/editor/plugins/resource_preloader_editor_plugin.cpp
index a057bbe05e..b59bf3a37b 100644
--- a/editor/plugins/resource_preloader_editor_plugin.cpp
+++ b/editor/plugins/resource_preloader_editor_plugin.cpp
@@ -32,6 +32,7 @@
#include "core/config/project_settings.h"
#include "core/io/resource_loader.h"
+#include "editor/editor_interface.h"
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
diff --git a/editor/plugins/tiles/tiles_editor_plugin.cpp b/editor/plugins/tiles/tiles_editor_plugin.cpp
index 1682d07e13..719de9dc81 100644
--- a/editor/plugins/tiles/tiles_editor_plugin.cpp
+++ b/editor/plugins/tiles/tiles_editor_plugin.cpp
@@ -34,6 +34,7 @@
#include "core/os/mutex.h"
+#include "editor/editor_interface.h"
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
@@ -209,7 +210,7 @@ void TilesEditorPlugin::make_visible(bool p_visible) {
}
bool TilesEditorPlugin::is_tile_map_selected() {
- TypedArray<Node> selection = get_editor_interface()->get_selection()->get_selected_nodes();
+ TypedArray<Node> selection = EditorInterface::get_singleton()->get_selection()->get_selected_nodes();
if (selection.size() == 1 && Object::cast_to<TileMap>(selection[0])) {
return true;
}
diff --git a/editor/plugins/voxel_gi_editor_plugin.cpp b/editor/plugins/voxel_gi_editor_plugin.cpp
index 9906399d67..5ae5468e4b 100644
--- a/editor/plugins/voxel_gi_editor_plugin.cpp
+++ b/editor/plugins/voxel_gi_editor_plugin.cpp
@@ -30,6 +30,7 @@
#include "voxel_gi_editor_plugin.h"
+#include "editor/editor_interface.h"
#include "editor/editor_node.h"
#include "editor/gui/editor_file_dialog.h"
@@ -190,7 +191,7 @@ VoxelGIEditorPlugin::VoxelGIEditorPlugin() {
probe_file->set_file_mode(EditorFileDialog::FILE_MODE_SAVE_FILE);
probe_file->add_filter("*.res");
probe_file->connect("file_selected", callable_mp(this, &VoxelGIEditorPlugin::_voxel_gi_save_path_and_bake));
- get_editor_interface()->get_base_control()->add_child(probe_file);
+ EditorInterface::get_singleton()->get_base_control()->add_child(probe_file);
probe_file->set_title(TTR("Select path for VoxelGI Data File"));
VoxelGI::bake_begin_function = bake_func_begin;
diff --git a/editor/register_editor_types.cpp b/editor/register_editor_types.cpp
index d0c441b027..66d6eb4923 100644
--- a/editor/register_editor_types.cpp
+++ b/editor/register_editor_types.cpp
@@ -35,6 +35,7 @@
#include "editor/editor_command_palette.h"
#include "editor/editor_feature_profile.h"
#include "editor/editor_file_system.h"
+#include "editor/editor_interface.h"
#include "editor/editor_node.h"
#include "editor/editor_paths.h"
#include "editor/editor_resource_picker.h"
@@ -230,10 +231,14 @@ void register_editor_types() {
GLOBAL_DEF("editor/version_control/plugin_name", "");
GLOBAL_DEF("editor/version_control/autoload_on_startup", false);
+
+ EditorInterface::create();
}
void unregister_editor_types() {
EditorNode::cleanup();
+ EditorInterface::free();
+
if (EditorPaths::get_singleton()) {
EditorPaths::free();
}
diff --git a/editor/scene_tree_dock.h b/editor/scene_tree_dock.h
index 779bfd53e3..75acb37973 100644
--- a/editor/scene_tree_dock.h
+++ b/editor/scene_tree_dock.h
@@ -31,12 +31,13 @@
#ifndef SCENE_TREE_DOCK_H
#define SCENE_TREE_DOCK_H
-#include "editor/editor_data.h"
#include "editor/gui/scene_tree_editor.h"
#include "editor/script_create_dialog.h"
#include "scene/gui/box_container.h"
#include "scene/resources/animation.h"
+class EditorData;
+class EditorSelection;
class EditorQuickOpen;
class MenuButton;
class ReparentDialog;
diff --git a/modules/multiplayer/editor/multiplayer_editor_plugin.cpp b/modules/multiplayer/editor/multiplayer_editor_plugin.cpp
index 28d05e1dee..af2db543c0 100644
--- a/modules/multiplayer/editor/multiplayer_editor_plugin.cpp
+++ b/modules/multiplayer/editor/multiplayer_editor_plugin.cpp
@@ -34,6 +34,7 @@
#include "editor_network_profiler.h"
#include "replication_editor.h"
+#include "editor/editor_interface.h"
#include "editor/editor_node.h"
void MultiplayerEditorDebugger::_bind_methods() {
@@ -119,7 +120,7 @@ MultiplayerEditorPlugin::MultiplayerEditorPlugin() {
}
void MultiplayerEditorPlugin::_open_request(const String &p_path) {
- get_editor_interface()->open_scene_from_path(p_path);
+ EditorInterface::get_singleton()->open_scene_from_path(p_path);
}
void MultiplayerEditorPlugin::_notification(int p_what) {
diff --git a/platform/linuxbsd/freedesktop_portal_desktop.cpp b/platform/linuxbsd/freedesktop_portal_desktop.cpp
index ec1fcf6698..b45b7e676d 100644
--- a/platform/linuxbsd/freedesktop_portal_desktop.cpp
+++ b/platform/linuxbsd/freedesktop_portal_desktop.cpp
@@ -138,6 +138,17 @@ FreeDesktopPortalDesktop::FreeDesktopPortalDesktop() {
#else
unsupported = false;
#endif
+ bool ver_ok = false;
+ int version_major = 0;
+ int version_minor = 0;
+ int version_rev = 0;
+ dbus_get_version(&version_major, &version_minor, &version_rev);
+ ver_ok = (version_major == 1 && version_minor >= 10) || (version_major > 1); // 1.10.0
+ print_verbose(vformat("PortalDesktop: DBus %d.%d.%d detected.", version_major, version_minor, version_rev));
+ if (!ver_ok) {
+ print_verbose("PortalDesktop: Unsupported DBus library version!");
+ unsupported = true;
+ }
}
#endif // DBUS_ENABLED
diff --git a/platform/linuxbsd/freedesktop_screensaver.cpp b/platform/linuxbsd/freedesktop_screensaver.cpp
index d07e781a5f..78f2337599 100644
--- a/platform/linuxbsd/freedesktop_screensaver.cpp
+++ b/platform/linuxbsd/freedesktop_screensaver.cpp
@@ -141,6 +141,17 @@ FreeDesktopScreenSaver::FreeDesktopScreenSaver() {
#else
unsupported = false;
#endif
+ bool ver_ok = false;
+ int version_major = 0;
+ int version_minor = 0;
+ int version_rev = 0;
+ dbus_get_version(&version_major, &version_minor, &version_rev);
+ ver_ok = (version_major == 1 && version_minor >= 10) || (version_major > 1); // 1.10.0
+ print_verbose(vformat("ScreenSaver: DBus %d.%d.%d detected.", version_major, version_minor, version_rev));
+ if (!ver_ok) {
+ print_verbose("ScreenSaver:: Unsupported DBus library version!");
+ unsupported = true;
+ }
}
#endif // DBUS_ENABLED
diff --git a/platform/linuxbsd/joypad_linux.cpp b/platform/linuxbsd/joypad_linux.cpp
index 0256af0a59..5c623b8ba2 100644
--- a/platform/linuxbsd/joypad_linux.cpp
+++ b/platform/linuxbsd/joypad_linux.cpp
@@ -82,7 +82,13 @@ JoypadLinux::JoypadLinux(Input *in) {
#endif
use_udev = initialize_libudev(dylibloader_verbose) == 0;
if (use_udev) {
- print_verbose("JoypadLinux: udev enabled and loaded successfully.");
+ if (!udev_new || !udev_unref || !udev_enumerate_new || !udev_enumerate_add_match_subsystem || !udev_enumerate_scan_devices || !udev_enumerate_get_list_entry || !udev_list_entry_get_next || !udev_list_entry_get_name || !udev_device_new_from_syspath || !udev_device_get_devnode || !udev_device_get_action || !udev_device_unref || !udev_enumerate_unref || !udev_monitor_new_from_netlink || !udev_monitor_filter_add_match_subsystem_devtype || !udev_monitor_enable_receiving || !udev_monitor_get_fd || !udev_monitor_receive_device || !udev_monitor_unref) {
+ // There's no API to check version, check if functions are available instead.
+ use_udev = false;
+ print_verbose("JoypadLinux: Unsupported udev library version!");
+ } else {
+ print_verbose("JoypadLinux: udev enabled and loaded successfully.");
+ }
} else {
print_verbose("JoypadLinux: udev enabled, but couldn't be loaded. Falling back to /dev/input to detect joypads.");
}
diff --git a/platform/linuxbsd/os_linuxbsd.cpp b/platform/linuxbsd/os_linuxbsd.cpp
index 88c3d2cc14..11c81be4a9 100644
--- a/platform/linuxbsd/os_linuxbsd.cpp
+++ b/platform/linuxbsd/os_linuxbsd.cpp
@@ -1103,6 +1103,16 @@ OS_LinuxBSD::OS_LinuxBSD() {
font_config_initialized = true;
#endif
if (font_config_initialized) {
+ bool ver_ok = false;
+ int version = FcGetVersion();
+ ver_ok = ((version / 100 / 100) == 2 && (version / 100 % 100) >= 11) || ((version / 100 / 100) > 2); // 2.11.0
+ print_verbose(vformat("FontConfig %d.%d.%d detected.", version / 100 / 100, version / 100 % 100, version % 100));
+ if (!ver_ok) {
+ font_config_initialized = false;
+ }
+ }
+
+ if (font_config_initialized) {
config = FcInitLoadConfigAndFonts();
if (!config) {
font_config_initialized = false;
diff --git a/platform/linuxbsd/tts_linux.cpp b/platform/linuxbsd/tts_linux.cpp
index ce0199e87f..a0cb4f5c6c 100644
--- a/platform/linuxbsd/tts_linux.cpp
+++ b/platform/linuxbsd/tts_linux.cpp
@@ -48,6 +48,11 @@ void TTS_Linux::speech_init_thread_func(void *p_userdata) {
if (initialize_speechd(dylibloader_verbose) != 0) {
print_verbose("Text-to-Speech: Cannot load Speech Dispatcher library!");
} else {
+ if (!spd_open || !spd_set_notification_on || !spd_list_synthesis_voices || !free_spd_voices || !spd_set_synthesis_voice || !spd_set_volume || !spd_set_voice_pitch || !spd_set_voice_rate || !spd_set_data_mode || !spd_say || !spd_pause || !spd_resume || !spd_cancel) {
+ // There's no API to check version, check if functions are available instead.
+ print_verbose("Text-to-Speech: Unsupported Speech Dispatcher library version!");
+ return;
+ }
#else
{
#endif
diff --git a/platform/linuxbsd/x11/display_server_x11.cpp b/platform/linuxbsd/x11/display_server_x11.cpp
index 52ee9e8e6f..48d4e078df 100644
--- a/platform/linuxbsd/x11/display_server_x11.cpp
+++ b/platform/linuxbsd/x11/display_server_x11.cpp
@@ -1354,7 +1354,7 @@ void DisplayServerX11::delete_sub_window(WindowID p_id) {
}
XDestroyWindow(x11_display, wd.x11_xim_window);
#ifdef XKB_ENABLED
- if (xkb_loaded) {
+ if (xkb_loaded_v05p) {
if (wd.xkb_state) {
xkb_compose_state_unref(wd.xkb_state);
wd.xkb_state = nullptr;
@@ -2982,7 +2982,7 @@ void DisplayServerX11::_handle_key_event(WindowID p_window, XKeyEvent *p_event,
String keysym;
#ifdef XKB_ENABLED
- if (xkb_loaded) {
+ if (xkb_loaded_v08p) {
KeySym keysym_unicode_nm = 0; // keysym used to find unicode
XLookupString(&xkeyevent_no_mod, nullptr, 0, &keysym_unicode_nm, nullptr);
keysym = String::chr(xkb_keysym_to_utf32(xkb_keysym_to_upper(keysym_unicode_nm)));
@@ -3077,7 +3077,7 @@ void DisplayServerX11::_handle_key_event(WindowID p_window, XKeyEvent *p_event,
} while (status == XBufferOverflow);
#endif
#ifdef XKB_ENABLED
- } else if (xkeyevent->type == KeyPress && wd.xkb_state && xkb_loaded) {
+ } else if (xkeyevent->type == KeyPress && wd.xkb_state && xkb_loaded_v05p) {
xkb_compose_feed_result res = xkb_compose_state_feed(wd.xkb_state, keysym_unicode);
if (res == XKB_COMPOSE_FEED_ACCEPTED) {
if (xkb_compose_state_get_status(wd.xkb_state) == XKB_COMPOSE_COMPOSED) {
@@ -5004,7 +5004,7 @@ DisplayServerX11::WindowID DisplayServerX11::_create_window(WindowMode p_mode, V
wd.x11_xim_window = XCreateWindow(x11_display, wd.x11_window, 0, 0, 1, 1, 0, CopyFromParent, InputOnly, CopyFromParent, CWEventMask, &window_attributes_ime);
#ifdef XKB_ENABLED
- if (dead_tbl && xkb_loaded) {
+ if (dead_tbl && xkb_loaded_v05p) {
wd.xkb_state = xkb_compose_state_new(dead_tbl, XKB_COMPOSE_STATE_NO_FLAGS);
}
#endif
@@ -5288,9 +5288,16 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
ERR_FAIL_MSG("Can't load XCursor dynamically.");
}
#ifdef XKB_ENABLED
- xkb_loaded = (initialize_xkbcommon(dylibloader_verbose) == 0);
- if (!xkb_context_new || !xkb_compose_table_new_from_locale || !xkb_compose_table_unref || !xkb_context_unref || !xkb_compose_state_feed || !xkb_compose_state_unref || !xkb_compose_state_new || !xkb_compose_state_get_status || !xkb_compose_state_get_utf8 || !xkb_keysym_to_utf32 || !xkb_keysym_to_upper) {
- xkb_loaded = false;
+ bool xkb_loaded = (initialize_xkbcommon(dylibloader_verbose) == 0);
+ xkb_loaded_v05p = xkb_loaded;
+ if (!xkb_context_new || !xkb_compose_table_new_from_locale || !xkb_compose_table_unref || !xkb_context_unref || !xkb_compose_state_feed || !xkb_compose_state_unref || !xkb_compose_state_new || !xkb_compose_state_get_status || !xkb_compose_state_get_utf8) {
+ xkb_loaded_v05p = false;
+ print_verbose("Detected XKBcommon library version older than 0.5, dead key composition and Unicode key labels disabled.");
+ }
+ xkb_loaded_v08p = xkb_loaded;
+ if (!xkb_keysym_to_utf32 || !xkb_keysym_to_upper) {
+ xkb_loaded_v08p = false;
+ print_verbose("Detected XKBcommon library version older than 0.8, Unicode key labels disabled.");
}
#endif
if (initialize_xext(dylibloader_verbose) != 0) {
@@ -5346,6 +5353,15 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
r_error = OK;
+ {
+ if (!XcursorImageCreate || !XcursorImageLoadCursor || !XcursorImageDestroy || !XcursorGetDefaultSize || !XcursorGetTheme || !XcursorLibraryLoadImage) {
+ // There's no API to check version, check if functions are available instead.
+ ERR_PRINT("Unsupported Xcursor library version.");
+ r_error = ERR_UNAVAILABLE;
+ return;
+ }
+ }
+
for (int i = 0; i < CURSOR_MAX; i++) {
cursors[i] = None;
img[i] = nullptr;
@@ -5362,6 +5378,71 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
return;
}
+ {
+ int version_major = 0;
+ int version_minor = 0;
+ int rc = XShapeQueryVersion(x11_display, &version_major, &version_minor);
+ print_verbose(vformat("Xshape %d.%d detected.", version_major, version_minor));
+ if (rc != 1 || version_major < 1) {
+ ERR_PRINT("Unsupported Xshape library version.");
+ r_error = ERR_UNAVAILABLE;
+ XCloseDisplay(x11_display);
+ return;
+ }
+ }
+
+ {
+ int version_major = 0;
+ int version_minor = 0;
+ int rc = XineramaQueryVersion(x11_display, &version_major, &version_minor);
+ print_verbose(vformat("Xinerama %d.%d detected.", version_major, version_minor));
+ if (rc != 1 || version_major < 1) {
+ ERR_PRINT("Unsupported Xinerama library version.");
+ r_error = ERR_UNAVAILABLE;
+ XCloseDisplay(x11_display);
+ return;
+ }
+ }
+
+ {
+ int version_major = 0;
+ int version_minor = 0;
+ int rc = XRRQueryVersion(x11_display, &version_major, &version_minor);
+ print_verbose(vformat("Xrandr %d.%d detected.", version_major, version_minor));
+ if (rc != 1 || (version_major == 1 && version_minor < 3) || (version_major < 1)) {
+ ERR_PRINT("Unsupported Xrandr library version.");
+ r_error = ERR_UNAVAILABLE;
+ XCloseDisplay(x11_display);
+ return;
+ }
+ }
+
+ {
+ int version_major = 0;
+ int version_minor = 0;
+ int rc = XRenderQueryVersion(x11_display, &version_major, &version_minor);
+ print_verbose(vformat("Xrender %d.%d detected.", version_major, version_minor));
+ if (rc != 1 || (version_major == 0 && version_minor < 11)) {
+ ERR_PRINT("Unsupported Xrender library version.");
+ r_error = ERR_UNAVAILABLE;
+ XCloseDisplay(x11_display);
+ return;
+ }
+ }
+
+ {
+ int version_major = 2; // Report 2.2 as supported by engine, but should work with 2.1 or 2.0 library as well.
+ int version_minor = 2;
+ int rc = XIQueryVersion(x11_display, &version_major, &version_minor);
+ print_verbose(vformat("Xinput %d.%d detected.", version_major, version_minor));
+ if (rc != Success || (version_major < 2)) {
+ ERR_PRINT("Unsupported Xinput2 library version.");
+ r_error = ERR_UNAVAILABLE;
+ XCloseDisplay(x11_display);
+ return;
+ }
+ }
+
char *modifiers = nullptr;
Bool xkb_dar = False;
XAutoRepeatOn(x11_display);
@@ -5784,7 +5865,7 @@ DisplayServerX11::~DisplayServerX11() {
}
XDestroyWindow(x11_display, wd.x11_xim_window);
#ifdef XKB_ENABLED
- if (xkb_loaded) {
+ if (xkb_loaded_v05p) {
if (wd.xkb_state) {
xkb_compose_state_unref(wd.xkb_state);
wd.xkb_state = nullptr;
@@ -5796,7 +5877,7 @@ DisplayServerX11::~DisplayServerX11() {
}
#ifdef XKB_ENABLED
- if (xkb_loaded) {
+ if (xkb_loaded_v05p) {
if (dead_tbl) {
xkb_compose_table_unref(dead_tbl);
}
diff --git a/platform/linuxbsd/x11/display_server_x11.h b/platform/linuxbsd/x11/display_server_x11.h
index c19d2f441a..f6a1bc8012 100644
--- a/platform/linuxbsd/x11/display_server_x11.h
+++ b/platform/linuxbsd/x11/display_server_x11.h
@@ -212,7 +212,8 @@ class DisplayServerX11 : public DisplayServer {
String im_text;
#ifdef XKB_ENABLED
- bool xkb_loaded = false;
+ bool xkb_loaded_v05p = false;
+ bool xkb_loaded_v08p = false;
xkb_context *xkb_ctx = nullptr;
xkb_compose_table *dead_tbl = nullptr;
#endif
diff --git a/platform/windows/crash_handler_windows.cpp b/platform/windows/crash_handler_windows.cpp
index 867f1d537c..e32fbd47dd 100644
--- a/platform/windows/crash_handler_windows.cpp
+++ b/platform/windows/crash_handler_windows.cpp
@@ -47,9 +47,6 @@
#include <psapi.h>
-#pragma comment(lib, "psapi.lib")
-#pragma comment(lib, "dbghelp.lib")
-
// Some versions of imagehlp.dll lack the proper packing directives themselves
// so we need to do it.
#pragma pack(push, before_imagehlp, 8)
diff --git a/platform/windows/detect.py b/platform/windows/detect.py
index 1b55574b19..ba8d27bba5 100644
--- a/platform/windows/detect.py
+++ b/platform/windows/detect.py
@@ -409,6 +409,9 @@ def configure_msvc(env, vcvars_msvc_config):
"wbemuuid",
]
+ if env.debug_features:
+ LIBS += ["psapi", "dbghelp"]
+
if env["vulkan"]:
env.AppendUnique(CPPDEFINES=["VULKAN_ENABLED"])
if not env["use_volk"]:
@@ -587,6 +590,9 @@ def configure_mingw(env):
]
)
+ if env.debug_features:
+ env.Append(LIBS=["psapi", "dbghelp"])
+
if env["vulkan"]:
env.Append(CPPDEFINES=["VULKAN_ENABLED"])
if not env["use_volk"]:
diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp
index 6ff928580a..4c2d7ee5cc 100644
--- a/platform/windows/display_server_windows.cpp
+++ b/platform/windows/display_server_windows.cpp
@@ -4406,5 +4406,4 @@ DisplayServerWindows::~DisplayServerWindows() {
if (tts) {
memdelete(tts);
}
- CoUninitialize();
}
diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp
index 6e219fb929..456240ba2d 100644
--- a/platform/windows/os_windows.cpp
+++ b/platform/windows/os_windows.cpp
@@ -55,6 +55,12 @@
#include <shlobj.h>
#include <wbemcli.h>
+#ifdef DEBUG_ENABLED
+#pragma pack(push, before_imagehlp, 8)
+#include <imagehlp.h>
+#pragma pack(pop, before_imagehlp)
+#endif
+
extern "C" {
__declspec(dllexport) DWORD NvOptimusEnablement = 1;
__declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1;
@@ -88,7 +94,7 @@ static String format_error_message(DWORD id) {
LocalFree(messageBuffer);
- return msg;
+ return msg.replace("\r", "").replace("\n", "");
}
void RedirectStream(const char *p_file_name, const char *p_mode, FILE *p_cpp_stream, const DWORD p_std_handle) {
@@ -195,7 +201,6 @@ void OS_Windows::initialize() {
IPUnix::make_default();
main_loop = nullptr;
- CoInitialize(nullptr);
HRESULT hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory), reinterpret_cast<IUnknown **>(&dwrite_factory));
if (SUCCEEDED(hr)) {
hr = dwrite_factory->GetSystemFontCollection(&font_collection, false);
@@ -277,6 +282,73 @@ Error OS_Windows::get_entropy(uint8_t *r_buffer, int p_bytes) {
return OK;
}
+#ifdef DEBUG_ENABLED
+void debug_dynamic_library_check_dependencies(const String &p_root_path, const String &p_path, HashSet<String> &r_checked, HashSet<String> &r_missing) {
+ if (r_checked.has(p_path)) {
+ return;
+ }
+ r_checked.insert(p_path);
+
+ LOADED_IMAGE loaded_image;
+ HANDLE file = CreateFileW((LPCWSTR)p_path.utf16().get_data(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr);
+ if (file != INVALID_HANDLE_VALUE) {
+ HANDLE file_mapping = CreateFileMappingW(file, nullptr, PAGE_READONLY | SEC_COMMIT, 0, 0, nullptr);
+ if (file_mapping != INVALID_HANDLE_VALUE) {
+ PVOID mapping = MapViewOfFile(file_mapping, FILE_MAP_READ, 0, 0, 0);
+ if (mapping) {
+ PIMAGE_DOS_HEADER dos_header = (PIMAGE_DOS_HEADER)mapping;
+ PIMAGE_NT_HEADERS nt_header = nullptr;
+ if (dos_header->e_magic == IMAGE_DOS_SIGNATURE) {
+ PCHAR nt_header_ptr;
+ nt_header_ptr = ((PCHAR)mapping) + dos_header->e_lfanew;
+ nt_header = (PIMAGE_NT_HEADERS)nt_header_ptr;
+ if (nt_header->Signature != IMAGE_NT_SIGNATURE) {
+ nt_header = nullptr;
+ }
+ }
+ if (nt_header) {
+ loaded_image.ModuleName = nullptr;
+ loaded_image.hFile = file;
+ loaded_image.MappedAddress = (PUCHAR)mapping;
+ loaded_image.FileHeader = nt_header;
+ loaded_image.Sections = (PIMAGE_SECTION_HEADER)((LPBYTE)&nt_header->OptionalHeader + nt_header->FileHeader.SizeOfOptionalHeader);
+ loaded_image.NumberOfSections = nt_header->FileHeader.NumberOfSections;
+ loaded_image.SizeOfImage = GetFileSize(file, nullptr);
+ loaded_image.Characteristics = nt_header->FileHeader.Characteristics;
+ loaded_image.LastRvaSection = loaded_image.Sections;
+ loaded_image.fSystemImage = false;
+ loaded_image.fDOSImage = false;
+ loaded_image.Links.Flink = &loaded_image.Links;
+ loaded_image.Links.Blink = &loaded_image.Links;
+
+ ULONG size = 0;
+ const IMAGE_IMPORT_DESCRIPTOR *import_desc = (const IMAGE_IMPORT_DESCRIPTOR *)ImageDirectoryEntryToData((HMODULE)loaded_image.MappedAddress, false, IMAGE_DIRECTORY_ENTRY_IMPORT, &size);
+ if (import_desc) {
+ for (; import_desc->Name && import_desc->FirstThunk; import_desc++) {
+ char16_t full_name_wc[MAX_PATH];
+ const char *name_cs = (const char *)ImageRvaToVa(loaded_image.FileHeader, loaded_image.MappedAddress, import_desc->Name, 0);
+ String name = String(name_cs);
+ if (name.begins_with("api-ms-win-")) {
+ r_checked.insert(name);
+ } else if (SearchPathW(nullptr, (LPCWSTR)name.utf16().get_data(), nullptr, MAX_PATH, (LPWSTR)full_name_wc, nullptr)) {
+ debug_dynamic_library_check_dependencies(p_root_path, String::utf16(full_name_wc), r_checked, r_missing);
+ } else if (SearchPathW((LPCWSTR)(p_path.get_base_dir().utf16().get_data()), (LPCWSTR)name.utf16().get_data(), nullptr, MAX_PATH, (LPWSTR)full_name_wc, nullptr)) {
+ debug_dynamic_library_check_dependencies(p_root_path, String::utf16(full_name_wc), r_checked, r_missing);
+ } else {
+ r_missing.insert(name);
+ }
+ }
+ }
+ }
+ UnmapViewOfFile(mapping);
+ }
+ CloseHandle(file_mapping);
+ }
+ CloseHandle(file);
+ }
+}
+#endif
+
Error OS_Windows::open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path, String *r_resolved_path) {
String path = p_path.replace("/", "\\");
@@ -299,7 +371,29 @@ Error OS_Windows::open_dynamic_library(const String p_path, void *&p_library_han
}
p_library_handle = (void *)LoadLibraryExW((LPCWSTR)(path.utf16().get_data()), nullptr, (p_also_set_library_path && has_dll_directory_api) ? LOAD_LIBRARY_SEARCH_DEFAULT_DIRS : 0);
- ERR_FAIL_COND_V_MSG(!p_library_handle, ERR_CANT_OPEN, "Can't open dynamic library: " + p_path + ", error: " + format_error_message(GetLastError()) + ".");
+#ifdef DEBUG_ENABLED
+ if (!p_library_handle) {
+ DWORD err_code = GetLastError();
+
+ HashSet<String> checekd_libs;
+ HashSet<String> missing_libs;
+ debug_dynamic_library_check_dependencies(path, path, checekd_libs, missing_libs);
+ if (!missing_libs.is_empty()) {
+ String missing;
+ for (const String &E : missing_libs) {
+ if (!missing.is_empty()) {
+ missing += ", ";
+ }
+ missing += E;
+ }
+ ERR_FAIL_V_MSG(ERR_CANT_OPEN, vformat("Can't open dynamic library: %s, missing dependencies: (%s), error: \"%s\".", p_path, missing, format_error_message(err_code)));
+ } else {
+ ERR_FAIL_V_MSG(ERR_CANT_OPEN, vformat("Can't open dynamic library: %s, error: \"%s\"." + p_path, format_error_message(err_code)));
+ }
+ }
+#else
+ ERR_FAIL_COND_V_MSG(!p_library_handle, ERR_CANT_OPEN, vformat("Can't open dynamic library: %s, error: \"%s\"." + p_path, format_error_message(GetLastError())));
+#endif
if (cookie) {
remove_dll_directory(cookie);
@@ -323,7 +417,7 @@ Error OS_Windows::get_dynamic_library_symbol_handle(void *p_library_handle, cons
p_symbol_handle = (void *)GetProcAddress((HMODULE)p_library_handle, p_name.utf8().get_data());
if (!p_symbol_handle) {
if (!p_optional) {
- ERR_FAIL_V_MSG(ERR_CANT_RESOLVE, "Can't resolve symbol " + p_name + ", error: " + String::num(GetLastError()) + ".");
+ ERR_FAIL_V_MSG(ERR_CANT_RESOLVE, vformat("Can't resolve symbol %s, error: \"%s\".", p_name, format_error_message(GetLastError())));
} else {
return ERR_CANT_RESOLVE;
}
@@ -373,8 +467,6 @@ Vector<String> OS_Windows::get_video_adapter_driver_info() const {
return Vector<String>();
}
- CoInitialize(nullptr);
-
HRESULT hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, uuid, (LPVOID *)&wbemLocator);
if (hr != S_OK) {
return Vector<String>();
@@ -1505,6 +1597,8 @@ Error OS_Windows::move_to_trash(const String &p_path) {
OS_Windows::OS_Windows(HINSTANCE _hInstance) {
hInstance = _hInstance;
+ CoInitializeEx(nullptr, COINIT_MULTITHREADED);
+
#ifdef WASAPI_ENABLED
AudioDriverManager::add_driver(&driver_wasapi);
#endif
@@ -1532,4 +1626,5 @@ OS_Windows::OS_Windows(HINSTANCE _hInstance) {
}
OS_Windows::~OS_Windows() {
+ CoUninitialize();
}
diff --git a/platform/windows/tts_windows.cpp b/platform/windows/tts_windows.cpp
index 54ab93ee01..907096d890 100644
--- a/platform/windows/tts_windows.cpp
+++ b/platform/windows/tts_windows.cpp
@@ -118,7 +118,7 @@ bool TTS_Windows::is_speaking() const {
SPVOICESTATUS status;
synth->GetStatus(&status, nullptr);
- return (status.dwRunningState == SPRS_IS_SPEAKING);
+ return (status.dwRunningState == SPRS_IS_SPEAKING || status.dwRunningState == 0 /* Waiting To Speak */);
}
bool TTS_Windows::is_paused() const {
@@ -251,7 +251,6 @@ TTS_Windows *TTS_Windows::get_singleton() {
TTS_Windows::TTS_Windows() {
singleton = this;
- CoInitialize(nullptr);
if (SUCCEEDED(CoCreateInstance(CLSID_SpVoice, nullptr, CLSCTX_ALL, IID_ISpVoice, (void **)&synth))) {
ULONGLONG event_mask = SPFEI(SPEI_END_INPUT_STREAM) | SPFEI(SPEI_START_INPUT_STREAM) | SPFEI(SPEI_WORD_BOUNDARY);
diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp
index ba361c2656..c678b4bf02 100644
--- a/scene/2d/physics_body_2d.cpp
+++ b/scene/2d/physics_body_2d.cpp
@@ -1036,7 +1036,7 @@ void RigidBody2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "linear_damp_mode", PROPERTY_HINT_ENUM, "Combine,Replace"), "set_linear_damp_mode", "get_linear_damp_mode");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "linear_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"), "set_linear_damp", "get_linear_damp");
ADD_GROUP("Angular", "angular_");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "angular_velocity", PROPERTY_HINT_NONE, "suffix:rad/s"), "set_angular_velocity", "get_angular_velocity");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "angular_velocity", PROPERTY_HINT_NONE, U"radians,suffix:\u00B0/s"), "set_angular_velocity", "get_angular_velocity");
ADD_PROPERTY(PropertyInfo(Variant::INT, "angular_damp_mode", PROPERTY_HINT_ENUM, "Combine,Replace"), "set_angular_damp_mode", "get_angular_damp_mode");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "angular_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"), "set_angular_damp", "get_angular_damp");
ADD_GROUP("Constant Forces", "constant_");
diff --git a/scene/3d/physics_body_3d.cpp b/scene/3d/physics_body_3d.cpp
index 89bb1b5c65..b7d63258db 100644
--- a/scene/3d/physics_body_3d.cpp
+++ b/scene/3d/physics_body_3d.cpp
@@ -1108,8 +1108,8 @@ void RigidBody3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "angular_damp_mode", PROPERTY_HINT_ENUM, "Combine,Replace"), "set_angular_damp_mode", "get_angular_damp_mode");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "angular_damp", PROPERTY_HINT_RANGE, "0,100,0.001,or_greater"), "set_angular_damp", "get_angular_damp");
ADD_GROUP("Constant Forces", "constant_");
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "constant_force"), "set_constant_force", "get_constant_force");
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "constant_torque"), "set_constant_torque", "get_constant_torque");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "constant_force", PROPERTY_HINT_NONE, U"suffix:kg\u22C5m/s\u00B2 (N)"), "set_constant_force", "get_constant_force");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "constant_torque", PROPERTY_HINT_NONE, U"suffix:kg\u22C5m\u00B2/s\u00B2/rad"), "set_constant_torque", "get_constant_torque");
ADD_SIGNAL(MethodInfo("body_shape_entered", PropertyInfo(Variant::RID, "body_rid"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"), PropertyInfo(Variant::INT, "body_shape_index"), PropertyInfo(Variant::INT, "local_shape_index")));
ADD_SIGNAL(MethodInfo("body_shape_exited", PropertyInfo(Variant::RID, "body_rid"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"), PropertyInfo(Variant::INT, "body_shape_index"), PropertyInfo(Variant::INT, "local_shape_index")));