summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/extension/gdextension.cpp5
-rw-r--r--doc/classes/EditorInterface.xml7
-rw-r--r--doc/classes/EditorPlugin.xml6
-rw-r--r--doc/classes/Node.xml13
-rw-r--r--doc/classes/ProjectSettings.xml6
-rw-r--r--doc/classes/SurfaceTool.xml2
-rw-r--r--doc/classes/XRInterface.xml3
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.cpp2
-rw-r--r--editor/create_dialog.cpp9
-rw-r--r--editor/create_dialog.h2
-rw-r--r--editor/debugger/editor_debugger_node.cpp12
-rw-r--r--editor/editor_autoload_settings.cpp2
-rw-r--r--editor/editor_interface.cpp6
-rw-r--r--editor/editor_interface.h6
-rw-r--r--editor/editor_node.cpp11
-rw-r--r--editor/editor_node.h1
-rw-r--r--editor/editor_themes.cpp103
-rw-r--r--editor/editor_themes.h16
-rw-r--r--editor/export/editor_export_platform.cpp18
-rw-r--r--editor/export/project_export.cpp8
-rw-r--r--editor/icons/AABB.svg2
-rw-r--r--editor/icons/Array.svg2
-rw-r--r--editor/icons/Basis.svg2
-rw-r--r--editor/icons/CheckBox.svg2
-rw-r--r--editor/icons/Color.svg2
-rw-r--r--editor/icons/Dictionary.svg2
-rw-r--r--editor/icons/GraphEdit.svg2
-rw-r--r--editor/icons/GraphElement.svg2
-rw-r--r--editor/icons/GraphNode.svg2
-rw-r--r--editor/icons/GuiToggleOnDisabledMirrored.svg (renamed from editor/icons/GuiToggleOnMirroredDisabled.svg)0
-rw-r--r--editor/icons/IOSDeviceWired.svg2
-rw-r--r--editor/icons/IOSDeviceWireless.svg2
-rw-r--r--editor/icons/IOSSimulator.svg2
-rw-r--r--editor/icons/MiniObject.svg2
-rw-r--r--editor/icons/Nil.svg2
-rw-r--r--editor/icons/NodePath.svg2
-rw-r--r--editor/icons/PackedByteArray.svg2
-rw-r--r--editor/icons/PackedColorArray.svg2
-rw-r--r--editor/icons/PackedFloat32Array.svg2
-rw-r--r--editor/icons/PackedFloat64Array.svg2
-rw-r--r--editor/icons/PackedInt32Array.svg2
-rw-r--r--editor/icons/PackedInt64Array.svg2
-rw-r--r--editor/icons/PackedStringArray.svg2
-rw-r--r--editor/icons/PackedVector2Array.svg2
-rw-r--r--editor/icons/PackedVector3Array.svg2
-rw-r--r--editor/icons/Plane.svg2
-rw-r--r--editor/icons/Projection.svg2
-rw-r--r--editor/icons/Quaternion.svg2
-rw-r--r--editor/icons/RID.svg2
-rw-r--r--editor/icons/Rect2.svg2
-rw-r--r--editor/icons/Rect2i.svg2
-rw-r--r--editor/icons/String.svg2
-rw-r--r--editor/icons/StringName.svg2
-rw-r--r--editor/icons/Transform2D.svg2
-rw-r--r--editor/icons/Transform3D.svg2
-rw-r--r--editor/icons/Uv.svg2
-rw-r--r--editor/icons/Variant.svg2
-rw-r--r--editor/icons/Vector2.svg2
-rw-r--r--editor/icons/Vector2i.svg2
-rw-r--r--editor/icons/Vector3.svg2
-rw-r--r--editor/icons/Vector3i.svg2
-rw-r--r--editor/icons/Vector4.svg2
-rw-r--r--editor/icons/Vector4i.svg2
-rw-r--r--editor/icons/bool.svg2
-rw-r--r--editor/icons/float.svg2
-rw-r--r--editor/icons/uint.svg2
-rw-r--r--editor/import_dock.cpp2
-rw-r--r--editor/plugins/abstract_polygon_2d_editor.cpp1
-rw-r--r--editor/plugins/animation_player_editor_plugin.cpp4
-rw-r--r--editor/plugins/canvas_item_editor_plugin.cpp74
-rw-r--r--editor/plugins/canvas_item_editor_plugin.h9
-rw-r--r--editor/plugins/control_editor_plugin.cpp5
-rw-r--r--editor/plugins/cpu_particles_2d_editor_plugin.cpp2
-rw-r--r--editor/plugins/gizmos/audio_listener_3d_gizmo_plugin.cpp4
-rw-r--r--editor/plugins/gizmos/audio_stream_player_3d_gizmo_plugin.cpp233
-rw-r--r--editor/plugins/gizmos/camera_3d_gizmo_plugin.cpp3
-rw-r--r--editor/plugins/gizmos/collision_shape_3d_gizmo_plugin.cpp79
-rw-r--r--editor/plugins/gizmos/collision_shape_3d_gizmo_plugin.h6
-rw-r--r--editor/plugins/gizmos/cpu_particles_3d_gizmo_plugin.cpp4
-rw-r--r--editor/plugins/gizmos/decal_gizmo_plugin.cpp72
-rw-r--r--editor/plugins/gizmos/decal_gizmo_plugin.h6
-rw-r--r--editor/plugins/gizmos/gizmo_3d_helper.cpp131
-rw-r--r--editor/plugins/gizmos/gizmo_3d_helper.h55
-rw-r--r--editor/plugins/gizmos/gpu_particles_3d_gizmo_plugin.cpp67
-rw-r--r--editor/plugins/gizmos/gpu_particles_collision_3d_gizmo_plugin.cpp61
-rw-r--r--editor/plugins/gizmos/gpu_particles_collision_3d_gizmo_plugin.h6
-rw-r--r--editor/plugins/gizmos/light_3d_gizmo_plugin.cpp198
-rw-r--r--editor/plugins/gizmos/lightmap_gi_gizmo_plugin.cpp10
-rw-r--r--editor/plugins/gizmos/marker_3d_gizmo_plugin.cpp6
-rw-r--r--editor/plugins/gizmos/reflection_probe_gizmo_plugin.cpp157
-rw-r--r--editor/plugins/gizmos/reflection_probe_gizmo_plugin.h6
-rw-r--r--editor/plugins/gizmos/voxel_gi_gizmo_plugin.cpp170
-rw-r--r--editor/plugins/gizmos/voxel_gi_gizmo_plugin.h6
-rw-r--r--editor/plugins/gpu_particles_2d_editor_plugin.cpp2
-rw-r--r--editor/plugins/gpu_particles_collision_sdf_editor_plugin.cpp3
-rw-r--r--editor/plugins/lightmap_gi_editor_plugin.cpp5
-rw-r--r--editor/plugins/mesh_instance_3d_editor_plugin.cpp11
-rw-r--r--editor/plugins/mesh_instance_3d_editor_plugin.h3
-rw-r--r--editor/plugins/mesh_library_editor_plugin.cpp3
-rw-r--r--editor/plugins/multimesh_editor_plugin.cpp3
-rw-r--r--editor/plugins/navigation_obstacle_3d_editor_plugin.cpp4
-rw-r--r--editor/plugins/node_3d_editor_gizmos.cpp3
-rw-r--r--editor/plugins/node_3d_editor_plugin.cpp71
-rw-r--r--editor/plugins/node_3d_editor_plugin.h10
-rw-r--r--editor/plugins/occluder_instance_3d_editor_plugin.cpp3
-rw-r--r--editor/plugins/path_2d_editor_plugin.cpp25
-rw-r--r--editor/plugins/path_2d_editor_plugin.h2
-rw-r--r--editor/plugins/path_3d_editor_plugin.cpp55
-rw-r--r--editor/plugins/path_3d_editor_plugin.h4
-rw-r--r--editor/plugins/physical_bone_3d_editor_plugin.cpp8
-rw-r--r--editor/plugins/polygon_3d_editor_plugin.cpp4
-rw-r--r--editor/plugins/script_editor_plugin.cpp2
-rw-r--r--editor/plugins/script_text_editor.cpp8
-rw-r--r--editor/plugins/skeleton_2d_editor_plugin.cpp3
-rw-r--r--editor/plugins/skeleton_3d_editor_plugin.cpp12
-rw-r--r--editor/plugins/skeleton_ik_3d_editor_plugin.cpp3
-rw-r--r--editor/plugins/text_shader_editor.cpp6
-rw-r--r--editor/plugins/theme_editor_plugin.cpp2
-rw-r--r--editor/plugins/theme_editor_preview.cpp2
-rw-r--r--editor/plugins/tiles/tile_data_editors.cpp9
-rw-r--r--editor/plugins/tiles/tiles_editor_plugin.cpp5
-rw-r--r--editor/plugins/version_control_editor_plugin.cpp78
-rw-r--r--editor/plugins/visual_shader_editor_plugin.cpp78
-rw-r--r--editor/plugins/voxel_gi_editor_plugin.cpp5
-rw-r--r--editor/rename_dialog.cpp8
-rw-r--r--editor/scene_tree_dock.cpp4
-rw-r--r--editor/window_wrapper.cpp2
-rw-r--r--main/main.cpp1
-rw-r--r--modules/csg/editor/csg_gizmos.cpp72
-rw-r--r--modules/csg/editor/csg_gizmos.h6
-rw-r--r--modules/gdscript/editor/gdscript_translation_parser_plugin.cpp11
-rw-r--r--modules/gdscript/gdscript_analyzer.cpp8
-rw-r--r--modules/gdscript/gdscript_warning.cpp9
-rw-r--r--modules/gdscript/gdscript_warning.h2
-rw-r--r--modules/gdscript/language_server/gdscript_extend_parser.cpp2
-rw-r--r--modules/gdscript/tests/scripts/analyzer/warnings/for_loop_specified_type_is_equal_to_inferred.gd4
-rw-r--r--modules/gdscript/tests/scripts/analyzer/warnings/for_loop_specified_type_is_equal_to_inferred.out5
-rw-r--r--modules/gdscript/tests/scripts/analyzer/warnings/for_loop_specified_type_is_supertype_of_inferred.gd4
-rw-r--r--modules/gdscript/tests/scripts/analyzer/warnings/for_loop_specified_type_is_supertype_of_inferred.out5
-rw-r--r--modules/gridmap/editor/grid_map_editor_plugin.cpp1
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs2
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathManager.cs49
-rw-r--r--modules/multiplayer/editor/replication_editor.cpp2
-rw-r--r--modules/openxr/openxr_api.cpp89
-rw-r--r--modules/openxr/openxr_api.h4
-rw-r--r--modules/openxr/openxr_interface.cpp21
-rw-r--r--modules/openxr/openxr_interface.h1
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java29
-rw-r--r--scene/gui/code_edit.cpp17
-rw-r--r--scene/gui/code_edit.h6
-rw-r--r--scene/gui/color_mode.cpp20
-rw-r--r--scene/gui/color_picker.cpp13
-rw-r--r--scene/gui/color_picker.h11
-rw-r--r--scene/gui/graph_edit.cpp142
-rw-r--r--scene/gui/graph_edit.h73
-rw-r--r--scene/gui/graph_element.cpp7
-rw-r--r--scene/gui/graph_element.h4
-rw-r--r--scene/gui/graph_node.cpp62
-rw-r--r--scene/gui/graph_node.h18
-rw-r--r--scene/gui/grid_container.cpp4
-rw-r--r--scene/gui/grid_container.h2
-rw-r--r--scene/gui/margin_container.cpp17
-rw-r--r--scene/gui/margin_container.h2
-rw-r--r--scene/gui/popup_menu.cpp4
-rw-r--r--scene/gui/rich_text_label.cpp13
-rw-r--r--scene/gui/rich_text_label.h3
-rw-r--r--scene/gui/split_container.cpp6
-rw-r--r--scene/gui/split_container.h4
-rw-r--r--scene/gui/text_edit.cpp19
-rw-r--r--scene/gui/text_edit.h15
-rw-r--r--scene/main/viewport.cpp38
-rw-r--r--scene/main/window.cpp19
-rw-r--r--scene/main/window.h26
-rw-r--r--scene/resources/syntax_highlighter.cpp2
-rw-r--r--scene/resources/theme.h30
-rw-r--r--servers/xr/xr_interface.cpp2
-rw-r--r--servers/xr/xr_interface.h1
-rw-r--r--tests/core/io/test_resource.h4
-rw-r--r--thirdparty/README.md2
-rw-r--r--thirdparty/libwebp/src/dec/vp8i_dec.h2
-rw-r--r--thirdparty/libwebp/src/dec/vp8l_dec.c46
-rw-r--r--thirdparty/libwebp/src/dec/vp8li_dec.h2
-rw-r--r--thirdparty/libwebp/src/demux/demux.c2
-rw-r--r--thirdparty/libwebp/src/enc/vp8i_enc.h2
-rw-r--r--thirdparty/libwebp/src/mux/muxi.h2
-rw-r--r--thirdparty/libwebp/src/utils/huffman_utils.c97
-rw-r--r--thirdparty/libwebp/src/utils/huffman_utils.h27
187 files changed, 1923 insertions, 1321 deletions
diff --git a/core/extension/gdextension.cpp b/core/extension/gdextension.cpp
index 96ad1570cd..3bc7dde10a 100644
--- a/core/extension/gdextension.cpp
+++ b/core/extension/gdextension.cpp
@@ -711,6 +711,11 @@ Ref<Resource> GDExtensionResourceLoader::load(const String &p_path, const String
// This is so relative path to dependencies are satisfied.
String copy_path = abs_path.get_base_dir().path_join("~" + abs_path.get_file());
+ // If there's a left-over copy (possibly from a crash) then delete it first.
+ if (FileAccess::exists(copy_path)) {
+ DirAccess::remove_absolute(copy_path);
+ }
+
Error copy_err = DirAccess::copy_absolute(abs_path, copy_path);
if (copy_err) {
if (r_error) {
diff --git a/doc/classes/EditorInterface.xml b/doc/classes/EditorInterface.xml
index 3ae4b7f812..64a311d857 100644
--- a/doc/classes/EditorInterface.xml
+++ b/doc/classes/EditorInterface.xml
@@ -109,6 +109,13 @@
Returns the editor's [EditorSettings] instance.
</description>
</method>
+ <method name="get_editor_theme" qualifiers="const">
+ <return type="Theme" />
+ <description>
+ Returns the editor's [Theme].
+ [b]Note:[/b] When creating custom editor UI, prefer accessing theme items directly from your GUI nodes using the [code]get_theme_*[/code] methods.
+ </description>
+ </method>
<method name="get_file_system_dock" qualifiers="const">
<return type="FileSystemDock" />
<description>
diff --git a/doc/classes/EditorPlugin.xml b/doc/classes/EditorPlugin.xml
index 8aea15c087..6f858942aa 100644
--- a/doc/classes/EditorPlugin.xml
+++ b/doc/classes/EditorPlugin.xml
@@ -246,7 +246,7 @@
# You can use a custom icon:
return preload("res://addons/my_plugin/my_plugin_icon.svg")
# Or use a built-in icon:
- return EditorInterface.get_base_control().get_theme_icon("Node", "EditorIcons")
+ return EditorInterface.get_editor_theme().get_icon("Node", "EditorIcons")
[/gdscript]
[csharp]
public override Texture2D _GetPluginIcon()
@@ -254,7 +254,7 @@
// You can use a custom icon:
return ResourceLoader.Load&lt;Texture2D&gt;("res://addons/my_plugin/my_plugin_icon.svg");
// Or use a built-in icon:
- return EditorInterface.Singleton.GetBaseControl().GetThemeIcon("Node", "EditorIcons");
+ return EditorInterface.Singleton.GetEditorTheme().GetIcon("Node", "EditorIcons");
}
[/csharp]
[/codeblocks]
@@ -354,7 +354,7 @@
return "My Super Cool Plugin 3000"
func _get_plugin_icon():
- return EditorInterface.get_base_control().get_theme_icon("Node", "EditorIcons")
+ return EditorInterface.get_editor_theme().get_icon("Node", "EditorIcons")
[/codeblock]
</description>
</method>
diff --git a/doc/classes/Node.xml b/doc/classes/Node.xml
index 7510d6bb64..c9c94eff36 100644
--- a/doc/classes/Node.xml
+++ b/doc/classes/Node.xml
@@ -100,10 +100,10 @@
<return type="void" />
<param index="0" name="event" type="InputEvent" />
<description>
- Called when an [InputEventKey] or [InputEventShortcut] hasn't been consumed by [method _input] or any GUI [Control] item. The input event propagates up through the node tree until a node consumes it.
+ Called when an [InputEventKey] or [InputEventShortcut] hasn't been consumed by [method _input] or any GUI [Control] item. It is called before [method _unhandled_key_input] and [method _unhandled_input]. The input event propagates up through the node tree until a node consumes it.
It is only called if shortcut processing is enabled, which is done automatically if this method is overridden, and can be toggled with [method set_process_shortcut_input].
To consume the input event and stop it propagating further to other nodes, [method Viewport.set_input_as_handled] can be called.
- This method can be used to handle shortcuts.
+ This method can be used to handle shortcuts. For generic GUI events, use [method _input] instead. Gameplay events should usually be handled with either [method _unhandled_input] or [method _unhandled_key_input].
[b]Note:[/b] This method is only called if the node is present in the scene tree (i.e. if it's not orphan).
</description>
</method>
@@ -111,10 +111,10 @@
<return type="void" />
<param index="0" name="event" type="InputEvent" />
<description>
- Called when an [InputEvent] hasn't been consumed by [method _input] or any GUI [Control] item. The input event propagates up through the node tree until a node consumes it.
+ Called when an [InputEvent] hasn't been consumed by [method _input] or any GUI [Control] item. It is called after [method _shortcut_input] and after [method _unhandled_key_input]. The input event propagates up through the node tree until a node consumes it.
It is only called if unhandled input processing is enabled, which is done automatically if this method is overridden, and can be toggled with [method set_process_unhandled_input].
To consume the input event and stop it propagating further to other nodes, [method Viewport.set_input_as_handled] can be called.
- For gameplay input, this and [method _unhandled_key_input] are usually a better fit than [method _input] as they allow the GUI to intercept the events first.
+ For gameplay input, this method is usually a better fit than [method _input], as GUI events need a higher priority. For keyboard shortcuts, consider using [method _shortcut_input] instead, as it is called before this method. Finally, to handle keyboard events, consider using [method _unhandled_key_input] for performance reasons.
[b]Note:[/b] This method is only called if the node is present in the scene tree (i.e. if it's not an orphan).
</description>
</method>
@@ -122,12 +122,11 @@
<return type="void" />
<param index="0" name="event" type="InputEvent" />
<description>
- Called when an [InputEventKey] hasn't been consumed by [method _input] or any GUI [Control] item. The input event propagates up through the node tree until a node consumes it.
+ Called when an [InputEventKey] hasn't been consumed by [method _input] or any GUI [Control] item. It is called after [method _shortcut_input] but before [method _unhandled_input]. The input event propagates up through the node tree until a node consumes it.
It is only called if unhandled key input processing is enabled, which is done automatically if this method is overridden, and can be toggled with [method set_process_unhandled_key_input].
To consume the input event and stop it propagating further to other nodes, [method Viewport.set_input_as_handled] can be called.
This method can be used to handle Unicode character input with [kbd]Alt[/kbd], [kbd]Alt + Ctrl[/kbd], and [kbd]Alt + Shift[/kbd] modifiers, after shortcuts were handled.
- For gameplay input, this and [method _unhandled_input] are usually a better fit than [method _input] as they allow the GUI to intercept the events first.
- This method also performs better than [method _unhandled_input], since unrelated events such as [InputEventMouseMotion] are automatically filtered.
+ For gameplay input, this and [method _unhandled_input] are usually a better fit than [method _input], as GUI events should be handled first. This method also performs better than [method _unhandled_input], since unrelated events such as [InputEventMouseMotion] are automatically filtered. For shortcuts, consider using [method _shortcut_input] instead.
[b]Note:[/b] This method is only called if the node is present in the scene tree (i.e. if it's not an orphan).
</description>
</method>
diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml
index d3b124dcde..150164e3a2 100644
--- a/doc/classes/ProjectSettings.xml
+++ b/doc/classes/ProjectSettings.xml
@@ -492,9 +492,6 @@
<member name="debug/gdscript/warnings/redundant_await" type="int" setter="" getter="" default="1">
When set to [code]warn[/code] or [code]error[/code], produces a warning or an error respectively when a function that is not a coroutine is called with await.
</member>
- <member name="debug/gdscript/warnings/redundant_for_variable_type" type="int" setter="" getter="" default="1">
- When set to [code]warn[/code] or [code]error[/code], produces a warning or an error respectively when a [code]for[/code] variable type specifier is a supertype of the inferred type.
- </member>
<member name="debug/gdscript/warnings/redundant_static_unload" type="int" setter="" getter="" default="1">
When set to [code]warn[/code] or [code]error[/code], produces a warning or an error respectively when the [code]@static_unload[/code] annotation is used in a script without any static variables.
</member>
@@ -2709,6 +2706,9 @@
<member name="xr/openxr/enabled" type="bool" setter="" getter="" default="false">
If [code]true[/code] Godot will setup and initialize OpenXR on startup.
</member>
+ <member name="xr/openxr/environment_blend_mode" type="int" setter="" getter="" default="&quot;0&quot;">
+ Specify how OpenXR should blend in the environment. This is specific to certain AR and passthrough devices where camera images are blended in by the XR compositor.
+ </member>
<member name="xr/openxr/form_factor" type="int" setter="" getter="" default="&quot;0&quot;">
Specify whether OpenXR should be configured for an HMD or a hand held device.
</member>
diff --git a/doc/classes/SurfaceTool.xml b/doc/classes/SurfaceTool.xml
index 494f41422f..5562342eac 100644
--- a/doc/classes/SurfaceTool.xml
+++ b/doc/classes/SurfaceTool.xml
@@ -119,7 +119,7 @@
Removes the index array by expanding the vertex array.
</description>
</method>
- <method name="generate_lod">
+ <method name="generate_lod" is_deprecated="true">
<return type="PackedInt32Array" />
<param index="0" name="nd_threshold" type="float" />
<param index="1" name="target_index_count" type="int" default="3" />
diff --git a/doc/classes/XRInterface.xml b/doc/classes/XRInterface.xml
index 7b741b43d8..99d6e67e51 100644
--- a/doc/classes/XRInterface.xml
+++ b/doc/classes/XRInterface.xml
@@ -188,6 +188,9 @@
<member name="ar_is_anchor_detection_enabled" type="bool" setter="set_anchor_detection_is_enabled" getter="get_anchor_detection_is_enabled" default="false">
On an AR interface, [code]true[/code] if anchor detection is enabled.
</member>
+ <member name="environment_blend_mode" type="int" setter="set_environment_blend_mode" getter="get_environment_blend_mode" enum="XRInterface.EnvironmentBlendMode" default="0">
+ Specify how XR should blend in the environment. This is specific to certain AR and passthrough devices where camera images are blended in by the XR compositor.
+ </member>
<member name="interface_is_primary" type="bool" setter="set_primary" getter="is_primary" default="false">
[code]true[/code] if this is the primary interface.
</member>
diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp
index 67e6326698..257d310075 100644
--- a/drivers/gles3/rasterizer_scene_gles3.cpp
+++ b/drivers/gles3/rasterizer_scene_gles3.cpp
@@ -2666,7 +2666,7 @@ RasterizerSceneGLES3::RasterizerSceneGLES3() {
global_defines += "#define MAX_GLOBAL_SHADER_UNIFORMS 256\n"; // TODO: this is arbitrary for now
global_defines += "\n#define MAX_LIGHT_DATA_STRUCTS " + itos(config->max_renderable_lights) + "\n";
global_defines += "\n#define MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS " + itos(MAX_DIRECTIONAL_LIGHTS) + "\n";
- global_defines += "\n#define MAX_FORWARD_LIGHTS uint(" + itos(config->max_lights_per_object) + ")\n";
+ global_defines += "\n#define MAX_FORWARD_LIGHTS " + itos(config->max_lights_per_object) + "u\n";
material_storage->shaders.scene_shader.initialize(global_defines);
scene_globals.shader_default_version = material_storage->shaders.scene_shader.version_create();
material_storage->shaders.scene_shader.version_bind_shader(scene_globals.shader_default_version, SceneShaderGLES3::MODE_COLOR);
diff --git a/editor/create_dialog.cpp b/editor/create_dialog.cpp
index ba189da779..26c89b0989 100644
--- a/editor/create_dialog.cpp
+++ b/editor/create_dialog.cpp
@@ -454,16 +454,10 @@ void CreateDialog::_sbox_input(const Ref<InputEvent> &p_ie) {
}
}
-void CreateDialog::_update_theme() {
- search_box->set_right_icon(search_options->get_editor_theme_icon(SNAME("Search")));
- favorite->set_icon(search_options->get_editor_theme_icon(SNAME("Favorites")));
-}
-
void CreateDialog::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
connect("confirmed", callable_mp(this, &CreateDialog::_confirmed));
- _update_theme();
} break;
case NOTIFICATION_EXIT_TREE: {
@@ -485,7 +479,8 @@ void CreateDialog::_notification(int p_what) {
favorites->add_theme_constant_override("icon_max_width", icon_width);
recent->set_fixed_icon_size(Size2(icon_width, icon_width));
- _update_theme();
+ search_box->set_right_icon(get_editor_theme_icon(SNAME("Search")));
+ favorite->set_icon(get_editor_theme_icon(SNAME("Favorites")));
} break;
}
}
diff --git a/editor/create_dialog.h b/editor/create_dialog.h
index 37579812cf..694efd1ee1 100644
--- a/editor/create_dialog.h
+++ b/editor/create_dialog.h
@@ -102,8 +102,6 @@ class CreateDialog : public ConfirmationDialog {
bool _is_class_disabled_by_feature_profile(const StringName &p_class) const;
void _load_favorites_and_history();
- void _update_theme();
-
protected:
void _notification(int p_what);
static void _bind_methods();
diff --git a/editor/debugger/editor_debugger_node.cpp b/editor/debugger/editor_debugger_node.cpp
index 99c66261e4..607f8f073e 100644
--- a/editor/debugger/editor_debugger_node.cpp
+++ b/editor/debugger/editor_debugger_node.cpp
@@ -63,8 +63,8 @@ EditorDebuggerNode::EditorDebuggerNode() {
singleton = this;
}
- add_theme_constant_override("margin_left", -EditorNode::get_singleton()->get_gui_base()->get_theme_stylebox(SNAME("BottomPanelDebuggerOverride"), EditorStringName(EditorStyles))->get_margin(SIDE_LEFT));
- add_theme_constant_override("margin_right", -EditorNode::get_singleton()->get_gui_base()->get_theme_stylebox(SNAME("BottomPanelDebuggerOverride"), EditorStringName(EditorStyles))->get_margin(SIDE_RIGHT));
+ add_theme_constant_override("margin_left", -EditorNode::get_singleton()->get_editor_theme()->get_stylebox(SNAME("BottomPanelDebuggerOverride"), EditorStringName(EditorStyles))->get_margin(SIDE_LEFT));
+ add_theme_constant_override("margin_right", -EditorNode::get_singleton()->get_editor_theme()->get_stylebox(SNAME("BottomPanelDebuggerOverride"), EditorStringName(EditorStyles))->get_margin(SIDE_RIGHT));
tabs = memnew(TabContainer);
tabs->set_tabs_visible(false);
@@ -119,7 +119,7 @@ ScriptEditorDebugger *EditorDebuggerNode::_add_debugger() {
if (tabs->get_tab_count() > 1) {
node->clear_style();
tabs->set_tabs_visible(true);
- tabs->add_theme_style_override("panel", EditorNode::get_singleton()->get_gui_base()->get_theme_stylebox(SNAME("DebuggerPanel"), EditorStringName(EditorStyles)));
+ tabs->add_theme_style_override("panel", EditorNode::get_singleton()->get_editor_theme()->get_stylebox(SNAME("DebuggerPanel"), EditorStringName(EditorStyles)));
}
if (!debugger_plugins.is_empty()) {
@@ -284,10 +284,10 @@ void EditorDebuggerNode::_notification(int p_what) {
switch (p_what) {
case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
if (tabs->get_tab_count() > 1) {
- add_theme_constant_override("margin_left", -EditorNode::get_singleton()->get_gui_base()->get_theme_stylebox(SNAME("BottomPanelDebuggerOverride"), EditorStringName(EditorStyles))->get_margin(SIDE_LEFT));
- add_theme_constant_override("margin_right", -EditorNode::get_singleton()->get_gui_base()->get_theme_stylebox(SNAME("BottomPanelDebuggerOverride"), EditorStringName(EditorStyles))->get_margin(SIDE_RIGHT));
+ add_theme_constant_override("margin_left", -EditorNode::get_singleton()->get_editor_theme()->get_stylebox(SNAME("BottomPanelDebuggerOverride"), EditorStringName(EditorStyles))->get_margin(SIDE_LEFT));
+ add_theme_constant_override("margin_right", -EditorNode::get_singleton()->get_editor_theme()->get_stylebox(SNAME("BottomPanelDebuggerOverride"), EditorStringName(EditorStyles))->get_margin(SIDE_RIGHT));
- tabs->add_theme_style_override("panel", EditorNode::get_singleton()->get_gui_base()->get_theme_stylebox(SNAME("DebuggerPanel"), EditorStringName(EditorStyles)));
+ tabs->add_theme_style_override("panel", EditorNode::get_singleton()->get_editor_theme()->get_stylebox(SNAME("DebuggerPanel"), EditorStringName(EditorStyles)));
}
} break;
diff --git a/editor/editor_autoload_settings.cpp b/editor/editor_autoload_settings.cpp
index 57172142e3..24daab3c12 100644
--- a/editor/editor_autoload_settings.cpp
+++ b/editor/editor_autoload_settings.cpp
@@ -882,7 +882,7 @@ EditorAutoloadSettings::EditorAutoloadSettings() {
error_message = memnew(Label);
error_message->hide();
error_message->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_RIGHT);
- error_message->add_theme_color_override("font_color", EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("error_color"), EditorStringName(Editor)));
+ error_message->add_theme_color_override("font_color", EditorNode::get_singleton()->get_editor_theme()->get_color(SNAME("error_color"), EditorStringName(Editor)));
add_child(error_message);
Label *l = memnew(Label);
diff --git a/editor/editor_interface.cpp b/editor/editor_interface.cpp
index 94040d4ca0..f8b1e1d2fb 100644
--- a/editor/editor_interface.cpp
+++ b/editor/editor_interface.cpp
@@ -45,6 +45,7 @@
#include "scene/gui/box_container.h"
#include "scene/gui/control.h"
#include "scene/main/window.h"
+#include "scene/resources/theme.h"
EditorInterface *EditorInterface::singleton = nullptr;
@@ -196,6 +197,10 @@ bool EditorInterface::is_plugin_enabled(const String &p_plugin) const {
// Editor GUI.
+Ref<Theme> EditorInterface::get_editor_theme() const {
+ return EditorNode::get_singleton()->get_editor_theme();
+}
+
Control *EditorInterface::get_base_control() const {
return EditorNode::get_singleton()->get_gui_base();
}
@@ -405,6 +410,7 @@ void EditorInterface::_bind_methods() {
// Editor GUI.
+ ClassDB::bind_method(D_METHOD("get_editor_theme"), &EditorInterface::get_editor_theme);
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);
diff --git a/editor/editor_interface.h b/editor/editor_interface.h
index 2ac1336202..932b18070c 100644
--- a/editor/editor_interface.h
+++ b/editor/editor_interface.h
@@ -50,6 +50,7 @@ class Mesh;
class Node;
class ScriptEditor;
class Texture2D;
+class Theme;
class VBoxContainer;
class Window;
@@ -84,11 +85,10 @@ public:
void set_plugin_enabled(const String &p_plugin, bool p_enabled);
bool is_plugin_enabled(const String &p_plugin) const;
- void add_editor_plugin(EditorPlugin *p_plugin);
- void remove_editor_plugin(EditorPlugin *p_plugin);
-
// Editor GUI.
+ Ref<Theme> get_editor_theme() const;
+
Control *get_base_control() const;
VBoxContainer *get_editor_main_screen() const;
ScriptEditor *get_script_editor() const;
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index 6dc8d4e152..df58f93bf4 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -493,7 +493,6 @@ void EditorNode::_update_theme(bool p_skip_creation) {
scene_root_parent->add_theme_style_override("panel", theme->get_stylebox(SNAME("Content"), EditorStringName(EditorStyles)));
bottom_panel->add_theme_style_override("panel", theme->get_stylebox(SNAME("BottomPanel"), EditorStringName(EditorStyles)));
main_menu->add_theme_style_override("hover", theme->get_stylebox(SNAME("MenuHover"), EditorStringName(EditorStyles)));
- prev_scene->set_icon(theme->get_icon(SNAME("PrevScene"), EditorStringName(EditorIcons)));
distraction_free->set_icon(theme->get_icon(SNAME("DistractionFree"), EditorStringName(EditorIcons)));
bottom_panel_raise->set_icon(theme->get_icon(SNAME("ExpandBottomDock"), EditorStringName(EditorIcons)));
@@ -3782,7 +3781,6 @@ Error EditorNode::load_scene(const String &p_scene, bool p_ignore_broken_deps, b
editor_folding.save_scene_folding(new_scene, lpath);
}
- prev_scene->set_disabled(previous_scenes.size() == 0);
opening_prev = false;
EditorDebuggerNode::get_singleton()->update_live_edit_root();
@@ -7153,15 +7151,6 @@ EditorNode::EditorNode() {
main_menu->add_child(file_menu);
main_menu->set_menu_tooltip(0, TTR("Operations with scene files."));
- prev_scene = memnew(Button);
- prev_scene->set_flat(true);
- prev_scene->set_tooltip_text(TTR("Go to previously opened scene."));
- prev_scene->set_disabled(true);
- prev_scene->connect("pressed", callable_mp(this, &EditorNode::_menu_option).bind(FILE_OPEN_PREV));
- gui_base->add_child(prev_scene);
- prev_scene->set_position(Point2(3, 24));
- prev_scene->hide();
-
accept = memnew(AcceptDialog);
accept->set_unparent_when_invisible(true);
diff --git a/editor/editor_node.h b/editor/editor_node.h
index a83570b2ea..5ecb3186e1 100644
--- a/editor/editor_node.h
+++ b/editor/editor_node.h
@@ -348,7 +348,6 @@ private:
PopupMenu *tool_menu = nullptr;
PopupMenu *export_as_menu = nullptr;
Button *export_button = nullptr;
- Button *prev_scene = nullptr;
Button *search_button = nullptr;
TextureProgressBar *audio_vu = nullptr;
diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp
index 54fd8d63af..98f0f70101 100644
--- a/editor/editor_themes.cpp
+++ b/editor/editor_themes.cpp
@@ -41,6 +41,7 @@
#include "scene/resources/style_box_flat.h"
#include "scene/resources/style_box_line.h"
#include "scene/resources/style_box_texture.h"
+#include "scene/theme/theme_db.h"
#include "modules/modules_enabled.gen.h" // For svg.
#ifdef MODULE_SVG_ENABLED
@@ -214,6 +215,103 @@ void EditorColorMap::create() {
add_conversion_exception("Breakpoint");
}
+Vector<StringName> EditorTheme::editor_theme_types;
+
+// TODO: Refactor these and corresponding Theme methods to use the bool get_xxx(r_value) pattern internally.
+
+// Keep in sync with Theme::get_color.
+Color EditorTheme::get_color(const StringName &p_name, const StringName &p_theme_type) const {
+ if (color_map.has(p_theme_type) && color_map[p_theme_type].has(p_name)) {
+ return color_map[p_theme_type][p_name];
+ } else {
+ if (editor_theme_types.has(p_theme_type)) {
+ WARN_PRINT(vformat("Trying to access a non-existing editor theme color '%s' in '%s'.", p_name, p_theme_type));
+ }
+ return Color();
+ }
+}
+
+// Keep in sync with Theme::get_constant.
+int EditorTheme::get_constant(const StringName &p_name, const StringName &p_theme_type) const {
+ if (constant_map.has(p_theme_type) && constant_map[p_theme_type].has(p_name)) {
+ return constant_map[p_theme_type][p_name];
+ } else {
+ if (editor_theme_types.has(p_theme_type)) {
+ WARN_PRINT(vformat("Trying to access a non-existing editor theme constant '%s' in '%s'.", p_name, p_theme_type));
+ }
+ return 0;
+ }
+}
+
+// Keep in sync with Theme::get_font.
+Ref<Font> EditorTheme::get_font(const StringName &p_name, const StringName &p_theme_type) const {
+ if (font_map.has(p_theme_type) && font_map[p_theme_type].has(p_name) && font_map[p_theme_type][p_name].is_valid()) {
+ return font_map[p_theme_type][p_name];
+ } else if (has_default_font()) {
+ if (editor_theme_types.has(p_theme_type)) {
+ WARN_PRINT(vformat("Trying to access a non-existing editor theme font '%s' in '%s'.", p_name, p_theme_type));
+ }
+ return default_font;
+ } else {
+ if (editor_theme_types.has(p_theme_type)) {
+ WARN_PRINT(vformat("Trying to access a non-existing editor theme font '%s' in '%s'.", p_name, p_theme_type));
+ }
+ return ThemeDB::get_singleton()->get_fallback_font();
+ }
+}
+
+// Keep in sync with Theme::get_font_size.
+int EditorTheme::get_font_size(const StringName &p_name, const StringName &p_theme_type) const {
+ if (font_size_map.has(p_theme_type) && font_size_map[p_theme_type].has(p_name) && (font_size_map[p_theme_type][p_name] > 0)) {
+ return font_size_map[p_theme_type][p_name];
+ } else if (has_default_font_size()) {
+ if (editor_theme_types.has(p_theme_type)) {
+ WARN_PRINT(vformat("Trying to access a non-existing editor theme font size '%s' in '%s'.", p_name, p_theme_type));
+ }
+ return default_font_size;
+ } else {
+ if (editor_theme_types.has(p_theme_type)) {
+ WARN_PRINT(vformat("Trying to access a non-existing editor theme font size '%s' in '%s'.", p_name, p_theme_type));
+ }
+ return ThemeDB::get_singleton()->get_fallback_font_size();
+ }
+}
+
+// Keep in sync with Theme::get_icon.
+Ref<Texture2D> EditorTheme::get_icon(const StringName &p_name, const StringName &p_theme_type) const {
+ if (icon_map.has(p_theme_type) && icon_map[p_theme_type].has(p_name) && icon_map[p_theme_type][p_name].is_valid()) {
+ return icon_map[p_theme_type][p_name];
+ } else {
+ if (editor_theme_types.has(p_theme_type)) {
+ WARN_PRINT(vformat("Trying to access a non-existing editor theme icon '%s' in '%s'.", p_name, p_theme_type));
+ }
+ return ThemeDB::get_singleton()->get_fallback_icon();
+ }
+}
+
+// Keep in sync with Theme::get_stylebox.
+Ref<StyleBox> EditorTheme::get_stylebox(const StringName &p_name, const StringName &p_theme_type) const {
+ if (style_map.has(p_theme_type) && style_map[p_theme_type].has(p_name) && style_map[p_theme_type][p_name].is_valid()) {
+ return style_map[p_theme_type][p_name];
+ } else {
+ if (editor_theme_types.has(p_theme_type)) {
+ WARN_PRINT(vformat("Trying to access a non-existing editor theme stylebox '%s' in '%s'.", p_name, p_theme_type));
+ }
+ return ThemeDB::get_singleton()->get_fallback_stylebox();
+ }
+}
+
+EditorTheme::EditorTheme() {
+ if (editor_theme_types.is_empty()) {
+ editor_theme_types.append(EditorStringName(Editor));
+ editor_theme_types.append(EditorStringName(EditorFonts));
+ editor_theme_types.append(EditorStringName(EditorIcons));
+ editor_theme_types.append(EditorStringName(EditorStyles));
+ }
+}
+
+// Editor theme generatior.
+
static Ref<StyleBoxTexture> make_stylebox(Ref<Texture2D> p_texture, float p_left, float p_top, float p_right, float p_bottom, float p_margin_left = -1, float p_margin_top = -1, float p_margin_right = -1, float p_margin_bottom = -1, bool p_draw_center = true) {
Ref<StyleBoxTexture> style(memnew(StyleBoxTexture));
style->set_texture(p_texture);
@@ -430,7 +528,7 @@ void editor_register_and_generate_icons(Ref<Theme> p_theme, bool p_dark_theme, f
Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
OS::get_singleton()->benchmark_begin_measure("create_editor_theme");
- Ref<Theme> theme = Ref<Theme>(memnew(Theme));
+ Ref<EditorTheme> theme = memnew(EditorTheme);
// Controls may rely on the scale for their internal drawing logic.
theme->set_default_base_scale(EDSCALE);
@@ -846,13 +944,12 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
// even though it may not be immediately obvious at first.
Ref<StyleBoxFlat> toolbar_stylebox = memnew(StyleBoxFlat);
toolbar_stylebox->set_bg_color(accent_color * Color(1, 1, 1, 0.1));
- toolbar_stylebox->set_corner_radius(CORNER_TOP_LEFT, corner_radius * EDSCALE);
- toolbar_stylebox->set_corner_radius(CORNER_TOP_RIGHT, corner_radius * EDSCALE);
toolbar_stylebox->set_anti_aliased(false);
// Add an underline to the StyleBox, but prevent its minimum vertical size from changing.
toolbar_stylebox->set_border_color(accent_color);
toolbar_stylebox->set_border_width(SIDE_BOTTOM, Math::round(2 * EDSCALE));
toolbar_stylebox->set_content_margin(SIDE_BOTTOM, 0);
+ toolbar_stylebox->set_expand_margin_all(2 * EDSCALE);
theme->set_stylebox("ContextualToolbar", EditorStringName(EditorStyles), toolbar_stylebox);
// Script Editor
diff --git a/editor/editor_themes.h b/editor/editor_themes.h
index 5949c17201..7ca0050103 100644
--- a/editor/editor_themes.h
+++ b/editor/editor_themes.h
@@ -53,6 +53,22 @@ public:
static HashSet<StringName> &get_color_conversion_exceptions() { return color_conversion_exceptions; };
};
+class EditorTheme : public Theme {
+ GDCLASS(EditorTheme, Theme);
+
+ static Vector<StringName> editor_theme_types;
+
+public:
+ virtual Color get_color(const StringName &p_name, const StringName &p_theme_type) const override;
+ virtual int get_constant(const StringName &p_name, const StringName &p_theme_type) const override;
+ virtual Ref<Font> get_font(const StringName &p_name, const StringName &p_theme_type) const override;
+ virtual int get_font_size(const StringName &p_name, const StringName &p_theme_type) const override;
+ virtual Ref<Texture2D> get_icon(const StringName &p_name, const StringName &p_theme_type) const override;
+ virtual Ref<StyleBox> get_stylebox(const StringName &p_name, const StringName &p_theme_type) const override;
+
+ EditorTheme();
+};
+
Ref<Theme> create_editor_theme(Ref<Theme> p_theme = nullptr);
Ref<Theme> create_custom_theme(Ref<Theme> p_theme = nullptr);
diff --git a/editor/export/editor_export_platform.cpp b/editor/export/editor_export_platform.cpp
index d65f10c441..c07f17b46f 100644
--- a/editor/export/editor_export_platform.cpp
+++ b/editor/export/editor_export_platform.cpp
@@ -73,12 +73,12 @@ bool EditorExportPlatform::fill_log_messages(RichTextLabel *p_log, Error p_err)
p_log->add_text(" - ");
if (p_err == OK) {
if (get_worst_message_type() >= EditorExportPlatform::EXPORT_MESSAGE_WARNING) {
- p_log->add_image(EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("StatusWarning")), 16 * EDSCALE, 16 * EDSCALE, Color(1.0, 1.0, 1.0), INLINE_ALIGNMENT_CENTER);
+ p_log->add_image(p_log->get_editor_theme_icon(SNAME("StatusWarning")), 16 * EDSCALE, 16 * EDSCALE, Color(1.0, 1.0, 1.0), INLINE_ALIGNMENT_CENTER);
p_log->add_text(" ");
p_log->add_text(TTR("Completed with warnings."));
has_messages = true;
} else {
- p_log->add_image(EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("StatusSuccess")), 16 * EDSCALE, 16 * EDSCALE, Color(1.0, 1.0, 1.0), INLINE_ALIGNMENT_CENTER);
+ p_log->add_image(p_log->get_editor_theme_icon(SNAME("StatusSuccess")), 16 * EDSCALE, 16 * EDSCALE, Color(1.0, 1.0, 1.0), INLINE_ALIGNMENT_CENTER);
p_log->add_text(" ");
p_log->add_text(TTR("Completed successfully."));
if (msg_count > 0) {
@@ -86,7 +86,7 @@ bool EditorExportPlatform::fill_log_messages(RichTextLabel *p_log, Error p_err)
}
}
} else {
- p_log->add_image(EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("StatusError")), 16 * EDSCALE, 16 * EDSCALE, Color(1.0, 1.0, 1.0), INLINE_ALIGNMENT_CENTER);
+ p_log->add_image(p_log->get_editor_theme_icon(SNAME("StatusError")), 16 * EDSCALE, 16 * EDSCALE, Color(1.0, 1.0, 1.0), INLINE_ALIGNMENT_CENTER);
p_log->add_text(" ");
p_log->add_text(TTR("Failed."));
has_messages = true;
@@ -99,20 +99,20 @@ bool EditorExportPlatform::fill_log_messages(RichTextLabel *p_log, Error p_err)
p_log->set_table_column_expand(1, true);
for (int m = 0; m < msg_count; m++) {
EditorExportPlatform::ExportMessage msg = get_message(m);
- Color color = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("font_color"), SNAME("Label"));
+ Color color = p_log->get_theme_color(SNAME("font_color"), SNAME("Label"));
Ref<Texture> icon;
switch (msg.msg_type) {
case EditorExportPlatform::EXPORT_MESSAGE_INFO: {
- color = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("font_color"), EditorStringName(Editor)) * Color(1, 1, 1, 0.6);
+ color = p_log->get_theme_color(SNAME("font_color"), EditorStringName(Editor)) * Color(1, 1, 1, 0.6);
} break;
case EditorExportPlatform::EXPORT_MESSAGE_WARNING: {
- icon = EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("Warning"));
- color = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("warning_color"), EditorStringName(Editor));
+ icon = p_log->get_editor_theme_icon(SNAME("Warning"));
+ color = p_log->get_theme_color(SNAME("warning_color"), EditorStringName(Editor));
} break;
case EditorExportPlatform::EXPORT_MESSAGE_ERROR: {
- icon = EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("Error"));
- color = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("error_color"), EditorStringName(Editor));
+ icon = p_log->get_editor_theme_icon(SNAME("Error"));
+ color = p_log->get_theme_color(SNAME("error_color"), EditorStringName(Editor));
} break;
default:
break;
diff --git a/editor/export/project_export.cpp b/editor/export/project_export.cpp
index 24a9e2ae36..58e4dc1069 100644
--- a/editor/export/project_export.cpp
+++ b/editor/export/project_export.cpp
@@ -1328,7 +1328,7 @@ ProjectExportDialog::ProjectExportDialog() {
script_key->connect("text_changed", callable_mp(this, &ProjectExportDialog::_script_encryption_key_changed));
script_key_error = memnew(Label);
script_key_error->set_text(String::utf8("• ") + TTR("Invalid Encryption Key (must be 64 hexadecimal characters long)"));
- script_key_error->add_theme_color_override("font_color", EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("error_color"), EditorStringName(Editor)));
+ script_key_error->add_theme_color_override("font_color", EditorNode::get_singleton()->get_editor_theme()->get_color(SNAME("error_color"), EditorStringName(Editor)));
sec_vb->add_margin_child(TTR("Encryption Key (256-bits as hexadecimal):"), script_key);
sec_vb->add_child(script_key_error);
sections->add_child(sec_vb);
@@ -1413,12 +1413,12 @@ ProjectExportDialog::ProjectExportDialog() {
export_error = memnew(Label);
main_vb->add_child(export_error);
export_error->hide();
- export_error->add_theme_color_override("font_color", EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("error_color"), EditorStringName(Editor)));
+ export_error->add_theme_color_override("font_color", EditorNode::get_singleton()->get_editor_theme()->get_color(SNAME("error_color"), EditorStringName(Editor)));
export_warning = memnew(Label);
main_vb->add_child(export_warning);
export_warning->hide();
- export_warning->add_theme_color_override("font_color", EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("warning_color"), EditorStringName(Editor)));
+ export_warning->add_theme_color_override("font_color", EditorNode::get_singleton()->get_editor_theme()->get_color(SNAME("warning_color"), EditorStringName(Editor)));
export_templates_error = memnew(HBoxContainer);
main_vb->add_child(export_templates_error);
@@ -1426,7 +1426,7 @@ ProjectExportDialog::ProjectExportDialog() {
Label *export_error2 = memnew(Label);
export_templates_error->add_child(export_error2);
- export_error2->add_theme_color_override("font_color", EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("error_color"), EditorStringName(Editor)));
+ export_error2->add_theme_color_override("font_color", EditorNode::get_singleton()->get_editor_theme()->get_color(SNAME("error_color"), EditorStringName(Editor)));
export_error2->set_text(String::utf8("• ") + TTR("Export templates for this platform are missing:") + " ");
result_dialog = memnew(AcceptDialog);
diff --git a/editor/icons/AABB.svg b/editor/icons/AABB.svg
index 7db093cc0d..94bf00d7bf 100644
--- a/editor/icons/AABB.svg
+++ b/editor/icons/AABB.svg
@@ -1 +1 @@
-<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m5 1a3 3 0 0 0 -3 3 3 3 0 0 0 .77734 2.0117 3 3 0 0 0 -2.7773 2.9883 3 3 0 0 0 3 3h2v-5h2v-6h-2zm6 0v5.1738a3 3 0 0 0 -1-.17383v-2h-2v8h2a3 3 0 0 0 3-3 3 3 0 0 0 3-3 3 3 0 0 0 -3-3v-2h-2zm-6 2v2a1 1 0 0 1 -1-1 1 1 0 0 1 1-1zm8 2a1 1 0 0 1 1 1 1 1 0 0 1 -1 1zm-10 3v2a1 1 0 0 1 -1-1 1 1 0 0 1 1-1zm7 0a1 1 0 0 1 1 1 1 1 0 0 1 -1 1z" fill="#ee5677"/><path d="m8 4v8h2a3 3 0 0 0 3-3 3 3 0 0 0 -3-3v-2zm-5 2a3 3 0 0 0 -3 3 3 3 0 0 0 3 3h2v-6zm0 2v2a1 1 0 0 1 -1-1 1 1 0 0 1 1-1zm7 0a1 1 0 0 1 1 1 1 1 0 0 1 -1 1z" fill="#fff" fill-opacity=".23529"/></svg>
+<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M5 1a3 3 0 0 0-2.223 5.012A3 3 0 0 0 3 12h2V7h2V1H5zm6 0v5.174A3 3 0 0 0 10 6V4H8v8h2a3 3 0 0 0 3-3 3 3 0 0 0 0-6V1h-2zM5 3v2a1 1 0 0 1 0-2zm8 2a1 1 0 0 1 0 2zM3 8v2a1 1 0 0 1 0-2zm7 0a1 1 0 0 1 0 2z" fill="#ee5677"/><path d="M8 4v8h2a3 3 0 0 0 0-6V4zM3 6a3 3 0 0 0 0 6h2V6zm0 2v2a1 1 0 0 1 0-2zm7 0a1 1 0 0 1 0 2z" fill="#fff" fill-opacity=".235"/></svg>
diff --git a/editor/icons/Array.svg b/editor/icons/Array.svg
index 068007bb29..fbf0df8f68 100644
--- a/editor/icons/Array.svg
+++ b/editor/icons/Array.svg
@@ -1 +1 @@
-<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m4 4a3 3 0 0 0 -3 3 3 3 0 0 0 3 3h2v-6zm6 0a3 3 0 0 0 -3 3v3h2v-3a1 1 0 0 1 1-1h1v-2zm4 0a3 3 0 0 0 -3 3v3h2v-3a1 1 0 0 1 1-1h1v-2zm-10 2v2a1 1 0 0 1 -1-1 1 1 0 0 1 1-1z" fill="#e0e0e0"/></svg>
+<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M4 4a3 3 0 0 0 0 6h2V4zm6 0a3 3 0 0 0-3 3v3h2V7a1 1 0 0 1 1-1h1V4zm4 0a3 3 0 0 0-3 3v3h2V7a1 1 0 0 1 1-1h1V4zM4 6v2a1 1 0 0 1 0-2z" fill="#e0e0e0"/></svg>
diff --git a/editor/icons/Basis.svg b/editor/icons/Basis.svg
index e425cf3bcd..6754da4213 100644
--- a/editor/icons/Basis.svg
+++ b/editor/icons/Basis.svg
@@ -1 +1 @@
-<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m0 2v8h2a3 3 0 0 0 3-3 3 3 0 0 0 -3-3v-2zm10 0v2h2v-2zm-3 2a2 2 0 0 0 -1.7324 1 2 2 0 0 0 0 2 2 2 0 0 0 1.7324 1h-2v2h2a2 2 0 0 0 1.7324-1 2 2 0 0 0 0-2 2 2 0 0 0 -1.7324-1h2v-2zm7 0a2 2 0 0 0 -1.7324 1 2 2 0 0 0 0 2 2 2 0 0 0 1.7324 1h-2v-2h-2v4h4a2 2 0 0 0 1.7324-1 2 2 0 0 0 0-2 2 2 0 0 0 -1.7324-1h2v-2zm-12 2a1 1 0 0 1 1 1 1 1 0 0 1 -1 1z" fill="#e1ec41"/><path d="m10 2v2h2v-2zm0 4v4h2v-4z" fill="#fff" fill-opacity=".39216"/></svg>
+<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M0 2v8h2a3 3 0 0 0 0-6V2zm10 0v2h2V2zM7 4a2 2 0 0 0 0 4H5v2h2a2 2 0 0 0 0-4h2V4zm7 0a2 2 0 0 0 0 4h-2V6h-2v4h4a2 2 0 0 0 0-4h2V4zM2 6a1 1 0 0 1 1 1 1 1 0 0 1-1 1z" fill="#e1ec41"/><path d="M10 2v2h2V2zm0 4v4h2V6z" fill="#fff" fill-opacity=".4"/></svg>
diff --git a/editor/icons/CheckBox.svg b/editor/icons/CheckBox.svg
index 32eaf2d212..cbe203c797 100644
--- a/editor/icons/CheckBox.svg
+++ b/editor/icons/CheckBox.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 2c-1.1046 0-2 .89543-2 2v9c0 1.1046.89543 2 2 2h9c1.1046 0 2-.89543 2-2v-4.9277l-2 2v2.9277h-9v-9h6.5859l2-2zm9.3633 2.0508-4.9492 4.9492-1.4141-1.4141-1.4141 1.4141 2.8281 2.8281 6.3633-6.3633z" fill="#8eef97"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M3 2a2 2 0 0 0-2 2v9a2 2 0 0 0 2 2h9a2 2 0 0 0 2-2V8l-2 2v3H3V4h7l2-2zm9.363 2.05L7.414 9 6 7.586 4.586 9l2.828 2.828 6.363-6.363z" fill="#8eef97"/></svg>
diff --git a/editor/icons/Color.svg b/editor/icons/Color.svg
index 5c6fca1876..a03753989f 100644
--- a/editor/icons/Color.svg
+++ b/editor/icons/Color.svg
@@ -1 +1 @@
-<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m4 4a3 3 0 0 0 -3 3 3 3 0 0 0 3 3h1v-2h-1a1 1 0 0 1 -1-1 1 1 0 0 1 1-1h1v-2z" fill="#ff5f5f"/><path d="m14 4a3 3 0 0 0 -3 3v3h2v-3a1 1 0 0 1 1-1h1v-2z" fill="#5fb2ff"/><path d="m6 2v5a3 3 0 0 0 3 3h1v-2h-1a1 1 0 0 1 -1-1v-5z" fill="#5fff97"/></svg>
+<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M4 4a3 3 0 0 0 0 6h1V8H4a1 1 0 0 1 0-2h1V4z" fill="#ff5f5f"/><path d="M6 2v5a3 3 0 0 0 3 3h1V8H9a1 1 0 0 1-1-1V2z" fill="#5fff97"/><path d="M14 4a3 3 0 0 0-3 3v3h2V7a1 1 0 0 1 1-1h1V4z" fill="#5fb2ff"/></svg>
diff --git a/editor/icons/Dictionary.svg b/editor/icons/Dictionary.svg
index 0284e847d9..98c9384184 100644
--- a/editor/icons/Dictionary.svg
+++ b/editor/icons/Dictionary.svg
@@ -1 +1 @@
-<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 2v2a3 3 0 0 0 -3 3 3 3 0 0 0 3 3h2v-8zm3 0v2h2v-2zm7 0v5a3 3 0 0 0 3 3v-2a1 1 0 0 1 -1-1v-1h1v-2h-1v-2zm-2 2a3 3 0 0 0 -3 3 3 3 0 0 0 3 3h1v-2h-1a1 1 0 0 1 -1-1 1 1 0 0 1 1-1h1v-2zm-3 3v-1h-2v4h2zm-5-1v2a1 1 0 0 1 -1-1 1 1 0 0 1 1-1z" fill="#54ed9e"/></svg>
+<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M3 2v2a3 3 0 0 0 0 6h2V2zm3 0v2h2V2zm7 0v5a3 3 0 0 0 3 3V8a1 1 0 0 1-1-1V6h1V4h-1V2zm-2 2a3 3 0 0 0 0 6h1V8h-1a1 1 0 0 1 0-2h1V4zM8 7V6H6v4h2zM3 6v2a1 1 0 0 1 0-2z" fill="#54ed9e"/></svg>
diff --git a/editor/icons/GraphEdit.svg b/editor/icons/GraphEdit.svg
index fd633a4662..24685e0caf 100644
--- a/editor/icons/GraphEdit.svg
+++ b/editor/icons/GraphEdit.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M11 1c-.554 0-1 .446-1 1v3c0 .554.446 1 1 1h3c.554 0 1-.446 1-1V2c0-.554-.446-1-1-1h-3zM9 3.883L6.732 5.016c.17.292.268.628.268.984v1.117l2.268-1.133A1.964 1.964 0 019 5V3.883zM2 5c-.554 0-1 .446-1 1v4c0 .554.446 1 1 1h3c.554 0 1-.446 1-1V6c0-.554-.446-1-1-1H2zm5 3.883V10c0 .356-.099.692-.268.984L9 12.117V11c0-.356.099-.692.268-.984L7 8.883zM11 10c-.554 0-1 .446-1 1v3c0 .554.446 1 1 1h3c.554 0 1-.446 1-1v-3c0-.554-.446-1-1-1h-3z" color="#000" fill="#8eef97"/><path d="M5 3h6" fill="none"/><rect width="3" height="1" x="-5" y="6.5" ry=".5" fill="#4a4a4a"/></svg>
+<svg height="16" width="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="M11 1a1 1 0 0 0-1 1v3a1 1 0 0 0 1 1h3a1 1 0 0 0 1-1V2a1 1 0 0 0-1-1zM6.732 5A2 2 0 0 1 7 6v1.117L9.268 6A2 2 0 0 1 9 5V3.883zM2 5a1 1 0 0 0-1 1v4a1 1 0 0 0 1 1h3a1 1 0 0 0 1-1V6a1 1 0 0 0-1-1zm5 3.883V10a2 2 0 0 1-.268 1L9 12.117V11a2 2 0 0 1 .268-1zM11 10a1 1 0 0 0-1 1v3a1 1 0 0 0 1 1h3a1 1 0 0 0 1-1v-3a1 1 0 0 0-1-1z" fill="#8eef97"/></svg>
diff --git a/editor/icons/GraphElement.svg b/editor/icons/GraphElement.svg
index 5629993c25..f579f59656 100644
--- a/editor/icons/GraphElement.svg
+++ b/editor/icons/GraphElement.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M8 2a6 6 0 00-6 6 6 6 0 006 6 6 6 0 006-6 6 6 0 00-6-6zm0 2a4 4 0 014 4 4 4 0 01-4 4 4 4 0 01-4-4 4 4 0 014-4zm0 2a2 2 0 100 4 2 2 0 000-4z" fill="#8eef97"/></svg>
+<svg height="16" width="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><circle cx="8" cy="8" r="2" fill="#8eef97"/><circle cx="8" cy="8" r="5" stroke-width="2" stroke="#8eef97" fill="none"/></svg>
diff --git a/editor/icons/GraphNode.svg b/editor/icons/GraphNode.svg
index 9bef701ffd..83f666ed06 100644
--- a/editor/icons/GraphNode.svg
+++ b/editor/icons/GraphNode.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M4.846 2A1.841 1.841 0 003 3.846V4h10v-.154A1.841 1.841 0 0011.154 2H4.846zM3 5v1a3 3 0 013 3 3 3 0 01-3 3v.154C3 13.177 3.823 14 4.846 14h6.308A1.841 1.841 0 0013 12.154V12a3 3 0 01-3-3 3 3 0 013-3V5H3zm0 2a2 2 0 00-2 2 2 2 0 002 2 2 2 0 002-2 2 2 0 00-2-2zm10 0a2 2 0 00-2 2 2 2 0 002 2 2 2 0 002-2 2 2 0 00-2-2z" fill="#8eef97"/></svg>
+<svg height="16" width="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="M5 2a2 2 0 0 0-2 2h10a2 2 0 0 0-2-2zM3 5v1a3 3 0 0 1 0 6 2 2 0 0 0 2 2h6a2 2 0 0 0 2-2 3 3 0 0 1 0-6V5zm0 2a2 2 0 0 0 0 4 2 2 0 0 0 0-4zm10 0a2 2 0 0 0 0 4 2 2 0 0 0 0-4z" fill="#8eef97"/></svg>
diff --git a/editor/icons/GuiToggleOnMirroredDisabled.svg b/editor/icons/GuiToggleOnDisabledMirrored.svg
index bbf9b0d95d..bbf9b0d95d 100644
--- a/editor/icons/GuiToggleOnMirroredDisabled.svg
+++ b/editor/icons/GuiToggleOnDisabledMirrored.svg
diff --git a/editor/icons/IOSDeviceWired.svg b/editor/icons/IOSDeviceWired.svg
index 15bb0b4523..a138458849 100644
--- a/editor/icons/IOSDeviceWired.svg
+++ b/editor/icons/IOSDeviceWired.svg
@@ -1 +1 @@
-<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" width="16" height="16" viewBox="0 0 4.233 4.233"><path fill="#e0e0e0" d="M1.795.265a.53.53 0 0 0-.53.529v2.645c0 .293.237.53.53.53h1.587a.53.53 0 0 0 .53-.53V.794a.53.53 0 0 0-.53-.53zm0 .529h.256v.165a.247.247 0 0 0 .247.248h.58A.247.247 0 0 0 3.126.96V.794h.256v2.645H1.795z"/><path fill="#e0e0e0" d="M1.743 2.964a.178.178 0 0 0-.178-.178H1.18a.534.534 0 0 0-.503-.356v.178H.32v.178h.356v.356H.32v.178h.356v.178a.533.533 0 0 0 .502-.356h.387c.099 0 .178-.08.178-.178z" style="stroke-width:.177922"/></svg>
+<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" width="16" height="16" viewBox="0 0 16 16"><path fill="#e0e0e0" d="M7 1a2 2 0 0 0-2 2v7.5h-.4a2 2 0 0 0-2-1.5v.8H1v.8h1.6v1.2H1v.8h1.6v.8a2 2 0 0 0 2-1.5H5V13a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2V3a2 2 0 0 0-2-2zm0 2h1v.6a1 1 0 0 0 1 1h2a1 1 0 0 0 1-1V3h1v10H7z"/></svg>
diff --git a/editor/icons/IOSDeviceWireless.svg b/editor/icons/IOSDeviceWireless.svg
index 91fc679460..a07fa85a6b 100644
--- a/editor/icons/IOSDeviceWireless.svg
+++ b/editor/icons/IOSDeviceWireless.svg
@@ -1 +1 @@
-<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" width="16" height="16" viewBox="0 0 4.233 4.233"><path fill="#e0e0e0" d="M1.795.265a.53.53 0 0 0-.53.529v2.645c0 .293.237.53.53.53h1.587a.53.53 0 0 0 .53-.53V.794a.53.53 0 0 0-.53-.53zm0 .529h.256v.165a.247.247 0 0 0 .247.248h.58A.247.247 0 0 0 3.126.96V.794h.256v2.645H1.795z"/><path d="M1.034 2.457a.444.444 0 0 1-.159-.34.444.444 0 0 1 .16-.34m-.286 1.02a.889.889 0 0 1-.318-.68.889.889 0 0 1 .318-.681" style="fill:none;fill-opacity:.996078;stroke:#e0e0e0;stroke-width:.222194;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:16.5;stroke-opacity:1;paint-order:stroke markers fill"/></svg>
+<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" width="16" height="16" viewBox="0 0 16 16"><path fill="#e0e0e0" d="M7 1a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2V3a2 2 0 0 0-2-2zm0 2h1v.6a1 1 0 0 0 1 1h2a1 1 0 0 0 1-1V3h1v10H7z"/><path d="M3.75 9a1.75 1.75 0 0 1 0-2.5m-1 4a3.5 3.5 0 0 1 0-5.5" fill="none" stroke="#e0e0e0" stroke-linecap="round"/></svg>
diff --git a/editor/icons/IOSSimulator.svg b/editor/icons/IOSSimulator.svg
index 59ab11a8a5..cb5e877a84 100644
--- a/editor/icons/IOSSimulator.svg
+++ b/editor/icons/IOSSimulator.svg
@@ -1 +1 @@
-<svg xmlns="http://www.w3.org/2000/svg" height="16" viewBox="0 0 4.233 4.233" width="16"><path d="M1.399.735H.32v2.763h1.078c0-.004-.006-.006-.006-.01V.745c0-.004.006-.006.006-.01z" fill="#4bb7f8"/><path d="M.49.9v2.432h.62v-.18H.67v-.35h.44v-.18H.67V1.08h.44V.9H.49z" fill="#e0e0e0"/><path d="M1.795.265a.53.53 0 0 0-.53.529v2.645c0 .293.237.53.53.53h1.587a.53.53 0 0 0 .53-.53V.794a.53.53 0 0 0-.53-.53zm0 .529h.256v.165a.247.247 0 0 0 .247.248h.58A.247.247 0 0 0 3.126.96V.794h.256v2.645H1.795z" fill="#e0e0e0"/></svg>
+<svg xmlns="http://www.w3.org/2000/svg" height="16" viewBox="0 0 16 16" width="16"><path d="M5 3H1v10h4z" fill="#4bb7f8"/><path d="M1.7 3.5v9h2.6v-.8H2.5v-1.3h1.8v-.8H2.5V4.3h1.8v-.8zM7 1a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2V3a2 2 0 0 0-2-2zm0 2h1v.6a1 1 0 0 0 1 1h2a1 1 0 0 0 1-1V3h1v10H7z" fill="#e0e0e0"/></svg>
diff --git a/editor/icons/MiniObject.svg b/editor/icons/MiniObject.svg
index 7fe3b773d6..3bba3bc1a3 100644
--- a/editor/icons/MiniObject.svg
+++ b/editor/icons/MiniObject.svg
@@ -1 +1 @@
-<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m6 2v8h2a3 3 0 0 0 3-3 3 3 0 0 0 -3-3v-2zm0 5a3 3 0 0 0 -3-3 3 3 0 0 0 -3 3 3 3 0 0 0 3 3 3 3 0 0 0 3-3zm7-3v5a1 1 0 0 1 -1 1h-1v2h1a3 3 0 0 0 3-3v-5zm-10 2a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1-1 1 1 0 0 1 1-1zm5 0a1 1 0 0 1 1 1 1 1 0 0 1 -1 1z" fill="#55f3e3"/></svg>
+<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M7 2v8h2a3 3 0 0 0 0-6V2zM6 7a3 3 0 0 0-6 0 3 3 0 0 0 6 0zm7-1v3a1 1 0 0 1-1 1h-1v2h1a3 3 0 0 0 3-3V6zM3 6a1 1 0 0 1 0 2 1 1 0 0 1 0-2zm6 0a1 1 0 0 1 0 2zm4-4h2v2h-2z" fill="#55f3e3"/></svg>
diff --git a/editor/icons/Nil.svg b/editor/icons/Nil.svg
index e4fbb90389..32a6ebcff3 100644
--- a/editor/icons/Nil.svg
+++ b/editor/icons/Nil.svg
@@ -1 +1 @@
-<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 2v2h2v-2zm4 0v5c0 1.6569 1.3431 3 3 3h1v-2h-1c-.55228-.0000096-.99999-.44772-1-1v-5zm-11 2v6h2v-4h1c.55228.0000096.99999.44772 1 1v3h2v-3c0-1.6569-1.3431-3-3-3zm7 2v4h2v-4z" fill="#e0e0e0"/></svg>
+<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M8 2v2h2V2zm3 0v5a3 3 0 0 0 3 3h1V8h-1a1 1 0 0 1-1-1V2zM1 4v6h2V6h1a1 1 0 0 1 1 1v3h2V7a3 3 0 0 0-3-3zm7 2v4h2V6z" fill="#e0e0e0"/></svg>
diff --git a/editor/icons/NodePath.svg b/editor/icons/NodePath.svg
index 14c753a136..2d3153372f 100644
--- a/editor/icons/NodePath.svg
+++ b/editor/icons/NodePath.svg
@@ -1 +1 @@
-<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m0 2v8h2v-2a3 3 0 0 0 3-3 3 3 0 0 0 -3-3zm6 0v5a3 3 0 0 0 3 3h1v-2h-1a1 1 0 0 1 -1-1v-1h2v-2h-2v-2zm5 0v8h2v-4a1 1 0 0 1 1 1v3h2v-3a3 3 0 0 0 -3-3v-2zm-9 2a1 1 0 0 1 1 1 1 1 0 0 1 -1 1z" fill="#417aec"/></svg>
+<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M0 2v8h2V8a3 3 0 0 0 0-6zm6 0v5a3 3 0 0 0 3 3h1V8H9a1 1 0 0 1-1-1V6h2V4H8V2zm5 0v8h2V6a1 1 0 0 1 1 1v3h2V7a3 3 0 0 0-3-3V2zM2 4a1 1 0 0 1 0 2z" fill="#417aec"/></svg>
diff --git a/editor/icons/PackedByteArray.svg b/editor/icons/PackedByteArray.svg
index 448e25c478..d7fa7fcfc5 100644
--- a/editor/icons/PackedByteArray.svg
+++ b/editor/icons/PackedByteArray.svg
@@ -1 +1 @@
-<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m0 0v12h4v-2h-2v-8h2v-2h-2zm12 0v2h2v8h-2v2h4v-12h-2z" fill="#e0e0e0"/><path d="m5 3a3 3 0 0 0 -3 3v3h2v-3a1 1 0 0 1 1-1h1v4h2a3 3 0 0 0 1-.17578v.17578h2a3 3 0 0 0 3-3v-3h-2v3a1 1 0 0 1 -1 1v-4h-2v3a1 1 0 0 1 -1 1v-4h-2z" fill="#5fff97"/><path d="m6 9v-6h2v4a1 1 0 0 0 1-1v-3h2v4a1 1 0 0 0 1-1v-3h2v3a3 3 0 0 1 -3 3h-2v-.1758a3 3 0 0 1 -1 .1758z" fill="#fff" fill-opacity=".39216"/></svg>
+<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M0 0v12h4v-2H2V2h2V0zm12 0v2h2v8h-2v2h4V0z" fill="#e0e0e0"/><path d="M5 3a3 3 0 0 0-3 3v3h2V6a1 1 0 0 1 1-1h1v4h2a3 3 0 0 0 1-.176V9h2a3 3 0 0 0 3-3V3h-2v3a1 1 0 0 1-1 1V3H9v3a1 1 0 0 1-1 1V3z" fill="#5fff97"/><path d="M6 9V3h2v4a1 1 0 0 0 1-1V3h2v4a1 1 0 0 0 1-1V3h2v3a3 3 0 0 1-3 3H9v-.176A3 3 0 0 1 8 9z" fill="#fff" fill-opacity=".4"/></svg>
diff --git a/editor/icons/PackedColorArray.svg b/editor/icons/PackedColorArray.svg
index 6911ff1d34..9f9616ea5c 100644
--- a/editor/icons/PackedColorArray.svg
+++ b/editor/icons/PackedColorArray.svg
@@ -1 +1 @@
-<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m0 0v12h4v-2h-2v-8h2v-2zm12 0v2h2v8h-2v2h4v-12z" fill="#e0e0e0"/><path d="m6 3.5a3 3 0 0 0 -3 3 3 3 0 0 0 3 3h1v-2h-1a1 1 0 0 1 -1-1 1 1 0 0 1 1-1h1v-2z" fill="#ff4545"/><path d="m13 3.5a3 3 0 0 0 -3 3v3h2v-3a1 1 0 0 1 1-1z" fill="#45d7ff"/><path d="m7 1.5v5a3 3 0 0 0 3 3v-2a1 1 0 0 1 -1-1v-5z" fill="#80ff45"/></svg>
+<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M0 0v12h4v-2H2V2h2V0zm12 0v2h2v8h-2v2h4V0z" fill="#e0e0e0"/><path d="M6 3.5a3 3 0 0 0 0 6h1v-2H6a1 1 0 0 1 0-2h1v-2z" fill="#ff4545"/><path d="M7 1.5v5a3 3 0 0 0 3 3v-2a1 1 0 0 1-1-1v-5z" fill="#80ff45"/><path d="M13 3.5a3 3 0 0 0-3 3v3h2v-3a1 1 0 0 1 1-1z" fill="#45d7ff"/></svg>
diff --git a/editor/icons/PackedFloat32Array.svg b/editor/icons/PackedFloat32Array.svg
index ccfbb748b7..da6433f909 100644
--- a/editor/icons/PackedFloat32Array.svg
+++ b/editor/icons/PackedFloat32Array.svg
@@ -1 +1 @@
-<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m0 0v12h4v-2h-2v-8h2v-2zm12 0v2h2v8h-2v2h4v-12z" fill="#e0e0e0"/><path d="m6 2a3 3 0 0 0 -3 3v5h2v-2h1v-2h-1v-1a1 1 0 0 1 1-1zm1 0v5a3 3 0 0 0 3 3v-2a1 1 0 0 1 -1-1v-5zm3 0v5a3 3 0 0 0 3 3v-2a1 1 0 0 1 -1-1v-1h1v-2h-1v-2z" fill="#35d4f4"/><path d="m7 2v5a3 3 0 0 0 3 3v-2a1 1 0 0 1 -1-1v-5z" fill="#fff" fill-opacity=".39216"/></svg>
+<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M0 0v12h4v-2H2V2h2V0zm12 0v2h2v8h-2v2h4V0z" fill="#e0e0e0"/><path d="M6 2a3 3 0 0 0-3 3v5h2V8h1V6H5V5a1 1 0 0 1 1-1zm1 0v5a3 3 0 0 0 3 3V8a1 1 0 0 1-1-1V2zm3 0v5a3 3 0 0 0 3 3V8a1 1 0 0 1-1-1V6h1V4h-1V2z" fill="#35d4f4"/><path d="M7 2v5a3 3 0 0 0 3 3V8a1 1 0 0 1-1-1V2z" fill="#fff" fill-opacity=".4"/></svg>
diff --git a/editor/icons/PackedFloat64Array.svg b/editor/icons/PackedFloat64Array.svg
index ccfbb748b7..da6433f909 100644
--- a/editor/icons/PackedFloat64Array.svg
+++ b/editor/icons/PackedFloat64Array.svg
@@ -1 +1 @@
-<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m0 0v12h4v-2h-2v-8h2v-2zm12 0v2h2v8h-2v2h4v-12z" fill="#e0e0e0"/><path d="m6 2a3 3 0 0 0 -3 3v5h2v-2h1v-2h-1v-1a1 1 0 0 1 1-1zm1 0v5a3 3 0 0 0 3 3v-2a1 1 0 0 1 -1-1v-5zm3 0v5a3 3 0 0 0 3 3v-2a1 1 0 0 1 -1-1v-1h1v-2h-1v-2z" fill="#35d4f4"/><path d="m7 2v5a3 3 0 0 0 3 3v-2a1 1 0 0 1 -1-1v-5z" fill="#fff" fill-opacity=".39216"/></svg>
+<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M0 0v12h4v-2H2V2h2V0zm12 0v2h2v8h-2v2h4V0z" fill="#e0e0e0"/><path d="M6 2a3 3 0 0 0-3 3v5h2V8h1V6H5V5a1 1 0 0 1 1-1zm1 0v5a3 3 0 0 0 3 3V8a1 1 0 0 1-1-1V2zm3 0v5a3 3 0 0 0 3 3V8a1 1 0 0 1-1-1V6h1V4h-1V2z" fill="#35d4f4"/><path d="M7 2v5a3 3 0 0 0 3 3V8a1 1 0 0 1-1-1V2z" fill="#fff" fill-opacity=".4"/></svg>
diff --git a/editor/icons/PackedInt32Array.svg b/editor/icons/PackedInt32Array.svg
index 973e4b9ab2..018fc23723 100644
--- a/editor/icons/PackedInt32Array.svg
+++ b/editor/icons/PackedInt32Array.svg
@@ -1 +1 @@
-<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m0 0v12h4v-2h-2v-8h2v-2zm12 0v2h2v8h-2v2h4v-12z" fill="#e0e0e0"/><path d="m3 2v2h2v-2zm2 2v2h-2v4h4v-4a1 1 0 0 1 1 1v3h2v-3a3 3 0 0 0 -3-3zm5 3a3 3 0 0 0 3 3v-2a1 1 0 0 1 -1-1v-1h1v-2h-1v-2h-2z" fill="#5abbef"/><path d="m5 4v6h2v-4a1 1 0 0 1 1 1v3h2v-3a3 3 0 0 0 -3-3z" fill="#fff" fill-opacity=".39216"/></svg>
+<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M0 0v12h4v-2H2V2h2V0zm12 0v2h2v8h-2v2h4V0z" fill="#e0e0e0"/><path d="M3 2v2h2V2zm2 2v2H3v4h4V6a1 1 0 0 1 1 1v3h2V7a3 3 0 0 0-3-3zm5 3a3 3 0 0 0 3 3V8a1 1 0 0 1-1-1V6h1V4h-1V2h-2z" fill="#5abbef"/><path d="M5 4v6h2V6a1 1 0 0 1 1 1v3h2V7a3 3 0 0 0-3-3z" fill="#fff" fill-opacity=".4"/></svg>
diff --git a/editor/icons/PackedInt64Array.svg b/editor/icons/PackedInt64Array.svg
index 973e4b9ab2..018fc23723 100644
--- a/editor/icons/PackedInt64Array.svg
+++ b/editor/icons/PackedInt64Array.svg
@@ -1 +1 @@
-<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m0 0v12h4v-2h-2v-8h2v-2zm12 0v2h2v8h-2v2h4v-12z" fill="#e0e0e0"/><path d="m3 2v2h2v-2zm2 2v2h-2v4h4v-4a1 1 0 0 1 1 1v3h2v-3a3 3 0 0 0 -3-3zm5 3a3 3 0 0 0 3 3v-2a1 1 0 0 1 -1-1v-1h1v-2h-1v-2h-2z" fill="#5abbef"/><path d="m5 4v6h2v-4a1 1 0 0 1 1 1v3h2v-3a3 3 0 0 0 -3-3z" fill="#fff" fill-opacity=".39216"/></svg>
+<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M0 0v12h4v-2H2V2h2V0zm12 0v2h2v8h-2v2h4V0z" fill="#e0e0e0"/><path d="M3 2v2h2V2zm2 2v2H3v4h4V6a1 1 0 0 1 1 1v3h2V7a3 3 0 0 0-3-3zm5 3a3 3 0 0 0 3 3V8a1 1 0 0 1-1-1V6h1V4h-1V2h-2z" fill="#5abbef"/><path d="M5 4v6h2V6a1 1 0 0 1 1 1v3h2V7a3 3 0 0 0-3-3z" fill="#fff" fill-opacity=".4"/></svg>
diff --git a/editor/icons/PackedStringArray.svg b/editor/icons/PackedStringArray.svg
index 5273d6bc56..7d4b685547 100644
--- a/editor/icons/PackedStringArray.svg
+++ b/editor/icons/PackedStringArray.svg
@@ -1 +1 @@
-<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m0 0v12h4v-2h-2v-8h2v-2zm12 0v2h2v8h-2v2h4v-12z" fill="#e0e0e0"/><path d="m7 2a3 3 0 0 0 -3 3v2a1 1 0 0 1 -1 1h-1v2h1a3 3 0 0 0 3-3v-2a1 1 0 0 1 1-1h1v3a3 3 0 0 0 3 3h2v-3a1 1 0 0 1 1-1v-2a3 3 0 0 0 -3 3v1a1 1 0 0 1 -1-1v-1h1v-2h-1v-2h-2z" fill="#4593ec"/><path d="m8 2v5a3 3 0 0 0 3 3v-2a1 1 0 0 1 -1-1v-1h1v-2h-1v-2z" fill="#fff" fill-opacity=".39216"/></svg>
+<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M0 0v12h4v-2H2V2h2V0zm12 0v2h2v8h-2v2h4V0z" fill="#e0e0e0"/><path d="M5 2a2.5 2.5 0 0 0 0 5 .5.5 0 0 1 0 1H2v2h3a2.5 2.5 0 0 0 0-5 .5.5 0 0 1 0-1h3v3a3 3 0 0 0 3 3h2V7a1 1 0 0 1 1-1V4a3 3 0 0 0-3 3v1a1 1 0 0 1-1-1V6h1V4h-1V2z" fill="#4593ec"/><path d="M8 2v5a3 3 0 0 0 3 3V8a1 1 0 0 1-1-1V6h1V4h-1V2z" fill="#fff" fill-opacity=".4"/></svg>
diff --git a/editor/icons/PackedVector2Array.svg b/editor/icons/PackedVector2Array.svg
index f7e23b800f..bf502f4868 100644
--- a/editor/icons/PackedVector2Array.svg
+++ b/editor/icons/PackedVector2Array.svg
@@ -1 +1 @@
-<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m0 0v12h4v-2h-2v-8h2v-2zm12 0v2h2v8h-2v2h4v-12z" fill="#e0e0e0"/><path d="m9 2v2h1a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 2 2 0 0 0 -1.7324 1 2 2 0 0 0 -.26562 1h-.0019531v2h5v-2h-3a3 3 0 0 0 2.5977-1.5 3 3 0 0 0 0-3 3 3 0 0 0 -2.5977-1.5zm-6 1v6h2a3 3 0 0 0 3-3v-3h-2v3a1 1 0 0 1 -1 1v-4z" fill="#ac73f1"/><path d="m9 2v2h1a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 2 2 0 0 0 -1.7324 1 2 2 0 0 0 -.26562 1h-.00195v2.0001h5v-2h-3a3 3 0 0 0 2.5977-1.5 3 3 0 0 0 0-3 3 3 0 0 0 -2.5977-1.5001z" fill="#fff" fill-opacity=".39216"/></svg>
+<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M0 0v12h4v-2H2V2h2V0zm12 0v2h2v8h-2v2h4V0z" fill="#e0e0e0"/><path d="M9 2v2h1a1 1 0 0 1 0 2 2 2 0 0 0-2 2v2h5V8h-3a3 3 0 0 0 0-6zM3 3v6h2a3 3 0 0 0 3-3V3H6v3a1 1 0 0 1-1 1V3z" fill="#ac73f1"/><path d="M9 2v2h1a1 1 0 0 1 0 2 2 2 0 0 0-2 2v2h5V8h-3a3 3 0 0 0 0-6z" fill="#fff" fill-opacity=".4"/></svg>
diff --git a/editor/icons/PackedVector3Array.svg b/editor/icons/PackedVector3Array.svg
index e78be63df2..9f4df41008 100644
--- a/editor/icons/PackedVector3Array.svg
+++ b/editor/icons/PackedVector3Array.svg
@@ -1 +1 @@
-<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m0 0v12h4v-2h-2v-8h2v-2zm12 0v2h2v8h-2v2h4v-12z" fill="#e0e0e0"/><path d="m8 1v2h2c0 .55228-.44772 1-1 1v2c.55228 0 1 .44772 1 1s-.44772 1-1 1h-1v2h1c1.0716-.0001501 2.0618-.57193 2.5977-1.5.5359-.9282.5359-2.0718 0-3-.10406-.1795-.22646-.34772-.36523-.50195.13856-.15301.26095-.31991.36523-.49805.26209-.45639.3995-.97371.39844-1.5h.003906v-2zm0 2h-2v3c-.0000096.55228-.44772.99999-1 1v-4h-2v6h2c1.6569 0 3-1.3431 3-3z" fill="#de66f0"/><path d="m8 1v2h2c0 .55228-.44772 1-1 1v2c.55228 0 1 .44772 1 1s-.44772 1-1 1h-1v2h1c1.0716-.0001501 2.0618-.57193 2.5977-1.5.5359-.9282.5359-2.0718 0-3-.10406-.1795-.22646-.34772-.36523-.50195.13856-.15301.26095-.31991.36523-.49805.26209-.45639.3995-.97371.39844-1.5h.003906v-2z" fill="#fff" fill-opacity=".39216"/></svg>
+<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M0 0v12h4v-2H2V2h2V0zm12 0v2h2v8h-2v2h4V0z" fill="#e0e0e0"/><path d="M8 1v2h2a1 1 0 0 1-1 1v2a1 1 0 0 1 0 2H8v2h1a3 3 0 0 0 2.232-5A3 3 0 0 0 12 3V1zm0 2H6v3a1 1 0 0 1-1 1V3H3v6h2a3 3 0 0 0 3-3z" fill="#de66f0"/><path d="M8 1v2h2a1 1 0 0 1-1 1v2a1 1 0 0 1 0 2H8v2h1a3 3 0 0 0 2.232-5A3 3 0 0 0 12 3V1z" fill="#fff" fill-opacity=".4"/></svg>
diff --git a/editor/icons/Plane.svg b/editor/icons/Plane.svg
index 5857ac56f7..eb3c5482a4 100644
--- a/editor/icons/Plane.svg
+++ b/editor/icons/Plane.svg
@@ -1 +1 @@
-<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 2v8h2v-2a3 3 0 0 0 3-3 3 3 0 0 0 -3-3zm6 0v5a3 3 0 0 0 3 3v-2a1 1 0 0 1 -1-1v-5zm-4 2a1 1 0 0 1 1 1 1 1 0 0 1 -1 1zm8 0v6h2v-4a1 1 0 0 1 1 1v3h2v-3a3 3 0 0 0 -3-3z" fill="#f74949"/></svg>
+<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M1 2v8h2V8a3 3 0 0 0 0-6zm6 0v5a3 3 0 0 0 3 3V8a1 1 0 0 1-1-1V2zM3 4a1 1 0 0 1 0 2zm8 0v6h2V6a1 1 0 0 1 1 1v3h2V7a3 3 0 0 0-3-3z" fill="#f74949"/></svg>
diff --git a/editor/icons/Projection.svg b/editor/icons/Projection.svg
index c6c9fed679..aa415cdedf 100644
--- a/editor/icons/Projection.svg
+++ b/editor/icons/Projection.svg
@@ -1 +1 @@
-<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m0 2v8h2v-2c.772 0 1.468-.3 2-.779v2.779h2v-3c0-.552.448-1 1-1h1v-2h-1c-.781 0-1.486.306-2.02.795-.107-1.56-1.393-2.795-2.98-2.795zm8 4v2c0 1 1 2 2 2h1c1 0 2-1 2-2v-2c0-1-1-2-2-2h-1c-1 0-2 1-2 2zm6-4v2h2v-2zm-12 2c.552 0 1 .448 1 1s-.448 1-1 1zm8 2h1v2h-1zm4 0v3c0 .552-.448 1-1 1h-1v2h1c1.657 0 3-1.343 3-3v-3z" fill="#44bd44"/><path d="m7 4c-1.657 0-3 1.343-3 3v3h2v-3c0-.552.448-1 1-1h1v-2z" fill="#fff" fill-opacity=".39216"/></svg>
+<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M0 2v8h2V8a3 3 0 0 0 2-.779V10h2V7a1 1 0 0 1 1-1h1V4H7a3 3 0 0 0-2.02.795A3 3 0 0 0 2 2zm8 4v2a2 2 0 0 0 2 2h1a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2h-1a2 2 0 0 0-2 2zm6-4v2h2V2zM2 4a1 1 0 0 1 0 2zm8 2h1v2h-1zm4 0v3a1 1 0 0 1-1 1h-1v2h1a3 3 0 0 0 3-3V6z" fill="#44bd44"/><path d="M7 4a3 3 0 0 0-3 3v3h2V7a1 1 0 0 1 1-1h1V4z" fill="#fff" fill-opacity=".4"/></svg>
diff --git a/editor/icons/Quaternion.svg b/editor/icons/Quaternion.svg
index cf29160ff4..39b4937420 100644
--- a/editor/icons/Quaternion.svg
+++ b/editor/icons/Quaternion.svg
@@ -1 +1 @@
-<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 3a3 3 0 0 0 -3 3 3 3 0 0 0 3 3v2h2v-2.7695a3 3 0 0 0 2 .76953h2v-6h-2v4a1 1 0 0 1 -1-1v-3h-2zm0 2v2a1 1 0 0 1 -1-1 1 1 0 0 1 1-1z" fill="#ec418e"/><path d="m4 3v3a3 3 0 0 0 3 3h2v-6h-2v4a1 1 0 0 1 -1-1v-3z" fill="#fff" fill-opacity=".39216"/><path d="m13 1v2h-2a3 3 0 0 0 -3 3 3 3 0 0 0 3 3h2v-3a3 3 0 0 0 3 3v-2a1 1 0 0 1 -1-1v-1h1v-2h-1v-2zm-2 4v2a1 1 0 0 1 -1-1 1 1 0 0 1 1-1z" fill="#ec418e"/></svg>
+<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M3 3a3 3 0 0 0 0 6v2h2V8.236A3 3 0 0 0 7 9h2v-.764A3 3 0 0 0 11 9h2V6a3 3 0 0 0 3 3V7a1 1 0 0 1-1-1V5h1V3h-1V1h-2v2h-2a3 3 0 0 0-2 .764V3H7v4a1 1 0 0 1-1-1V3zm0 4a1 1 0 0 1 0-2zm8 0a1 1 0 0 1 0-2z" fill="#ec418e"/><path d="M4 3v3a3 3 0 0 0 3 3h2V3H7v4a1 1 0 0 1-1-1V3z" fill="#fff" fill-opacity=".4"/></svg>
diff --git a/editor/icons/RID.svg b/editor/icons/RID.svg
index 40764867ba..d24977463c 100644
--- a/editor/icons/RID.svg
+++ b/editor/icons/RID.svg
@@ -1 +1 @@
-<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7 2v2h2v-2zm7 0v2h-1a3 3 0 0 0 -3 3 3 3 0 0 0 3 3h1 2v-8zm-10 2a3 3 0 0 0 -3 3v3h2v-3a1 1 0 0 1 1-1h1v-2zm3 2v4h2v-4zm6 0h1v2h-1a1 1 0 0 1 -1-1 1 1 0 0 1 1-1z" fill="#41ec80"/></svg>
+<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M7 2v2h2V2zm7 0v2h-1a3 3 0 0 0 0 6h3V2zM4 4a3 3 0 0 0-3 3v3h2V7a1 1 0 0 1 1-1h1V4zm3 2v4h2V6zm6 0h1v2h-1a1 1 0 0 1 0-2z" fill="#41ec80"/></svg>
diff --git a/editor/icons/Rect2.svg b/editor/icons/Rect2.svg
index 5b069bd3c1..bdb70284ec 100644
--- a/editor/icons/Rect2.svg
+++ b/editor/icons/Rect2.svg
@@ -1 +1 @@
-<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m13 2v2h-1a3 3 0 0 0 -2.5 1.3457 3 3 0 0 0 -2.5-1.3457 3 3 0 0 0 -3 3 3 3 0 0 0 3 3h1v-2h-1a1 1 0 0 1 -1-1h3a3 3 0 0 0 3 3h1v-2h-1a1 1 0 0 1 -1-1 1 1 0 0 1 1-1h1v1a3 3 0 0 0 3 3v-2a1 1 0 0 1 -1-1v-1h1v-2h-1v-2zm-10 2a3 3 0 0 0 -3 3v3h2v-3a1 1 0 0 1 1-1h1v-2z" fill="#f1738f"/></svg>
+<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M13 2v2h-1a3 3 0 0 0-2.5 1.346A3 3 0 1 0 7 10h1V8H7a1 1 0 0 1-1-1h3a3 3 0 0 0 3 3h1V8h-1a1 1 0 0 1 0-2h1v1a3 3 0 0 0 3 3V8a1 1 0 0 1-1-1V6h1V4h-1V2zM3 4a3 3 0 0 0-3 3v3h2V7a1 1 0 0 1 1-1h1V4z" fill="#f1738f"/></svg>
diff --git a/editor/icons/Rect2i.svg b/editor/icons/Rect2i.svg
index 76f4fededf..f091f6529e 100644
--- a/editor/icons/Rect2i.svg
+++ b/editor/icons/Rect2i.svg
@@ -1 +1 @@
-<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m9 2v2h-1c-1.7267 0-3 1.3359-3 3 0 1.6569 1.3431 3 3 3h1v-2h-1c-.55228 0-1-.44772-1-1s.44772-1 1-1h1v1c0 1.6569 1.3431 3 3 3v-2c-.55228 0-.93526-.45152-1-1v-1h1v-2h-1v-2zm-5 2c-1.6569 0-2.9547 1.3438-3 3v3h2v-3c0-.55228.44772-1 1-1h1v-2z" fill="#f1738f"/><path d="m13 2v2h2v-2zm0 4v4h2v-4z" fill="#5abbef"/></svg>
+<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M9 2v2H8a3 3 0 0 0 0 6h1V8H8a1 1 0 0 1 0-2h1v1a3 3 0 0 0 3 3V8a1 1 0 0 1-1-1V6h1V4h-1V2zM4 4a3 3 0 0 0-3 3v3h2V7a1 1 0 0 1 1-1h1V4z" fill="#f1738f"/><path d="M13 2v2h2V2zm0 4v4h2V6z" fill="#5abbef"/></svg>
diff --git a/editor/icons/String.svg b/editor/icons/String.svg
index abcb92d4b2..0028973437 100644
--- a/editor/icons/String.svg
+++ b/editor/icons/String.svg
@@ -1 +1 @@
-<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m5 2a3 3 0 0 0 -3 3v2a1 1 0 0 1 -1 1h-1v2h1a3 3 0 0 0 3-3v-2a1 1 0 0 1 1-1h1v-2zm2 0v5a3 3 0 0 0 3 3h1v-2h-1a1 1 0 0 1 -1-1v-1h2v-2h-2v-2zm8 2a3 3 0 0 0 -3 3v3h2v-3a1 1 0 0 1 1-1h1v-2z" fill="#4593ec"/></svg>
+<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M7 2H4a2.5 2.5 0 0 0 0 5 .5.5 0 0 1 0 1H1v2h3a2.5 2.5 0 0 0 0-5 .5.5 0 0 1 0-1h3zm1 0v5a3 3 0 0 0 3 3V8a1 1 0 0 1-1-1V6h1V4h-1V2zm4 8h2V7a1 1 0 0 1 1-1V4a3 3 0 0 0-3 3z" fill="#4593ec"/></svg>
diff --git a/editor/icons/StringName.svg b/editor/icons/StringName.svg
index 3b67f2accd..3520c20150 100644
--- a/editor/icons/StringName.svg
+++ b/editor/icons/StringName.svg
@@ -1 +1 @@
-<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m5 2c-1.6569 0-3 1.3431-3 3v2c0 .55228-.44772 1-1 1h-1v2h1c1.6569 0 3-1.3431 3-3v-2c0-.55228.44772-1 1-1h1v3c0 1.6569 1.3431 3 3 3h3v-4h1c.55228 0 1 .44772 1 1v3h2v-3c0-1.6569-1.3431-3-3-3h-5v-2zm3 4h2v2h-1c-.55228 0-1-.44772-1-1z" fill="#4593ec"/><path d="m10 4v6h2v-4h1c.55228 0 1 .44772 1 1v3h2v-3c0-1.6569-1.3431-3-3-3h-1z" fill="#fff" fill-opacity=".39216"/></svg>
+<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M3 2a2.5 2.5 0 0 0 0 5 .5.5 0 0 1 0 1H0v2h3a2.5 2.5 0 0 0 0-5 .5.5 0 0 1 0-1h3v3a3 3 0 0 0 3 3h3V6a2 2 0 0 1 2 2v2h2V8a4 4 0 0 0-4-4H8V2zm7 4v2H9a1 1 0 0 1-1-1V6z" fill="#4593ec"/><path d="M6 2v5a3 3 0 0 0 3 3h1V8H9a1 1 0 0 1-1-1V6h2V4H8V2z" fill="#fff" fill-opacity=".4"/></svg>
diff --git a/editor/icons/Transform2D.svg b/editor/icons/Transform2D.svg
index 75be0b73e1..58e5621b33 100644
--- a/editor/icons/Transform2D.svg
+++ b/editor/icons/Transform2D.svg
@@ -1 +1 @@
-<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m0 2v2h2v6h2v-6h2v-2zm7 0v2a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 2 2 0 0 0 -1.7324 1 2 2 0 0 0 -.26562 1h-.0019531v2h7a4 4 0 0 0 3.4648-2 4 4 0 0 0 0-4 4 4 0 0 0 -3.4648-2h-2v6h-3a3 3 0 0 0 2.5977-1.5 3 3 0 0 0 0-3 3 3 0 0 0 -2.5977-1.5zm5 2a2 2 0 0 1 1.7324 1 2 2 0 0 1 0 2 2 2 0 0 1 -1.7324 1z" fill="#b9ec41"/><path d="m7 2v2c.55228 0 1 .44772 1 1s-.44772 1-1 1c-.71466-.0001326-1.3751.38108-1.7324 1-.17472.30426-.26633.64914-.26562 1h-.0019531v2h5v-2h-3c1.0716-.00015 2.0618-.57193 2.5977-1.5.5359-.9282.5359-2.0718 0-3-.53582-.92807-1.526-1.4998-2.5977-1.5z" fill="#fff" fill-opacity=".39216"/></svg>
+<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M0 2v2h2v6h2V4h3a1 1 0 0 1 0 2 2 2 0 0 0-2 2v2h7a4 4 0 0 0 0-8h-2v6H7a3 3 0 0 0 0-6zm12 2a2 2 0 0 1 0 4z" fill="#b9ec41"/><path d="M6.5 2v2H7a1 1 0 0 1 0 2 2 2 0 0 0-2 2v2h5V8H7a3 3 0 0 0 0-6h-.5z" fill="#fff" fill-opacity=".4"/></svg>
diff --git a/editor/icons/Transform3D.svg b/editor/icons/Transform3D.svg
index 10d2769d97..f07775446f 100644
--- a/editor/icons/Transform3D.svg
+++ b/editor/icons/Transform3D.svg
@@ -1 +1 @@
-<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m4 4h3.349c0 .549-.451 1.267-1 1.267v1c.549 0 1 .326 1 .874 0 .549-.451.859-1 .859h-1v2h1c1.07 0 2.063-.573 2.598-1.5s.535-1.806 0-2.733c-.104-.18-.227-.348-.366-.502.139-.153.261-.32.366-.498.262-.457.398-.64.398-.767h.004v-2h-9.349v2h2v6h2zm6 6h2c1.428 0 2.751-.764 3.465-2 .713-1.236.713-2.764 0-4-.714-1.236-2.037-2-3.465-2h-2zm2-6c.714 0 1.376.382 1.732 1 .357.618.357 1.382 0 2-.356.618-1.018 1-1.732 1z" fill="#f68f45"/><path d="m6.00006 2v2h1.349c0 .549-.451 1.267-1 1.267v1c.549 0 1 .326 1 .874 0 .549-.451.859-1 .859h-1v2h1c1.07 0 2.062-.573 2.598-1.5.535-.927.535-1.806 0-2.733-.104-.18-.227-.348-.366-.502.139-.153.261-.32.366-.498.262-.457.398-.64.398-.767h.004v-2z" fill="#fff" fill-opacity=".39216"/></svg>
+<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M4 4h3.349a1 1.267 0 0 1-1 1.267v1a.866.866 0 0 1 0 1.732h-1v2h1a2.81 2.81 0 0 0 2.232-4.734A1.32 1.32 0 0 0 9.345 4V2H0v2h2v6h2zm6 6h2a4 4 0 0 0 0-8h-2zm2-6a2 2 0 0 1 0 4z" fill="#f68f45"/><path d="M5.5 4h1.849a1 1.267 0 0 1-1 1.267v1a.866.866 0 0 1 0 1.732h-1v2h1a2.81 2.81 0 0 0 2.232-4.734A1.32 1.32 0 0 0 9.345 4V2H5.5z" fill="#fff" fill-opacity=".4"/></svg>
diff --git a/editor/icons/Uv.svg b/editor/icons/Uv.svg
index 82c914c84f..be004249ec 100644
--- a/editor/icons/Uv.svg
+++ b/editor/icons/Uv.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 5v4a3 3 0 0 0 1.5 2.5977 3 3 0 0 0 3 0 3 3 0 0 0 1.5-2.5977v-4h-2v4a1 1 0 0 1 -1 1 1 1 0 0 1 -1-1v-4zm8 0 2 7h1 1 1l2-7h-2l-1.5 5.25-1.5-5.25z" fill="#e0e0e0"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M1 5v4a3 3 0 0 0 6 0V5H5v4a1 1 0 0 1-2 0V5zm8 0 2 7h3l2-7h-2l-1.5 5.25L11 5z" fill="#e0e0e0"/></svg>
diff --git a/editor/icons/Variant.svg b/editor/icons/Variant.svg
index dff2c67ebc..c4e485d1e1 100644
--- a/editor/icons/Variant.svg
+++ b/editor/icons/Variant.svg
@@ -1 +1 @@
-<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 4a3 3 0 0 0 -3 3 3 3 0 0 0 3 3h2v-6zm3 0v6h2v-4a1 1 0 0 1 1 1v3h2v-3a3 3 0 0 0 -3-3zm5 3a3 3 0 0 0 3 3v2h2v-8h-2v4a1 1 0 0 1 -1-1v-3h-2zm-8-1v2a1 1 0 0 1 -1-1 1 1 0 0 1 1-1z" fill="#41ecad"/></svg>
+<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M3 3a3 3 0 0 0 0 6h2V3zm3 0v6h2V5a1 1 0 0 1 1 1v3h2V6a3 3 0 0 0-3-3zm5 2a3 3 0 0 0 3 3 1 1 0 0 1-1 1h-1v2h1a3 3 0 0 0 3-3V3h-2v3a1 1 0 0 1-1-1V3h-2zM3 7a1 1 0 0 1 0-2z" fill="#41ecad"/></svg>
diff --git a/editor/icons/Vector2.svg b/editor/icons/Vector2.svg
index 2bab922ca9..fd6ea7a5cf 100644
--- a/editor/icons/Vector2.svg
+++ b/editor/icons/Vector2.svg
@@ -1 +1 @@
-<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m12 2v2h1a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 2 2 0 0 0 -1.7324 1 2 2 0 0 0 -.26562 1h-.001953v2h5v-2h-3a3 3 0 0 0 2.5977-1.5 3 3 0 0 0 0-3 3 3 0 0 0 -2.5977-1.5zm-11 2v6h2a3 3 0 0 0 3-3v-3h-2v3a1 1 0 0 1 -1 1v-4zm5 3a3 3 0 0 0 3 3h1v-2h-1a1 1 0 0 1 -1-1 1 1 0 0 1 1-1h1v-2h-1a3 3 0 0 0 -3 3z" fill="#ac73f1"/><path d="m12 2v2h1a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 2 2 0 0 0 -1.7324 1 2 2 0 0 0 -.26562 1h-.001953v2h5v-2h-3a3 3 0 0 0 2.5977-1.5 3 3 0 0 0 0-3 3 3 0 0 0 -2.5977-1.5z" fill="#fff" fill-opacity=".39216"/></svg>
+<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M12 2v2h1a1 1 0 0 1 0 2 2 2 0 0 0-2 2v2h5V8h-3a3 3 0 0 0 0-6zM1 4v6h2a3 3 0 0 0 3-3V4H4v3a1 1 0 0 1-1 1V4zm9 6V8H9a1 1 0 0 1 0-2h1V4H9a3 3 0 0 0 0 6z" fill="#ac73f1"/><path d="M12 2v2h1a1 1 0 0 1 0 2 2 2 0 0 0-2 2v2h5V8h-3a3 3 0 0 0 0-6z" fill="#fff" fill-opacity=".4"/></svg>
diff --git a/editor/icons/Vector2i.svg b/editor/icons/Vector2i.svg
index f2923542e8..5e82eb34d1 100644
--- a/editor/icons/Vector2i.svg
+++ b/editor/icons/Vector2i.svg
@@ -1 +1 @@
-<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 2v2h1c.55228 0 1 .44772 1 1s-.44772 1-1 1c-.71466-.0001248-1.3751.38109-1.7324 1-.17472.30426-.26633.64914-.26562 1h-.002v2h5v-2h-3c1.0717-.0001344 2.0619-.57191 2.5977-1.5.5359-.9282.5359-2.0718 0-3-.53578-.92809-1.526-1.4999-2.5977-1.5zm-7 2v6h2c1.6569 0 3-1.3431 3-3v-3h-2v3c0 .55228-.44772 1-1 1v-4z" fill="#ac73f1"/><path d="m8 2v2h1c.55228 0 1 .44772 1 1s-.44772 1-1 1c-.71466-.0001248-1.3751.38109-1.7324 1-.17472.30426-.26633.64914-.26562 1h-.001953v2h5v-2h-3c1.0717-.0001344 2.0619-.57191 2.5977-1.5.5359-.9282.5359-2.0718 0-3-.53583-.92809-1.526-1.4999-2.5977-1.5z" fill="#fff" fill-opacity=".39216"/><path d="m13 2v2h2v-2zm0 4v4h2v-4z" fill="#5abbef"/></svg>
+<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M8 2v2h1a1 1 0 0 1 0 2 2 2 0 0 0-2 2v2h5V8H9a3 3 0 0 0 0-6zM1 4v6h2a3 3 0 0 0 3-3V4H4v3a1 1 0 0 1-1 1V4z" fill="#ac73f1"/><path d="M8 2v2h1a1 1 0 0 1 0 2 2 2 0 0 0-2 2v2h5V8H9a3 3 0 0 0 0-6z" fill="#fff" fill-opacity=".4"/><path d="M13 2v2h2V2zm0 4v4h2V6z" fill="#5abbef"/></svg>
diff --git a/editor/icons/Vector3.svg b/editor/icons/Vector3.svg
index 85cac571cf..a78f8904d7 100644
--- a/editor/icons/Vector3.svg
+++ b/editor/icons/Vector3.svg
@@ -1 +1 @@
-<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m12 2v2h2a1 1 0 0 1 -1 1v2a1 1 0 0 1 1 1 1 1 0 0 1 -1 1h-1v2h1a3 3 0 0 0 2.5977-1.5 3 3 0 0 0 0-3 3 3 0 0 0 -.36523-.50195 3 3 0 0 0 .36523-.49805 3 3 0 0 0 .39844-1.5h.003906v-2zm-11 2v6h2a3 3 0 0 0 3-3v-3h-2v3a1 1 0 0 1 -1 1v-4zm5 3a3 3 0 0 0 3 3h1v-2h-1a1 1 0 0 1 -1-1 1 1 0 0 1 1-1h1v-2h-1a3 3 0 0 0 -3 3z" fill="#de66f0"/><path d="m12 2v2h2a1 1 0 0 1 -1 1v2a1 1 0 0 1 1 1 1 1 0 0 1 -1 1h-1v2h1a3 3 0 0 0 2.5977-1.5 3 3 0 0 0 0-3 3 3 0 0 0 -.36523-.50195 3 3 0 0 0 .36523-.49805 3 3 0 0 0 .39844-1.5h.003906v-2z" fill="#fff" fill-opacity=".39216"/></svg>
+<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M11 2v2h2a1 1 0 0 1-1 1v2a1 1 0 0 1 0 2h-1v2h1a3 3 0 0 0 2.232-5A3 3 0 0 0 15 4V2zM1 4v6h2a3 3 0 0 0 3-3V4H4v3a1 1 0 0 1-1 1V4zm9 6V8H9a1 1 0 0 1 0-2h1V4H9a3 3 0 0 0 0 6z" fill="#de66f0"/><path d="M11 2v2h2a1 1 0 0 1-1 1v2a1 1 0 0 1 0 2h-1v2h1a3 3 0 0 0 2.232-5A3 3 0 0 0 15 4V2z" fill="#fff" fill-opacity=".4"/></svg>
diff --git a/editor/icons/Vector3i.svg b/editor/icons/Vector3i.svg
index 26e9c1b3ef..0f7dd4799c 100644
--- a/editor/icons/Vector3i.svg
+++ b/editor/icons/Vector3i.svg
@@ -1 +1 @@
-<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 2v2h2c0 .55228-.44772 1-1 1v2c.55228 0 1 .44772 1 1s-.45296.92408-1 1h-1v2h1c1.0717-.000134 2.0619-.57191 2.5977-1.5.5359-.9282.5359-2.0718 0-3-.10406-.1795-.22646-.34771-.36523-.50195.13855-.15301.26094-.31991.36523-.49805.26209-.45639.3995-.97371.39844-1.5h.0039v-2zm-7 2v6h2c1.6569 0 3-1.3431 3-3v-3h-2v3c0 .55228-.44772 1-1 1v-4z" fill="#de66f0"/><path d="m8 2v2h2c0 .55228-.44772 1-1 1v2c.55228 0 1 .44772 1 1s-.44948.95585-1 1h-1v2h1c1.0717-.000134 2.0619-.57191 2.5977-1.5.5359-.9282.5359-2.0718 0-3-.10406-.1795-.22646-.34771-.36523-.50195.13855-.15301.26094-.31991.36523-.49805.26209-.45639.3995-.97371.39844-1.5h.0039v-2z" fill="#fff" fill-opacity=".39216"/><path d="m13 2v2h2v-2zm0 4v4h2v-4z" fill="#5abbef"/></svg>
+<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M8 2v2h2a1 1 0 0 1-1 1v2a1 1 0 0 1 0 2H8v2h1a3 3 0 0 0 2.232-5A3 3 0 0 0 12 4V2zM1 4v6h2a3 3 0 0 0 3-3V4H4v3a1 1 0 0 1-1 1V4z" fill="#de66f0"/><path d="M8 2v2h2a1 1 0 0 1-1 1v2a1 1 0 0 1 0 2H8v2h1a3 3 0 0 0 2.232-5A3 3 0 0 0 12 4V2z" fill="#fff" fill-opacity=".4"/><path d="M13 2v2h2V2zm0 4v4h2V6z" fill="#5abbef"/></svg>
diff --git a/editor/icons/Vector4.svg b/editor/icons/Vector4.svg
index 2eefa0a7e3..224d61e8e1 100644
--- a/editor/icons/Vector4.svg
+++ b/editor/icons/Vector4.svg
@@ -1 +1 @@
-<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m11 3v5h3v3h2v-9h-2v4h-1v-3zm-10 1v6h2c1.646 0 3-1.354 3-3v-3h-2v3c0 .549-.451 1-1 1v-4zm5 3c0 1.646 1.354 3 3 3h1v-2h-1c-.549 0-1-.451-1-1s.451-1 1-1h1v-2h-1c-1.646 0-3 1.354-3 3z" fill="#f066bd"/><path d="m11 3v5h3v3h2v-9h-2v4h-1v-3z" fill="#fff" fill-opacity=".39216"/></svg>
+<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M11 3v5h3v3h2V2h-2v4h-1V3zM1 4v6h2a3 3 0 0 0 3-3V4H4v3a1 1 0 0 1-1 1V4zm9 6V8H9a1 1 0 0 1 0-2h1V4H9a3 3 0 0 0 0 6z" fill="#f066bd"/><path d="M11 3v5h3v3h2V2h-2v4h-1V3z" fill="#fff" fill-opacity=".4"/></svg>
diff --git a/editor/icons/Vector4i.svg b/editor/icons/Vector4i.svg
index d86cba253b..1bcedeccbb 100644
--- a/editor/icons/Vector4i.svg
+++ b/editor/icons/Vector4i.svg
@@ -1 +1 @@
-<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7 3v5h3v3h2v-9h-2v4h-1v-3zm-6 1v6h2c1.657 0 3-1.343 3-3v-3h-2v3c0 .552-.448 1-1 1v-4z" fill="#f066bd"/><path d="m7 3v5h3v3h2v-9h-2v4h-1v-3z" fill="#fff" fill-opacity=".39216"/><path d="m13 2v2h2v-2zm0 4v4h2v-4z" fill="#5abbef"/></svg>
+<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M7 3v5h3v3h2V2h-2v4H9V3zM1 4v6h2a3 3 0 0 0 3-3V4H4v3a1 1 0 0 1-1 1V4z" fill="#f066bd"/><path d="M7 3v5h3v3h2V2h-2v4H9V3z" fill="#fff" fill-opacity=".4"/><path d="M13 2v2h2V2zm0 4v4h2V6z" fill="#5abbef"/></svg>
diff --git a/editor/icons/bool.svg b/editor/icons/bool.svg
index 674cbc9e6c..4fd042bbc7 100644
--- a/editor/icons/bool.svg
+++ b/editor/icons/bool.svg
@@ -1 +1 @@
-<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m0 2v8h2a3 3 0 0 0 2.5-1.3457 3 3 0 0 0 2.5 1.3457 3 3 0 0 0 2-.76758 3 3 0 0 0 2 .76758 3 3 0 0 0 2.5-1.3457 3 3 0 0 0 2.5 1.3457v-2a1 1 0 0 1 -1-1v-5h-2v2.7695a3 3 0 0 0 -2-.76953 3 3 0 0 0 -2 .76758 3 3 0 0 0 -2-.76758 3 3 0 0 0 -2.5 1.3457 3 3 0 0 0 -2.5-1.3457v-2zm2 4a1 1 0 0 1 1 1 1 1 0 0 1 -1 1zm5 0a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1-1 1 1 0 0 1 1-1zm4 0a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1-1 1 1 0 0 1 1-1z" fill="#6f91f0"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M0 4v8h2a3 3 0 0 0 2.5-1.346 3 3 0 0 0 4.5.578 3 3 0 0 0 4.5-.578A3 3 0 0 0 16 12v-2a1 1 0 0 1-1-1V4h-2v2.77a3 3 0 0 0-4 0 3 3 0 0 0-4.5.578A3 3 0 0 0 2 6V4zm2 4a1 1 0 0 1 0 2zm5 0a1 1 0 0 1 0 2 1 1 0 0 1 0-2zm4 0a1 1 0 0 1 0 2 1 1 0 0 1 0-2z" fill="#6f91f0"/></svg>
diff --git a/editor/icons/float.svg b/editor/icons/float.svg
index b941332e6c..051234584d 100644
--- a/editor/icons/float.svg
+++ b/editor/icons/float.svg
@@ -1 +1 @@
-<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 2a3 3 0 0 0 -3 3v5h2v-2h2v-2h-2v-1a1 1 0 0 1 1-1h1v-2zm3 0v5a3 3 0 0 0 3 3h1v-2h-1a1 1 0 0 1 -1-1v-5zm6 0v5a3 3 0 0 0 3 3h1v-2h-1a1 1 0 0 1 -1-1v-1h2v-2h-2v-2z" fill="#35d4f4"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M3 4a3 3 0 0 0-3 3v5h2v-2h2V8H2V7a1 1 0 0 1 1-1h1V4zm3 0v5a3 3 0 0 0 3 3h1v-2H9a1 1 0 0 1-1-1V4zm6 0v5a3 3 0 0 0 3 3h1v-2h-1a1 1 0 0 1-1-1V8h2V6h-2V4z" fill="#35d4f4"/></svg>
diff --git a/editor/icons/uint.svg b/editor/icons/uint.svg
index 7dd5a92925..1be22d7a2f 100644
--- a/editor/icons/uint.svg
+++ b/editor/icons/uint.svg
@@ -1 +1 @@
-<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m5 2v2h2v-2zm2 2v2h-2v-2h-2v4c-.5522847 0-1-.4477153-1-1v-3h-2v3a3 3 0 0 0 0 .0507812 3 3 0 0 0 3 2.9492188h6v-4c.5522847 0 1 .4477153 1 1v3h2v-3c0-1.6568542-1.343146-3-3-3zm5 3c0 1.6568542 1.343146 3 3 3h1v-2h-1c-.552285 0-1-.4477153-1-1v-1h2v-2h-2v-2h-2z" fill="#5abbef"/><path d="m5 10v-6h-2v4a1 1 0 0 1 -1-1v-3h-2v3a3 3 0 0 0 3 3z" fill="#fff" fill-opacity=".39216"/></svg>
+<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M5 2v2h2V2zm2 2v2H5V4H3v4a1 1 0 0 1-1-1V4H0v3a3 3 0 0 0 0 .05A3 3 0 0 0 3 10h6V6a1 1 0 0 1 1 1v3h2V7a3 3 0 0 0-3-3zm5 3a3 3 0 0 0 3 3h1V8h-1a1 1 0 0 1-1-1V6h2V4h-2V2h-2z" fill="#5abbef"/><path d="M5 10V4H3v4a1 1 0 0 1-1-1V4H0v3a3 3 0 0 0 3 3zm2 0h2V6a1 1 0 0 1 1 1v3h2V7a3 3 0 0 0-3-3H7z" fill="#fff" fill-opacity=".4"/></svg>
diff --git a/editor/import_dock.cpp b/editor/import_dock.cpp
index 614047296a..d13c0e7f86 100644
--- a/editor/import_dock.cpp
+++ b/editor/import_dock.cpp
@@ -709,7 +709,7 @@ ImportDock::ImportDock() {
content->hide();
imported = memnew(Label);
- imported->add_theme_style_override("normal", EditorNode::get_singleton()->get_gui_base()->get_theme_stylebox(SNAME("normal"), SNAME("LineEdit")));
+ imported->add_theme_style_override("normal", EditorNode::get_singleton()->get_editor_theme()->get_stylebox(SNAME("normal"), SNAME("LineEdit")));
imported->set_clip_text(true);
content->add_child(imported);
HBoxContainer *hb = memnew(HBoxContainer);
diff --git a/editor/plugins/abstract_polygon_2d_editor.cpp b/editor/plugins/abstract_polygon_2d_editor.cpp
index 86653f8775..fd15735e65 100644
--- a/editor/plugins/abstract_polygon_2d_editor.cpp
+++ b/editor/plugins/abstract_polygon_2d_editor.cpp
@@ -725,7 +725,6 @@ AbstractPolygon2DEditor::AbstractPolygon2DEditor(bool p_wip_destructive) {
selected_point = Vertex();
edge_point = PosVertex();
- add_child(memnew(VSeparator));
button_create = memnew(Button);
button_create->set_flat(true);
add_child(button_create);
diff --git a/editor/plugins/animation_player_editor_plugin.cpp b/editor/plugins/animation_player_editor_plugin.cpp
index 59e114fe45..a9c3eebc3f 100644
--- a/editor/plugins/animation_player_editor_plugin.cpp
+++ b/editor/plugins/animation_player_editor_plugin.cpp
@@ -111,11 +111,11 @@ void AnimationPlayerEditor::_notification(int p_what) {
get_tree()->connect("node_removed", callable_mp(this, &AnimationPlayerEditor::_node_removed));
- add_theme_style_override("panel", EditorNode::get_singleton()->get_gui_base()->get_theme_stylebox(SNAME("panel"), SNAME("Panel")));
+ add_theme_style_override("panel", EditorNode::get_singleton()->get_editor_theme()->get_stylebox(SNAME("panel"), SNAME("Panel")));
} break;
case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
- add_theme_style_override("panel", EditorNode::get_singleton()->get_gui_base()->get_theme_stylebox(SNAME("panel"), SNAME("Panel")));
+ add_theme_style_override("panel", EditorNode::get_singleton()->get_editor_theme()->get_stylebox(SNAME("panel"), SNAME("Panel")));
} break;
case NOTIFICATION_TRANSLATION_CHANGED:
diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp
index e544ff325a..0130a9df2a 100644
--- a/editor/plugins/canvas_item_editor_plugin.cpp
+++ b/editor/plugins/canvas_item_editor_plugin.cpp
@@ -3896,7 +3896,7 @@ void CanvasItemEditor::_update_editor_settings() {
key_auto_insert_button->add_theme_color_override("icon_pressed_color", key_auto_color.lerp(Color(1, 0, 0), 0.55));
animation_menu->set_icon(get_editor_theme_icon(SNAME("GuiTabMenuHl")));
- context_menu_panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("ContextualToolbar"), EditorStringName(EditorStyles)));
+ context_toolbar_panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("ContextualToolbar"), EditorStringName(EditorStyles)));
panner->setup((ViewPanner::ControlScheme)EDITOR_GET("editors/panning/2d_editor_panning_scheme").operator int(), ED_GET_SHORTCUT("canvas_item_editor/pan_view"), bool(EDITOR_GET("editors/panning/simple_panning")));
panner->set_scroll_speed(EDITOR_GET("editors/panning/2d_editor_pan_speed"));
@@ -4956,13 +4956,51 @@ void CanvasItemEditor::clear() {
}
void CanvasItemEditor::add_control_to_menu_panel(Control *p_control) {
- ERR_FAIL_COND(!p_control);
+ ERR_FAIL_NULL(p_control);
+ ERR_FAIL_COND(p_control->get_parent());
- context_menu_hbox->add_child(p_control);
+ VSeparator *sep = memnew(VSeparator);
+ context_toolbar_hbox->add_child(sep);
+ context_toolbar_hbox->add_child(p_control);
+ context_toolbar_separators[p_control] = sep;
+
+ p_control->connect("visibility_changed", callable_mp(this, &CanvasItemEditor::_update_context_toolbar));
+
+ _update_context_toolbar();
}
void CanvasItemEditor::remove_control_from_menu_panel(Control *p_control) {
- context_menu_hbox->remove_child(p_control);
+ ERR_FAIL_NULL(p_control);
+ ERR_FAIL_COND(p_control->get_parent() != context_toolbar_hbox);
+
+ p_control->disconnect("visibility_changed", callable_mp(this, &CanvasItemEditor::_update_context_toolbar));
+
+ context_toolbar_hbox->remove_child(context_toolbar_separators[p_control]);
+ context_toolbar_hbox->remove_child(p_control);
+ context_toolbar_separators.erase(p_control);
+
+ _update_context_toolbar();
+}
+
+void CanvasItemEditor::_update_context_toolbar() {
+ bool has_visible = false;
+ bool first_visible = false;
+
+ for (int i = 0; i < context_toolbar_hbox->get_child_count(); i++) {
+ Control *child = Object::cast_to<Control>(context_toolbar_hbox->get_child(i));
+ if (!child || !context_toolbar_separators.has(child)) {
+ continue;
+ }
+ if (child->is_visible()) {
+ first_visible = !has_visible;
+ has_visible = true;
+ }
+
+ VSeparator *sep = context_toolbar_separators[child];
+ sep->set_visible(!first_visible && child->is_visible());
+ }
+
+ context_toolbar_panel->set_visible(has_visible);
}
void CanvasItemEditor::add_control_to_left_panel(Control *p_control) {
@@ -5012,9 +5050,17 @@ CanvasItemEditor::CanvasItemEditor() {
EditorRunBar::get_singleton()->call_deferred(SNAME("connect"), "play_pressed", callable_mp(this, &CanvasItemEditor::_update_override_camera_button).bind(true));
EditorRunBar::get_singleton()->call_deferred(SNAME("connect"), "stop_pressed", callable_mp(this, &CanvasItemEditor::_update_override_camera_button).bind(false));
+ // Add some margin to the sides for better aesthetics.
+ // This prevents the first button's hover/pressed effect from "touching" the panel's border,
+ // which looks ugly.
+ MarginContainer *toolbar_margin = memnew(MarginContainer);
+ toolbar_margin->add_theme_constant_override("margin_left", 4 * EDSCALE);
+ toolbar_margin->add_theme_constant_override("margin_right", 4 * EDSCALE);
+ add_child(toolbar_margin);
+
// A fluid container for all toolbars.
HFlowContainer *main_flow = memnew(HFlowContainer);
- add_child(main_flow);
+ toolbar_margin->add_child(main_flow);
// Main toolbars.
HBoxContainer *main_menu_hbox = memnew(HBoxContainer);
@@ -5122,13 +5168,6 @@ CanvasItemEditor::CanvasItemEditor() {
viewport->add_child(controls_vb);
- // Add some margin to the left for better esthetics.
- // This prevents the first button's hover/pressed effect from "touching" the panel's border,
- // which looks ugly.
- Control *margin_left = memnew(Control);
- main_menu_hbox->add_child(margin_left);
- margin_left->set_custom_minimum_size(Size2(2, 0) * EDSCALE);
-
select_button = memnew(Button);
select_button->set_flat(true);
main_menu_hbox->add_child(select_button);
@@ -5370,15 +5409,14 @@ CanvasItemEditor::CanvasItemEditor() {
main_menu_hbox->add_child(memnew(VSeparator));
// Contextual toolbars.
- context_menu_panel = memnew(PanelContainer);
- context_menu_hbox = memnew(HBoxContainer);
- context_menu_panel->add_child(context_menu_hbox);
- main_flow->add_child(context_menu_panel);
+ context_toolbar_panel = memnew(PanelContainer);
+ context_toolbar_hbox = memnew(HBoxContainer);
+ context_toolbar_panel->add_child(context_toolbar_hbox);
+ main_flow->add_child(context_toolbar_panel);
// Animation controls.
animation_hb = memnew(HBoxContainer);
- context_menu_hbox->add_child(animation_hb);
- animation_hb->add_child(memnew(VSeparator));
+ add_control_to_menu_panel(animation_hb);
animation_hb->hide();
key_loc_button = memnew(Button);
diff --git a/editor/plugins/canvas_item_editor_plugin.h b/editor/plugins/canvas_item_editor_plugin.h
index 06f91be081..9aac6e44df 100644
--- a/editor/plugins/canvas_item_editor_plugin.h
+++ b/editor/plugins/canvas_item_editor_plugin.h
@@ -48,6 +48,7 @@ class PanelContainer;
class StyleBoxTexture;
class ViewPanner;
class VScrollBar;
+class VSeparator;
class VSplitContainer;
class CanvasItemEditorSelectedItem : public Object {
@@ -192,10 +193,14 @@ private:
HScrollBar *h_scroll = nullptr;
VScrollBar *v_scroll = nullptr;
+
// Used for secondary menu items which are displayed depending on the currently selected node
// (such as MeshInstance's "Mesh" menu).
- PanelContainer *context_menu_panel = nullptr;
- HBoxContainer *context_menu_hbox = nullptr;
+ PanelContainer *context_toolbar_panel = nullptr;
+ HBoxContainer *context_toolbar_hbox = nullptr;
+ HashMap<Control *, VSeparator *> context_toolbar_separators;
+
+ void _update_context_toolbar();
Transform2D transform;
GridVisibility grid_visibility = GRID_VISIBILITY_SHOW_WHEN_SNAPPING;
diff --git a/editor/plugins/control_editor_plugin.cpp b/editor/plugins/control_editor_plugin.cpp
index f1667d14ab..2477d121c0 100644
--- a/editor/plugins/control_editor_plugin.cpp
+++ b/editor/plugins/control_editor_plugin.cpp
@@ -33,6 +33,7 @@
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "editor/editor_undo_redo_manager.h"
#include "editor/plugins/canvas_item_editor_plugin.h"
#include "scene/gui/grid_container.h"
@@ -193,7 +194,7 @@ void EditorPropertyAnchorsPreset::setup(const Vector<String> &p_options) {
String preset_name = option_name.trim_prefix("Preset");
String humanized_name = preset_name.capitalize();
String icon_name = "ControlAlign" + preset_name;
- options->add_icon_item(EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(icon_name), humanized_name);
+ options->add_icon_item(EditorNode::get_singleton()->get_editor_theme()->get_icon(icon_name, EditorStringName(EditorIcons)), humanized_name);
} else {
options->add_item(option_name);
}
@@ -976,8 +977,6 @@ void ControlEditorToolbar::_notification(int p_what) {
}
ControlEditorToolbar::ControlEditorToolbar() {
- add_child(memnew(VSeparator));
-
// Anchor and offset tools.
anchors_button = memnew(ControlEditorPopupButton);
anchors_button->set_tooltip_text(TTR("Presets for the anchor and offset values of a Control node."));
diff --git a/editor/plugins/cpu_particles_2d_editor_plugin.cpp b/editor/plugins/cpu_particles_2d_editor_plugin.cpp
index 967ef3cb6b..f0fd40a77e 100644
--- a/editor/plugins/cpu_particles_2d_editor_plugin.cpp
+++ b/editor/plugins/cpu_particles_2d_editor_plugin.cpp
@@ -267,8 +267,6 @@ CPUParticles2DEditorPlugin::CPUParticles2DEditorPlugin() {
add_control_to_container(CONTAINER_CANVAS_EDITOR_MENU, toolbar);
toolbar->hide();
- toolbar->add_child(memnew(VSeparator));
-
menu = memnew(MenuButton);
menu->get_popup()->add_item(TTR("Restart"), MENU_RESTART);
menu->get_popup()->add_item(TTR("Load Emission Mask"), MENU_LOAD_EMISSION_MASK);
diff --git a/editor/plugins/gizmos/audio_listener_3d_gizmo_plugin.cpp b/editor/plugins/gizmos/audio_listener_3d_gizmo_plugin.cpp
index 894047c524..56a3cb488b 100644
--- a/editor/plugins/gizmos/audio_listener_3d_gizmo_plugin.cpp
+++ b/editor/plugins/gizmos/audio_listener_3d_gizmo_plugin.cpp
@@ -30,11 +30,13 @@
#include "audio_listener_3d_gizmo_plugin.h"
+#include "editor/editor_node.h"
+#include "editor/editor_string_names.h"
#include "editor/plugins/node_3d_editor_plugin.h"
#include "scene/3d/audio_listener_3d.h"
AudioListener3DGizmoPlugin::AudioListener3DGizmoPlugin() {
- create_icon_material("audio_listener_3d_icon", Node3DEditor::get_singleton()->get_editor_theme_icon(SNAME("GizmoAudioListener3D")));
+ create_icon_material("audio_listener_3d_icon", EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("GizmoAudioListener3D"), EditorStringName(EditorIcons)));
}
bool AudioListener3DGizmoPlugin::has_gizmo(Node3D *p_spatial) {
diff --git a/editor/plugins/gizmos/audio_stream_player_3d_gizmo_plugin.cpp b/editor/plugins/gizmos/audio_stream_player_3d_gizmo_plugin.cpp
index ad40af7784..cda00b9543 100644
--- a/editor/plugins/gizmos/audio_stream_player_3d_gizmo_plugin.cpp
+++ b/editor/plugins/gizmos/audio_stream_player_3d_gizmo_plugin.cpp
@@ -30,7 +30,9 @@
#include "audio_stream_player_3d_gizmo_plugin.h"
+#include "editor/editor_node.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "editor/editor_undo_redo_manager.h"
#include "editor/plugins/node_3d_editor_plugin.h"
#include "scene/3d/audio_stream_player_3d.h"
@@ -38,7 +40,7 @@
AudioStreamPlayer3DGizmoPlugin::AudioStreamPlayer3DGizmoPlugin() {
Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/stream_player_3d", Color(0.4, 0.8, 1));
- create_icon_material("stream_player_3d_icon", Node3DEditor::get_singleton()->get_editor_theme_icon(SNAME("Gizmo3DSamplePlayer")));
+ create_icon_material("stream_player_3d_icon", EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("Gizmo3DSamplePlayer"), EditorStringName(EditorIcons)));
create_material("stream_player_3d_material_primary", gizmo_color);
create_material("stream_player_3d_material_secondary", gizmo_color * Color(1, 1, 1, 0.35));
// Enable vertex colors for the billboard material as the gizmo color depends on the
@@ -121,136 +123,137 @@ void AudioStreamPlayer3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gi
}
void AudioStreamPlayer3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
- const AudioStreamPlayer3D *player = Object::cast_to<AudioStreamPlayer3D>(p_gizmo->get_node_3d());
-
p_gizmo->clear();
- const Ref<Material> icon = get_material("stream_player_3d_icon", p_gizmo);
-
- if (player->get_attenuation_model() != AudioStreamPlayer3D::ATTENUATION_DISABLED || player->get_max_distance() > CMP_EPSILON) {
- // Draw a circle to represent sound volume attenuation.
- // Use only a billboard circle to represent radius.
- // This helps distinguish AudioStreamPlayer3D gizmos from OmniLight3D gizmos.
- const Ref<Material> lines_billboard_material = get_material("stream_player_3d_material_billboard", p_gizmo);
-
- // Soft distance cap varies depending on attenuation model, as some will fade out more aggressively than others.
- // Multipliers were empirically determined through testing.
- float soft_multiplier;
- switch (player->get_attenuation_model()) {
- case AudioStreamPlayer3D::ATTENUATION_INVERSE_DISTANCE:
- soft_multiplier = 12.0;
- break;
- case AudioStreamPlayer3D::ATTENUATION_INVERSE_SQUARE_DISTANCE:
- soft_multiplier = 4.0;
- break;
- case AudioStreamPlayer3D::ATTENUATION_LOGARITHMIC:
- soft_multiplier = 3.25;
- break;
- default:
- // Ensures Max Distance's radius visualization is not capped by Unit Size
- // (when the attenuation mode is Disabled).
- soft_multiplier = 10000.0;
- break;
- }
-
- // Draw the distance at which the sound can be reasonably heard.
- // This can be either a hard distance cap with the Max Distance property (if set above 0.0),
- // or a soft distance cap with the Unit Size property (sound never reaches true zero).
- // When Max Distance is 0.0, `r` represents the distance above which the
- // sound can't be heard in *most* (but not all) scenarios.
- float r;
- if (player->get_max_distance() > CMP_EPSILON) {
- r = MIN(player->get_unit_size() * soft_multiplier, player->get_max_distance());
- } else {
- r = player->get_unit_size() * soft_multiplier;
- }
- Vector<Vector3> points_billboard;
-
- for (int i = 0; i < 120; i++) {
- // Create a circle.
- const float ra = Math::deg_to_rad((float)(i * 3));
- const float rb = Math::deg_to_rad((float)((i + 1) * 3));
- const Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * r;
- const Point2 b = Vector2(Math::sin(rb), Math::cos(rb)) * r;
-
- // Draw a billboarded circle.
- points_billboard.push_back(Vector3(a.x, a.y, 0));
- points_billboard.push_back(Vector3(b.x, b.y, 0));
- }
-
- Color color;
- switch (player->get_attenuation_model()) {
- // Pick cold colors for all attenuation models (except Disabled),
- // so that soft caps can be easily distinguished from hard caps
- // (which use warm colors).
- case AudioStreamPlayer3D::ATTENUATION_INVERSE_DISTANCE:
- color = Color(0.4, 0.8, 1);
- break;
- case AudioStreamPlayer3D::ATTENUATION_INVERSE_SQUARE_DISTANCE:
- color = Color(0.4, 0.5, 1);
- break;
- case AudioStreamPlayer3D::ATTENUATION_LOGARITHMIC:
- color = Color(0.4, 0.2, 1);
- break;
- default:
- // Disabled attenuation mode.
- // This is never reached when Max Distance is 0, but the
- // hue-inverted form of this color will be used if Max Distance is greater than 0.
- color = Color(1, 1, 1);
- break;
+ if (p_gizmo->is_selected()) {
+ const AudioStreamPlayer3D *player = Object::cast_to<AudioStreamPlayer3D>(p_gizmo->get_node_3d());
+
+ if (player->get_attenuation_model() != AudioStreamPlayer3D::ATTENUATION_DISABLED || player->get_max_distance() > CMP_EPSILON) {
+ // Draw a circle to represent sound volume attenuation.
+ // Use only a billboard circle to represent radius.
+ // This helps distinguish AudioStreamPlayer3D gizmos from OmniLight3D gizmos.
+ const Ref<Material> lines_billboard_material = get_material("stream_player_3d_material_billboard", p_gizmo);
+
+ // Soft distance cap varies depending on attenuation model, as some will fade out more aggressively than others.
+ // Multipliers were empirically determined through testing.
+ float soft_multiplier;
+ switch (player->get_attenuation_model()) {
+ case AudioStreamPlayer3D::ATTENUATION_INVERSE_DISTANCE:
+ soft_multiplier = 12.0;
+ break;
+ case AudioStreamPlayer3D::ATTENUATION_INVERSE_SQUARE_DISTANCE:
+ soft_multiplier = 4.0;
+ break;
+ case AudioStreamPlayer3D::ATTENUATION_LOGARITHMIC:
+ soft_multiplier = 3.25;
+ break;
+ default:
+ // Ensures Max Distance's radius visualization is not capped by Unit Size
+ // (when the attenuation mode is Disabled).
+ soft_multiplier = 10000.0;
+ break;
+ }
+
+ // Draw the distance at which the sound can be reasonably heard.
+ // This can be either a hard distance cap with the Max Distance property (if set above 0.0),
+ // or a soft distance cap with the Unit Size property (sound never reaches true zero).
+ // When Max Distance is 0.0, `r` represents the distance above which the
+ // sound can't be heard in *most* (but not all) scenarios.
+ float r;
+ if (player->get_max_distance() > CMP_EPSILON) {
+ r = MIN(player->get_unit_size() * soft_multiplier, player->get_max_distance());
+ } else {
+ r = player->get_unit_size() * soft_multiplier;
+ }
+ Vector<Vector3> points_billboard;
+
+ for (int i = 0; i < 120; i++) {
+ // Create a circle.
+ const float ra = Math::deg_to_rad((float)(i * 3));
+ const float rb = Math::deg_to_rad((float)((i + 1) * 3));
+ const Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * r;
+ const Point2 b = Vector2(Math::sin(rb), Math::cos(rb)) * r;
+
+ // Draw a billboarded circle.
+ points_billboard.push_back(Vector3(a.x, a.y, 0));
+ points_billboard.push_back(Vector3(b.x, b.y, 0));
+ }
+
+ Color color;
+ switch (player->get_attenuation_model()) {
+ // Pick cold colors for all attenuation models (except Disabled),
+ // so that soft caps can be easily distinguished from hard caps
+ // (which use warm colors).
+ case AudioStreamPlayer3D::ATTENUATION_INVERSE_DISTANCE:
+ color = Color(0.4, 0.8, 1);
+ break;
+ case AudioStreamPlayer3D::ATTENUATION_INVERSE_SQUARE_DISTANCE:
+ color = Color(0.4, 0.5, 1);
+ break;
+ case AudioStreamPlayer3D::ATTENUATION_LOGARITHMIC:
+ color = Color(0.4, 0.2, 1);
+ break;
+ default:
+ // Disabled attenuation mode.
+ // This is never reached when Max Distance is 0, but the
+ // hue-inverted form of this color will be used if Max Distance is greater than 0.
+ color = Color(1, 1, 1);
+ break;
+ }
+
+ if (player->get_max_distance() > CMP_EPSILON) {
+ // Sound is hard-capped by max distance. The attenuation model still matters,
+ // so invert the hue of the color that was chosen above.
+ color.set_h(color.get_h() + 0.5);
+ }
+
+ p_gizmo->add_lines(points_billboard, lines_billboard_material, true, color);
}
- if (player->get_max_distance() > CMP_EPSILON) {
- // Sound is hard-capped by max distance. The attenuation model still matters,
- // so invert the hue of the color that was chosen above.
- color.set_h(color.get_h() + 0.5);
- }
+ if (player->is_emission_angle_enabled()) {
+ const float pc = player->get_emission_angle();
+ const float ofs = -Math::cos(Math::deg_to_rad(pc));
+ const float radius = Math::sin(Math::deg_to_rad(pc));
- p_gizmo->add_lines(points_billboard, lines_billboard_material, true, color);
- }
+ Vector<Vector3> points_primary;
+ points_primary.resize(200);
- if (player->is_emission_angle_enabled()) {
- const float pc = player->get_emission_angle();
- const float ofs = -Math::cos(Math::deg_to_rad(pc));
- const float radius = Math::sin(Math::deg_to_rad(pc));
+ real_t step = Math_TAU / 100.0;
+ for (int i = 0; i < 100; i++) {
+ const float a = i * step;
+ const float an = (i + 1) * step;
- Vector<Vector3> points_primary;
- points_primary.resize(200);
+ const Vector3 from(Math::sin(a) * radius, Math::cos(a) * radius, ofs);
+ const Vector3 to(Math::sin(an) * radius, Math::cos(an) * radius, ofs);
- real_t step = Math_TAU / 100.0;
- for (int i = 0; i < 100; i++) {
- const float a = i * step;
- const float an = (i + 1) * step;
+ points_primary.write[i * 2 + 0] = from;
+ points_primary.write[i * 2 + 1] = to;
+ }
- const Vector3 from(Math::sin(a) * radius, Math::cos(a) * radius, ofs);
- const Vector3 to(Math::sin(an) * radius, Math::cos(an) * radius, ofs);
+ const Ref<Material> material_primary = get_material("stream_player_3d_material_primary", p_gizmo);
+ p_gizmo->add_lines(points_primary, material_primary);
- points_primary.write[i * 2 + 0] = from;
- points_primary.write[i * 2 + 1] = to;
- }
+ Vector<Vector3> points_secondary;
+ points_secondary.resize(16);
- const Ref<Material> material_primary = get_material("stream_player_3d_material_primary", p_gizmo);
- p_gizmo->add_lines(points_primary, material_primary);
+ for (int i = 0; i < 8; i++) {
+ const float a = i * (Math_TAU / 8.0);
+ const Vector3 from(Math::sin(a) * radius, Math::cos(a) * radius, ofs);
- Vector<Vector3> points_secondary;
- points_secondary.resize(16);
+ points_secondary.write[i * 2 + 0] = from;
+ points_secondary.write[i * 2 + 1] = Vector3();
+ }
- for (int i = 0; i < 8; i++) {
- const float a = i * (Math_TAU / 8.0);
- const Vector3 from(Math::sin(a) * radius, Math::cos(a) * radius, ofs);
+ const Ref<Material> material_secondary = get_material("stream_player_3d_material_secondary", p_gizmo);
+ p_gizmo->add_lines(points_secondary, material_secondary);
- points_secondary.write[i * 2 + 0] = from;
- points_secondary.write[i * 2 + 1] = Vector3();
+ Vector<Vector3> handles;
+ const float ha = Math::deg_to_rad(player->get_emission_angle());
+ handles.push_back(Vector3(Math::sin(ha), 0, -Math::cos(ha)));
+ p_gizmo->add_handles(handles, get_material("handles"));
}
-
- const Ref<Material> material_secondary = get_material("stream_player_3d_material_secondary", p_gizmo);
- p_gizmo->add_lines(points_secondary, material_secondary);
-
- Vector<Vector3> handles;
- const float ha = Math::deg_to_rad(player->get_emission_angle());
- handles.push_back(Vector3(Math::sin(ha), 0, -Math::cos(ha)));
- p_gizmo->add_handles(handles, get_material("handles"));
}
+ const Ref<Material> icon = get_material("stream_player_3d_icon", p_gizmo);
p_gizmo->add_unscaled_billboard(icon, 0.05);
}
diff --git a/editor/plugins/gizmos/camera_3d_gizmo_plugin.cpp b/editor/plugins/gizmos/camera_3d_gizmo_plugin.cpp
index b0fc5d1ec0..af7874e4da 100644
--- a/editor/plugins/gizmos/camera_3d_gizmo_plugin.cpp
+++ b/editor/plugins/gizmos/camera_3d_gizmo_plugin.cpp
@@ -33,6 +33,7 @@
#include "core/config/project_settings.h"
#include "editor/editor_node.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "editor/editor_undo_redo_manager.h"
#include "editor/plugins/node_3d_editor_plugin.h"
#include "scene/3d/camera_3d.h"
@@ -41,7 +42,7 @@ Camera3DGizmoPlugin::Camera3DGizmoPlugin() {
Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/camera", Color(0.8, 0.4, 0.8));
create_material("camera_material", gizmo_color);
- create_icon_material("camera_icon", Node3DEditor::get_singleton()->get_editor_theme_icon("GizmoCamera3D"));
+ create_icon_material("camera_icon", EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("GizmoCamera3D"), EditorStringName(EditorIcons)));
create_handle_material("handles");
}
diff --git a/editor/plugins/gizmos/collision_shape_3d_gizmo_plugin.cpp b/editor/plugins/gizmos/collision_shape_3d_gizmo_plugin.cpp
index 3becc9c9fd..2695253b78 100644
--- a/editor/plugins/gizmos/collision_shape_3d_gizmo_plugin.cpp
+++ b/editor/plugins/gizmos/collision_shape_3d_gizmo_plugin.cpp
@@ -34,6 +34,7 @@
#include "core/math/geometry_3d.h"
#include "editor/editor_settings.h"
#include "editor/editor_undo_redo_manager.h"
+#include "editor/plugins/gizmos/gizmo_3d_helper.h"
#include "editor/plugins/node_3d_editor_plugin.h"
#include "scene/3d/collision_shape_3d.h"
#include "scene/resources/box_shape_3d.h"
@@ -47,6 +48,7 @@
#include "scene/resources/world_boundary_shape_3d.h"
CollisionShape3DGizmoPlugin::CollisionShape3DGizmoPlugin() {
+ helper.instantiate();
const Color gizmo_color = EDITOR_GET("editors/3d_gizmos/gizmo_colors/shape");
create_material("shape_material", gizmo_color);
const float gizmo_value = gizmo_color.get_v();
@@ -55,6 +57,9 @@ CollisionShape3DGizmoPlugin::CollisionShape3DGizmoPlugin() {
create_handle_material("handles");
}
+CollisionShape3DGizmoPlugin::~CollisionShape3DGizmoPlugin() {
+}
+
bool CollisionShape3DGizmoPlugin::has_gizmo(Node3D *p_spatial) {
return Object::cast_to<CollisionShape3D>(p_spatial) != nullptr;
}
@@ -80,7 +85,7 @@ String CollisionShape3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_g
}
if (Object::cast_to<BoxShape3D>(*s)) {
- return "Size";
+ return helper->box_get_handle_name(p_id);
}
if (Object::cast_to<CapsuleShape3D>(*s)) {
@@ -135,8 +140,7 @@ Variant CollisionShape3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p
}
void CollisionShape3DGizmoPlugin::begin_handle_action(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) {
- initial_transform = p_gizmo->get_node_3d()->get_global_transform();
- initial_value = get_handle_value(p_gizmo, p_id, p_secondary);
+ helper->initialize_handle_action(get_handle_value(p_gizmo, p_id, p_secondary), p_gizmo->get_node_3d()->get_global_transform());
}
void CollisionShape3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) {
@@ -147,13 +151,8 @@ void CollisionShape3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, i
return;
}
- Transform3D gt = initial_transform;
- Transform3D gi = gt.affine_inverse();
-
- Vector3 ray_from = p_camera->project_ray_origin(p_point);
- Vector3 ray_dir = p_camera->project_ray_normal(p_point);
-
- Vector3 sg[2] = { gi.xform(ray_from), gi.xform(ray_from + ray_dir * 4096) };
+ Vector3 sg[2];
+ helper->get_segment(p_camera, p_point, sg);
if (Object::cast_to<SphereShape3D>(*s)) {
Ref<SphereShape3D> ss = s;
@@ -188,38 +187,12 @@ void CollisionShape3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, i
}
if (Object::cast_to<BoxShape3D>(*s)) {
- Vector3 axis;
- axis[p_id / 2] = 1.0;
Ref<BoxShape3D> bs = s;
- Vector3 ra, rb;
- int sign = p_id % 2 * -2 + 1;
- Vector3 initial_size = initial_value;
-
- Geometry3D::get_closest_points_between_segments(Vector3(), axis * 4096 * sign, sg[0], sg[1], ra, rb);
- if (ra[p_id / 2] == 0) {
- // Point before half of the shape. Needs to be calculated in opposite direction.
- Geometry3D::get_closest_points_between_segments(Vector3(), axis * 4096 * -sign, sg[0], sg[1], ra, rb);
- }
-
- float d = ra[p_id / 2] * sign;
-
- Vector3 he = bs->get_size();
- he[p_id / 2] = d * 2;
- if (Node3DEditor::get_singleton()->is_snap_enabled()) {
- he[p_id / 2] = Math::snapped(he[p_id / 2], Node3DEditor::get_singleton()->get_translate_snap());
- }
-
- if (Input::get_singleton()->is_key_pressed(Key::ALT)) {
- he[p_id / 2] = MAX(he[p_id / 2], 0.001);
- bs->set_size(he);
- cs->set_global_position(initial_transform.get_origin());
- } else {
- he[p_id / 2] = MAX(he[p_id / 2], -initial_size[p_id / 2] + 0.002);
- bs->set_size((initial_size + (he - initial_size) * 0.5).abs());
- Vector3 pos = initial_transform.affine_inverse().xform(initial_transform.get_origin());
- pos += (bs->get_size() - initial_size) * 0.5 * sign;
- cs->set_global_position(initial_transform.xform(pos));
- }
+ Vector3 size = bs->get_size();
+ Vector3 position;
+ helper->box_set_handle(sg, p_id, size, position);
+ bs->set_size(size);
+ cs->set_global_position(position);
}
if (Object::cast_to<CapsuleShape3D>(*s)) {
@@ -291,20 +264,7 @@ void CollisionShape3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo
}
if (Object::cast_to<BoxShape3D>(*s)) {
- Ref<BoxShape3D> ss = s;
- if (p_cancel) {
- cs->set_global_position(initial_transform.get_origin());
- ss->set_size(p_restore);
- return;
- }
-
- EditorUndoRedoManager *ur = EditorUndoRedoManager::get_singleton();
- ur->create_action(TTR("Change Box Shape Size"));
- ur->add_do_method(ss.ptr(), "set_size", ss->get_size());
- ur->add_do_method(cs, "set_global_position", cs->get_global_position());
- ur->add_undo_method(ss.ptr(), "set_size", p_restore);
- ur->add_undo_method(cs, "set_global_position", initial_transform.get_origin());
- ur->commit_action();
+ helper->box_commit_handle(TTR("Change Box Shape Size"), p_cancel, cs, s.ptr());
}
if (Object::cast_to<CapsuleShape3D>(*s)) {
@@ -446,14 +406,7 @@ void CollisionShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
lines.push_back(b);
}
- Vector<Vector3> handles;
-
- for (int i = 0; i < 3; i++) {
- Vector3 ax;
- ax[i] = bs->get_size()[i] / 2;
- handles.push_back(ax);
- handles.push_back(-ax);
- }
+ const Vector<Vector3> handles = helper->box_get_handles(bs->get_size());
p_gizmo->add_lines(lines, material);
p_gizmo->add_collision_segments(lines);
diff --git a/editor/plugins/gizmos/collision_shape_3d_gizmo_plugin.h b/editor/plugins/gizmos/collision_shape_3d_gizmo_plugin.h
index 6b7740de2f..464012acf9 100644
--- a/editor/plugins/gizmos/collision_shape_3d_gizmo_plugin.h
+++ b/editor/plugins/gizmos/collision_shape_3d_gizmo_plugin.h
@@ -33,11 +33,12 @@
#include "editor/plugins/node_3d_editor_gizmos.h"
+class Gizmo3DHelper;
+
class CollisionShape3DGizmoPlugin : public EditorNode3DGizmoPlugin {
GDCLASS(CollisionShape3DGizmoPlugin, EditorNode3DGizmoPlugin);
- Transform3D initial_transform;
- Variant initial_value;
+ Ref<Gizmo3DHelper> helper;
public:
bool has_gizmo(Node3D *p_spatial) override;
@@ -52,6 +53,7 @@ public:
void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel = false) override;
CollisionShape3DGizmoPlugin();
+ ~CollisionShape3DGizmoPlugin();
};
#endif // COLLISION_SHAPE_3D_GIZMO_PLUGIN_H
diff --git a/editor/plugins/gizmos/cpu_particles_3d_gizmo_plugin.cpp b/editor/plugins/gizmos/cpu_particles_3d_gizmo_plugin.cpp
index e00b5349d2..3745b407a3 100644
--- a/editor/plugins/gizmos/cpu_particles_3d_gizmo_plugin.cpp
+++ b/editor/plugins/gizmos/cpu_particles_3d_gizmo_plugin.cpp
@@ -30,11 +30,13 @@
#include "cpu_particles_3d_gizmo_plugin.h"
+#include "editor/editor_node.h"
+#include "editor/editor_string_names.h"
#include "editor/plugins/node_3d_editor_plugin.h"
#include "scene/3d/cpu_particles_3d.h"
CPUParticles3DGizmoPlugin::CPUParticles3DGizmoPlugin() {
- create_icon_material("particles_icon", Node3DEditor::get_singleton()->get_editor_theme_icon(SNAME("GizmoCPUParticles3D")));
+ create_icon_material("particles_icon", EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("GizmoCPUParticles3D"), EditorStringName(EditorIcons)));
}
bool CPUParticles3DGizmoPlugin::has_gizmo(Node3D *p_spatial) {
diff --git a/editor/plugins/gizmos/decal_gizmo_plugin.cpp b/editor/plugins/gizmos/decal_gizmo_plugin.cpp
index b439598ef4..68206a7ee5 100644
--- a/editor/plugins/gizmos/decal_gizmo_plugin.cpp
+++ b/editor/plugins/gizmos/decal_gizmo_plugin.cpp
@@ -32,10 +32,12 @@
#include "editor/editor_settings.h"
#include "editor/editor_undo_redo_manager.h"
+#include "editor/plugins/gizmos/gizmo_3d_helper.h"
#include "editor/plugins/node_3d_editor_plugin.h"
#include "scene/3d/decal.h"
DecalGizmoPlugin::DecalGizmoPlugin() {
+ helper.instantiate();
Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/decal", Color(0.6, 0.5, 1.0));
create_material("decal_material", gizmo_color);
@@ -43,6 +45,9 @@ DecalGizmoPlugin::DecalGizmoPlugin() {
create_handle_material("handles");
}
+DecalGizmoPlugin::~DecalGizmoPlugin() {
+}
+
bool DecalGizmoPlugin::has_gizmo(Node3D *p_spatial) {
return Object::cast_to<Decal>(p_spatial) != nullptr;
}
@@ -56,16 +61,7 @@ int DecalGizmoPlugin::get_priority() const {
}
String DecalGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const {
- switch (p_id) {
- case 0:
- return "Size X";
- case 1:
- return "Size Y";
- case 2:
- return "Size Z";
- }
-
- return "";
+ return helper->box_get_handle_name(p_id);
}
Variant DecalGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const {
@@ -73,52 +69,25 @@ Variant DecalGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int
return decal->get_size();
}
+void DecalGizmoPlugin::begin_handle_action(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) {
+ helper->initialize_handle_action(get_handle_value(p_gizmo, p_id, p_secondary), p_gizmo->get_node_3d()->get_global_transform());
+}
+
void DecalGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) {
Decal *decal = Object::cast_to<Decal>(p_gizmo->get_node_3d());
- Transform3D gt = decal->get_global_transform();
-
- Transform3D gi = gt.affine_inverse();
-
Vector3 size = decal->get_size();
- Vector3 ray_from = p_camera->project_ray_origin(p_point);
- Vector3 ray_dir = p_camera->project_ray_normal(p_point);
-
- Vector3 sg[2] = { gi.xform(ray_from), gi.xform(ray_from + ray_dir * 16384) };
-
- Vector3 axis;
- axis[p_id] = 1.0;
-
- Vector3 ra, rb;
- Geometry3D::get_closest_points_between_segments(Vector3(), axis * 16384, sg[0], sg[1], ra, rb);
- float d = ra[p_id] * 2;
- if (Node3DEditor::get_singleton()->is_snap_enabled()) {
- d = Math::snapped(d, Node3DEditor::get_singleton()->get_translate_snap());
- }
-
- if (d < 0.001) {
- d = 0.001;
- }
+ Vector3 sg[2];
+ helper->get_segment(p_camera, p_point, sg);
- size[p_id] = d;
+ Vector3 position;
+ helper->box_set_handle(sg, p_id, size, position);
decal->set_size(size);
+ decal->set_global_position(position);
}
void DecalGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel) {
- Decal *decal = Object::cast_to<Decal>(p_gizmo->get_node_3d());
-
- Vector3 restore = p_restore;
-
- if (p_cancel) {
- decal->set_size(restore);
- return;
- }
-
- EditorUndoRedoManager *ur = EditorUndoRedoManager::get_singleton();
- ur->create_action(TTR("Change Decal Size"));
- ur->add_do_method(decal, "set_size", decal->get_size());
- ur->add_undo_method(decal, "set_size", restore);
- ur->commit_action();
+ helper->box_commit_handle(TTR("Change Decal Size"), p_cancel, p_gizmo->get_node_3d());
}
void DecalGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
@@ -153,14 +122,7 @@ void DecalGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
lines.push_back(Vector3(0, half_size_y, 0));
lines.push_back(Vector3(0, half_size_y * 1.2, 0));
- Vector<Vector3> handles;
-
- for (int i = 0; i < 3; i++) {
- Vector3 ax;
- ax[i] = aabb.position[i] + aabb.size[i];
- handles.push_back(ax);
- }
-
+ Vector<Vector3> handles = helper->box_get_handles(decal->get_size());
Ref<Material> material = get_material("decal_material", p_gizmo);
p_gizmo->add_lines(lines, material);
diff --git a/editor/plugins/gizmos/decal_gizmo_plugin.h b/editor/plugins/gizmos/decal_gizmo_plugin.h
index 800a14b2d5..c7809dc556 100644
--- a/editor/plugins/gizmos/decal_gizmo_plugin.h
+++ b/editor/plugins/gizmos/decal_gizmo_plugin.h
@@ -33,9 +33,13 @@
#include "editor/plugins/node_3d_editor_gizmos.h"
+class Gizmo3DHelper;
+
class DecalGizmoPlugin : public EditorNode3DGizmoPlugin {
GDCLASS(DecalGizmoPlugin, EditorNode3DGizmoPlugin);
+ Ref<Gizmo3DHelper> helper;
+
public:
bool has_gizmo(Node3D *p_spatial) override;
String get_gizmo_name() const override;
@@ -44,10 +48,12 @@ public:
String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const override;
Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const override;
+ void begin_handle_action(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) override;
void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) override;
void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel = false) override;
DecalGizmoPlugin();
+ ~DecalGizmoPlugin();
};
#endif // DECAL_GIZMO_PLUGIN_H
diff --git a/editor/plugins/gizmos/gizmo_3d_helper.cpp b/editor/plugins/gizmos/gizmo_3d_helper.cpp
new file mode 100644
index 0000000000..6c7acb6708
--- /dev/null
+++ b/editor/plugins/gizmos/gizmo_3d_helper.cpp
@@ -0,0 +1,131 @@
+/**************************************************************************/
+/* gizmo_3d_helper.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 "gizmo_3d_helper.h"
+
+#include "editor/editor_undo_redo_manager.h"
+#include "editor/plugins/node_3d_editor_plugin.h"
+#include "scene/3d/camera_3d.h"
+
+void Gizmo3DHelper::initialize_handle_action(const Variant &p_initial_value, const Transform3D &p_initial_transform) {
+ initial_value = p_initial_value;
+ initial_transform = p_initial_transform;
+}
+
+void Gizmo3DHelper::get_segment(Camera3D *p_camera, const Point2 &p_point, Vector3 *r_segment) {
+ Transform3D gt = initial_transform;
+ Transform3D gi = gt.affine_inverse();
+
+ Vector3 ray_from = p_camera->project_ray_origin(p_point);
+ Vector3 ray_dir = p_camera->project_ray_normal(p_point);
+
+ r_segment[0] = gi.xform(ray_from);
+ r_segment[1] = gi.xform(ray_from + ray_dir * 4096);
+}
+
+Vector<Vector3> Gizmo3DHelper::box_get_handles(const Vector3 &p_box_size) {
+ Vector<Vector3> handles;
+ for (int i = 0; i < 3; i++) {
+ Vector3 ax;
+ ax[i] = p_box_size[i] / 2;
+ handles.push_back(ax);
+ handles.push_back(-ax);
+ }
+ return handles;
+}
+
+String Gizmo3DHelper::box_get_handle_name(int p_id) const {
+ switch (p_id) {
+ case 0:
+ case 1:
+ return "Size X";
+ case 2:
+ case 3:
+ return "Size Y";
+ case 4:
+ case 5:
+ return "Size Z";
+ }
+ return "";
+}
+
+void Gizmo3DHelper::box_set_handle(const Vector3 p_segment[2], int p_id, Vector3 &r_box_size, Vector3 &r_box_position) {
+ Vector3 axis;
+ axis[p_id / 2] = 1.0;
+ Vector3 ra, rb;
+ int sign = p_id % 2 * -2 + 1;
+ Vector3 initial_size = initial_value;
+
+ Geometry3D::get_closest_points_between_segments(Vector3(), axis * 4096 * sign, p_segment[0], p_segment[1], ra, rb);
+ if (ra[p_id / 2] == 0) {
+ // Point before half of the shape. Needs to be calculated in opposite direction.
+ Geometry3D::get_closest_points_between_segments(Vector3(), axis * 4096 * -sign, p_segment[0], p_segment[1], ra, rb);
+ }
+
+ float d = ra[p_id / 2] * sign;
+
+ Vector3 he = r_box_size;
+ he[p_id / 2] = d * 2;
+ if (Node3DEditor::get_singleton()->is_snap_enabled()) {
+ he[p_id / 2] = Math::snapped(he[p_id / 2], Node3DEditor::get_singleton()->get_translate_snap());
+ }
+
+ if (Input::get_singleton()->is_key_pressed(Key::ALT)) {
+ he[p_id / 2] = MAX(he[p_id / 2], 0.001);
+ r_box_size = he;
+ r_box_position = initial_transform.get_origin();
+ } else {
+ he[p_id / 2] = MAX(he[p_id / 2], -initial_size[p_id / 2] + 0.002);
+ r_box_size = (initial_size + (he - initial_size) * 0.5).abs();
+ Vector3 pos = initial_transform.affine_inverse().xform(initial_transform.get_origin());
+ pos += (r_box_size - initial_size) * 0.5 * sign;
+ r_box_position = initial_transform.xform(pos);
+ }
+}
+
+void Gizmo3DHelper::box_commit_handle(const String &p_action_name, bool p_cancel, Object *p_position_object, Object *p_size_object, const StringName &p_position_property, const StringName &p_size_property) {
+ if (!p_size_object) {
+ p_size_object = p_position_object;
+ }
+
+ if (p_cancel) {
+ p_size_object->set(p_size_property, initial_value);
+ p_position_object->set(p_position_property, initial_transform.get_origin());
+ return;
+ }
+
+ EditorUndoRedoManager *ur = EditorUndoRedoManager::get_singleton();
+ ur->create_action(p_action_name);
+ ur->add_do_property(p_size_object, p_size_property, p_size_object->get(p_size_property));
+ ur->add_do_property(p_position_object, p_position_property, p_position_object->get(p_position_property));
+ ur->add_undo_property(p_size_object, p_size_property, initial_value);
+ ur->add_undo_property(p_position_object, p_position_property, initial_transform.get_origin());
+ ur->commit_action();
+}
diff --git a/editor/plugins/gizmos/gizmo_3d_helper.h b/editor/plugins/gizmos/gizmo_3d_helper.h
new file mode 100644
index 0000000000..387ea020b8
--- /dev/null
+++ b/editor/plugins/gizmos/gizmo_3d_helper.h
@@ -0,0 +1,55 @@
+/**************************************************************************/
+/* gizmo_3d_helper.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 GIZMO_3D_HELPER_H
+#define GIZMO_3D_HELPER_H
+
+#include "core/object/ref_counted.h"
+
+class Camera3D;
+
+class Gizmo3DHelper : public RefCounted {
+ GDCLASS(Gizmo3DHelper, RefCounted);
+
+ int current_handle_id;
+ Variant initial_value;
+ Transform3D initial_transform;
+
+public:
+ void initialize_handle_action(const Variant &p_initial_value, const Transform3D &p_initial_transform);
+ void get_segment(Camera3D *p_camera, const Point2 &p_point, Vector3 *r_segment);
+
+ Vector<Vector3> box_get_handles(const Vector3 &p_box_size);
+ String box_get_handle_name(int p_id) const;
+ void box_set_handle(const Vector3 p_segment[2], int p_id, Vector3 &r_box_size, Vector3 &r_box_position);
+ void box_commit_handle(const String &p_action_name, bool p_cancel, Object *p_position_object, Object *p_size_object = nullptr, const StringName &p_position_property = "global_position", const StringName &p_size_property = "size");
+};
+
+#endif // GIZMO_3D_HELPER_H
diff --git a/editor/plugins/gizmos/gpu_particles_3d_gizmo_plugin.cpp b/editor/plugins/gizmos/gpu_particles_3d_gizmo_plugin.cpp
index f17518482a..2b673207ab 100644
--- a/editor/plugins/gizmos/gpu_particles_3d_gizmo_plugin.cpp
+++ b/editor/plugins/gizmos/gpu_particles_3d_gizmo_plugin.cpp
@@ -30,7 +30,9 @@
#include "gpu_particles_3d_gizmo_plugin.h"
+#include "editor/editor_node.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "editor/editor_undo_redo_manager.h"
#include "editor/plugins/node_3d_editor_plugin.h"
#include "scene/3d/gpu_particles_3d.h"
@@ -40,7 +42,7 @@ GPUParticles3DGizmoPlugin::GPUParticles3DGizmoPlugin() {
create_material("particles_material", gizmo_color);
gizmo_color.a = MAX((gizmo_color.a - 0.2) * 0.02, 0.0);
create_material("particles_solid_material", gizmo_color);
- create_icon_material("particles_icon", Node3DEditor::get_singleton()->get_editor_theme_icon(SNAME("GizmoGPUParticles3D")));
+ create_icon_material("particles_icon", EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("GizmoGPUParticles3D"), EditorStringName(EditorIcons)));
create_handle_material("handles");
}
@@ -151,49 +153,50 @@ void GPUParticles3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo,
}
void GPUParticles3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
- GPUParticles3D *particles = Object::cast_to<GPUParticles3D>(p_gizmo->get_node_3d());
-
p_gizmo->clear();
- Vector<Vector3> lines;
- AABB aabb = particles->get_visibility_aabb();
+ if (p_gizmo->is_selected()) {
+ GPUParticles3D *particles = Object::cast_to<GPUParticles3D>(p_gizmo->get_node_3d());
- for (int i = 0; i < 12; i++) {
- Vector3 a, b;
- aabb.get_edge(i, a, b);
- lines.push_back(a);
- lines.push_back(b);
- }
+ Vector<Vector3> lines;
+ AABB aabb = particles->get_visibility_aabb();
- Vector<Vector3> handles;
+ for (int i = 0; i < 12; i++) {
+ Vector3 a, b;
+ aabb.get_edge(i, a, b);
+ lines.push_back(a);
+ lines.push_back(b);
+ }
- for (int i = 0; i < 3; i++) {
- Vector3 ax;
- ax[i] = aabb.position[i] + aabb.size[i];
- ax[(i + 1) % 3] = aabb.position[(i + 1) % 3] + aabb.size[(i + 1) % 3] * 0.5;
- ax[(i + 2) % 3] = aabb.position[(i + 2) % 3] + aabb.size[(i + 2) % 3] * 0.5;
- handles.push_back(ax);
- }
+ Vector<Vector3> handles;
- Vector3 center = aabb.get_center();
- for (int i = 0; i < 3; i++) {
- Vector3 ax;
- ax[i] = 1.0;
- handles.push_back(center + ax);
- lines.push_back(center);
- lines.push_back(center + ax);
- }
+ for (int i = 0; i < 3; i++) {
+ Vector3 ax;
+ ax[i] = aabb.position[i] + aabb.size[i];
+ ax[(i + 1) % 3] = aabb.position[(i + 1) % 3] + aabb.size[(i + 1) % 3] * 0.5;
+ ax[(i + 2) % 3] = aabb.position[(i + 2) % 3] + aabb.size[(i + 2) % 3] * 0.5;
+ handles.push_back(ax);
+ }
- Ref<Material> material = get_material("particles_material", p_gizmo);
- Ref<Material> icon = get_material("particles_icon", p_gizmo);
+ Vector3 center = aabb.get_center();
+ for (int i = 0; i < 3; i++) {
+ Vector3 ax;
+ ax[i] = 1.0;
+ handles.push_back(center + ax);
+ lines.push_back(center);
+ lines.push_back(center + ax);
+ }
- p_gizmo->add_lines(lines, material);
+ Ref<Material> material = get_material("particles_material", p_gizmo);
+
+ p_gizmo->add_lines(lines, material);
- if (p_gizmo->is_selected()) {
Ref<Material> solid_material = get_material("particles_solid_material", p_gizmo);
p_gizmo->add_solid_box(solid_material, aabb.get_size(), aabb.get_center());
+
+ p_gizmo->add_handles(handles, get_material("handles"));
}
- p_gizmo->add_handles(handles, get_material("handles"));
+ Ref<Material> icon = get_material("particles_icon", p_gizmo);
p_gizmo->add_unscaled_billboard(icon, 0.05);
}
diff --git a/editor/plugins/gizmos/gpu_particles_collision_3d_gizmo_plugin.cpp b/editor/plugins/gizmos/gpu_particles_collision_3d_gizmo_plugin.cpp
index 248e15c2c1..2cbfccc05e 100644
--- a/editor/plugins/gizmos/gpu_particles_collision_3d_gizmo_plugin.cpp
+++ b/editor/plugins/gizmos/gpu_particles_collision_3d_gizmo_plugin.cpp
@@ -32,10 +32,13 @@
#include "editor/editor_settings.h"
#include "editor/editor_undo_redo_manager.h"
+#include "editor/plugins/gizmos/gizmo_3d_helper.h"
#include "editor/plugins/node_3d_editor_plugin.h"
#include "scene/3d/gpu_particles_collision_3d.h"
GPUParticlesCollision3DGizmoPlugin::GPUParticlesCollision3DGizmoPlugin() {
+ helper.instantiate();
+
Color gizmo_color_attractor = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/particle_attractor", Color(1, 0.7, 0.5));
create_material("shape_material_attractor", gizmo_color_attractor);
gizmo_color_attractor.a = 0.15;
@@ -49,6 +52,9 @@ GPUParticlesCollision3DGizmoPlugin::GPUParticlesCollision3DGizmoPlugin() {
create_handle_material("handles");
}
+GPUParticlesCollision3DGizmoPlugin::~GPUParticlesCollision3DGizmoPlugin() {
+}
+
bool GPUParticlesCollision3DGizmoPlugin::has_gizmo(Node3D *p_spatial) {
return (Object::cast_to<GPUParticlesCollision3D>(p_spatial) != nullptr) || (Object::cast_to<GPUParticlesAttractor3D>(p_spatial) != nullptr);
}
@@ -69,7 +75,7 @@ String GPUParticlesCollision3DGizmoPlugin::get_handle_name(const EditorNode3DGiz
}
if (Object::cast_to<GPUParticlesCollisionBox3D>(cs) || Object::cast_to<GPUParticlesAttractorBox3D>(cs) || Object::cast_to<GPUParticlesAttractorVectorField3D>(cs) || Object::cast_to<GPUParticlesCollisionSDF3D>(cs) || Object::cast_to<GPUParticlesCollisionHeightField3D>(cs)) {
- return "Size";
+ return helper->box_get_handle_name(p_id);
}
return "";
@@ -89,16 +95,15 @@ Variant GPUParticlesCollision3DGizmoPlugin::get_handle_value(const EditorNode3DG
return Variant();
}
+void GPUParticlesCollision3DGizmoPlugin::begin_handle_action(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) {
+ helper->initialize_handle_action(get_handle_value(p_gizmo, p_id, p_secondary), p_gizmo->get_node_3d()->get_global_transform());
+}
+
void GPUParticlesCollision3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) {
Node3D *sn = p_gizmo->get_node_3d();
- Transform3D gt = sn->get_global_transform();
- Transform3D gi = gt.affine_inverse();
-
- Vector3 ray_from = p_camera->project_ray_origin(p_point);
- Vector3 ray_dir = p_camera->project_ray_normal(p_point);
-
- Vector3 sg[2] = { gi.xform(ray_from), gi.xform(ray_from + ray_dir * 4096) };
+ Vector3 sg[2];
+ helper->get_segment(p_camera, p_point, sg);
if (Object::cast_to<GPUParticlesCollisionSphere3D>(sn) || Object::cast_to<GPUParticlesAttractorSphere3D>(sn)) {
Vector3 ra, rb;
@@ -116,22 +121,11 @@ void GPUParticlesCollision3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_g
}
if (Object::cast_to<GPUParticlesCollisionBox3D>(sn) || Object::cast_to<GPUParticlesAttractorBox3D>(sn) || Object::cast_to<GPUParticlesAttractorVectorField3D>(sn) || Object::cast_to<GPUParticlesCollisionSDF3D>(sn) || Object::cast_to<GPUParticlesCollisionHeightField3D>(sn)) {
- Vector3 axis;
- axis[p_id] = 1.0;
- Vector3 ra, rb;
- Geometry3D::get_closest_points_between_segments(Vector3(), axis * 4096, sg[0], sg[1], ra, rb);
- float d = ra[p_id] * 2;
- if (Node3DEditor::get_singleton()->is_snap_enabled()) {
- d = Math::snapped(d, Node3DEditor::get_singleton()->get_translate_snap());
- }
-
- if (d < 0.001) {
- d = 0.001;
- }
-
- Vector3 he = sn->call("get_size");
- he[p_id] = d;
- sn->call("set_size", he);
+ Vector3 size = sn->call("get_size");
+ Vector3 position;
+ helper->box_set_handle(sg, p_id, size, position);
+ sn->call("set_size", size);
+ sn->set_global_position(position);
}
}
@@ -152,16 +146,7 @@ void GPUParticlesCollision3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *
}
if (Object::cast_to<GPUParticlesCollisionBox3D>(sn) || Object::cast_to<GPUParticlesAttractorBox3D>(sn) || Object::cast_to<GPUParticlesAttractorVectorField3D>(sn) || Object::cast_to<GPUParticlesCollisionSDF3D>(sn) || Object::cast_to<GPUParticlesCollisionHeightField3D>(sn)) {
- if (p_cancel) {
- sn->call("set_size", p_restore);
- return;
- }
-
- EditorUndoRedoManager *ur = EditorUndoRedoManager::get_singleton();
- ur->create_action(TTR("Change Box Shape Size"));
- ur->add_do_method(sn, "set_size", sn->call("get_size"));
- ur->add_undo_method(sn, "set_size", p_restore);
- ur->commit_action();
+ helper->box_commit_handle("Change Box Shape Size", p_cancel, sn);
}
}
@@ -237,13 +222,7 @@ void GPUParticlesCollision3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
lines.push_back(b);
}
- Vector<Vector3> handles;
-
- for (int i = 0; i < 3; i++) {
- Vector3 ax;
- ax[i] = cs->call("get_size").operator Vector3()[i] / 2;
- handles.push_back(ax);
- }
+ Vector<Vector3> handles = helper->box_get_handles(aabb.size);
p_gizmo->add_lines(lines, material);
p_gizmo->add_collision_segments(lines);
diff --git a/editor/plugins/gizmos/gpu_particles_collision_3d_gizmo_plugin.h b/editor/plugins/gizmos/gpu_particles_collision_3d_gizmo_plugin.h
index 6045f6e440..98572ff837 100644
--- a/editor/plugins/gizmos/gpu_particles_collision_3d_gizmo_plugin.h
+++ b/editor/plugins/gizmos/gpu_particles_collision_3d_gizmo_plugin.h
@@ -33,9 +33,13 @@
#include "editor/plugins/node_3d_editor_gizmos.h"
+class Gizmo3DHelper;
+
class GPUParticlesCollision3DGizmoPlugin : public EditorNode3DGizmoPlugin {
GDCLASS(GPUParticlesCollision3DGizmoPlugin, EditorNode3DGizmoPlugin);
+ Ref<Gizmo3DHelper> helper;
+
public:
bool has_gizmo(Node3D *p_spatial) override;
String get_gizmo_name() const override;
@@ -44,10 +48,12 @@ public:
String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const override;
Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const override;
+ void begin_handle_action(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) override;
void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) override;
void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel = false) override;
GPUParticlesCollision3DGizmoPlugin();
+ ~GPUParticlesCollision3DGizmoPlugin();
};
#endif // GPU_PARTICLES_COLLISION_3D_GIZMO_PLUGIN_H
diff --git a/editor/plugins/gizmos/light_3d_gizmo_plugin.cpp b/editor/plugins/gizmos/light_3d_gizmo_plugin.cpp
index 021cf4e8f1..967f8a65ce 100644
--- a/editor/plugins/gizmos/light_3d_gizmo_plugin.cpp
+++ b/editor/plugins/gizmos/light_3d_gizmo_plugin.cpp
@@ -33,6 +33,7 @@
#include "core/config/project_settings.h"
#include "editor/editor_node.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "editor/editor_undo_redo_manager.h"
#include "editor/plugins/node_3d_editor_plugin.h"
#include "scene/3d/light_3d.h"
@@ -43,9 +44,9 @@ Light3DGizmoPlugin::Light3DGizmoPlugin() {
create_material("lines_secondary", Color(1, 1, 1, 0.35), false, false, true);
create_material("lines_billboard", Color(1, 1, 1), true, false, true);
- create_icon_material("light_directional_icon", Node3DEditor::get_singleton()->get_editor_theme_icon(SNAME("GizmoDirectionalLight")));
- create_icon_material("light_omni_icon", Node3DEditor::get_singleton()->get_editor_theme_icon(SNAME("GizmoLight")));
- create_icon_material("light_spot_icon", Node3DEditor::get_singleton()->get_editor_theme_icon(SNAME("GizmoSpotLight")));
+ create_icon_material("light_directional_icon", EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("GizmoDirectionalLight"), EditorStringName(EditorIcons)));
+ create_icon_material("light_omni_icon", EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("GizmoLight"), EditorStringName(EditorIcons)));
+ create_icon_material("light_spot_icon", EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("GizmoSpotLight"), EditorStringName(EditorIcons)));
create_handle_material("handles");
create_handle_material("handles_billboard", true);
@@ -158,124 +159,133 @@ void Light3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
p_gizmo->clear();
if (Object::cast_to<DirectionalLight3D>(light)) {
- Ref<Material> material = get_material("lines_primary", p_gizmo);
- Ref<Material> icon = get_material("light_directional_icon", p_gizmo);
+ if (p_gizmo->is_selected()) {
+ Ref<Material> material = get_material("lines_primary", p_gizmo);
- const int arrow_points = 7;
- const float arrow_length = 1.5;
+ const int arrow_points = 7;
+ const float arrow_length = 1.5;
- Vector3 arrow[arrow_points] = {
- Vector3(0, 0, -1),
- Vector3(0, 0.8, 0),
- Vector3(0, 0.3, 0),
- Vector3(0, 0.3, arrow_length),
- Vector3(0, -0.3, arrow_length),
- Vector3(0, -0.3, 0),
- Vector3(0, -0.8, 0)
- };
+ Vector3 arrow[arrow_points] = {
+ Vector3(0, 0, -1),
+ Vector3(0, 0.8, 0),
+ Vector3(0, 0.3, 0),
+ Vector3(0, 0.3, arrow_length),
+ Vector3(0, -0.3, arrow_length),
+ Vector3(0, -0.3, 0),
+ Vector3(0, -0.8, 0)
+ };
- int arrow_sides = 2;
+ int arrow_sides = 2;
- Vector<Vector3> lines;
+ Vector<Vector3> lines;
- for (int i = 0; i < arrow_sides; i++) {
- for (int j = 0; j < arrow_points; j++) {
- Basis ma(Vector3(0, 0, 1), Math_PI * i / arrow_sides);
+ for (int i = 0; i < arrow_sides; i++) {
+ for (int j = 0; j < arrow_points; j++) {
+ Basis ma(Vector3(0, 0, 1), Math_PI * i / arrow_sides);
- Vector3 v1 = arrow[j] - Vector3(0, 0, arrow_length);
- Vector3 v2 = arrow[(j + 1) % arrow_points] - Vector3(0, 0, arrow_length);
+ Vector3 v1 = arrow[j] - Vector3(0, 0, arrow_length);
+ Vector3 v2 = arrow[(j + 1) % arrow_points] - Vector3(0, 0, arrow_length);
- lines.push_back(ma.xform(v1));
- lines.push_back(ma.xform(v2));
+ lines.push_back(ma.xform(v1));
+ lines.push_back(ma.xform(v2));
+ }
}
+
+ p_gizmo->add_lines(lines, material, false, color);
}
- p_gizmo->add_lines(lines, material, false, color);
+ Ref<Material> icon = get_material("light_directional_icon", p_gizmo);
p_gizmo->add_unscaled_billboard(icon, 0.05, color);
}
if (Object::cast_to<OmniLight3D>(light)) {
- // Use both a billboard circle and 3 non-billboard circles for a better sphere-like representation
- const Ref<Material> lines_material = get_material("lines_secondary", p_gizmo);
- const Ref<Material> lines_billboard_material = get_material("lines_billboard", p_gizmo);
- const Ref<Material> icon = get_material("light_omni_icon", p_gizmo);
+ if (p_gizmo->is_selected()) {
+ // Use both a billboard circle and 3 non-billboard circles for a better sphere-like representation
+ const Ref<Material> lines_material = get_material("lines_secondary", p_gizmo);
+ const Ref<Material> lines_billboard_material = get_material("lines_billboard", p_gizmo);
+
+ OmniLight3D *on = Object::cast_to<OmniLight3D>(light);
+ const float r = on->get_param(Light3D::PARAM_RANGE);
+ Vector<Vector3> points;
+ Vector<Vector3> points_billboard;
+
+ for (int i = 0; i < 120; i++) {
+ // Create a circle
+ const float ra = Math::deg_to_rad((float)(i * 3));
+ const float rb = Math::deg_to_rad((float)((i + 1) * 3));
+ const Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * r;
+ const Point2 b = Vector2(Math::sin(rb), Math::cos(rb)) * r;
+
+ // Draw axis-aligned circles
+ points.push_back(Vector3(a.x, 0, a.y));
+ points.push_back(Vector3(b.x, 0, b.y));
+ points.push_back(Vector3(0, a.x, a.y));
+ points.push_back(Vector3(0, b.x, b.y));
+ points.push_back(Vector3(a.x, a.y, 0));
+ points.push_back(Vector3(b.x, b.y, 0));
+
+ // Draw a billboarded circle
+ points_billboard.push_back(Vector3(a.x, a.y, 0));
+ points_billboard.push_back(Vector3(b.x, b.y, 0));
+ }
+
+ p_gizmo->add_lines(points, lines_material, true, color);
+ p_gizmo->add_lines(points_billboard, lines_billboard_material, true, color);
- OmniLight3D *on = Object::cast_to<OmniLight3D>(light);
- const float r = on->get_param(Light3D::PARAM_RANGE);
- Vector<Vector3> points;
- Vector<Vector3> points_billboard;
-
- for (int i = 0; i < 120; i++) {
- // Create a circle
- const float ra = Math::deg_to_rad((float)(i * 3));
- const float rb = Math::deg_to_rad((float)((i + 1) * 3));
- const Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * r;
- const Point2 b = Vector2(Math::sin(rb), Math::cos(rb)) * r;
-
- // Draw axis-aligned circles
- points.push_back(Vector3(a.x, 0, a.y));
- points.push_back(Vector3(b.x, 0, b.y));
- points.push_back(Vector3(0, a.x, a.y));
- points.push_back(Vector3(0, b.x, b.y));
- points.push_back(Vector3(a.x, a.y, 0));
- points.push_back(Vector3(b.x, b.y, 0));
-
- // Draw a billboarded circle
- points_billboard.push_back(Vector3(a.x, a.y, 0));
- points_billboard.push_back(Vector3(b.x, b.y, 0));
+ Vector<Vector3> handles;
+ handles.push_back(Vector3(r, 0, 0));
+ p_gizmo->add_handles(handles, get_material("handles_billboard"), Vector<int>(), true);
}
- p_gizmo->add_lines(points, lines_material, true, color);
- p_gizmo->add_lines(points_billboard, lines_billboard_material, true, color);
+ const Ref<Material> icon = get_material("light_omni_icon", p_gizmo);
p_gizmo->add_unscaled_billboard(icon, 0.05, color);
-
- Vector<Vector3> handles;
- handles.push_back(Vector3(r, 0, 0));
- p_gizmo->add_handles(handles, get_material("handles_billboard"), Vector<int>(), true);
}
if (Object::cast_to<SpotLight3D>(light)) {
- const Ref<Material> material_primary = get_material("lines_primary", p_gizmo);
- const Ref<Material> material_secondary = get_material("lines_secondary", p_gizmo);
- const Ref<Material> icon = get_material("light_spot_icon", p_gizmo);
-
- Vector<Vector3> points_primary;
- Vector<Vector3> points_secondary;
- SpotLight3D *sl = Object::cast_to<SpotLight3D>(light);
+ if (p_gizmo->is_selected()) {
+ const Ref<Material> material_primary = get_material("lines_primary", p_gizmo);
+ const Ref<Material> material_secondary = get_material("lines_secondary", p_gizmo);
+
+ Vector<Vector3> points_primary;
+ Vector<Vector3> points_secondary;
+ SpotLight3D *sl = Object::cast_to<SpotLight3D>(light);
+
+ float r = sl->get_param(Light3D::PARAM_RANGE);
+ float w = r * Math::sin(Math::deg_to_rad(sl->get_param(Light3D::PARAM_SPOT_ANGLE)));
+ float d = r * Math::cos(Math::deg_to_rad(sl->get_param(Light3D::PARAM_SPOT_ANGLE)));
+
+ for (int i = 0; i < 120; i++) {
+ // Draw a circle
+ const float ra = Math::deg_to_rad((float)(i * 3));
+ const float rb = Math::deg_to_rad((float)((i + 1) * 3));
+ const Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * w;
+ const Point2 b = Vector2(Math::sin(rb), Math::cos(rb)) * w;
+
+ points_primary.push_back(Vector3(a.x, a.y, -d));
+ points_primary.push_back(Vector3(b.x, b.y, -d));
+
+ if (i % 15 == 0) {
+ // Draw 8 lines from the cone origin to the sides of the circle
+ points_secondary.push_back(Vector3(a.x, a.y, -d));
+ points_secondary.push_back(Vector3());
+ }
+ }
- float r = sl->get_param(Light3D::PARAM_RANGE);
- float w = r * Math::sin(Math::deg_to_rad(sl->get_param(Light3D::PARAM_SPOT_ANGLE)));
- float d = r * Math::cos(Math::deg_to_rad(sl->get_param(Light3D::PARAM_SPOT_ANGLE)));
+ points_primary.push_back(Vector3(0, 0, -r));
+ points_primary.push_back(Vector3());
- for (int i = 0; i < 120; i++) {
- // Draw a circle
- const float ra = Math::deg_to_rad((float)(i * 3));
- const float rb = Math::deg_to_rad((float)((i + 1) * 3));
- const Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * w;
- const Point2 b = Vector2(Math::sin(rb), Math::cos(rb)) * w;
+ p_gizmo->add_lines(points_primary, material_primary, false, color);
+ p_gizmo->add_lines(points_secondary, material_secondary, false, color);
- points_primary.push_back(Vector3(a.x, a.y, -d));
- points_primary.push_back(Vector3(b.x, b.y, -d));
+ Vector<Vector3> handles = {
+ Vector3(0, 0, -r),
+ Vector3(w, 0, -d)
+ };
- if (i % 15 == 0) {
- // Draw 8 lines from the cone origin to the sides of the circle
- points_secondary.push_back(Vector3(a.x, a.y, -d));
- points_secondary.push_back(Vector3());
- }
+ p_gizmo->add_handles(handles, get_material("handles"));
}
- points_primary.push_back(Vector3(0, 0, -r));
- points_primary.push_back(Vector3());
-
- p_gizmo->add_lines(points_primary, material_primary, false, color);
- p_gizmo->add_lines(points_secondary, material_secondary, false, color);
-
- Vector<Vector3> handles = {
- Vector3(0, 0, -r),
- Vector3(w, 0, -d)
- };
-
- p_gizmo->add_handles(handles, get_material("handles"));
+ const Ref<Material> icon = get_material("light_spot_icon", p_gizmo);
p_gizmo->add_unscaled_billboard(icon, 0.05, color);
}
}
diff --git a/editor/plugins/gizmos/lightmap_gi_gizmo_plugin.cpp b/editor/plugins/gizmos/lightmap_gi_gizmo_plugin.cpp
index a1a25958c4..b860f5c0ee 100644
--- a/editor/plugins/gizmos/lightmap_gi_gizmo_plugin.cpp
+++ b/editor/plugins/gizmos/lightmap_gi_gizmo_plugin.cpp
@@ -30,7 +30,9 @@
#include "lightmap_gi_gizmo_plugin.h"
+#include "editor/editor_node.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "editor/plugins/node_3d_editor_plugin.h"
#include "scene/3d/lightmap_gi.h"
@@ -48,7 +50,7 @@ LightmapGIGizmoPlugin::LightmapGIGizmoPlugin() {
add_material("lightmap_probe_material", mat);
- create_icon_material("baked_indirect_light_icon", Node3DEditor::get_singleton()->get_editor_theme_icon(SNAME("GizmoLightmapGI")));
+ create_icon_material("baked_indirect_light_icon", EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("GizmoLightmapGI"), EditorStringName(EditorIcons)));
}
bool LightmapGIGizmoPlugin::has_gizmo(Node3D *p_spatial) {
@@ -68,17 +70,17 @@ void LightmapGIGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
LightmapGI *baker = Object::cast_to<LightmapGI>(p_gizmo->get_node_3d());
Ref<LightmapGIData> data = baker->get_light_data();
+ p_gizmo->clear();
+
p_gizmo->add_unscaled_billboard(icon, 0.05);
- if (data.is_null()) {
+ if (data.is_null() || !p_gizmo->is_selected()) {
return;
}
Ref<Material> material_lines = get_material("lightmap_lines", p_gizmo);
Ref<Material> material_probes = get_material("lightmap_probe_material", p_gizmo);
- p_gizmo->clear();
-
Vector<Vector3> lines;
HashSet<Vector2i> lines_found;
diff --git a/editor/plugins/gizmos/marker_3d_gizmo_plugin.cpp b/editor/plugins/gizmos/marker_3d_gizmo_plugin.cpp
index d86ede5e44..fa2c95d8db 100644
--- a/editor/plugins/gizmos/marker_3d_gizmo_plugin.cpp
+++ b/editor/plugins/gizmos/marker_3d_gizmo_plugin.cpp
@@ -61,7 +61,7 @@ Marker3DGizmoPlugin::Marker3DGizmoPlugin() {
// Use a darkened axis color for the negative axis.
// This makes it possible to see in which direction the Marker3D node is rotated
// (which can be important depending on how it's used).
- const Color color_x = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("axis_x_color"), EditorStringName(Editor));
+ const Color color_x = EditorNode::get_singleton()->get_editor_theme()->get_color(SNAME("axis_x_color"), EditorStringName(Editor));
cursor_colors.push_back(color_x);
cursor_colors.push_back(color_x);
// FIXME: Use less strong darkening factor once GH-48573 is fixed.
@@ -69,13 +69,13 @@ Marker3DGizmoPlugin::Marker3DGizmoPlugin() {
cursor_colors.push_back(color_x.lerp(Color(0, 0, 0), 0.75));
cursor_colors.push_back(color_x.lerp(Color(0, 0, 0), 0.75));
- const Color color_y = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("axis_y_color"), EditorStringName(Editor));
+ const Color color_y = EditorNode::get_singleton()->get_editor_theme()->get_color(SNAME("axis_y_color"), EditorStringName(Editor));
cursor_colors.push_back(color_y);
cursor_colors.push_back(color_y);
cursor_colors.push_back(color_y.lerp(Color(0, 0, 0), 0.75));
cursor_colors.push_back(color_y.lerp(Color(0, 0, 0), 0.75));
- const Color color_z = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("axis_z_color"), EditorStringName(Editor));
+ const Color color_z = EditorNode::get_singleton()->get_editor_theme()->get_color(SNAME("axis_z_color"), EditorStringName(Editor));
cursor_colors.push_back(color_z);
cursor_colors.push_back(color_z);
cursor_colors.push_back(color_z.lerp(Color(0, 0, 0), 0.75));
diff --git a/editor/plugins/gizmos/reflection_probe_gizmo_plugin.cpp b/editor/plugins/gizmos/reflection_probe_gizmo_plugin.cpp
index d9c2316ce0..d25311f1be 100644
--- a/editor/plugins/gizmos/reflection_probe_gizmo_plugin.cpp
+++ b/editor/plugins/gizmos/reflection_probe_gizmo_plugin.cpp
@@ -30,12 +30,16 @@
#include "reflection_probe_gizmo_plugin.h"
+#include "editor/editor_node.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "editor/editor_undo_redo_manager.h"
+#include "editor/plugins/gizmos/gizmo_3d_helper.h"
#include "editor/plugins/node_3d_editor_plugin.h"
#include "scene/3d/reflection_probe.h"
ReflectionProbeGizmoPlugin::ReflectionProbeGizmoPlugin() {
+ helper.instantiate();
Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/reflection_probe", Color(0.6, 1, 0.5));
create_material("reflection_probe_material", gizmo_color);
@@ -46,10 +50,13 @@ ReflectionProbeGizmoPlugin::ReflectionProbeGizmoPlugin() {
gizmo_color.a = 0.1;
create_material("reflection_probe_solid_material", gizmo_color);
- create_icon_material("reflection_probe_icon", Node3DEditor::get_singleton()->get_editor_theme_icon(SNAME("GizmoReflectionProbe")));
+ create_icon_material("reflection_probe_icon", EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("GizmoReflectionProbe"), EditorStringName(EditorIcons)));
create_handle_material("handles");
}
+ReflectionProbeGizmoPlugin::~ReflectionProbeGizmoPlugin() {
+}
+
bool ReflectionProbeGizmoPlugin::has_gizmo(Node3D *p_spatial) {
return Object::cast_to<ReflectionProbe>(p_spatial) != nullptr;
}
@@ -63,21 +70,17 @@ int ReflectionProbeGizmoPlugin::get_priority() const {
}
String ReflectionProbeGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const {
+ if (p_id < 6) {
+ return helper->box_get_handle_name(p_id);
+ }
switch (p_id) {
- case 0:
- return "Size X";
- case 1:
- return "Size Y";
- case 2:
- return "Size Z";
- case 3:
+ case 6:
return "Origin X";
- case 4:
+ case 7:
return "Origin Y";
- case 5:
+ case 8:
return "Origin Z";
}
-
return "";
}
@@ -86,47 +89,30 @@ Variant ReflectionProbeGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_
return AABB(probe->get_origin_offset(), probe->get_size());
}
+void ReflectionProbeGizmoPlugin::begin_handle_action(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) {
+ // The initial value is only used for resizing the box, so we only need AABB size.
+ AABB aabb = get_handle_value(p_gizmo, p_id, p_secondary);
+ helper->initialize_handle_action(aabb.size, p_gizmo->get_node_3d()->get_global_transform());
+}
+
void ReflectionProbeGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) {
ReflectionProbe *probe = Object::cast_to<ReflectionProbe>(p_gizmo->get_node_3d());
- Transform3D gt = probe->get_global_transform();
- Transform3D gi = gt.affine_inverse();
+ Vector3 sg[2];
+ helper->get_segment(p_camera, p_point, sg);
- if (p_id < 3) {
+ if (p_id < 6) {
Vector3 size = probe->get_size();
-
- Vector3 ray_from = p_camera->project_ray_origin(p_point);
- Vector3 ray_dir = p_camera->project_ray_normal(p_point);
-
- Vector3 sg[2] = { gi.xform(ray_from), gi.xform(ray_from + ray_dir * 16384) };
-
- Vector3 axis;
- axis[p_id] = 1.0;
-
- Vector3 ra, rb;
- Geometry3D::get_closest_points_between_segments(Vector3(), axis * 16384, sg[0], sg[1], ra, rb);
- float d = ra[p_id] * 2;
- if (Node3DEditor::get_singleton()->is_snap_enabled()) {
- d = Math::snapped(d, Node3DEditor::get_singleton()->get_translate_snap());
- }
-
- if (d < 0.001) {
- d = 0.001;
- }
-
- size[p_id] = d;
+ Vector3 position;
+ helper->box_set_handle(sg, p_id, size, position);
probe->set_size(size);
+ probe->set_global_position(position);
} else {
- p_id -= 3;
+ p_id -= 6;
Vector3 origin = probe->get_origin_offset();
origin[p_id] = 0;
- Vector3 ray_from = p_camera->project_ray_origin(p_point);
- Vector3 ray_dir = p_camera->project_ray_normal(p_point);
-
- Vector3 sg[2] = { gi.xform(ray_from), gi.xform(ray_from + ray_dir * 16384) };
-
Vector3 axis;
axis[p_id] = 1.0;
@@ -146,6 +132,11 @@ void ReflectionProbeGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, in
void ReflectionProbeGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel) {
ReflectionProbe *probe = Object::cast_to<ReflectionProbe>(p_gizmo->get_node_3d());
+ if (p_id < 6) {
+ helper->box_commit_handle(TTR("Change Probe Size"), p_cancel, probe);
+ return;
+ }
+
AABB restore = p_restore;
if (p_cancel) {
@@ -155,70 +146,64 @@ void ReflectionProbeGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo,
}
EditorUndoRedoManager *ur = EditorUndoRedoManager::get_singleton();
- ur->create_action(TTR("Change Probe Size"));
- ur->add_do_method(probe, "set_size", probe->get_size());
+ ur->create_action(TTR("Change Probe Origin Offset"));
ur->add_do_method(probe, "set_origin_offset", probe->get_origin_offset());
- ur->add_undo_method(probe, "set_size", restore.size);
ur->add_undo_method(probe, "set_origin_offset", restore.position);
ur->commit_action();
}
void ReflectionProbeGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
- ReflectionProbe *probe = Object::cast_to<ReflectionProbe>(p_gizmo->get_node_3d());
-
p_gizmo->clear();
- Vector<Vector3> lines;
- Vector<Vector3> internal_lines;
- Vector3 size = probe->get_size();
+ if (p_gizmo->is_selected()) {
+ ReflectionProbe *probe = Object::cast_to<ReflectionProbe>(p_gizmo->get_node_3d());
+ Vector<Vector3> lines;
+ Vector<Vector3> internal_lines;
+ Vector3 size = probe->get_size();
- AABB aabb;
- aabb.position = -size / 2;
- aabb.size = size;
+ AABB aabb;
+ aabb.position = -size / 2;
+ aabb.size = size;
- for (int i = 0; i < 12; i++) {
- Vector3 a, b;
- aabb.get_edge(i, a, b);
- lines.push_back(a);
- lines.push_back(b);
- }
+ for (int i = 0; i < 12; i++) {
+ Vector3 a, b;
+ aabb.get_edge(i, a, b);
+ lines.push_back(a);
+ lines.push_back(b);
+ }
- for (int i = 0; i < 8; i++) {
- Vector3 ep = aabb.get_endpoint(i);
- internal_lines.push_back(probe->get_origin_offset());
- internal_lines.push_back(ep);
- }
+ for (int i = 0; i < 8; i++) {
+ Vector3 ep = aabb.get_endpoint(i);
+ internal_lines.push_back(probe->get_origin_offset());
+ internal_lines.push_back(ep);
+ }
- Vector<Vector3> handles;
+ Vector<Vector3> handles = helper->box_get_handles(probe->get_size());
- for (int i = 0; i < 3; i++) {
- Vector3 ax;
- ax[i] = aabb.position[i] + aabb.size[i];
- handles.push_back(ax);
- }
+ for (int i = 0; i < 3; i++) {
+ Vector3 orig_handle = probe->get_origin_offset();
+ orig_handle[i] -= 0.25;
+ lines.push_back(orig_handle);
+ handles.push_back(orig_handle);
- for (int i = 0; i < 3; i++) {
- Vector3 orig_handle = probe->get_origin_offset();
- orig_handle[i] -= 0.25;
- lines.push_back(orig_handle);
- handles.push_back(orig_handle);
+ orig_handle[i] += 0.5;
+ lines.push_back(orig_handle);
+ }
- orig_handle[i] += 0.5;
- lines.push_back(orig_handle);
- }
+ Ref<Material> material = get_material("reflection_probe_material", p_gizmo);
+ Ref<Material> material_internal = get_material("reflection_internal_material", p_gizmo);
- Ref<Material> material = get_material("reflection_probe_material", p_gizmo);
- Ref<Material> material_internal = get_material("reflection_internal_material", p_gizmo);
- Ref<Material> icon = get_material("reflection_probe_icon", p_gizmo);
+ p_gizmo->add_lines(lines, material);
+ p_gizmo->add_lines(internal_lines, material_internal);
- p_gizmo->add_lines(lines, material);
- p_gizmo->add_lines(internal_lines, material_internal);
+ if (p_gizmo->is_selected()) {
+ Ref<Material> solid_material = get_material("reflection_probe_solid_material", p_gizmo);
+ p_gizmo->add_solid_box(solid_material, probe->get_size());
+ }
- if (p_gizmo->is_selected()) {
- Ref<Material> solid_material = get_material("reflection_probe_solid_material", p_gizmo);
- p_gizmo->add_solid_box(solid_material, probe->get_size());
+ p_gizmo->add_handles(handles, get_material("handles"));
}
+ Ref<Material> icon = get_material("reflection_probe_icon", p_gizmo);
p_gizmo->add_unscaled_billboard(icon, 0.05);
- p_gizmo->add_handles(handles, get_material("handles"));
}
diff --git a/editor/plugins/gizmos/reflection_probe_gizmo_plugin.h b/editor/plugins/gizmos/reflection_probe_gizmo_plugin.h
index bc9840b27c..b980f5a944 100644
--- a/editor/plugins/gizmos/reflection_probe_gizmo_plugin.h
+++ b/editor/plugins/gizmos/reflection_probe_gizmo_plugin.h
@@ -33,9 +33,13 @@
#include "editor/plugins/node_3d_editor_gizmos.h"
+class Gizmo3DHelper;
+
class ReflectionProbeGizmoPlugin : public EditorNode3DGizmoPlugin {
GDCLASS(ReflectionProbeGizmoPlugin, EditorNode3DGizmoPlugin);
+ Ref<Gizmo3DHelper> helper;
+
public:
bool has_gizmo(Node3D *p_spatial) override;
String get_gizmo_name() const override;
@@ -44,10 +48,12 @@ public:
String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const override;
Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const override;
+ void begin_handle_action(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) override;
void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) override;
void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel = false) override;
ReflectionProbeGizmoPlugin();
+ ~ReflectionProbeGizmoPlugin();
};
#endif // REFLECTION_PROBE_GIZMO_PLUGIN_H
diff --git a/editor/plugins/gizmos/voxel_gi_gizmo_plugin.cpp b/editor/plugins/gizmos/voxel_gi_gizmo_plugin.cpp
index 08dbe76d87..b916e99ab6 100644
--- a/editor/plugins/gizmos/voxel_gi_gizmo_plugin.cpp
+++ b/editor/plugins/gizmos/voxel_gi_gizmo_plugin.cpp
@@ -30,12 +30,17 @@
#include "voxel_gi_gizmo_plugin.h"
+#include "editor/editor_node.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "editor/editor_undo_redo_manager.h"
+#include "editor/plugins/gizmos/gizmo_3d_helper.h"
#include "editor/plugins/node_3d_editor_plugin.h"
#include "scene/3d/voxel_gi.h"
VoxelGIGizmoPlugin::VoxelGIGizmoPlugin() {
+ helper.instantiate();
+
Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/voxel_gi", Color(0.5, 1, 0.6));
create_material("voxel_gi_material", gizmo_color);
@@ -47,10 +52,13 @@ VoxelGIGizmoPlugin::VoxelGIGizmoPlugin() {
gizmo_color.a = 0.05;
create_material("voxel_gi_solid_material", gizmo_color);
- create_icon_material("voxel_gi_icon", Node3DEditor::get_singleton()->get_editor_theme_icon(SNAME("GizmoVoxelGI")));
+ create_icon_material("voxel_gi_icon", EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("GizmoVoxelGI"), EditorStringName(EditorIcons)));
create_handle_material("handles");
}
+VoxelGIGizmoPlugin::~VoxelGIGizmoPlugin() {
+}
+
bool VoxelGIGizmoPlugin::has_gizmo(Node3D *p_spatial) {
return Object::cast_to<VoxelGI>(p_spatial) != nullptr;
}
@@ -64,16 +72,7 @@ int VoxelGIGizmoPlugin::get_priority() const {
}
String VoxelGIGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const {
- switch (p_id) {
- case 0:
- return "Size X";
- case 1:
- return "Size Y";
- case 2:
- return "Size Z";
- }
-
- return "";
+ return helper->box_get_handle_name(p_id);
}
Variant VoxelGIGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const {
@@ -81,129 +80,98 @@ Variant VoxelGIGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, i
return probe->get_size();
}
+void VoxelGIGizmoPlugin::begin_handle_action(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) {
+ helper->initialize_handle_action(get_handle_value(p_gizmo, p_id, p_secondary), p_gizmo->get_node_3d()->get_global_transform());
+}
+
void VoxelGIGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) {
VoxelGI *probe = Object::cast_to<VoxelGI>(p_gizmo->get_node_3d());
- Transform3D gt = probe->get_global_transform();
- Transform3D gi = gt.affine_inverse();
+ Vector3 sg[2];
+ helper->get_segment(p_camera, p_point, sg);
Vector3 size = probe->get_size();
-
- Vector3 ray_from = p_camera->project_ray_origin(p_point);
- Vector3 ray_dir = p_camera->project_ray_normal(p_point);
-
- Vector3 sg[2] = { gi.xform(ray_from), gi.xform(ray_from + ray_dir * 16384) };
-
- Vector3 axis;
- axis[p_id] = 1.0;
-
- Vector3 ra, rb;
- Geometry3D::get_closest_points_between_segments(Vector3(), axis * 16384, sg[0], sg[1], ra, rb);
- float d = ra[p_id] * 2;
- if (Node3DEditor::get_singleton()->is_snap_enabled()) {
- d = Math::snapped(d, Node3DEditor::get_singleton()->get_translate_snap());
- }
-
- if (d < 0.001) {
- d = 0.001;
- }
-
- size[p_id] = d;
+ Vector3 position;
+ helper->box_set_handle(sg, p_id, size, position);
probe->set_size(size);
+ probe->set_global_position(position);
}
void VoxelGIGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel) {
- VoxelGI *probe = Object::cast_to<VoxelGI>(p_gizmo->get_node_3d());
-
- Vector3 restore = p_restore;
-
- if (p_cancel) {
- probe->set_size(restore);
- return;
- }
-
- EditorUndoRedoManager *ur = EditorUndoRedoManager::get_singleton();
- ur->create_action(TTR("Change Probe Size"));
- ur->add_do_method(probe, "set_size", probe->get_size());
- ur->add_undo_method(probe, "set_size", restore);
- ur->commit_action();
+ helper->box_commit_handle(TTR("Change Probe Size"), p_cancel, p_gizmo->get_node_3d());
}
void VoxelGIGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
- VoxelGI *probe = Object::cast_to<VoxelGI>(p_gizmo->get_node_3d());
+ p_gizmo->clear();
- Ref<Material> material = get_material("voxel_gi_material", p_gizmo);
- Ref<Material> icon = get_material("voxel_gi_icon", p_gizmo);
- Ref<Material> material_internal = get_material("voxel_gi_internal_material", p_gizmo);
+ if (p_gizmo->is_selected()) {
+ VoxelGI *probe = Object::cast_to<VoxelGI>(p_gizmo->get_node_3d());
+ Ref<Material> material = get_material("voxel_gi_material", p_gizmo);
+ Ref<Material> material_internal = get_material("voxel_gi_internal_material", p_gizmo);
- p_gizmo->clear();
+ Vector<Vector3> lines;
+ Vector3 size = probe->get_size();
- Vector<Vector3> lines;
- Vector3 size = probe->get_size();
+ static const int subdivs[VoxelGI::SUBDIV_MAX] = { 64, 128, 256, 512 };
- static const int subdivs[VoxelGI::SUBDIV_MAX] = { 64, 128, 256, 512 };
+ AABB aabb = AABB(-size / 2, size);
+ int subdiv = subdivs[probe->get_subdiv()];
+ float cell_size = aabb.get_longest_axis_size() / subdiv;
- AABB aabb = AABB(-size / 2, size);
- int subdiv = subdivs[probe->get_subdiv()];
- float cell_size = aabb.get_longest_axis_size() / subdiv;
+ for (int i = 0; i < 12; i++) {
+ Vector3 a, b;
+ aabb.get_edge(i, a, b);
+ lines.push_back(a);
+ lines.push_back(b);
+ }
- for (int i = 0; i < 12; i++) {
- Vector3 a, b;
- aabb.get_edge(i, a, b);
- lines.push_back(a);
- lines.push_back(b);
- }
+ p_gizmo->add_lines(lines, material);
- p_gizmo->add_lines(lines, material);
+ lines.clear();
- lines.clear();
+ for (int i = 1; i < subdiv; i++) {
+ for (int j = 0; j < 3; j++) {
+ if (cell_size * i > aabb.size[j]) {
+ continue;
+ }
- for (int i = 1; i < subdiv; i++) {
- for (int j = 0; j < 3; j++) {
- if (cell_size * i > aabb.size[j]) {
- continue;
- }
+ int j_n1 = (j + 1) % 3;
+ int j_n2 = (j + 2) % 3;
- int j_n1 = (j + 1) % 3;
- int j_n2 = (j + 2) % 3;
+ for (int k = 0; k < 4; k++) {
+ Vector3 from = aabb.position, to = aabb.position;
+ from[j] += cell_size * i;
+ to[j] += cell_size * i;
- for (int k = 0; k < 4; k++) {
- Vector3 from = aabb.position, to = aabb.position;
- from[j] += cell_size * i;
- to[j] += cell_size * i;
+ if (k & 1) {
+ to[j_n1] += aabb.size[j_n1];
+ } else {
+ to[j_n2] += aabb.size[j_n2];
+ }
- if (k & 1) {
- to[j_n1] += aabb.size[j_n1];
- } else {
- to[j_n2] += aabb.size[j_n2];
- }
+ if (k & 2) {
+ from[j_n1] += aabb.size[j_n1];
+ from[j_n2] += aabb.size[j_n2];
+ }
- if (k & 2) {
- from[j_n1] += aabb.size[j_n1];
- from[j_n2] += aabb.size[j_n2];
+ lines.push_back(from);
+ lines.push_back(to);
}
-
- lines.push_back(from);
- lines.push_back(to);
}
}
- }
- p_gizmo->add_lines(lines, material_internal);
+ p_gizmo->add_lines(lines, material_internal);
- Vector<Vector3> handles;
+ Vector<Vector3> handles = helper->box_get_handles(probe->get_size());
- for (int i = 0; i < 3; i++) {
- Vector3 ax;
- ax[i] = aabb.position[i] + aabb.size[i];
- handles.push_back(ax);
- }
+ if (p_gizmo->is_selected()) {
+ Ref<Material> solid_material = get_material("voxel_gi_solid_material", p_gizmo);
+ p_gizmo->add_solid_box(solid_material, aabb.get_size());
+ }
- if (p_gizmo->is_selected()) {
- Ref<Material> solid_material = get_material("voxel_gi_solid_material", p_gizmo);
- p_gizmo->add_solid_box(solid_material, aabb.get_size());
+ p_gizmo->add_handles(handles, get_material("handles"));
}
+ Ref<Material> icon = get_material("voxel_gi_icon", p_gizmo);
p_gizmo->add_unscaled_billboard(icon, 0.05);
- p_gizmo->add_handles(handles, get_material("handles"));
}
diff --git a/editor/plugins/gizmos/voxel_gi_gizmo_plugin.h b/editor/plugins/gizmos/voxel_gi_gizmo_plugin.h
index 4d1f282bd6..a5447c8b5c 100644
--- a/editor/plugins/gizmos/voxel_gi_gizmo_plugin.h
+++ b/editor/plugins/gizmos/voxel_gi_gizmo_plugin.h
@@ -33,9 +33,13 @@
#include "editor/plugins/node_3d_editor_gizmos.h"
+class Gizmo3DHelper;
+
class VoxelGIGizmoPlugin : public EditorNode3DGizmoPlugin {
GDCLASS(VoxelGIGizmoPlugin, EditorNode3DGizmoPlugin);
+ Ref<Gizmo3DHelper> helper;
+
public:
bool has_gizmo(Node3D *p_spatial) override;
String get_gizmo_name() const override;
@@ -44,10 +48,12 @@ public:
String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const override;
Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const override;
+ void begin_handle_action(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) override;
void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) override;
void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel = false) override;
VoxelGIGizmoPlugin();
+ ~VoxelGIGizmoPlugin();
};
#endif // VOXEL_GI_GIZMO_PLUGIN_H
diff --git a/editor/plugins/gpu_particles_2d_editor_plugin.cpp b/editor/plugins/gpu_particles_2d_editor_plugin.cpp
index a6ae6c1256..af04d45ba8 100644
--- a/editor/plugins/gpu_particles_2d_editor_plugin.cpp
+++ b/editor/plugins/gpu_particles_2d_editor_plugin.cpp
@@ -369,8 +369,6 @@ GPUParticles2DEditorPlugin::GPUParticles2DEditorPlugin() {
add_control_to_container(CONTAINER_CANVAS_EDITOR_MENU, toolbar);
toolbar->hide();
- toolbar->add_child(memnew(VSeparator));
-
menu = memnew(MenuButton);
menu->get_popup()->add_item(TTR("Restart"), MENU_RESTART);
menu->get_popup()->add_item(TTR("Generate Visibility Rect"), MENU_GENERATE_VISIBILITY_RECT);
diff --git a/editor/plugins/gpu_particles_collision_sdf_editor_plugin.cpp b/editor/plugins/gpu_particles_collision_sdf_editor_plugin.cpp
index af861b04b5..e86ce440ee 100644
--- a/editor/plugins/gpu_particles_collision_sdf_editor_plugin.cpp
+++ b/editor/plugins/gpu_particles_collision_sdf_editor_plugin.cpp
@@ -32,6 +32,7 @@
#include "editor/editor_interface.h"
#include "editor/editor_node.h"
+#include "editor/editor_string_names.h"
#include "editor/gui/editor_file_dialog.h"
void GPUParticlesCollisionSDF3DEditorPlugin::_bake() {
@@ -183,7 +184,7 @@ GPUParticlesCollisionSDF3DEditorPlugin::GPUParticlesCollisionSDF3DEditorPlugin()
bake_hb->hide();
bake = memnew(Button);
bake->set_flat(true);
- bake->set_icon(EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("Bake")));
+ bake->set_icon(EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("Bake"), EditorStringName(EditorIcons)));
bake->set_text(TTR("Bake SDF"));
bake->connect("pressed", callable_mp(this, &GPUParticlesCollisionSDF3DEditorPlugin::_bake));
bake_hb->add_child(bake);
diff --git a/editor/plugins/lightmap_gi_editor_plugin.cpp b/editor/plugins/lightmap_gi_editor_plugin.cpp
index efd11cfab9..c09dbeb1cc 100644
--- a/editor/plugins/lightmap_gi_editor_plugin.cpp
+++ b/editor/plugins/lightmap_gi_editor_plugin.cpp
@@ -31,6 +31,7 @@
#include "lightmap_gi_editor_plugin.h"
#include "editor/editor_node.h"
+#include "editor/editor_string_names.h"
#include "editor/gui/editor_file_dialog.h"
void LightmapGIEditorPlugin::_bake_select_file(const String &p_file) {
@@ -168,7 +169,9 @@ void LightmapGIEditorPlugin::_bind_methods() {
LightmapGIEditorPlugin::LightmapGIEditorPlugin() {
bake = memnew(Button);
bake->set_flat(true);
- bake->set_icon(EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("Bake")));
+ // TODO: Rework this as a dedicated toolbar control so we can hook into theme changes and update it
+ // when the editor theme updates.
+ bake->set_icon(EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("Bake"), EditorStringName(EditorIcons)));
bake->set_text(TTR("Bake Lightmaps"));
bake->hide();
bake->connect("pressed", Callable(this, "_bake"));
diff --git a/editor/plugins/mesh_instance_3d_editor_plugin.cpp b/editor/plugins/mesh_instance_3d_editor_plugin.cpp
index c299ba97d5..8d112446a3 100644
--- a/editor/plugins/mesh_instance_3d_editor_plugin.cpp
+++ b/editor/plugins/mesh_instance_3d_editor_plugin.cpp
@@ -513,17 +513,20 @@ void MeshInstance3DEditor::_create_outline_mesh() {
ur->commit_action();
}
-void MeshInstance3DEditor::_bind_methods() {
+void MeshInstance3DEditor::_notification(int p_what) {
+ switch (p_what) {
+ case NOTIFICATION_THEME_CHANGED: {
+ options->set_icon(get_editor_theme_icon(SNAME("MeshInstance3D")));
+ } break;
+ }
}
MeshInstance3DEditor::MeshInstance3DEditor() {
options = memnew(MenuButton);
+ options->set_text(TTR("Mesh"));
options->set_switch_on_hover(true);
Node3DEditor::get_singleton()->add_control_to_menu_panel(options);
- options->set_text(TTR("Mesh"));
- options->set_icon(EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("MeshInstance3D")));
-
options->get_popup()->add_item(TTR("Create Trimesh Static Body"), MENU_OPTION_CREATE_STATIC_TRIMESH_BODY);
options->get_popup()->set_item_tooltip(-1, TTR("Creates a StaticBody3D and assigns a polygon-based collision shape to it automatically.\nThis is the most accurate (but slowest) option for collision detection."));
options->get_popup()->add_separator();
diff --git a/editor/plugins/mesh_instance_3d_editor_plugin.h b/editor/plugins/mesh_instance_3d_editor_plugin.h
index ea67d1aae9..eb984e240e 100644
--- a/editor/plugins/mesh_instance_3d_editor_plugin.h
+++ b/editor/plugins/mesh_instance_3d_editor_plugin.h
@@ -79,7 +79,8 @@ class MeshInstance3DEditor : public Control {
protected:
void _node_removed(Node *p_node);
- static void _bind_methods();
+
+ void _notification(int p_what);
public:
void edit(MeshInstance3D *p_mesh);
diff --git a/editor/plugins/mesh_library_editor_plugin.cpp b/editor/plugins/mesh_library_editor_plugin.cpp
index 750a71905b..79331098fb 100644
--- a/editor/plugins/mesh_library_editor_plugin.cpp
+++ b/editor/plugins/mesh_library_editor_plugin.cpp
@@ -33,6 +33,7 @@
#include "editor/editor_interface.h"
#include "editor/editor_node.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "editor/gui/editor_file_dialog.h"
#include "editor/inspector_dock.h"
#include "editor/plugins/node_3d_editor_plugin.h"
@@ -275,7 +276,7 @@ MeshLibraryEditor::MeshLibraryEditor() {
Node3DEditor::get_singleton()->add_control_to_menu_panel(menu);
menu->set_position(Point2(1, 1));
menu->set_text(TTR("MeshLibrary"));
- menu->set_icon(EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("MeshLibrary")));
+ menu->set_icon(EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("MeshLibrary"), EditorStringName(EditorIcons)));
menu->get_popup()->add_item(TTR("Add Item"), MENU_OPTION_ADD_ITEM);
menu->get_popup()->add_item(TTR("Remove Selected Item"), MENU_OPTION_REMOVE_ITEM);
menu->get_popup()->add_separator();
diff --git a/editor/plugins/multimesh_editor_plugin.cpp b/editor/plugins/multimesh_editor_plugin.cpp
index a980b30bfe..da1abc2af1 100644
--- a/editor/plugins/multimesh_editor_plugin.cpp
+++ b/editor/plugins/multimesh_editor_plugin.cpp
@@ -31,6 +31,7 @@
#include "multimesh_editor_plugin.h"
#include "editor/editor_node.h"
+#include "editor/editor_string_names.h"
#include "editor/gui/scene_tree_editor.h"
#include "editor/plugins/node_3d_editor_plugin.h"
#include "scene/3d/mesh_instance_3d.h"
@@ -272,7 +273,7 @@ MultiMeshEditor::MultiMeshEditor() {
Node3DEditor::get_singleton()->add_control_to_menu_panel(options);
options->set_text("MultiMesh");
- options->set_icon(EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("MultiMeshInstance3D")));
+ options->set_icon(EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("MultiMeshInstance3D"), EditorStringName(EditorIcons)));
options->get_popup()->add_item(TTR("Populate Surface"));
options->get_popup()->connect("id_pressed", callable_mp(this, &MultiMeshEditor::_menu_option));
diff --git a/editor/plugins/navigation_obstacle_3d_editor_plugin.cpp b/editor/plugins/navigation_obstacle_3d_editor_plugin.cpp
index 4892538a0a..4f90061797 100644
--- a/editor/plugins/navigation_obstacle_3d_editor_plugin.cpp
+++ b/editor/plugins/navigation_obstacle_3d_editor_plugin.cpp
@@ -38,6 +38,7 @@
#include "core/os/keyboard.h"
#include "editor/editor_node.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "editor/editor_undo_redo_manager.h"
#include "node_3d_editor_plugin.h"
#include "scene/3d/camera_3d.h"
@@ -521,7 +522,6 @@ void NavigationObstacle3DEditor::_bind_methods() {
NavigationObstacle3DEditor::NavigationObstacle3DEditor() {
obstacle_node = nullptr;
- add_child(memnew(VSeparator));
button_create = memnew(Button);
button_create->set_flat(true);
add_child(button_create);
@@ -554,7 +554,7 @@ NavigationObstacle3DEditor::NavigationObstacle3DEditor() {
handle_material->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA);
handle_material->set_flag(StandardMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
handle_material->set_flag(StandardMaterial3D::FLAG_SRGB_VERTEX_COLOR, true);
- Ref<Texture2D> handle = EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("Editor3DHandle"));
+ Ref<Texture2D> handle = EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("Editor3DHandle"), EditorStringName(EditorIcons));
handle_material->set_point_size(handle->get_width());
handle_material->set_texture(StandardMaterial3D::TEXTURE_ALBEDO, handle);
diff --git a/editor/plugins/node_3d_editor_gizmos.cpp b/editor/plugins/node_3d_editor_gizmos.cpp
index f6e93e292f..d28a93d9e5 100644
--- a/editor/plugins/node_3d_editor_gizmos.cpp
+++ b/editor/plugins/node_3d_editor_gizmos.cpp
@@ -34,6 +34,7 @@
#include "core/math/geometry_3d.h"
#include "editor/editor_node.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "editor/plugins/node_3d_editor_plugin.h"
#include "scene/resources/primitive_meshes.h"
@@ -940,7 +941,7 @@ void EditorNode3DGizmoPlugin::create_handle_material(const String &p_name, bool
handle_material->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED);
handle_material->set_flag(StandardMaterial3D::FLAG_USE_POINT_SIZE, true);
- Ref<Texture2D> handle_t = p_icon != nullptr ? p_icon : Node3DEditor::get_singleton()->get_editor_theme_icon(SNAME("Editor3DHandle"));
+ Ref<Texture2D> handle_t = p_icon != nullptr ? p_icon : EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("Editor3DHandle"), EditorStringName(EditorIcons));
handle_material->set_point_size(handle_t->get_width());
handle_material->set_texture(StandardMaterial3D::TEXTURE_ALBEDO, handle_t);
handle_material->set_albedo(Color(1, 1, 1));
diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp
index ca13a061bb..b2229442e3 100644
--- a/editor/plugins/node_3d_editor_plugin.cpp
+++ b/editor/plugins/node_3d_editor_plugin.cpp
@@ -7581,7 +7581,7 @@ void Node3DEditor::_update_theme() {
environ_sky_color->set_custom_minimum_size(Size2(0, get_theme_constant(SNAME("color_picker_button_height"), EditorStringName(Editor))));
environ_ground_color->set_custom_minimum_size(Size2(0, get_theme_constant(SNAME("color_picker_button_height"), EditorStringName(Editor))));
- context_menu_panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("ContextualToolbar"), EditorStringName(EditorStyles)));
+ context_toolbar_panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("ContextualToolbar"), EditorStringName(EditorStyles)));
}
void Node3DEditor::_notification(int p_what) {
@@ -7679,11 +7679,51 @@ Vector<int> Node3DEditor::get_subgizmo_selection() {
}
void Node3DEditor::add_control_to_menu_panel(Control *p_control) {
- context_menu_hbox->add_child(p_control);
+ ERR_FAIL_NULL(p_control);
+ ERR_FAIL_COND(p_control->get_parent());
+
+ VSeparator *sep = memnew(VSeparator);
+ context_toolbar_hbox->add_child(sep);
+ context_toolbar_hbox->add_child(p_control);
+ context_toolbar_separators[p_control] = sep;
+
+ p_control->connect("visibility_changed", callable_mp(this, &Node3DEditor::_update_context_toolbar));
+
+ _update_context_toolbar();
}
void Node3DEditor::remove_control_from_menu_panel(Control *p_control) {
- context_menu_hbox->remove_child(p_control);
+ ERR_FAIL_NULL(p_control);
+ ERR_FAIL_COND(p_control->get_parent() != context_toolbar_hbox);
+
+ p_control->disconnect("visibility_changed", callable_mp(this, &Node3DEditor::_update_context_toolbar));
+
+ context_toolbar_hbox->remove_child(context_toolbar_separators[p_control]);
+ context_toolbar_hbox->remove_child(p_control);
+ context_toolbar_separators.erase(p_control);
+
+ _update_context_toolbar();
+}
+
+void Node3DEditor::_update_context_toolbar() {
+ bool has_visible = false;
+ bool first_visible = false;
+
+ for (int i = 0; i < context_toolbar_hbox->get_child_count(); i++) {
+ Control *child = Object::cast_to<Control>(context_toolbar_hbox->get_child(i));
+ if (!child || !context_toolbar_separators.has(child)) {
+ continue;
+ }
+ if (child->is_visible()) {
+ first_visible = !has_visible;
+ has_visible = true;
+ }
+
+ VSeparator *sep = context_toolbar_separators[child];
+ sep->set_visible(!first_visible && child->is_visible());
+ }
+
+ context_toolbar_panel->set_visible(has_visible);
}
void Node3DEditor::set_can_preview(Camera3D *p_preview) {
@@ -8161,9 +8201,17 @@ Node3DEditor::Node3DEditor() {
camera_override_viewport_id = 0;
+ // Add some margin to the sides for better aesthetics.
+ // This prevents the first button's hover/pressed effect from "touching" the panel's border,
+ // which looks ugly.
+ MarginContainer *toolbar_margin = memnew(MarginContainer);
+ toolbar_margin->add_theme_constant_override("margin_left", 4 * EDSCALE);
+ toolbar_margin->add_theme_constant_override("margin_right", 4 * EDSCALE);
+ vbc->add_child(toolbar_margin);
+
// A fluid container for all toolbars.
HFlowContainer *main_flow = memnew(HFlowContainer);
- vbc->add_child(main_flow);
+ toolbar_margin->add_child(main_flow);
// Main toolbars.
HBoxContainer *main_menu_hbox = memnew(HBoxContainer);
@@ -8171,13 +8219,6 @@ Node3DEditor::Node3DEditor() {
String sct;
- // Add some margin to the left for better esthetics.
- // This prevents the first button's hover/pressed effect from "touching" the panel's border,
- // which looks ugly.
- Control *margin_left = memnew(Control);
- main_menu_hbox->add_child(margin_left);
- margin_left->set_custom_minimum_size(Size2(2, 0) * EDSCALE);
-
tool_button[TOOL_MODE_SELECT] = memnew(Button);
main_menu_hbox->add_child(tool_button[TOOL_MODE_SELECT]);
tool_button[TOOL_MODE_SELECT]->set_toggle_mode(true);
@@ -8365,10 +8406,10 @@ Node3DEditor::Node3DEditor() {
main_menu_hbox->add_child(memnew(VSeparator));
- context_menu_panel = memnew(PanelContainer);
- context_menu_hbox = memnew(HBoxContainer);
- context_menu_panel->add_child(context_menu_hbox);
- main_flow->add_child(context_menu_panel);
+ context_toolbar_panel = memnew(PanelContainer);
+ context_toolbar_hbox = memnew(HBoxContainer);
+ context_toolbar_panel->add_child(context_toolbar_hbox);
+ main_flow->add_child(context_toolbar_panel);
// Get the view menu popup and have it stay open when a checkable item is selected
p = view_menu->get_popup();
diff --git a/editor/plugins/node_3d_editor_plugin.h b/editor/plugins/node_3d_editor_plugin.h
index e58e224ff4..2fb7804a67 100644
--- a/editor/plugins/node_3d_editor_plugin.h
+++ b/editor/plugins/node_3d_editor_plugin.h
@@ -56,9 +56,10 @@ class PanelContainer;
class ProceduralSkyMaterial;
class SubViewport;
class SubViewportContainer;
+class VSeparator;
class VSplitContainer;
-class WorldEnvironment;
class ViewportNavigationControl;
+class WorldEnvironment;
class ViewportRotationControl : public Control {
GDCLASS(ViewportRotationControl, Control);
@@ -715,8 +716,11 @@ private:
void _update_camera_override_viewport(Object *p_viewport);
// Used for secondary menu items which are displayed depending on the currently selected node
// (such as MeshInstance's "Mesh" menu).
- PanelContainer *context_menu_panel = nullptr;
- HBoxContainer *context_menu_hbox = nullptr;
+ PanelContainer *context_toolbar_panel = nullptr;
+ HBoxContainer *context_toolbar_hbox = nullptr;
+ HashMap<Control *, VSeparator *> context_toolbar_separators;
+
+ void _update_context_toolbar();
void _generate_selection_boxes();
diff --git a/editor/plugins/occluder_instance_3d_editor_plugin.cpp b/editor/plugins/occluder_instance_3d_editor_plugin.cpp
index 3a05352ecf..321c330816 100644
--- a/editor/plugins/occluder_instance_3d_editor_plugin.cpp
+++ b/editor/plugins/occluder_instance_3d_editor_plugin.cpp
@@ -31,6 +31,7 @@
#include "occluder_instance_3d_editor_plugin.h"
#include "editor/editor_node.h"
+#include "editor/editor_string_names.h"
#include "editor/gui/editor_file_dialog.h"
void OccluderInstance3DEditorPlugin::_bake_select_file(const String &p_file) {
@@ -104,7 +105,7 @@ void OccluderInstance3DEditorPlugin::_bind_methods() {
OccluderInstance3DEditorPlugin::OccluderInstance3DEditorPlugin() {
bake = memnew(Button);
bake->set_flat(true);
- bake->set_icon(EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("Bake")));
+ bake->set_icon(EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("Bake"), EditorStringName(EditorIcons)));
bake->set_text(TTR("Bake Occluders"));
bake->hide();
bake->connect("pressed", Callable(this, "_bake"));
diff --git a/editor/plugins/path_2d_editor_plugin.cpp b/editor/plugins/path_2d_editor_plugin.cpp
index 3a7805ba4c..61617bfd4f 100644
--- a/editor/plugins/path_2d_editor_plugin.cpp
+++ b/editor/plugins/path_2d_editor_plugin.cpp
@@ -532,19 +532,14 @@ Path2DEditor::Path2DEditor() {
mode = MODE_EDIT;
action = ACTION_NONE;
- base_hb = memnew(HBoxContainer);
- CanvasItemEditor::get_singleton()->add_control_to_menu_panel(base_hb);
-
- sep = memnew(VSeparator);
- base_hb->add_child(sep);
-
curve_edit = memnew(Button);
curve_edit->set_flat(true);
curve_edit->set_toggle_mode(true);
+ curve_edit->set_pressed(true);
curve_edit->set_focus_mode(Control::FOCUS_NONE);
curve_edit->set_tooltip_text(TTR("Select Points") + "\n" + TTR("Shift+Drag: Select Control Points") + "\n" + keycode_get_string((Key)KeyModifierMask::CMD_OR_CTRL) + TTR("Click: Add Point") + "\n" + TTR("Left Click: Split Segment (in curve)") + "\n" + TTR("Right Click: Delete Point"));
curve_edit->connect("pressed", callable_mp(this, &Path2DEditor::_mode_selected).bind(MODE_EDIT));
- base_hb->add_child(curve_edit);
+ add_child(curve_edit);
curve_edit_curve = memnew(Button);
curve_edit_curve->set_flat(true);
@@ -552,7 +547,7 @@ Path2DEditor::Path2DEditor() {
curve_edit_curve->set_focus_mode(Control::FOCUS_NONE);
curve_edit_curve->set_tooltip_text(TTR("Select Control Points (Shift+Drag)"));
curve_edit_curve->connect("pressed", callable_mp(this, &Path2DEditor::_mode_selected).bind(MODE_EDIT_CURVE));
- base_hb->add_child(curve_edit_curve);
+ add_child(curve_edit_curve);
curve_create = memnew(Button);
curve_create->set_flat(true);
@@ -560,7 +555,7 @@ Path2DEditor::Path2DEditor() {
curve_create->set_focus_mode(Control::FOCUS_NONE);
curve_create->set_tooltip_text(TTR("Add Point (in empty space)"));
curve_create->connect("pressed", callable_mp(this, &Path2DEditor::_mode_selected).bind(MODE_CREATE));
- base_hb->add_child(curve_create);
+ add_child(curve_create);
curve_del = memnew(Button);
curve_del->set_flat(true);
@@ -568,20 +563,20 @@ Path2DEditor::Path2DEditor() {
curve_del->set_focus_mode(Control::FOCUS_NONE);
curve_del->set_tooltip_text(TTR("Delete Point"));
curve_del->connect("pressed", callable_mp(this, &Path2DEditor::_mode_selected).bind(MODE_DELETE));
- base_hb->add_child(curve_del);
+ add_child(curve_del);
curve_close = memnew(Button);
curve_close->set_flat(true);
curve_close->set_focus_mode(Control::FOCUS_NONE);
curve_close->set_tooltip_text(TTR("Close Curve"));
curve_close->connect("pressed", callable_mp(this, &Path2DEditor::_mode_selected).bind(ACTION_CLOSE));
- base_hb->add_child(curve_close);
+ add_child(curve_close);
PopupMenu *menu;
handle_menu = memnew(MenuButton);
handle_menu->set_text(TTR("Options"));
- base_hb->add_child(handle_menu);
+ add_child(handle_menu);
menu = handle_menu->get_popup();
menu->add_check_item(TTR("Mirror Handle Angles"));
@@ -589,10 +584,6 @@ Path2DEditor::Path2DEditor() {
menu->add_check_item(TTR("Mirror Handle Lengths"));
menu->set_item_checked(HANDLE_OPTION_LENGTH, mirror_handle_length);
menu->connect("id_pressed", callable_mp(this, &Path2DEditor::_handle_option_pressed));
-
- base_hb->hide();
-
- curve_edit->set_pressed(true);
}
void Path2DEditorPlugin::edit(Object *p_object) {
@@ -606,11 +597,9 @@ bool Path2DEditorPlugin::handles(Object *p_object) const {
void Path2DEditorPlugin::make_visible(bool p_visible) {
if (p_visible) {
path2d_editor->show();
- path2d_editor->base_hb->show();
} else {
path2d_editor->hide();
- path2d_editor->base_hb->hide();
path2d_editor->edit(nullptr);
}
}
diff --git a/editor/plugins/path_2d_editor_plugin.h b/editor/plugins/path_2d_editor_plugin.h
index 25af0bf616..b8816d9b1e 100644
--- a/editor/plugins/path_2d_editor_plugin.h
+++ b/editor/plugins/path_2d_editor_plugin.h
@@ -34,7 +34,6 @@
#include "editor/editor_plugin.h"
#include "scene/2d/path_2d.h"
#include "scene/gui/box_container.h"
-#include "scene/gui/separator.h"
class CanvasItemEditor;
class MenuButton;
@@ -47,7 +46,6 @@ class Path2DEditor : public HBoxContainer {
Path2D *node = nullptr;
HBoxContainer *base_hb = nullptr;
- Separator *sep = nullptr;
enum Mode {
MODE_CREATE,
diff --git a/editor/plugins/path_3d_editor_plugin.cpp b/editor/plugins/path_3d_editor_plugin.cpp
index f4c36f3816..40e8482a0b 100644
--- a/editor/plugins/path_3d_editor_plugin.cpp
+++ b/editor/plugins/path_3d_editor_plugin.cpp
@@ -35,6 +35,7 @@
#include "core/os/keyboard.h"
#include "editor/editor_node.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "editor/editor_undo_redo_manager.h"
#include "node_3d_editor_plugin.h"
#include "scene/gui/menu_button.h"
@@ -623,21 +624,9 @@ bool Path3DEditorPlugin::handles(Object *p_object) const {
void Path3DEditorPlugin::make_visible(bool p_visible) {
if (p_visible) {
- curve_create->show();
- curve_edit->show();
- curve_edit_curve->show();
- curve_del->show();
- curve_close->show();
- handle_menu->show();
- sep->show();
+ topmenu_bar->show();
} else {
- curve_create->hide();
- curve_edit->hide();
- curve_edit_curve->hide();
- curve_del->hide();
- curve_close->hide();
- handle_menu->hide();
- sep->hide();
+ topmenu_bar->hide();
{
Path3D *pre = path;
@@ -696,11 +685,11 @@ void Path3DEditorPlugin::_handle_option_pressed(int p_option) {
void Path3DEditorPlugin::_update_theme() {
// TODO: Split the EditorPlugin instance from the UI instance and connect this properly.
// See the 2D path editor for inspiration.
- curve_edit->set_icon(Node3DEditor::get_singleton()->get_editor_theme_icon(SNAME("CurveEdit")));
- curve_edit_curve->set_icon(Node3DEditor::get_singleton()->get_editor_theme_icon(SNAME("CurveCurve")));
- curve_create->set_icon(Node3DEditor::get_singleton()->get_editor_theme_icon(SNAME("CurveCreate")));
- curve_del->set_icon(Node3DEditor::get_singleton()->get_editor_theme_icon(SNAME("CurveDelete")));
- curve_close->set_icon(Node3DEditor::get_singleton()->get_editor_theme_icon(SNAME("CurveClose")));
+ curve_edit->set_icon(EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("CurveEdit"), EditorStringName(EditorIcons)));
+ curve_edit_curve->set_icon(EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("CurveCurve"), EditorStringName(EditorIcons)));
+ curve_create->set_icon(EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("CurveCreate"), EditorStringName(EditorIcons)));
+ curve_del->set_icon(EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("CurveDelete"), EditorStringName(EditorIcons)));
+ curve_close->set_icon(EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("CurveClose"), EditorStringName(EditorIcons)));
}
void Path3DEditorPlugin::_notification(int p_what) {
@@ -736,55 +725,49 @@ Path3DEditorPlugin::Path3DEditorPlugin() {
gizmo_plugin.instantiate();
Node3DEditor::get_singleton()->add_gizmo_plugin(gizmo_plugin);
- sep = memnew(VSeparator);
- sep->hide();
- Node3DEditor::get_singleton()->add_control_to_menu_panel(sep);
+ topmenu_bar = memnew(HBoxContainer);
+ topmenu_bar->hide();
+ Node3DEditor::get_singleton()->add_control_to_menu_panel(topmenu_bar);
curve_edit = memnew(Button);
curve_edit->set_flat(true);
curve_edit->set_toggle_mode(true);
- curve_edit->hide();
curve_edit->set_focus_mode(Control::FOCUS_NONE);
curve_edit->set_tooltip_text(TTR("Select Points") + "\n" + TTR("Shift+Drag: Select Control Points") + "\n" + keycode_get_string((Key)KeyModifierMask::CMD_OR_CTRL) + TTR("Click: Add Point") + "\n" + TTR("Right Click: Delete Point"));
- Node3DEditor::get_singleton()->add_control_to_menu_panel(curve_edit);
+ topmenu_bar->add_child(curve_edit);
curve_edit_curve = memnew(Button);
curve_edit_curve->set_flat(true);
curve_edit_curve->set_toggle_mode(true);
- curve_edit_curve->hide();
curve_edit_curve->set_focus_mode(Control::FOCUS_NONE);
curve_edit_curve->set_tooltip_text(TTR("Select Control Points (Shift+Drag)"));
- Node3DEditor::get_singleton()->add_control_to_menu_panel(curve_edit_curve);
+ topmenu_bar->add_child(curve_edit_curve);
curve_create = memnew(Button);
curve_create->set_flat(true);
curve_create->set_toggle_mode(true);
- curve_create->hide();
curve_create->set_focus_mode(Control::FOCUS_NONE);
curve_create->set_tooltip_text(TTR("Add Point (in empty space)") + "\n" + TTR("Split Segment (in curve)"));
- Node3DEditor::get_singleton()->add_control_to_menu_panel(curve_create);
+ topmenu_bar->add_child(curve_create);
curve_del = memnew(Button);
curve_del->set_flat(true);
curve_del->set_toggle_mode(true);
- curve_del->hide();
curve_del->set_focus_mode(Control::FOCUS_NONE);
curve_del->set_tooltip_text(TTR("Delete Point"));
- Node3DEditor::get_singleton()->add_control_to_menu_panel(curve_del);
+ topmenu_bar->add_child(curve_del);
curve_close = memnew(Button);
curve_close->set_flat(true);
- curve_close->hide();
curve_close->set_focus_mode(Control::FOCUS_NONE);
curve_close->set_tooltip_text(TTR("Close Curve"));
- Node3DEditor::get_singleton()->add_control_to_menu_panel(curve_close);
+ topmenu_bar->add_child(curve_close);
PopupMenu *menu;
handle_menu = memnew(MenuButton);
handle_menu->set_text(TTR("Options"));
- handle_menu->hide();
- Node3DEditor::get_singleton()->add_control_to_menu_panel(handle_menu);
+ topmenu_bar->add_child(handle_menu);
menu = handle_menu->get_popup();
menu->add_check_item(TTR("Mirror Handle Angles"));
@@ -822,6 +805,6 @@ Path3DGizmoPlugin::Path3DGizmoPlugin() {
Color path_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/path", Color(0.5, 0.5, 1.0, 0.8));
create_material("path_material", path_color);
create_material("path_thin_material", Color(0.5, 0.5, 0.5));
- create_handle_material("handles", false, Node3DEditor::get_singleton()->get_editor_theme_icon(SNAME("EditorPathSmoothHandle")));
- create_handle_material("sec_handles", false, Node3DEditor::get_singleton()->get_editor_theme_icon(SNAME("EditorCurveHandle")));
+ create_handle_material("handles", false, EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("EditorPathSmoothHandle"), EditorStringName(EditorIcons)));
+ create_handle_material("sec_handles", false, EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("EditorCurveHandle"), EditorStringName(EditorIcons)));
}
diff --git a/editor/plugins/path_3d_editor_plugin.h b/editor/plugins/path_3d_editor_plugin.h
index 9cac6e395a..871e6a1563 100644
--- a/editor/plugins/path_3d_editor_plugin.h
+++ b/editor/plugins/path_3d_editor_plugin.h
@@ -35,8 +35,8 @@
#include "editor/plugins/node_3d_editor_gizmos.h"
#include "scene/3d/camera_3d.h"
#include "scene/3d/path_3d.h"
-#include "scene/gui/separator.h"
+class HBoxContainer;
class MenuButton;
class Path3DGizmo : public EditorNode3DGizmo {
@@ -87,7 +87,7 @@ public:
class Path3DEditorPlugin : public EditorPlugin {
GDCLASS(Path3DEditorPlugin, EditorPlugin);
- Separator *sep = nullptr;
+ HBoxContainer *topmenu_bar = nullptr;
Button *curve_create = nullptr;
Button *curve_edit = nullptr;
Button *curve_edit_curve = nullptr;
diff --git a/editor/plugins/physical_bone_3d_editor_plugin.cpp b/editor/plugins/physical_bone_3d_editor_plugin.cpp
index c9b77b3edb..d01725fc42 100644
--- a/editor/plugins/physical_bone_3d_editor_plugin.cpp
+++ b/editor/plugins/physical_bone_3d_editor_plugin.cpp
@@ -30,6 +30,8 @@
#include "physical_bone_3d_editor_plugin.h"
+#include "editor/editor_node.h"
+#include "editor/editor_string_names.h"
#include "editor/plugins/node_3d_editor_plugin.h"
#include "scene/gui/separator.h"
@@ -53,14 +55,14 @@ PhysicalBone3DEditor::PhysicalBone3DEditor() {
spatial_editor_hb->set_alignment(BoxContainer::ALIGNMENT_BEGIN);
Node3DEditor::get_singleton()->add_control_to_menu_panel(spatial_editor_hb);
- spatial_editor_hb->add_child(memnew(VSeparator));
-
button_transform_joint = memnew(Button);
button_transform_joint->set_flat(true);
spatial_editor_hb->add_child(button_transform_joint);
button_transform_joint->set_text(TTR("Move Joint"));
- button_transform_joint->set_icon(Node3DEditor::get_singleton()->get_editor_theme_icon(SNAME("PhysicalBone3D")));
+ // TODO: Rework this as a dedicated toolbar control so we can hook into theme changes and update it
+ // when the editor theme updates.
+ button_transform_joint->set_icon(EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("PhysicalBone3D"), EditorStringName(EditorIcons)));
button_transform_joint->set_toggle_mode(true);
button_transform_joint->connect("toggled", callable_mp(this, &PhysicalBone3DEditor::_on_toggle_button_transform_joint));
diff --git a/editor/plugins/polygon_3d_editor_plugin.cpp b/editor/plugins/polygon_3d_editor_plugin.cpp
index 451bd7a738..1fe1e1089e 100644
--- a/editor/plugins/polygon_3d_editor_plugin.cpp
+++ b/editor/plugins/polygon_3d_editor_plugin.cpp
@@ -36,6 +36,7 @@
#include "core/os/keyboard.h"
#include "editor/editor_node.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "editor/editor_undo_redo_manager.h"
#include "editor/plugins/canvas_item_editor_plugin.h"
#include "editor/plugins/node_3d_editor_plugin.h"
@@ -536,7 +537,6 @@ void Polygon3DEditor::_bind_methods() {
Polygon3DEditor::Polygon3DEditor() {
node = nullptr;
- add_child(memnew(VSeparator));
button_create = memnew(Button);
button_create->set_flat(true);
add_child(button_create);
@@ -569,7 +569,7 @@ Polygon3DEditor::Polygon3DEditor() {
handle_material->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA);
handle_material->set_flag(StandardMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
handle_material->set_flag(StandardMaterial3D::FLAG_SRGB_VERTEX_COLOR, true);
- Ref<Texture2D> handle = EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("Editor3DHandle"));
+ Ref<Texture2D> handle = EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("Editor3DHandle"), EditorStringName(EditorIcons));
handle_material->set_point_size(handle->get_width());
handle_material->set_texture(StandardMaterial3D::TEXTURE_ALBEDO, handle);
diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp
index 2fe607a08c..89d9b0d023 100644
--- a/editor/plugins/script_editor_plugin.cpp
+++ b/editor/plugins/script_editor_plugin.cpp
@@ -3876,7 +3876,7 @@ ScriptEditor::ScriptEditor(WindowWrapper *p_wrapper) {
filename = memnew(Label);
filename->set_clip_text(true);
filename->set_h_size_flags(SIZE_EXPAND_FILL);
- filename->add_theme_style_override("normal", EditorNode::get_singleton()->get_gui_base()->get_theme_stylebox(SNAME("normal"), SNAME("LineEdit")));
+ filename->add_theme_style_override("normal", EditorNode::get_singleton()->get_editor_theme()->get_stylebox(SNAME("normal"), SNAME("LineEdit")));
buttons_hbox->add_child(filename);
members_overview_alphabeta_sort_button = memnew(Button);
diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp
index 8132fd8e9b..5aaa3365b3 100644
--- a/editor/plugins/script_text_editor.cpp
+++ b/editor/plugins/script_text_editor.cpp
@@ -2124,16 +2124,16 @@ void ScriptTextEditor::_enable_code_editor() {
editor_box->add_child(warnings_panel);
warnings_panel->add_theme_font_override(
- "normal_font", EditorNode::get_singleton()->get_gui_base()->get_theme_font(SNAME("main"), EditorStringName(EditorFonts)));
+ "normal_font", EditorNode::get_singleton()->get_editor_theme()->get_font(SNAME("main"), EditorStringName(EditorFonts)));
warnings_panel->add_theme_font_size_override(
- "normal_font_size", EditorNode::get_singleton()->get_gui_base()->get_theme_font_size(SNAME("main_size"), EditorStringName(EditorFonts)));
+ "normal_font_size", EditorNode::get_singleton()->get_editor_theme()->get_font_size(SNAME("main_size"), EditorStringName(EditorFonts)));
warnings_panel->connect("meta_clicked", callable_mp(this, &ScriptTextEditor::_warning_clicked));
editor_box->add_child(errors_panel);
errors_panel->add_theme_font_override(
- "normal_font", EditorNode::get_singleton()->get_gui_base()->get_theme_font(SNAME("main"), EditorStringName(EditorFonts)));
+ "normal_font", EditorNode::get_singleton()->get_editor_theme()->get_font(SNAME("main"), EditorStringName(EditorFonts)));
errors_panel->add_theme_font_size_override(
- "normal_font_size", EditorNode::get_singleton()->get_gui_base()->get_theme_font_size(SNAME("main_size"), EditorStringName(EditorFonts)));
+ "normal_font_size", EditorNode::get_singleton()->get_editor_theme()->get_font_size(SNAME("main_size"), EditorStringName(EditorFonts)));
errors_panel->connect("meta_clicked", callable_mp(this, &ScriptTextEditor::_error_clicked));
add_child(context_menu);
diff --git a/editor/plugins/skeleton_2d_editor_plugin.cpp b/editor/plugins/skeleton_2d_editor_plugin.cpp
index 9b67648322..44543ffa9f 100644
--- a/editor/plugins/skeleton_2d_editor_plugin.cpp
+++ b/editor/plugins/skeleton_2d_editor_plugin.cpp
@@ -31,6 +31,7 @@
#include "skeleton_2d_editor_plugin.h"
#include "editor/editor_node.h"
+#include "editor/editor_string_names.h"
#include "editor/editor_undo_redo_manager.h"
#include "editor/plugins/canvas_item_editor_plugin.h"
#include "scene/2d/mesh_instance_2d.h"
@@ -98,7 +99,7 @@ Skeleton2DEditor::Skeleton2DEditor() {
CanvasItemEditor::get_singleton()->add_control_to_menu_panel(options);
options->set_text(TTR("Skeleton2D"));
- options->set_icon(EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("Skeleton2D")));
+ options->set_icon(EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("Skeleton2D"), EditorStringName(EditorIcons)));
options->get_popup()->add_item(TTR("Reset to Rest Pose"), MENU_OPTION_SET_REST);
options->get_popup()->add_separator();
diff --git a/editor/plugins/skeleton_3d_editor_plugin.cpp b/editor/plugins/skeleton_3d_editor_plugin.cpp
index 7aa333c198..764c1a94c8 100644
--- a/editor/plugins/skeleton_3d_editor_plugin.cpp
+++ b/editor/plugins/skeleton_3d_editor_plugin.cpp
@@ -712,12 +712,12 @@ void Skeleton3DEditor::create_editors() {
add_child(file_dialog);
// Create Top Menu Bar.
- separator = memnew(VSeparator);
- ne->add_control_to_menu_panel(separator);
+ HBoxContainer *topmenu_bar = memnew(HBoxContainer);
+ ne->add_control_to_menu_panel(topmenu_bar);
// Create Skeleton Option in Top Menu Bar.
skeleton_options = memnew(MenuButton);
- ne->add_control_to_menu_panel(skeleton_options);
+ topmenu_bar->add_child(skeleton_options);
skeleton_options->set_text(TTR("Skeleton3D"));
@@ -737,7 +737,7 @@ void Skeleton3DEditor::create_editors() {
button_binds.resize(1);
edit_mode_button = memnew(Button);
- ne->add_control_to_menu_panel(edit_mode_button);
+ topmenu_bar->add_child(edit_mode_button);
edit_mode_button->set_flat(true);
edit_mode_button->set_toggle_mode(true);
edit_mode_button->set_focus_mode(FOCUS_NONE);
@@ -753,7 +753,7 @@ void Skeleton3DEditor::create_editors() {
// Keying buttons.
animation_hb = memnew(HBoxContainer);
- ne->add_control_to_menu_panel(animation_hb);
+ topmenu_bar->add_child(animation_hb);
animation_hb->add_child(memnew(VSeparator));
animation_hb->hide();
@@ -936,7 +936,7 @@ void fragment() {
}
)");
handle_material->set_shader(handle_shader);
- Ref<Texture2D> handle = EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("EditorBoneHandle"));
+ Ref<Texture2D> handle = EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("EditorBoneHandle"), EditorStringName(EditorIcons));
handle_material->set_shader_parameter("point_size", handle->get_width());
handle_material->set_shader_parameter("texture_albedo", handle);
diff --git a/editor/plugins/skeleton_ik_3d_editor_plugin.cpp b/editor/plugins/skeleton_ik_3d_editor_plugin.cpp
index d081dd7c06..74b60c132e 100644
--- a/editor/plugins/skeleton_ik_3d_editor_plugin.cpp
+++ b/editor/plugins/skeleton_ik_3d_editor_plugin.cpp
@@ -31,6 +31,7 @@
#include "skeleton_ik_3d_editor_plugin.h"
#include "editor/editor_node.h"
+#include "editor/editor_string_names.h"
#include "scene/3d/skeleton_ik_3d.h"
#include "scene/gui/button.h"
@@ -84,7 +85,7 @@ void SkeletonIK3DEditorPlugin::_bind_methods() {
SkeletonIK3DEditorPlugin::SkeletonIK3DEditorPlugin() {
play_btn = memnew(Button);
- play_btn->set_icon(EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("Play")));
+ play_btn->set_icon(EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("Play"), EditorStringName(EditorIcons)));
play_btn->set_text(TTR("Play IK"));
play_btn->set_toggle_mode(true);
play_btn->hide();
diff --git a/editor/plugins/text_shader_editor.cpp b/editor/plugins/text_shader_editor.cpp
index 27e32cc8f7..b68b283a61 100644
--- a/editor/plugins/text_shader_editor.cpp
+++ b/editor/plugins/text_shader_editor.cpp
@@ -327,8 +327,8 @@ void ShaderTextEditor::_load_theme_settings() {
if (warnings_panel) {
// Warnings panel.
- warnings_panel->add_theme_font_override("normal_font", EditorNode::get_singleton()->get_gui_base()->get_theme_font(SNAME("main"), EditorStringName(EditorFonts)));
- warnings_panel->add_theme_font_size_override("normal_font_size", EditorNode::get_singleton()->get_gui_base()->get_theme_font_size(SNAME("main_size"), EditorStringName(EditorFonts)));
+ warnings_panel->add_theme_font_override("normal_font", EditorNode::get_singleton()->get_editor_theme()->get_font(SNAME("main"), EditorStringName(EditorFonts)));
+ warnings_panel->add_theme_font_size_override("normal_font_size", EditorNode::get_singleton()->get_editor_theme()->get_font_size(SNAME("main_size"), EditorStringName(EditorFonts)));
}
}
@@ -1167,7 +1167,7 @@ TextShaderEditor::TextShaderEditor() {
hbc->add_child(edit_menu);
hbc->add_child(goto_menu);
hbc->add_child(help_menu);
- hbc->add_theme_style_override("panel", EditorNode::get_singleton()->get_gui_base()->get_theme_stylebox(SNAME("ScriptEditorPanel"), EditorStringName(EditorStyles)));
+ hbc->add_theme_style_override("panel", EditorNode::get_singleton()->get_editor_theme()->get_stylebox(SNAME("ScriptEditorPanel"), EditorStringName(EditorStyles)));
VSplitContainer *editor_box = memnew(VSplitContainer);
main_container->add_child(editor_box);
diff --git a/editor/plugins/theme_editor_plugin.cpp b/editor/plugins/theme_editor_plugin.cpp
index ffe6c01ef0..f52a0913e2 100644
--- a/editor/plugins/theme_editor_plugin.cpp
+++ b/editor/plugins/theme_editor_plugin.cpp
@@ -3548,7 +3548,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_button_icon(preview_tabs->get_tab_count() - 1, EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("close"), SNAME("TabBar")));
+ preview_tabs->set_tab_button_icon(preview_tabs->get_tab_count() - 1, EditorNode::get_singleton()->get_editor_theme()->get_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);
diff --git a/editor/plugins/theme_editor_preview.cpp b/editor/plugins/theme_editor_preview.cpp
index 61bce0a89c..14a25e4e29 100644
--- a/editor/plugins/theme_editor_preview.cpp
+++ b/editor/plugins/theme_editor_preview.cpp
@@ -217,7 +217,7 @@ void ThemeEditorPreview::_notification(int p_what) {
theme_cache.preview_picker_overlay_color = get_theme_color(SNAME("preview_picker_overlay_color"), SNAME("ThemeEditor"));
theme_cache.preview_picker_label = get_theme_stylebox(SNAME("preview_picker_label"), SNAME("ThemeEditor"));
theme_cache.preview_picker_font = get_theme_font(SNAME("status_source"), EditorStringName(EditorFonts));
- theme_cache.font_size = get_theme_font_size(SNAME("font_size"), EditorStringName(EditorFonts));
+ theme_cache.font_size = get_theme_default_font_size();
} break;
case NOTIFICATION_PROCESS: {
diff --git a/editor/plugins/tiles/tile_data_editors.cpp b/editor/plugins/tiles/tile_data_editors.cpp
index 26487e8dfd..a63c2f5742 100644
--- a/editor/plugins/tiles/tile_data_editors.cpp
+++ b/editor/plugins/tiles/tile_data_editors.cpp
@@ -883,10 +883,10 @@ GenericTilePolygonEditor::GenericTilePolygonEditor() {
button_advanced_menu->get_popup()->add_item(TTR("Reset to default tile shape"), RESET_TO_DEFAULT_TILE, Key::F);
button_advanced_menu->get_popup()->add_item(TTR("Clear"), CLEAR_TILE, Key::C);
button_advanced_menu->get_popup()->add_separator();
- button_advanced_menu->get_popup()->add_icon_item(get_editor_theme_icon(SNAME("RotateRight")), TTR("Rotate Right"), ROTATE_RIGHT, Key::R);
- button_advanced_menu->get_popup()->add_icon_item(get_editor_theme_icon(SNAME("RotateLeft")), TTR("Rotate Left"), ROTATE_LEFT, Key::E);
- button_advanced_menu->get_popup()->add_icon_item(get_editor_theme_icon(SNAME("MirrorX")), TTR("Flip Horizontally"), FLIP_HORIZONTALLY, Key::H);
- button_advanced_menu->get_popup()->add_icon_item(get_editor_theme_icon(SNAME("MirrorY")), TTR("Flip Vertically"), FLIP_VERTICALLY, Key::V);
+ button_advanced_menu->get_popup()->add_item(TTR("Rotate Right"), ROTATE_RIGHT, Key::R);
+ button_advanced_menu->get_popup()->add_item(TTR("Rotate Left"), ROTATE_LEFT, Key::E);
+ button_advanced_menu->get_popup()->add_item(TTR("Flip Horizontally"), FLIP_HORIZONTALLY, Key::H);
+ button_advanced_menu->get_popup()->add_item(TTR("Flip Vertically"), FLIP_VERTICALLY, Key::V);
button_advanced_menu->get_popup()->connect("id_pressed", callable_mp(this, &GenericTilePolygonEditor::_advanced_menu_item_pressed));
button_advanced_menu->set_focus_mode(FOCUS_ALL);
toolbar->add_child(button_advanced_menu);
@@ -937,7 +937,6 @@ GenericTilePolygonEditor::GenericTilePolygonEditor() {
root->add_child(editor_zoom_widget);
button_center_view = memnew(Button);
- button_center_view->set_icon(EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("CenterView")));
button_center_view->set_anchors_and_offsets_preset(Control::PRESET_TOP_RIGHT, Control::PRESET_MODE_MINSIZE, 5);
button_center_view->connect("pressed", callable_mp(this, &GenericTilePolygonEditor::_center_view));
button_center_view->set_flat(true);
diff --git a/editor/plugins/tiles/tiles_editor_plugin.cpp b/editor/plugins/tiles/tiles_editor_plugin.cpp
index 904348d3bf..e8498501c6 100644
--- a/editor/plugins/tiles/tiles_editor_plugin.cpp
+++ b/editor/plugins/tiles/tiles_editor_plugin.cpp
@@ -38,6 +38,7 @@
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_string_names.h"
#include "editor/plugins/canvas_item_editor_plugin.h"
#include "scene/2d/tile_map.h"
@@ -289,10 +290,12 @@ void TilesEditorUtils::display_tile_set_editor_panel() {
}
void TilesEditorUtils::draw_selection_rect(CanvasItem *p_ci, const Rect2 &p_rect, const Color &p_color) {
+ Ref<Texture2D> selection_texture = EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("TileSelection"), EditorStringName(EditorIcons));
+
real_t scale = p_ci->get_global_transform().get_scale().x * 0.5;
p_ci->draw_set_transform(p_rect.position, 0, Vector2(1, 1) / scale);
RS::get_singleton()->canvas_item_add_nine_patch(
- p_ci->get_canvas_item(), Rect2(Vector2(), p_rect.size * scale), Rect2(), EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("TileSelection"))->get_rid(),
+ p_ci->get_canvas_item(), Rect2(Vector2(), p_rect.size * scale), Rect2(), selection_texture->get_rid(),
Vector2(2, 2), Vector2(2, 2), RS::NINE_PATCH_STRETCH, RS::NINE_PATCH_STRETCH, false, p_color);
p_ci->draw_set_transform_matrix(Transform2D());
}
diff --git a/editor/plugins/version_control_editor_plugin.cpp b/editor/plugins/version_control_editor_plugin.cpp
index a6c98e646e..d6b08b42cb 100644
--- a/editor/plugins/version_control_editor_plugin.cpp
+++ b/editor/plugins/version_control_editor_plugin.cpp
@@ -174,7 +174,7 @@ void VersionControlEditorPlugin::_update_set_up_warning(String p_new_text) {
set_up_ssh_passphrase->get_text().is_empty();
if (empty_settings) {
- set_up_warning_text->add_theme_color_override(SNAME("font_color"), EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("warning_color"), EditorStringName(Editor)));
+ set_up_warning_text->add_theme_color_override(SNAME("font_color"), EditorNode::get_singleton()->get_editor_theme()->get_color(SNAME("warning_color"), EditorStringName(Editor)));
set_up_warning_text->set_text(TTR("Remote settings are empty. VCS features that use the network may not work."));
} else {
set_up_warning_text->set_text("");
@@ -192,7 +192,7 @@ void VersionControlEditorPlugin::_refresh_branch_list() {
String current_branch = EditorVCSInterface::get_singleton()->get_current_branch_name();
for (int i = 0; i < branch_list.size(); i++) {
- branch_select->add_icon_item(EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("VcsBranches")), branch_list[i], i);
+ branch_select->add_icon_item(EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("VcsBranches"), EditorStringName(EditorIcons)), branch_list[i], i);
if (branch_list[i] == current_branch) {
branch_select->select(i);
@@ -252,7 +252,7 @@ void VersionControlEditorPlugin::_refresh_remote_list() {
remote_select->set_disabled(remotes.is_empty());
for (int i = 0; i < remotes.size(); i++) {
- remote_select->add_icon_item(EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("ArrowUp")), remotes[i], i);
+ remote_select->add_icon_item(EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("ArrowUp"), EditorStringName(EditorIcons)), remotes[i], i);
remote_select->set_item_metadata(i, remotes[i]);
if (remotes[i] == current_remote) {
@@ -422,9 +422,9 @@ void VersionControlEditorPlugin::_add_new_item(Tree *p_tree, String p_file_path,
new_item->set_meta(SNAME("change_type"), p_change);
new_item->set_custom_color(0, change_type_to_color[p_change]);
- new_item->add_button(0, EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("File")), BUTTON_TYPE_OPEN, false, TTR("Open in editor"));
+ new_item->add_button(0, EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("File"), EditorStringName(EditorIcons)), BUTTON_TYPE_OPEN, false, TTR("Open in editor"));
if (p_tree == unstaged_files) {
- new_item->add_button(0, EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("Close")), BUTTON_TYPE_DISCARD, false, TTR("Discard changes"));
+ new_item->add_button(0, EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("Close"), EditorStringName(EditorIcons)), BUTTON_TYPE_DISCARD, false, TTR("Discard changes"));
}
}
@@ -570,8 +570,8 @@ void VersionControlEditorPlugin::_display_diff(int p_idx) {
String commit_author = meta_data[SNAME("commit_author")];
String commit_date_string = meta_data[SNAME("commit_date_string")];
- diff->push_font(EditorNode::get_singleton()->get_gui_base()->get_theme_font(SNAME("doc_bold"), EditorStringName(EditorFonts)));
- diff->push_color(EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("accent_color"), EditorStringName(Editor)));
+ diff->push_font(EditorNode::get_singleton()->get_editor_theme()->get_font(SNAME("doc_bold"), EditorStringName(EditorFonts)));
+ diff->push_color(EditorNode::get_singleton()->get_editor_theme()->get_color(SNAME("accent_color"), EditorStringName(Editor)));
diff->add_text(TTR("Commit:") + " " + commit_id);
diff->add_newline();
diff->add_text(TTR("Author:") + " " + commit_author);
@@ -590,13 +590,13 @@ void VersionControlEditorPlugin::_display_diff(int p_idx) {
for (int i = 0; i < diff_content.size(); i++) {
EditorVCSInterface::DiffFile diff_file = diff_content[i];
- diff->push_font(EditorNode::get_singleton()->get_gui_base()->get_theme_font(SNAME("doc_bold"), EditorStringName(EditorFonts)));
- diff->push_color(EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("accent_color"), EditorStringName(Editor)));
+ diff->push_font(EditorNode::get_singleton()->get_editor_theme()->get_font(SNAME("doc_bold"), EditorStringName(EditorFonts)));
+ diff->push_color(EditorNode::get_singleton()->get_editor_theme()->get_color(SNAME("accent_color"), EditorStringName(Editor)));
diff->add_text(TTR("File:") + " " + diff_file.new_file);
diff->pop();
diff->pop();
- diff->push_font(EditorNode::get_singleton()->get_gui_base()->get_theme_font(SNAME("status_source"), EditorStringName(EditorFonts)));
+ diff->push_font(EditorNode::get_singleton()->get_editor_theme()->get_font(SNAME("status_source"), EditorStringName(EditorFonts)));
for (int j = 0; j < diff_file.diff_hunks.size(); j++) {
EditorVCSInterface::DiffHunk hunk = diff_file.diff_hunks[j];
@@ -679,9 +679,9 @@ void VersionControlEditorPlugin::_display_diff_split_view(List<EditorVCSInterfac
EditorVCSInterface::DiffLine diff_line = parsed_diff[i];
bool has_change = diff_line.status != " ";
- static const Color red = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("error_color"), EditorStringName(Editor));
- static const Color green = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("success_color"), EditorStringName(Editor));
- static const Color white = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("font_color"), SNAME("Label")) * Color(1, 1, 1, 0.6);
+ static const Color red = EditorNode::get_singleton()->get_editor_theme()->get_color(SNAME("error_color"), EditorStringName(Editor));
+ static const Color green = EditorNode::get_singleton()->get_editor_theme()->get_color(SNAME("success_color"), EditorStringName(Editor));
+ static const Color white = EditorNode::get_singleton()->get_editor_theme()->get_color(SNAME("font_color"), SNAME("Label")) * Color(1, 1, 1, 0.6);
if (diff_line.old_line_no >= 0) {
diff->push_cell();
@@ -761,11 +761,11 @@ void VersionControlEditorPlugin::_display_diff_unified_view(List<EditorVCSInterf
Color color;
if (diff_line.status == "+") {
- color = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("success_color"), EditorStringName(Editor));
+ color = EditorNode::get_singleton()->get_editor_theme()->get_color(SNAME("success_color"), EditorStringName(Editor));
} else if (diff_line.status == "-") {
- color = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("error_color"), EditorStringName(Editor));
+ color = EditorNode::get_singleton()->get_editor_theme()->get_color(SNAME("error_color"), EditorStringName(Editor));
} else {
- color = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("font_color"), SNAME("Label"));
+ color = EditorNode::get_singleton()->get_editor_theme()->get_color(SNAME("font_color"), SNAME("Label"));
color *= Color(1, 1, 1, 0.6);
}
@@ -856,13 +856,13 @@ void VersionControlEditorPlugin::_popup_remote_remove_confirm(int p_index) {
void VersionControlEditorPlugin::_update_extra_options() {
extra_options_remove_branch_list->clear();
for (int i = 0; i < branch_select->get_item_count(); i++) {
- extra_options_remove_branch_list->add_icon_item(EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("VcsBranches")), branch_select->get_item_text(branch_select->get_item_id(i)));
+ extra_options_remove_branch_list->add_icon_item(EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("VcsBranches"), EditorStringName(EditorIcons)), branch_select->get_item_text(branch_select->get_item_id(i)));
}
extra_options_remove_branch_list->update_canvas_items();
extra_options_remove_remote_list->clear();
for (int i = 0; i < remote_select->get_item_count(); i++) {
- extra_options_remove_remote_list->add_icon_item(EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("ArrowUp")), remote_select->get_item_text(remote_select->get_item_id(i)));
+ extra_options_remove_remote_list->add_icon_item(EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("ArrowUp"), EditorStringName(EditorIcons)), remote_select->get_item_text(remote_select->get_item_id(i)));
}
extra_options_remove_remote_list->update_canvas_items();
}
@@ -1161,7 +1161,7 @@ VersionControlEditorPlugin::VersionControlEditorPlugin() {
refresh_button = memnew(Button);
refresh_button->set_tooltip_text(TTR("Detect new changes"));
refresh_button->set_flat(true);
- refresh_button->set_icon(EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("Reload")));
+ refresh_button->set_icon(EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("Reload"), EditorStringName(EditorIcons)));
refresh_button->connect(SNAME("pressed"), callable_mp(this, &VersionControlEditorPlugin::_refresh_stage_area));
refresh_button->connect(SNAME("pressed"), callable_mp(this, &VersionControlEditorPlugin::_refresh_commit_list));
refresh_button->connect(SNAME("pressed"), callable_mp(this, &VersionControlEditorPlugin::_refresh_branch_list));
@@ -1181,14 +1181,14 @@ VersionControlEditorPlugin::VersionControlEditorPlugin() {
discard_all_button = memnew(Button);
discard_all_button->set_tooltip_text(TTR("Discard all changes"));
- discard_all_button->set_icon(EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("Close")));
+ discard_all_button->set_icon(EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("Close"), EditorStringName(EditorIcons)));
discard_all_button->connect(SNAME("pressed"), callable_mp(this, &VersionControlEditorPlugin::_confirm_discard_all));
discard_all_button->set_flat(true);
unstage_title->add_child(discard_all_button);
stage_all_button = memnew(Button);
stage_all_button->set_flat(true);
- stage_all_button->set_icon(EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("MoveDown")));
+ stage_all_button->set_icon(EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("MoveDown"), EditorStringName(EditorIcons)));
stage_all_button->set_tooltip_text(TTR("Stage all changes"));
unstage_title->add_child(stage_all_button);
@@ -1218,7 +1218,7 @@ VersionControlEditorPlugin::VersionControlEditorPlugin() {
unstage_all_button = memnew(Button);
unstage_all_button->set_flat(true);
- unstage_all_button->set_icon(EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("MoveUp")));
+ unstage_all_button->set_icon(EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("MoveUp"), EditorStringName(EditorIcons)));
unstage_all_button->set_tooltip_text(TTR("Unstage all changes"));
stage_title->add_child(unstage_all_button);
@@ -1413,26 +1413,26 @@ VersionControlEditorPlugin::VersionControlEditorPlugin() {
fetch_button = memnew(Button);
fetch_button->set_flat(true);
fetch_button->set_tooltip_text(TTR("Fetch"));
- fetch_button->set_icon(EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("Reload")));
+ fetch_button->set_icon(EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("Reload"), EditorStringName(EditorIcons)));
fetch_button->connect(SNAME("pressed"), callable_mp(this, &VersionControlEditorPlugin::_fetch));
menu_bar->add_child(fetch_button);
pull_button = memnew(Button);
pull_button->set_flat(true);
pull_button->set_tooltip_text(TTR("Pull"));
- pull_button->set_icon(EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("MoveDown")));
+ pull_button->set_icon(EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("MoveDown"), EditorStringName(EditorIcons)));
pull_button->connect(SNAME("pressed"), callable_mp(this, &VersionControlEditorPlugin::_pull));
menu_bar->add_child(pull_button);
push_button = memnew(Button);
push_button->set_flat(true);
push_button->set_tooltip_text(TTR("Push"));
- push_button->set_icon(EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("MoveUp")));
+ push_button->set_icon(EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("MoveUp"), EditorStringName(EditorIcons)));
push_button->connect(SNAME("pressed"), callable_mp(this, &VersionControlEditorPlugin::_push));
menu_bar->add_child(push_button);
extra_options = memnew(MenuButton);
- extra_options->set_icon(EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("GuiTabMenuHl")));
+ extra_options->set_icon(EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("GuiTabMenuHl"), EditorStringName(EditorIcons)));
extra_options->get_popup()->connect(SNAME("about_to_popup"), callable_mp(this, &VersionControlEditorPlugin::_update_extra_options));
extra_options->get_popup()->connect(SNAME("id_pressed"), callable_mp(this, &VersionControlEditorPlugin::_extra_option_selected));
menu_bar->add_child(extra_options);
@@ -1463,19 +1463,19 @@ VersionControlEditorPlugin::VersionControlEditorPlugin() {
change_type_to_strings[EditorVCSInterface::CHANGE_TYPE_TYPECHANGE] = TTR("Typechange");
change_type_to_strings[EditorVCSInterface::CHANGE_TYPE_UNMERGED] = TTR("Unmerged");
- change_type_to_color[EditorVCSInterface::CHANGE_TYPE_NEW] = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("success_color"), EditorStringName(Editor));
- change_type_to_color[EditorVCSInterface::CHANGE_TYPE_MODIFIED] = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("warning_color"), EditorStringName(Editor));
- change_type_to_color[EditorVCSInterface::CHANGE_TYPE_RENAMED] = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("warning_color"), EditorStringName(Editor));
- change_type_to_color[EditorVCSInterface::CHANGE_TYPE_DELETED] = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("error_color"), EditorStringName(Editor));
- change_type_to_color[EditorVCSInterface::CHANGE_TYPE_TYPECHANGE] = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("font_color"), EditorStringName(Editor));
- change_type_to_color[EditorVCSInterface::CHANGE_TYPE_UNMERGED] = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("warning_color"), EditorStringName(Editor));
-
- change_type_to_icon[EditorVCSInterface::CHANGE_TYPE_NEW] = EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("StatusSuccess"));
- change_type_to_icon[EditorVCSInterface::CHANGE_TYPE_MODIFIED] = EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("StatusWarning"));
- change_type_to_icon[EditorVCSInterface::CHANGE_TYPE_RENAMED] = EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("StatusWarning"));
- change_type_to_icon[EditorVCSInterface::CHANGE_TYPE_TYPECHANGE] = EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("StatusWarning"));
- change_type_to_icon[EditorVCSInterface::CHANGE_TYPE_DELETED] = EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("StatusError"));
- change_type_to_icon[EditorVCSInterface::CHANGE_TYPE_UNMERGED] = EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("StatusWarning"));
+ change_type_to_color[EditorVCSInterface::CHANGE_TYPE_NEW] = EditorNode::get_singleton()->get_editor_theme()->get_color(SNAME("success_color"), EditorStringName(Editor));
+ change_type_to_color[EditorVCSInterface::CHANGE_TYPE_MODIFIED] = EditorNode::get_singleton()->get_editor_theme()->get_color(SNAME("warning_color"), EditorStringName(Editor));
+ change_type_to_color[EditorVCSInterface::CHANGE_TYPE_RENAMED] = EditorNode::get_singleton()->get_editor_theme()->get_color(SNAME("warning_color"), EditorStringName(Editor));
+ change_type_to_color[EditorVCSInterface::CHANGE_TYPE_DELETED] = EditorNode::get_singleton()->get_editor_theme()->get_color(SNAME("error_color"), EditorStringName(Editor));
+ change_type_to_color[EditorVCSInterface::CHANGE_TYPE_TYPECHANGE] = EditorNode::get_singleton()->get_editor_theme()->get_color(SNAME("font_color"), EditorStringName(Editor));
+ change_type_to_color[EditorVCSInterface::CHANGE_TYPE_UNMERGED] = EditorNode::get_singleton()->get_editor_theme()->get_color(SNAME("warning_color"), EditorStringName(Editor));
+
+ change_type_to_icon[EditorVCSInterface::CHANGE_TYPE_NEW] = EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("StatusSuccess"), EditorStringName(EditorIcons));
+ change_type_to_icon[EditorVCSInterface::CHANGE_TYPE_MODIFIED] = EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("StatusWarning"), EditorStringName(EditorIcons));
+ change_type_to_icon[EditorVCSInterface::CHANGE_TYPE_RENAMED] = EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("StatusWarning"), EditorStringName(EditorIcons));
+ change_type_to_icon[EditorVCSInterface::CHANGE_TYPE_TYPECHANGE] = EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("StatusWarning"), EditorStringName(EditorIcons));
+ change_type_to_icon[EditorVCSInterface::CHANGE_TYPE_DELETED] = EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("StatusError"), EditorStringName(EditorIcons));
+ change_type_to_icon[EditorVCSInterface::CHANGE_TYPE_UNMERGED] = EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("StatusWarning"), EditorStringName(EditorIcons));
version_control_dock = memnew(VBoxContainer);
version_control_dock->set_v_size_flags(Control::SIZE_EXPAND_FILL);
diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp
index dcdd80a314..13d16297c8 100644
--- a/editor/plugins/visual_shader_editor_plugin.cpp
+++ b/editor/plugins/visual_shader_editor_plugin.cpp
@@ -419,8 +419,8 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id, bool
// Visual shader specific theme for MSDF font.
Ref<Theme> vstheme;
vstheme.instantiate();
- Ref<Font> label_font = EditorNode::get_singleton()->get_editor_theme()->get_font("main_msdf", EditorStringName(EditorIcons));
- Ref<Font> label_bold_font = EditorNode::get_singleton()->get_editor_theme()->get_font("main_bold_msdf", EditorStringName(EditorIcons));
+ Ref<Font> label_font = EditorNode::get_singleton()->get_editor_theme()->get_font("main_msdf", EditorStringName(EditorFonts));
+ Ref<Font> label_bold_font = EditorNode::get_singleton()->get_editor_theme()->get_font("main_bold_msdf", EditorStringName(EditorFonts));
vstheme->set_font("font", "Label", label_font);
vstheme->set_font("font", "GraphNodeTitleLabel", label_bold_font);
vstheme->set_font("font", "LineEdit", label_font);
@@ -796,7 +796,7 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id, bool
name_box->connect("focus_exited", callable_mp(editor, &VisualShaderEditor::_port_name_focus_out).bind(name_box, p_id, i, false), CONNECT_DEFERRED);
Button *remove_btn = memnew(Button);
- remove_btn->set_icon(EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("Remove")));
+ remove_btn->set_icon(EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("Remove"), EditorStringName(EditorIcons)));
remove_btn->set_tooltip_text(TTR("Remove") + " " + name_left);
remove_btn->connect("pressed", callable_mp(editor, &VisualShaderEditor::_remove_input_port).bind(p_id, i), CONNECT_DEFERRED);
hb->add_child(remove_btn);
@@ -823,7 +823,7 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id, bool
if (valid_right) {
if (is_group) {
Button *remove_btn = memnew(Button);
- remove_btn->set_icon(EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("Remove")));
+ remove_btn->set_icon(EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("Remove"), EditorStringName(EditorIcons)));
remove_btn->set_tooltip_text(TTR("Remove") + " " + name_left);
remove_btn->connect("pressed", callable_mp(editor, &VisualShaderEditor::_remove_output_port).bind(p_id, i), CONNECT_DEFERRED);
hb->add_child(remove_btn);
@@ -4709,28 +4709,28 @@ void VisualShaderEditor::_update_varying_tree() {
switch (varying->type) {
case VisualShader::VARYING_TYPE_FLOAT:
- item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("float")));
+ item->set_icon(0, EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("float"), EditorStringName(EditorIcons)));
break;
case VisualShader::VARYING_TYPE_INT:
- item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("int")));
+ item->set_icon(0, EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("int"), EditorStringName(EditorIcons)));
break;
case VisualShader::VARYING_TYPE_UINT:
- item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("uint")));
+ item->set_icon(0, EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("uint"), EditorStringName(EditorIcons)));
break;
case VisualShader::VARYING_TYPE_VECTOR_2D:
- item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("Vector2")));
+ item->set_icon(0, EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("Vector2"), EditorStringName(EditorIcons)));
break;
case VisualShader::VARYING_TYPE_VECTOR_3D:
- item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("Vector3")));
+ item->set_icon(0, EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("Vector3"), EditorStringName(EditorIcons)));
break;
case VisualShader::VARYING_TYPE_VECTOR_4D:
- item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("Vector4")));
+ item->set_icon(0, EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("Vector4"), EditorStringName(EditorIcons)));
break;
case VisualShader::VARYING_TYPE_BOOLEAN:
- item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("bool")));
+ item->set_icon(0, EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("bool"), EditorStringName(EditorIcons)));
break;
case VisualShader::VARYING_TYPE_TRANSFORM:
- item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("Transform3D")));
+ item->set_icon(0, EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("Transform3D"), EditorStringName(EditorIcons)));
break;
default:
break;
@@ -6195,15 +6195,15 @@ public:
editor = p_editor;
input = p_input;
Ref<Texture2D> type_icon[] = {
- EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("float")),
- EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("int")),
- EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("uint")),
- EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("Vector2")),
- EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("Vector3")),
- EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("Vector4")),
- EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("bool")),
- EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("Transform3D")),
- EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("ImageTexture")),
+ EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("float"), EditorStringName(EditorIcons)),
+ EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("int"), EditorStringName(EditorIcons)),
+ EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("uint"), EditorStringName(EditorIcons)),
+ EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("Vector2"), EditorStringName(EditorIcons)),
+ EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("Vector3"), EditorStringName(EditorIcons)),
+ EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("Vector4"), EditorStringName(EditorIcons)),
+ EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("bool"), EditorStringName(EditorIcons)),
+ EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("Transform3D"), EditorStringName(EditorIcons)),
+ EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("ImageTexture"), EditorStringName(EditorIcons)),
};
add_item("[None]");
@@ -6245,14 +6245,14 @@ public:
varying = p_varying;
Ref<Texture2D> type_icon[] = {
- EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("float")),
- EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("int")),
- EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("uint")),
- EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("Vector2")),
- EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("Vector3")),
- EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("Vector4")),
- EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("bool")),
- EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("Transform3D")),
+ EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("float"), EditorStringName(EditorIcons)),
+ EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("int"), EditorStringName(EditorIcons)),
+ EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("uint"), EditorStringName(EditorIcons)),
+ EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("Vector2"), EditorStringName(EditorIcons)),
+ EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("Vector3"), EditorStringName(EditorIcons)),
+ EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("Vector4"), EditorStringName(EditorIcons)),
+ EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("bool"), EditorStringName(EditorIcons)),
+ EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("Transform3D"), EditorStringName(EditorIcons)),
};
bool is_getter = Ref<VisualShaderNodeVaryingGetter>(p_varying.ptr()).is_valid();
@@ -6325,16 +6325,16 @@ public:
parameter_ref = p_parameter_ref;
Ref<Texture2D> type_icon[] = {
- EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("float")),
- EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("int")),
- EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("uint")),
- EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("bool")),
- EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("Vector2")),
- EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("Vector3")),
- EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("Vector4")),
- EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("Transform3D")),
- EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("Color")),
- EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("ImageTexture")),
+ EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("float"), EditorStringName(EditorIcons)),
+ EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("int"), EditorStringName(EditorIcons)),
+ EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("uint"), EditorStringName(EditorIcons)),
+ EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("bool"), EditorStringName(EditorIcons)),
+ EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("Vector2"), EditorStringName(EditorIcons)),
+ EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("Vector3"), EditorStringName(EditorIcons)),
+ EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("Vector4"), EditorStringName(EditorIcons)),
+ EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("Transform3D"), EditorStringName(EditorIcons)),
+ EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("Color"), EditorStringName(EditorIcons)),
+ EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("ImageTexture"), EditorStringName(EditorIcons)),
};
add_item("[None]");
diff --git a/editor/plugins/voxel_gi_editor_plugin.cpp b/editor/plugins/voxel_gi_editor_plugin.cpp
index 50c68f7d21..91d90aaf80 100644
--- a/editor/plugins/voxel_gi_editor_plugin.cpp
+++ b/editor/plugins/voxel_gi_editor_plugin.cpp
@@ -32,6 +32,7 @@
#include "editor/editor_interface.h"
#include "editor/editor_node.h"
+#include "editor/editor_string_names.h"
#include "editor/gui/editor_file_dialog.h"
void VoxelGIEditorPlugin::_bake() {
@@ -185,7 +186,9 @@ VoxelGIEditorPlugin::VoxelGIEditorPlugin() {
bake_hb->hide();
bake = memnew(Button);
bake->set_flat(true);
- bake->set_icon(EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon(SNAME("Bake")));
+ // TODO: Rework this as a dedicated toolbar control so we can hook into theme changes and update it
+ // when the editor theme updates.
+ bake->set_icon(EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("Bake"), EditorStringName(EditorIcons)));
bake->set_text(TTR("Bake VoxelGI"));
bake->connect("pressed", callable_mp(this, &VoxelGIEditorPlugin::_bake));
bake_hb->add_child(bake);
diff --git a/editor/rename_dialog.cpp b/editor/rename_dialog.cpp
index 9eeea0ac54..a3a16dccd8 100644
--- a/editor/rename_dialog.cpp
+++ b/editor/rename_dialog.cpp
@@ -397,11 +397,11 @@ void RenameDialog::_update_preview(String new_text) {
if (new_name == preview_node->get_name()) {
// New name is identical to the old one. Don't color it as much to avoid distracting the user.
- const Color accent_color = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("accent_color"), EditorStringName(Editor));
- const Color text_color = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("default_color"), SNAME("RichTextLabel"));
+ const Color accent_color = EditorNode::get_singleton()->get_editor_theme()->get_color(SNAME("accent_color"), EditorStringName(Editor));
+ const Color text_color = EditorNode::get_singleton()->get_editor_theme()->get_color(SNAME("default_color"), SNAME("RichTextLabel"));
lbl_preview->add_theme_color_override("font_color", accent_color.lerp(text_color, 0.5));
} else {
- lbl_preview->add_theme_color_override("font_color", EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("success_color"), EditorStringName(Editor)));
+ lbl_preview->add_theme_color_override("font_color", EditorNode::get_singleton()->get_editor_theme()->get_color(SNAME("success_color"), EditorStringName(Editor)));
}
}
@@ -487,7 +487,7 @@ void RenameDialog::_error_handler(void *p_self, const char *p_func, const char *
self->has_errors = true;
self->lbl_preview_title->set_text(TTR("Regular Expression Error:"));
- self->lbl_preview->add_theme_color_override("font_color", EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("error_color"), EditorStringName(Editor)));
+ self->lbl_preview->add_theme_color_override("font_color", EditorNode::get_singleton()->get_editor_theme()->get_color(SNAME("error_color"), EditorStringName(Editor)));
self->lbl_preview->set_text(vformat(TTR("At character %s"), err_str));
}
diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp
index 6903f5160d..29a9b63d2e 100644
--- a/editor/scene_tree_dock.cpp
+++ b/editor/scene_tree_dock.cpp
@@ -2074,6 +2074,10 @@ void SceneTreeDock::_script_created(Ref<Script> p_script) {
return;
}
+ if (p_script->is_built_in()) {
+ p_script->set_path(edited_scene->get_scene_file_path() + "::");
+ }
+
EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
undo_redo->create_action(TTR("Attach Script"), UndoRedo::MERGE_DISABLE, selected.front()->get());
for (Node *E : selected) {
diff --git a/editor/window_wrapper.cpp b/editor/window_wrapper.cpp
index 2570574823..f0eba7b215 100644
--- a/editor/window_wrapper.cpp
+++ b/editor/window_wrapper.cpp
@@ -385,7 +385,7 @@ void ScreenSelect::_notification(int p_what) {
connect("gui_input", callable_mp(this, &ScreenSelect::_handle_mouse_shortcut));
} break;
case NOTIFICATION_THEME_CHANGED: {
- set_icon(EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon("MakeFloating"));
+ set_icon(get_editor_theme_icon("MakeFloating"));
popup_background->add_theme_style_override("panel", get_theme_stylebox("PanelForeground", EditorStringName(EditorStyles)));
const real_t popup_height = real_t(get_theme_font_size("font_size")) * 2.0;
diff --git a/main/main.cpp b/main/main.cpp
index aa2f5f2451..e24690f992 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -2048,6 +2048,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
GLOBAL_DEF_BASIC(PropertyInfo(Variant::INT, "xr/openxr/form_factor", PROPERTY_HINT_ENUM, "Head Mounted,Handheld"), "0");
GLOBAL_DEF_BASIC(PropertyInfo(Variant::INT, "xr/openxr/view_configuration", PROPERTY_HINT_ENUM, "Mono,Stereo"), "1"); // "Mono,Stereo,Quad,Observer"
GLOBAL_DEF_BASIC(PropertyInfo(Variant::INT, "xr/openxr/reference_space", PROPERTY_HINT_ENUM, "Local,Stage"), "1");
+ GLOBAL_DEF_BASIC(PropertyInfo(Variant::INT, "xr/openxr/environment_blend_mode", PROPERTY_HINT_ENUM, "Opaque,Additive,Alpha"), "0");
GLOBAL_DEF_BASIC("xr/openxr/submit_depth_buffer", false);
GLOBAL_DEF_BASIC("xr/openxr/startup_alert", true);
diff --git a/modules/csg/editor/csg_gizmos.cpp b/modules/csg/editor/csg_gizmos.cpp
index 2c533cb36d..ebf0f5a91f 100644
--- a/modules/csg/editor/csg_gizmos.cpp
+++ b/modules/csg/editor/csg_gizmos.cpp
@@ -35,12 +35,15 @@
#include "editor/editor_node.h"
#include "editor/editor_settings.h"
#include "editor/editor_undo_redo_manager.h"
+#include "editor/plugins/gizmos/gizmo_3d_helper.h"
#include "editor/plugins/node_3d_editor_plugin.h"
#include "scene/3d/camera_3d.h"
///////////
CSGShape3DGizmoPlugin::CSGShape3DGizmoPlugin() {
+ helper.instantiate();
+
Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/csg", Color(0.0, 0.4, 1, 0.15));
create_material("shape_union_material", gizmo_color);
create_material("shape_union_solid_material", gizmo_color);
@@ -56,6 +59,9 @@ CSGShape3DGizmoPlugin::CSGShape3DGizmoPlugin() {
create_handle_material("handles");
}
+CSGShape3DGizmoPlugin::~CSGShape3DGizmoPlugin() {
+}
+
String CSGShape3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const {
CSGShape3D *cs = Object::cast_to<CSGShape3D>(p_gizmo->get_node_3d());
@@ -64,7 +70,7 @@ String CSGShape3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo,
}
if (Object::cast_to<CSGBox3D>(cs)) {
- return "Size";
+ return helper->box_get_handle_name(p_id);
}
if (Object::cast_to<CSGCylinder3D>(cs)) {
@@ -104,17 +110,15 @@ Variant CSGShape3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo
return Variant();
}
+void CSGShape3DGizmoPlugin::begin_handle_action(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) {
+ helper->initialize_handle_action(get_handle_value(p_gizmo, p_id, p_secondary), p_gizmo->get_node_3d()->get_global_transform());
+}
+
void CSGShape3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) {
CSGShape3D *cs = Object::cast_to<CSGShape3D>(p_gizmo->get_node_3d());
- Transform3D gt = cs->get_global_transform();
- //gt.orthonormalize();
- Transform3D gi = gt.affine_inverse();
-
- Vector3 ray_from = p_camera->project_ray_origin(p_point);
- Vector3 ray_dir = p_camera->project_ray_normal(p_point);
-
- Vector3 sg[2] = { gi.xform(ray_from), gi.xform(ray_from + ray_dir * 16384) };
+ Vector3 sg[2];
+ helper->get_segment(p_camera, p_point, sg);
if (Object::cast_to<CSGSphere3D>(cs)) {
CSGSphere3D *s = Object::cast_to<CSGSphere3D>(cs);
@@ -135,29 +139,11 @@ void CSGShape3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_i
if (Object::cast_to<CSGBox3D>(cs)) {
CSGBox3D *s = Object::cast_to<CSGBox3D>(cs);
-
- Vector3 axis;
- axis[p_id] = 1.0;
- Vector3 ra, rb;
- Geometry3D::get_closest_points_between_segments(Vector3(), axis * 4096, sg[0], sg[1], ra, rb);
- float d = ra[p_id];
-
- if (Math::is_nan(d)) {
- // The handle is perpendicular to the camera.
- return;
- }
-
- if (Node3DEditor::get_singleton()->is_snap_enabled()) {
- d = Math::snapped(d, Node3DEditor::get_singleton()->get_translate_snap());
- }
-
- if (d < 0.001) {
- d = 0.001;
- }
-
- Vector3 h = s->get_size();
- h[p_id] = d * 2;
- s->set_size(h);
+ Vector3 size = s->get_size();
+ Vector3 position;
+ helper->box_set_handle(sg, p_id, size, position);
+ s->set_size(size);
+ s->set_global_position(position);
}
if (Object::cast_to<CSGCylinder3D>(cs)) {
@@ -225,17 +211,7 @@ void CSGShape3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int
}
if (Object::cast_to<CSGBox3D>(cs)) {
- CSGBox3D *s = Object::cast_to<CSGBox3D>(cs);
- if (p_cancel) {
- s->set_size(p_restore);
- return;
- }
-
- EditorUndoRedoManager *ur = EditorUndoRedoManager::get_singleton();
- ur->create_action(TTR("Change Box Shape Size"));
- ur->add_do_method(s, "set_size", s->get_size());
- ur->add_undo_method(s, "set_size", p_restore);
- ur->commit_action();
+ helper->box_commit_handle(TTR("Change Box Shape Size"), p_cancel, cs);
}
if (Object::cast_to<CSGCylinder3D>(cs)) {
@@ -394,15 +370,7 @@ void CSGShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
if (Object::cast_to<CSGBox3D>(cs)) {
CSGBox3D *s = Object::cast_to<CSGBox3D>(cs);
-
- Vector<Vector3> handles;
-
- for (int i = 0; i < 3; i++) {
- Vector3 h;
- h[i] = s->get_size()[i] / 2;
- handles.push_back(h);
- }
-
+ Vector<Vector3> handles = helper->box_get_handles(s->get_size());
p_gizmo->add_handles(handles, handles_material);
}
diff --git a/modules/csg/editor/csg_gizmos.h b/modules/csg/editor/csg_gizmos.h
index deac1d428d..6281db0a21 100644
--- a/modules/csg/editor/csg_gizmos.h
+++ b/modules/csg/editor/csg_gizmos.h
@@ -38,9 +38,13 @@
#include "editor/editor_plugin.h"
#include "editor/plugins/node_3d_editor_gizmos.h"
+class Gizmo3DHelper;
+
class CSGShape3DGizmoPlugin : public EditorNode3DGizmoPlugin {
GDCLASS(CSGShape3DGizmoPlugin, EditorNode3DGizmoPlugin);
+ Ref<Gizmo3DHelper> helper;
+
public:
virtual bool has_gizmo(Node3D *p_spatial) override;
virtual String get_gizmo_name() const override;
@@ -50,10 +54,12 @@ public:
virtual String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const override;
virtual Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const override;
+ void begin_handle_action(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) override;
virtual void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) override;
virtual void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel) override;
CSGShape3DGizmoPlugin();
+ ~CSGShape3DGizmoPlugin();
};
class EditorPluginCSG : public EditorPlugin {
diff --git a/modules/gdscript/editor/gdscript_translation_parser_plugin.cpp b/modules/gdscript/editor/gdscript_translation_parser_plugin.cpp
index 064143f400..becc2876f9 100644
--- a/modules/gdscript/editor/gdscript_translation_parser_plugin.cpp
+++ b/modules/gdscript/editor/gdscript_translation_parser_plugin.cpp
@@ -225,10 +225,15 @@ void GDScriptEditorTranslationParserPlugin::_assess_assignment(const GDScriptPar
if (p_assignment->assignee->type == GDScriptParser::Node::IDENTIFIER) {
assignee_name = static_cast<const GDScriptParser::IdentifierNode *>(p_assignment->assignee)->name;
} else if (p_assignment->assignee->type == GDScriptParser::Node::SUBSCRIPT) {
- assignee_name = static_cast<const GDScriptParser::SubscriptNode *>(p_assignment->assignee)->attribute->name;
+ const GDScriptParser::SubscriptNode *subscript = static_cast<const GDScriptParser::SubscriptNode *>(p_assignment->assignee);
+ if (subscript->is_attribute && subscript->attribute) {
+ assignee_name = subscript->attribute->name;
+ } else if (subscript->index && _is_constant_string(subscript->index)) {
+ assignee_name = subscript->index->reduced_value;
+ }
}
- if (assignment_patterns.has(assignee_name) && _is_constant_string(p_assignment->assigned_value)) {
+ if (assignee_name != StringName() && assignment_patterns.has(assignee_name) && _is_constant_string(p_assignment->assigned_value)) {
// If the assignment is towards one of the extract patterns (text, tooltip_text etc.), and the value is a constant string, we collect the string.
ids->push_back(p_assignment->assigned_value->reduced_value);
} else if (assignee_name == fd_filters && p_assignment->assigned_value->type == GDScriptParser::Node::CALL) {
@@ -236,7 +241,7 @@ void GDScriptEditorTranslationParserPlugin::_assess_assignment(const GDScriptPar
// get_node("FileDialog").filters = PackedStringArray(["*.png ; PNG Images","*.gd ; GDScript Files"]).
const GDScriptParser::CallNode *call_node = static_cast<const GDScriptParser::CallNode *>(p_assignment->assigned_value);
- if (call_node->arguments[0]->type == GDScriptParser::Node::ARRAY) {
+ if (!call_node->arguments.is_empty() && call_node->arguments[0]->type == GDScriptParser::Node::ARRAY) {
const GDScriptParser::ArrayNode *array_node = static_cast<const GDScriptParser::ArrayNode *>(call_node->arguments[0]);
// Extract the name in "extension ; name" of PackedStringArray.
diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp
index 7b3d31f4a8..42be231424 100644
--- a/modules/gdscript/gdscript_analyzer.cpp
+++ b/modules/gdscript/gdscript_analyzer.cpp
@@ -2142,15 +2142,7 @@ void GDScriptAnalyzer::resolve_for(GDScriptParser::ForNode *p_for) {
}
} else if (!is_type_compatible(specified_type, variable_type)) {
p_for->use_conversion_assign = true;
-#ifdef DEBUG_ENABLED
- } else {
- parser->push_warning(p_for->datatype_specifier, GDScriptWarning::REDUNDANT_FOR_VARIABLE_TYPE, p_for->variable->name, variable_type.to_string(), specified_type.to_string());
-#endif
}
-#ifdef DEBUG_ENABLED
- } else if (variable_type.is_hard_type()) {
- parser->push_warning(p_for->datatype_specifier, GDScriptWarning::REDUNDANT_FOR_VARIABLE_TYPE, p_for->variable->name, variable_type.to_string(), specified_type.to_string());
-#endif
}
p_for->variable->set_datatype(specified_type);
} else {
diff --git a/modules/gdscript/gdscript_warning.cpp b/modules/gdscript/gdscript_warning.cpp
index fcc6ea34de..ef2913926c 100644
--- a/modules/gdscript/gdscript_warning.cpp
+++ b/modules/gdscript/gdscript_warning.cpp
@@ -119,14 +119,6 @@ String GDScriptWarning::get_message() const {
return R"(The "@static_unload" annotation is redundant because the file does not have a class with static variables.)";
case REDUNDANT_AWAIT:
return R"("await" keyword not needed in this case, because the expression isn't a coroutine nor a signal.)";
- case REDUNDANT_FOR_VARIABLE_TYPE:
- CHECK_SYMBOLS(3);
- if (symbols[1] == symbols[2]) {
- return vformat(R"(The for loop iterator "%s" already has inferred type "%s", the specified type is redundant.)", symbols[0], symbols[1]);
- } else {
- return vformat(R"(The for loop iterator "%s" has inferred type "%s" but its supertype "%s" is specified.)", symbols[0], symbols[1], symbols[2]);
- }
- break;
case ASSERT_ALWAYS_TRUE:
return "Assert statement is redundant because the expression is always true.";
case ASSERT_ALWAYS_FALSE:
@@ -224,7 +216,6 @@ String GDScriptWarning::get_name_from_code(Code p_code) {
"STATIC_CALLED_ON_INSTANCE",
"REDUNDANT_STATIC_UNLOAD",
"REDUNDANT_AWAIT",
- "REDUNDANT_FOR_VARIABLE_TYPE",
"ASSERT_ALWAYS_TRUE",
"ASSERT_ALWAYS_FALSE",
"INTEGER_DIVISION",
diff --git a/modules/gdscript/gdscript_warning.h b/modules/gdscript/gdscript_warning.h
index a26cfaf72c..2b17709338 100644
--- a/modules/gdscript/gdscript_warning.h
+++ b/modules/gdscript/gdscript_warning.h
@@ -74,7 +74,6 @@ public:
STATIC_CALLED_ON_INSTANCE, // A static method was called on an instance of a class instead of on the class itself.
REDUNDANT_STATIC_UNLOAD, // The `@static_unload` annotation is used but the class does not have static data.
REDUNDANT_AWAIT, // await is used but expression is synchronous (not a signal nor a coroutine).
- REDUNDANT_FOR_VARIABLE_TYPE, // The for variable type specifier is a supertype of the inferred type.
ASSERT_ALWAYS_TRUE, // Expression for assert argument is always true.
ASSERT_ALWAYS_FALSE, // Expression for assert argument is always false.
INTEGER_DIVISION, // Integer divide by integer, decimal part is discarded.
@@ -123,7 +122,6 @@ public:
WARN, // STATIC_CALLED_ON_INSTANCE
WARN, // REDUNDANT_STATIC_UNLOAD
WARN, // REDUNDANT_AWAIT
- WARN, // REDUNDANT_FOR_VARIABLE_TYPE
WARN, // ASSERT_ALWAYS_TRUE
WARN, // ASSERT_ALWAYS_FALSE
WARN, // INTEGER_DIVISION
diff --git a/modules/gdscript/language_server/gdscript_extend_parser.cpp b/modules/gdscript/language_server/gdscript_extend_parser.cpp
index 362f253a99..36806d2f73 100644
--- a/modules/gdscript/language_server/gdscript_extend_parser.cpp
+++ b/modules/gdscript/language_server/gdscript_extend_parser.cpp
@@ -972,7 +972,7 @@ Dictionary ExtendGDScriptParser::dump_class_api(const GDScriptParser::ClassNode
api["name"] = m.signal->identifier->name;
Array pars;
for (int j = 0; j < m.signal->parameters.size(); j++) {
- pars.append(String(m.signal->parameters[i]->identifier->name));
+ pars.append(String(m.signal->parameters[j]->identifier->name));
}
api["arguments"] = pars;
if (const lsp::DocumentSymbol *symbol = get_symbol_defined_at_line(LINE_NUMBER_TO_INDEX(m.signal->start_line))) {
diff --git a/modules/gdscript/tests/scripts/analyzer/warnings/for_loop_specified_type_is_equal_to_inferred.gd b/modules/gdscript/tests/scripts/analyzer/warnings/for_loop_specified_type_is_equal_to_inferred.gd
deleted file mode 100644
index 1b32491e48..0000000000
--- a/modules/gdscript/tests/scripts/analyzer/warnings/for_loop_specified_type_is_equal_to_inferred.gd
+++ /dev/null
@@ -1,4 +0,0 @@
-func test():
- var a: Array[Node] = []
- for node: Node in a:
- print(node)
diff --git a/modules/gdscript/tests/scripts/analyzer/warnings/for_loop_specified_type_is_equal_to_inferred.out b/modules/gdscript/tests/scripts/analyzer/warnings/for_loop_specified_type_is_equal_to_inferred.out
deleted file mode 100644
index 3b3fbd9bd1..0000000000
--- a/modules/gdscript/tests/scripts/analyzer/warnings/for_loop_specified_type_is_equal_to_inferred.out
+++ /dev/null
@@ -1,5 +0,0 @@
-GDTEST_OK
->> WARNING
->> Line: 3
->> REDUNDANT_FOR_VARIABLE_TYPE
->> The for loop iterator "node" already has inferred type "Node", the specified type is redundant.
diff --git a/modules/gdscript/tests/scripts/analyzer/warnings/for_loop_specified_type_is_supertype_of_inferred.gd b/modules/gdscript/tests/scripts/analyzer/warnings/for_loop_specified_type_is_supertype_of_inferred.gd
deleted file mode 100644
index fcbc13c53d..0000000000
--- a/modules/gdscript/tests/scripts/analyzer/warnings/for_loop_specified_type_is_supertype_of_inferred.gd
+++ /dev/null
@@ -1,4 +0,0 @@
-func test():
- var a: Array[Node2D] = []
- for node: Node in a:
- print(node)
diff --git a/modules/gdscript/tests/scripts/analyzer/warnings/for_loop_specified_type_is_supertype_of_inferred.out b/modules/gdscript/tests/scripts/analyzer/warnings/for_loop_specified_type_is_supertype_of_inferred.out
deleted file mode 100644
index 36d4a161d3..0000000000
--- a/modules/gdscript/tests/scripts/analyzer/warnings/for_loop_specified_type_is_supertype_of_inferred.out
+++ /dev/null
@@ -1,5 +0,0 @@
-GDTEST_OK
->> WARNING
->> Line: 3
->> REDUNDANT_FOR_VARIABLE_TYPE
->> The for loop iterator "node" has inferred type "Node2D" but its supertype "Node" is specified.
diff --git a/modules/gridmap/editor/grid_map_editor_plugin.cpp b/modules/gridmap/editor/grid_map_editor_plugin.cpp
index f96cc86142..6a20768583 100644
--- a/modules/gridmap/editor/grid_map_editor_plugin.cpp
+++ b/modules/gridmap/editor/grid_map_editor_plugin.cpp
@@ -749,6 +749,7 @@ EditorPlugin::AfterGUIInput GridMapEditor::forward_spatial_input_event(Camera3D
for (int i = 0; i < options->get_popup()->get_item_count(); ++i) {
const Ref<Shortcut> &shortcut = options->get_popup()->get_item_shortcut(i);
if (shortcut.is_valid() && shortcut->matches_event(p_event)) {
+ accept_event();
_menu_option(options->get_popup()->get_item_id(i));
return EditorPlugin::AFTER_GUI_INPUT_STOP;
}
diff --git a/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs b/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs
index f01fbbd1b9..1c1185d91b 100644
--- a/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs
@@ -499,7 +499,7 @@ namespace GodotTools
_toolBarBuildButton = new Button
{
Flat = true,
- Icon = editorBaseControl.GetThemeIcon("BuildCSharp", "EditorIcons"),
+ Icon = EditorInterface.Singleton.GetEditorTheme().GetIcon("BuildCSharp", "EditorIcons"),
FocusMode = Control.FocusModeEnum.None,
Shortcut = EditorDefShortcut("mono/build_solution", "Build Project".TTR(), (Key)KeyModifierMask.MaskAlt | Key.B),
ShortcutInTooltip = true,
diff --git a/modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathManager.cs b/modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathManager.cs
index fbbd01dafd..a0ab381b9b 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathManager.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathManager.cs
@@ -5,10 +5,14 @@ using Godot;
using GodotTools.Internals;
using JetBrains.Rider.PathLocator;
+#nullable enable
+
namespace GodotTools.Ides.Rider
{
public static class RiderPathManager
{
+ private const string EditorPathSettingName = "dotnet/editor/editor_path_optional";
+
private static readonly RiderPathLocator RiderPathLocator;
private static readonly RiderFileOpener RiderFileOpener;
@@ -19,13 +23,14 @@ namespace GodotTools.Ides.Rider
RiderFileOpener = new RiderFileOpener(riderLocatorEnvironment);
}
- public static readonly string EditorPathSettingName = "dotnet/editor/editor_path_optional";
-
- private static string GetRiderPathFromSettings()
+ private static string? GetRiderPathFromSettings()
{
var editorSettings = EditorInterface.Singleton.GetEditorSettings();
if (editorSettings.HasSetting(EditorPathSettingName))
+ {
return (string)editorSettings.GetSetting(EditorPathSettingName);
+ }
+
return null;
}
@@ -37,7 +42,7 @@ namespace GodotTools.Ides.Rider
{
if (!editorSettings.HasSetting(EditorPathSettingName))
{
- Globals.EditorDef(EditorPathSettingName, "Optional");
+ Globals.EditorDef(EditorPathSettingName, "");
editorSettings.AddPropertyInfo(new Godot.Collections.Dictionary
{
["type"] = (int)Variant.Type.String,
@@ -55,9 +60,10 @@ namespace GodotTools.Ides.Rider
}
var paths = RiderPathLocator.GetAllRiderPaths();
-
- if (!paths.Any())
+ if (paths.Length == 0)
+ {
return;
+ }
string newPath = paths.Last().Path;
Globals.EditorDef(EditorPathSettingName, newPath);
@@ -67,18 +73,16 @@ namespace GodotTools.Ides.Rider
public static bool IsRider(string path)
{
- if (string.IsNullOrEmpty(path))
- return false;
-
if (path.IndexOfAny(Path.GetInvalidPathChars()) != -1)
+ {
return false;
+ }
var fileInfo = new FileInfo(path);
- string filename = fileInfo.Name.ToLowerInvariant();
- return filename.StartsWith("rider", StringComparison.Ordinal);
+ return fileInfo.Name.StartsWith("rider", StringComparison.OrdinalIgnoreCase);
}
- private static string CheckAndUpdatePath(string riderPath)
+ private static string? CheckAndUpdatePath(string? riderPath)
{
if (File.Exists(riderPath))
{
@@ -87,11 +91,14 @@ namespace GodotTools.Ides.Rider
var allInfos = RiderPathLocator.GetAllRiderPaths();
if (allInfos.Length == 0)
+ {
return null;
- var riderInfos = allInfos.Where(info => IsRider(info.Path)).ToArray();
- string newPath = riderInfos.Length > 0
- ? riderInfos[riderInfos.Length - 1].Path
- : allInfos[allInfos.Length - 1].Path;
+ }
+
+ // RiderPathLocator includes Rider and Fleet locations, prefer Rider when available.
+ var preferredInfo = allInfos.LastOrDefault(info => IsRider(info.Path), allInfos[allInfos.Length - 1]);
+ string newPath = preferredInfo.Path;
+
var editorSettings = EditorInterface.Singleton.GetEditorSettings();
editorSettings.SetSetting(EditorPathSettingName, newPath);
Globals.EditorDef(EditorPathSettingName, newPath);
@@ -100,8 +107,14 @@ namespace GodotTools.Ides.Rider
public static void OpenFile(string slnPath, string scriptPath, int line, int column)
{
- string pathFromSettings = GetRiderPathFromSettings();
- string path = CheckAndUpdatePath(pathFromSettings);
+ string? pathFromSettings = GetRiderPathFromSettings();
+ string? path = CheckAndUpdatePath(pathFromSettings);
+ if (string.IsNullOrEmpty(path))
+ {
+ GD.PushError($"Error when trying to run code editor: JetBrains Rider or Fleet. Could not find path to the editor.");
+ return;
+ }
+
RiderFileOpener.OpenFile(path, slnPath, scriptPath, line, column);
}
}
diff --git a/modules/multiplayer/editor/replication_editor.cpp b/modules/multiplayer/editor/replication_editor.cpp
index 0051d82e99..1c7546436b 100644
--- a/modules/multiplayer/editor/replication_editor.cpp
+++ b/modules/multiplayer/editor/replication_editor.cpp
@@ -359,7 +359,7 @@ void ReplicationEditor::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE:
case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
- add_theme_style_override("panel", EditorNode::get_singleton()->get_gui_base()->get_theme_stylebox(SNAME("panel"), SNAME("Panel")));
+ add_theme_style_override("panel", EditorNode::get_singleton()->get_editor_theme()->get_stylebox(SNAME("panel"), SNAME("Panel")));
add_pick_button->set_icon(get_theme_icon(SNAME("Add"), EditorStringName(EditorIcons)));
pin->set_icon(get_theme_icon(SNAME("Pin"), EditorStringName(EditorIcons)));
} break;
diff --git a/modules/openxr/openxr_api.cpp b/modules/openxr/openxr_api.cpp
index a66afee1c5..32abc0a1c7 100644
--- a/modules/openxr/openxr_api.cpp
+++ b/modules/openxr/openxr_api.cpp
@@ -481,11 +481,19 @@ bool OpenXRAPI::load_supported_view_configuration_types() {
result = xrEnumerateViewConfigurations(instance, system_id, num_view_configuration_types, &num_view_configuration_types, supported_view_configuration_types);
ERR_FAIL_COND_V_MSG(XR_FAILED(result), false, "OpenXR: Failed to enumerateview configurations");
+ ERR_FAIL_COND_V_MSG(num_view_configuration_types == 0, false, "OpenXR: Failed to enumerateview configurations"); // JIC there should be at least 1!
for (uint32_t i = 0; i < num_view_configuration_types; i++) {
print_verbose(String("OpenXR: Found supported view configuration ") + OpenXRUtil::get_view_configuration_name(supported_view_configuration_types[i]));
}
+ // Check value we loaded at startup...
+ if (!is_view_configuration_supported(view_configuration)) {
+ print_verbose(String("OpenXR: ") + OpenXRUtil::get_view_configuration_name(view_configuration) + String(" isn't supported, defaulting to ") + OpenXRUtil::get_view_configuration_name(supported_view_configuration_types[0]));
+
+ view_configuration = supported_view_configuration_types[0];
+ }
+
return true;
}
@@ -512,11 +520,19 @@ bool OpenXRAPI::load_supported_environmental_blend_modes() {
result = xrEnumerateEnvironmentBlendModes(instance, system_id, view_configuration, num_supported_environment_blend_modes, &num_supported_environment_blend_modes, supported_environment_blend_modes);
ERR_FAIL_COND_V_MSG(XR_FAILED(result), false, "OpenXR: Failed to enumerate environmental blend modes");
+ ERR_FAIL_COND_V_MSG(num_supported_environment_blend_modes == 0, false, "OpenXR: Failed to enumerate environmental blend modes"); // JIC there should be at least 1!
for (uint32_t i = 0; i < num_supported_environment_blend_modes; i++) {
print_verbose(String("OpenXR: Found environmental blend mode ") + OpenXRUtil::get_environment_blend_mode_name(supported_environment_blend_modes[i]));
}
+ // Check value we loaded at startup...
+ if (!is_environment_blend_mode_supported(environment_blend_mode)) {
+ print_verbose(String("OpenXR: ") + OpenXRUtil::get_environment_blend_mode_name(environment_blend_mode) + String(" isn't supported, defaulting to ") + OpenXRUtil::get_environment_blend_mode_name(supported_environment_blend_modes[0]));
+
+ environment_blend_mode = supported_environment_blend_modes[0];
+ }
+
return true;
}
@@ -665,11 +681,19 @@ bool OpenXRAPI::load_supported_reference_spaces() {
result = xrEnumerateReferenceSpaces(session, num_reference_spaces, &num_reference_spaces, supported_reference_spaces);
ERR_FAIL_COND_V_MSG(XR_FAILED(result), false, "OpenXR: Failed to enumerate reference spaces");
+ ERR_FAIL_COND_V_MSG(num_reference_spaces == 0, false, "OpenXR: Failed to enumerate reference spaces");
for (uint32_t i = 0; i < num_reference_spaces; i++) {
print_verbose(String("OpenXR: Found supported reference space ") + OpenXRUtil::get_reference_space_name(supported_reference_spaces[i]));
}
+ // Check value we loaded at startup...
+ if (!is_reference_space_supported(reference_space)) {
+ print_verbose(String("OpenXR: ") + OpenXRUtil::get_reference_space_name(reference_space) + String(" isn't supported, defaulting to ") + OpenXRUtil::get_reference_space_name(supported_reference_spaces[0]));
+
+ reference_space = supported_reference_spaces[0];
+ }
+
return true;
}
@@ -1434,7 +1458,9 @@ Size2 OpenXRAPI::get_recommended_target_size() {
XRPose::TrackingConfidence OpenXRAPI::get_head_center(Transform3D &r_transform, Vector3 &r_linear_velocity, Vector3 &r_angular_velocity) {
XrResult result;
- ERR_FAIL_COND_V(!running, XRPose::XR_TRACKING_CONFIDENCE_NONE);
+ if (!running) {
+ return XRPose::XR_TRACKING_CONFIDENCE_NONE;
+ }
// xrWaitFrame not run yet
if (frame_state.predictedDisplayTime == 0) {
@@ -1487,7 +1513,9 @@ XRPose::TrackingConfidence OpenXRAPI::get_head_center(Transform3D &r_transform,
}
bool OpenXRAPI::get_view_transform(uint32_t p_view, Transform3D &r_transform) {
- ERR_FAIL_COND_V(!running, false);
+ if (!running) {
+ return false;
+ }
// xrWaitFrame not run yet
if (frame_state.predictedDisplayTime == 0) {
@@ -1506,9 +1534,12 @@ bool OpenXRAPI::get_view_transform(uint32_t p_view, Transform3D &r_transform) {
}
bool OpenXRAPI::get_view_projection(uint32_t p_view, double p_z_near, double p_z_far, Projection &p_camera_matrix) {
- ERR_FAIL_COND_V(!running, false);
ERR_FAIL_NULL_V(graphics_extension, false);
+ if (!running) {
+ return false;
+ }
+
// xrWaitFrame not run yet
if (frame_state.predictedDisplayTime == 0) {
return false;
@@ -1917,10 +1948,15 @@ void OpenXRAPI::end_frame() {
}
}
+ XrCompositionLayerFlags layer_flags = XR_COMPOSITION_LAYER_CORRECT_CHROMATIC_ABERRATION_BIT;
+ if (layers_list.size() > 0 || environment_blend_mode != XR_ENVIRONMENT_BLEND_MODE_OPAQUE) {
+ layer_flags |= XR_COMPOSITION_LAYER_BLEND_TEXTURE_SOURCE_ALPHA_BIT;
+ }
+
XrCompositionLayerProjection projection_layer = {
XR_TYPE_COMPOSITION_LAYER_PROJECTION, // type
nullptr, // next
- layers_list.size() > 0 ? XR_COMPOSITION_LAYER_BLEND_TEXTURE_SOURCE_ALPHA_BIT | XR_COMPOSITION_LAYER_CORRECT_CHROMATIC_ABERRATION_BIT : XR_COMPOSITION_LAYER_CORRECT_CHROMATIC_ABERRATION_BIT, // layerFlags
+ layer_flags, // layerFlags
play_space, // space
view_count, // viewCount
projection_views, // views
@@ -1984,8 +2020,8 @@ OpenXRAPI::OpenXRAPI() {
} else {
// Load settings from project settings
- int ff = GLOBAL_GET("xr/openxr/form_factor");
- switch (ff) {
+ int form_factor_setting = GLOBAL_GET("xr/openxr/form_factor");
+ switch (form_factor_setting) {
case 0: {
form_factor = XR_FORM_FACTOR_HEAD_MOUNTED_DISPLAY;
} break;
@@ -1996,8 +2032,8 @@ OpenXRAPI::OpenXRAPI() {
break;
}
- int vc = GLOBAL_GET("xr/openxr/view_configuration");
- switch (vc) {
+ int view_configuration_setting = GLOBAL_GET("xr/openxr/view_configuration");
+ switch (view_configuration_setting) {
case 0: {
view_configuration = XR_VIEW_CONFIGURATION_TYPE_PRIMARY_MONO;
} break;
@@ -2016,8 +2052,8 @@ OpenXRAPI::OpenXRAPI() {
break;
}
- int rs = GLOBAL_GET("xr/openxr/reference_space");
- switch (rs) {
+ int reference_space_setting = GLOBAL_GET("xr/openxr/reference_space");
+ switch (reference_space_setting) {
case 0: {
reference_space = XR_REFERENCE_SPACE_TYPE_LOCAL;
} break;
@@ -2028,6 +2064,21 @@ OpenXRAPI::OpenXRAPI() {
break;
}
+ int environment_blend_mode_setting = GLOBAL_GET("xr/openxr/environment_blend_mode");
+ switch (environment_blend_mode_setting) {
+ case 0: {
+ environment_blend_mode = XR_ENVIRONMENT_BLEND_MODE_OPAQUE;
+ } break;
+ case 1: {
+ environment_blend_mode = XR_ENVIRONMENT_BLEND_MODE_ADDITIVE;
+ } break;
+ case 2: {
+ environment_blend_mode = XR_ENVIRONMENT_BLEND_MODE_ALPHA_BLEND;
+ } break;
+ default:
+ break;
+ }
+
submit_depth_buffer = GLOBAL_GET("xr/openxr/submit_depth_buffer");
}
@@ -2857,12 +2908,24 @@ const XrEnvironmentBlendMode *OpenXRAPI::get_supported_environment_blend_modes(u
return supported_environment_blend_modes;
}
-bool OpenXRAPI::set_environment_blend_mode(XrEnvironmentBlendMode mode) {
+bool OpenXRAPI::is_environment_blend_mode_supported(XrEnvironmentBlendMode p_blend_mode) const {
+ ERR_FAIL_NULL_V(supported_environment_blend_modes, false);
+
for (uint32_t i = 0; i < num_supported_environment_blend_modes; i++) {
- if (supported_environment_blend_modes[i] == mode) {
- environment_blend_mode = mode;
+ if (supported_environment_blend_modes[i] == p_blend_mode) {
return true;
}
}
+
+ return false;
+}
+
+bool OpenXRAPI::set_environment_blend_mode(XrEnvironmentBlendMode p_blend_mode) {
+ // We allow setting this when not initialised and will check if it is supported when initialising.
+ // After OpenXR is initialised we verify we're setting a supported blend mode.
+ if (!is_initialized() || is_environment_blend_mode_supported(p_blend_mode)) {
+ environment_blend_mode = p_blend_mode;
+ return true;
+ }
return false;
}
diff --git a/modules/openxr/openxr_api.h b/modules/openxr/openxr_api.h
index 6d1c731e7a..26de535153 100644
--- a/modules/openxr/openxr_api.h
+++ b/modules/openxr/openxr_api.h
@@ -405,7 +405,9 @@ public:
void unregister_composition_layer_provider(OpenXRCompositionLayerProvider *provider);
const XrEnvironmentBlendMode *get_supported_environment_blend_modes(uint32_t &count);
- bool set_environment_blend_mode(XrEnvironmentBlendMode mode);
+ bool is_environment_blend_mode_supported(XrEnvironmentBlendMode p_blend_mode) const;
+ bool set_environment_blend_mode(XrEnvironmentBlendMode p_blend_mode);
+ XrEnvironmentBlendMode get_environment_blend_mode() const { return environment_blend_mode; }
OpenXRAPI();
~OpenXRAPI();
diff --git a/modules/openxr/openxr_interface.cpp b/modules/openxr/openxr_interface.cpp
index 4dda51147b..cf8d1654b1 100644
--- a/modules/openxr/openxr_interface.cpp
+++ b/modules/openxr/openxr_interface.cpp
@@ -985,6 +985,27 @@ Array OpenXRInterface::get_supported_environment_blend_modes() {
return modes;
}
+XRInterface::EnvironmentBlendMode OpenXRInterface::get_environment_blend_mode() const {
+ if (openxr_api) {
+ XrEnvironmentBlendMode oxr_blend_mode = openxr_api->get_environment_blend_mode();
+ switch (oxr_blend_mode) {
+ case XR_ENVIRONMENT_BLEND_MODE_OPAQUE: {
+ return XR_ENV_BLEND_MODE_OPAQUE;
+ } break;
+ case XR_ENVIRONMENT_BLEND_MODE_ADDITIVE: {
+ return XR_ENV_BLEND_MODE_ADDITIVE;
+ } break;
+ case XR_ENVIRONMENT_BLEND_MODE_ALPHA_BLEND: {
+ return XR_ENV_BLEND_MODE_ALPHA_BLEND;
+ } break;
+ default:
+ break;
+ }
+ }
+
+ return XR_ENV_BLEND_MODE_OPAQUE;
+}
+
bool OpenXRInterface::set_environment_blend_mode(XRInterface::EnvironmentBlendMode mode) {
if (openxr_api) {
XrEnvironmentBlendMode oxr_blend_mode;
diff --git a/modules/openxr/openxr_interface.h b/modules/openxr/openxr_interface.h
index 09e1c31728..81efbd6777 100644
--- a/modules/openxr/openxr_interface.h
+++ b/modules/openxr/openxr_interface.h
@@ -152,6 +152,7 @@ public:
/** environment blend mode. */
virtual Array get_supported_environment_blend_modes() override;
+ virtual XRInterface::EnvironmentBlendMode get_environment_blend_mode() const override;
virtual bool set_environment_blend_mode(XRInterface::EnvironmentBlendMode mode) override;
void on_state_ready();
diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java
index a7064dfc1d..3070a8a207 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java
@@ -33,6 +33,7 @@ package org.godotengine.godot.input;
import org.godotengine.godot.*;
import android.content.Context;
+import android.content.res.Configuration;
import android.os.Handler;
import android.os.Message;
import android.text.InputFilter;
@@ -209,6 +210,13 @@ public class GodotEditText extends EditText {
mRenderView.getView().requestFocus();
}
+ // When a hardware keyboard is connected, all key events come through so we can route them
+ // directly to the engine.
+ // This is not the case when using a soft keyboard, requiring extra processing from this class.
+ if (hasHardwareKeyboard()) {
+ return mRenderView.getInputHandler().onKeyDown(keyCode, keyEvent);
+ }
+
// pass event to godot in special cases
if (needHandlingInGodot(keyCode, keyEvent) && mRenderView.getInputHandler().onKeyDown(keyCode, keyEvent)) {
return true;
@@ -219,6 +227,13 @@ public class GodotEditText extends EditText {
@Override
public boolean onKeyUp(int keyCode, KeyEvent keyEvent) {
+ // When a hardware keyboard is connected, all key events come through so we can route them
+ // directly to the engine.
+ // This is not the case when using a soft keyboard, requiring extra processing from this class.
+ if (hasHardwareKeyboard()) {
+ return mRenderView.getInputHandler().onKeyUp(keyCode, keyEvent);
+ }
+
if (needHandlingInGodot(keyCode, keyEvent) && mRenderView.getInputHandler().onKeyUp(keyCode, keyEvent)) {
return true;
} else {
@@ -235,10 +250,20 @@ public class GodotEditText extends EditText {
isModifiedKey;
}
+ boolean hasHardwareKeyboard() {
+ Configuration config = getResources().getConfiguration();
+ return config.keyboard != Configuration.KEYBOARD_NOKEYS &&
+ config.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO;
+ }
+
// ===========================================================
// Methods
// ===========================================================
public void showKeyboard(String p_existing_text, VirtualKeyboardType p_type, int p_max_input_length, int p_cursor_start, int p_cursor_end) {
+ if (hasHardwareKeyboard()) {
+ return;
+ }
+
int maxInputLength = (p_max_input_length <= 0) ? Integer.MAX_VALUE : p_max_input_length;
if (p_cursor_start == -1) { // cursor position not given
this.mOriginText = p_existing_text;
@@ -262,6 +287,10 @@ public class GodotEditText extends EditText {
}
public void hideKeyboard() {
+ if (hasHardwareKeyboard()) {
+ return;
+ }
+
final Message msg = new Message();
msg.what = HANDLER_CLOSE_IME_KEYBOARD;
msg.obj = this;
diff --git a/scene/gui/code_edit.cpp b/scene/gui/code_edit.cpp
index f74d7fb906..6ef8eacfd0 100644
--- a/scene/gui/code_edit.cpp
+++ b/scene/gui/code_edit.cpp
@@ -2399,6 +2399,19 @@ void CodeEdit::set_symbol_lookup_word_as_valid(bool p_valid) {
}
}
+/* Visual */
+Color CodeEdit::_get_brace_mismatch_color() const {
+ return theme_cache.brace_mismatch_color;
+}
+
+Color CodeEdit::_get_code_folding_color() const {
+ return theme_cache.code_folding_color;
+}
+
+Ref<Texture2D> CodeEdit::_get_folded_eol_icon() const {
+ return theme_cache.folded_eol_icon;
+}
+
void CodeEdit::_bind_methods() {
/* Indent management */
ClassDB::bind_method(D_METHOD("set_indent_size", "size"), &CodeEdit::set_indent_size);
@@ -2644,7 +2657,7 @@ void CodeEdit::_bind_methods() {
BIND_THEME_ITEM(Theme::DATA_TYPE_ICON, CodeEdit, folded_eol_icon);
BIND_THEME_ITEM(Theme::DATA_TYPE_COLOR, CodeEdit, breakpoint_color);
- BIND_THEME_ITEM_CUSTOM(Theme::DATA_TYPE_COLOR, CodeEdit, breakpoint_icon, "breakpoint");
+ BIND_THEME_ITEM_CUSTOM(Theme::DATA_TYPE_ICON, CodeEdit, breakpoint_icon, "breakpoint");
BIND_THEME_ITEM(Theme::DATA_TYPE_COLOR, CodeEdit, bookmark_color);
BIND_THEME_ITEM_CUSTOM(Theme::DATA_TYPE_ICON, CodeEdit, bookmark_icon, "bookmark");
@@ -2677,6 +2690,8 @@ void CodeEdit::_bind_methods() {
/* Other visuals */
BIND_THEME_ITEM_CUSTOM(Theme::DATA_TYPE_STYLEBOX, CodeEdit, style_normal, "normal");
+ BIND_THEME_ITEM(Theme::DATA_TYPE_COLOR, CodeEdit, brace_mismatch_color);
+
BIND_THEME_ITEM(Theme::DATA_TYPE_FONT, CodeEdit, font);
BIND_THEME_ITEM(Theme::DATA_TYPE_FONT_SIZE, CodeEdit, font_size);
diff --git a/scene/gui/code_edit.h b/scene/gui/code_edit.h
index 53ff65f376..e688af2bda 100644
--- a/scene/gui/code_edit.h
+++ b/scene/gui/code_edit.h
@@ -278,11 +278,17 @@ private:
/* Other visuals */
Ref<StyleBox> style_normal;
+ Color brace_mismatch_color;
+
Ref<Font> font;
int font_size = 16;
int line_spacing = 1;
} theme_cache;
+ virtual Color _get_brace_mismatch_color() const override;
+ virtual Color _get_code_folding_color() const override;
+ virtual Ref<Texture2D> _get_folded_eol_icon() const override;
+
/* Callbacks */
int lines_edited_changed = 0;
int lines_edited_from = -1;
diff --git a/scene/gui/color_mode.cpp b/scene/gui/color_mode.cpp
index adea06eee7..7d068a101e 100644
--- a/scene/gui/color_mode.cpp
+++ b/scene/gui/color_mode.cpp
@@ -73,10 +73,10 @@ void ColorModeRGB::slider_draw(int p_which) {
Color left_color;
Color right_color;
Color color = color_picker->get_pick_color();
- const real_t margin = 16 * color_picker->get_theme_default_base_scale();
+ const real_t margin = 16 * color_picker->theme_cache.base_scale;
if (p_which == ColorPicker::SLIDER_COUNT) {
- slider->draw_texture_rect(color_picker->get_theme_icon(SNAME("sample_bg"), SNAME("ColorPicker")), Rect2(Point2(0, 0), Size2(size.x, margin)), true);
+ slider->draw_texture_rect(color_picker->theme_cache.sample_bg, Rect2(Point2(0, 0), Size2(size.x, margin)), true);
left_color = color;
left_color.a = 0;
@@ -168,10 +168,10 @@ void ColorModeHSV::slider_draw(int p_which) {
Color left_color;
Color right_color;
Color color = color_picker->get_pick_color();
- const real_t margin = 16 * color_picker->get_theme_default_base_scale();
+ const real_t margin = 16 * color_picker->theme_cache.base_scale;
if (p_which == ColorPicker::SLIDER_COUNT) {
- slider->draw_texture_rect(color_picker->get_theme_icon(SNAME("sample_bg"), SNAME("ColorPicker")), Rect2(Point2(0, 0), Size2(size.x, margin)), true);
+ slider->draw_texture_rect(color_picker->theme_cache.sample_bg, Rect2(Point2(0, 0), Size2(size.x, margin)), true);
left_color = color;
left_color.a = 0;
@@ -204,7 +204,7 @@ void ColorModeHSV::slider_draw(int p_which) {
slider->draw_polygon(pos, col);
if (p_which == 0) { // H
- Ref<Texture2D> hue = color_picker->get_theme_icon(SNAME("color_hue"), SNAME("ColorPicker"));
+ Ref<Texture2D> hue = color_picker->theme_cache.color_hue;
slider->draw_texture_rect(hue, Rect2(Vector2(), Vector2(size.x, margin)), false, Color::from_hsv(0, 0, color.get_v(), color.get_s()));
}
}
@@ -243,10 +243,10 @@ void ColorModeRAW::slider_draw(int p_which) {
Color left_color;
Color right_color;
Color color = color_picker->get_pick_color();
- const real_t margin = 16 * color_picker->get_theme_default_base_scale();
+ const real_t margin = 16 * color_picker->theme_cache.base_scale;
if (p_which == ColorPicker::SLIDER_COUNT) {
- slider->draw_texture_rect(color_picker->get_theme_icon(SNAME("sample_bg"), SNAME("ColorPicker")), Rect2(Point2(0, 0), Size2(size.x, margin)), true);
+ slider->draw_texture_rect(color_picker->theme_cache.sample_bg, Rect2(Point2(0, 0), Size2(size.x, margin)), true);
left_color = color;
left_color.a = 0;
@@ -334,7 +334,7 @@ Color ColorModeOKHSL::get_color() const {
void ColorModeOKHSL::slider_draw(int p_which) {
HSlider *slider = color_picker->get_slider(p_which);
Size2 size = slider->get_size();
- const real_t margin = 16 * color_picker->get_theme_default_base_scale();
+ const real_t margin = 16 * color_picker->theme_cache.base_scale;
Vector<Vector2> pos;
Vector<Color> col;
@@ -370,7 +370,7 @@ void ColorModeOKHSL::slider_draw(int p_which) {
col.resize(4);
if (p_which == ColorPicker::SLIDER_COUNT) {
- slider->draw_texture_rect(color_picker->get_theme_icon(SNAME("sample_bg"), SNAME("ColorPicker")), Rect2(Point2(0, 0), Size2(size.x, margin)), true);
+ slider->draw_texture_rect(color_picker->theme_cache.sample_bg, Rect2(Point2(0, 0), Size2(size.x, margin)), true);
left_color = color;
left_color.a = 0;
@@ -399,7 +399,7 @@ void ColorModeOKHSL::slider_draw(int p_which) {
slider->draw_polygon(pos, col);
if (p_which == 0) { // H
- Ref<Texture2D> hue = color_picker->get_theme_icon(SNAME("color_okhsl_hue"), SNAME("ColorPicker"));
+ Ref<Texture2D> hue = color_picker->theme_cache.color_okhsl_hue;
slider->draw_texture_rect(hue, Rect2(Vector2(), Vector2(size.x, margin)), false, Color::from_hsv(0, 0, color.get_ok_hsl_l() * 2.0, color.get_ok_hsl_s()));
return;
}
diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp
index d8342356d4..5ec0714b64 100644
--- a/scene/gui/color_picker.cpp
+++ b/scene/gui/color_picker.cpp
@@ -673,7 +673,7 @@ ColorPicker::PickerShapeType ColorPicker::get_picker_shape() const {
}
inline int ColorPicker::_get_preset_size() {
- return (int(get_minimum_size().width) - (preset_container->get_theme_constant(SNAME("h_separation")) * (PRESET_COLUMN_COUNT - 1))) / PRESET_COLUMN_COUNT;
+ return (int(get_minimum_size().width) - (preset_container->get_h_separation() * (PRESET_COLUMN_COUNT - 1))) / PRESET_COLUMN_COUNT;
}
void ColorPicker::_add_preset_button(int p_size, const Color &p_color) {
@@ -997,7 +997,7 @@ void ColorPicker::_sample_draw() {
const Rect2 rect_old = Rect2(Point2(), Size2(sample->get_size().width * 0.5, sample->get_size().height * 0.95));
if (old_color.a < 1.0) {
- sample->draw_texture_rect(theme_cache.sample_background_icon, rect_old, true);
+ sample->draw_texture_rect(theme_cache.sample_bg, rect_old, true);
}
sample->draw_rect(rect_old, old_color);
@@ -1011,7 +1011,7 @@ void ColorPicker::_sample_draw() {
}
if (color.a < 1.0) {
- sample->draw_texture_rect(theme_cache.sample_background_icon, rect_new, true);
+ sample->draw_texture_rect(theme_cache.sample_bg, rect_new, true);
}
sample->draw_rect(rect_new, color);
@@ -1125,7 +1125,7 @@ void ColorPicker::_hsv_draw(int p_which, Control *c) {
} else if (p_which == 1) {
if (actual_shape == SHAPE_HSV_RECTANGLE) {
c->draw_set_transform(Point2(), -Math_PI / 2, Size2(c->get_size().x, -c->get_size().y));
- c->draw_texture_rect(theme_cache.color_hue_icon, Rect2(Point2(), Size2(1, 1)));
+ c->draw_texture_rect(theme_cache.color_hue, Rect2(Point2(), Size2(1, 1)));
c->draw_set_transform(Point2(), 0, Size2(1, 1));
int y = c->get_size().y - c->get_size().y * (1.0 - h);
Color col;
@@ -1703,10 +1703,11 @@ void ColorPicker::_bind_methods() {
BIND_THEME_ITEM(Theme::DATA_TYPE_ICON, ColorPicker, shape_circle);
BIND_THEME_ITEM(Theme::DATA_TYPE_ICON, ColorPicker, bar_arrow);
- BIND_THEME_ITEM_CUSTOM(Theme::DATA_TYPE_ICON, ColorPicker, sample_background_icon, "sample_bg");
+ BIND_THEME_ITEM(Theme::DATA_TYPE_ICON, ColorPicker, sample_bg);
BIND_THEME_ITEM(Theme::DATA_TYPE_ICON, ColorPicker, overbright_indicator);
BIND_THEME_ITEM(Theme::DATA_TYPE_ICON, ColorPicker, picker_cursor);
- BIND_THEME_ITEM_CUSTOM(Theme::DATA_TYPE_ICON, ColorPicker, color_hue_icon, "color_hue");
+ BIND_THEME_ITEM(Theme::DATA_TYPE_ICON, ColorPicker, color_hue);
+ BIND_THEME_ITEM(Theme::DATA_TYPE_ICON, ColorPicker, color_okhsl_hue);
BIND_THEME_ITEM_EXT(Theme::DATA_TYPE_STYLEBOX, ColorPicker, mode_button_normal, "tab_unselected", "TabContainer");
BIND_THEME_ITEM_EXT(Theme::DATA_TYPE_STYLEBOX, ColorPicker, mode_button_pressed, "tab_selected", "TabContainer");
diff --git a/scene/gui/color_picker.h b/scene/gui/color_picker.h
index 12c7018149..96dbca9a0c 100644
--- a/scene/gui/color_picker.h
+++ b/scene/gui/color_picker.h
@@ -81,6 +81,12 @@ public:
class ColorPicker : public VBoxContainer {
GDCLASS(ColorPicker, VBoxContainer);
+ // These classes poke into theme items for their internal logic.
+ friend class ColorModeRGB;
+ friend class ColorModeHSV;
+ friend class ColorModeRAW;
+ friend class ColorModeOKHSL;
+
public:
enum ColorModeType {
MODE_RGB,
@@ -229,10 +235,11 @@ private:
Ref<Texture2D> shape_circle;
Ref<Texture2D> bar_arrow;
- Ref<Texture2D> sample_background_icon;
+ Ref<Texture2D> sample_bg;
Ref<Texture2D> overbright_indicator;
Ref<Texture2D> picker_cursor;
- Ref<Texture2D> color_hue_icon;
+ Ref<Texture2D> color_hue;
+ Ref<Texture2D> color_okhsl_hue;
/* Mode buttons */
Ref<StyleBox> mode_button_normal;
diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp
index be0ae45e7e..6b5e3486ac 100644
--- a/scene/gui/graph_edit.cpp
+++ b/scene/gui/graph_edit.cpp
@@ -38,6 +38,7 @@
#include "scene/gui/graph_edit_arranger.h"
#include "scene/gui/view_panner.h"
#include "scene/resources/style_box_flat.h"
+#include "scene/theme/theme_db.h"
constexpr int MINIMAP_OFFSET = 12;
constexpr int MINIMAP_PADDING = 5;
@@ -56,23 +57,8 @@ GraphEditFilter::GraphEditFilter(GraphEdit *p_edit) {
ge = p_edit;
}
-GraphEditMinimap::GraphEditMinimap(GraphEdit *p_edit) {
- ge = p_edit;
-
- graph_proportions = Vector2(1, 1);
- graph_padding = Vector2(0, 0);
- camera_position = Vector2(100, 50);
- camera_size = Vector2(200, 200);
- minimap_padding = Vector2(MINIMAP_PADDING, MINIMAP_PADDING);
- minimap_offset = minimap_padding + _convert_from_graph_position(graph_padding);
-
- is_pressing = false;
- is_resizing = false;
-}
-
Control::CursorShape GraphEditMinimap::get_cursor_shape(const Point2 &p_pos) const {
- Ref<Texture2D> resizer = get_theme_icon(SNAME("resizer"));
- if (is_resizing || (p_pos.x < resizer->get_width() && p_pos.y < resizer->get_height())) {
+ if (is_resizing || (p_pos.x < theme_cache.resizer->get_width() && p_pos.y < theme_cache.resizer->get_height())) {
return CURSOR_FDIAGSIZE;
}
@@ -172,8 +158,7 @@ void GraphEditMinimap::gui_input(const Ref<InputEvent> &p_ev) {
if (mb->is_pressed()) {
is_pressing = true;
- Ref<Texture2D> resizer = get_theme_icon(SNAME("resizer"));
- Rect2 resizer_hitbox = Rect2(Point2(), resizer->get_size());
+ Rect2 resizer_hitbox = Rect2(Point2(), theme_cache.resizer->get_size());
if (resizer_hitbox.has_point(mb->get_position())) {
is_resizing = true;
} else {
@@ -207,6 +192,21 @@ void GraphEditMinimap::_adjust_graph_scroll(const Vector2 &p_offset) {
ge->set_scroll_offset(p_offset + graph_offset - camera_size / 2);
}
+void GraphEditMinimap::_bind_methods() {
+ BIND_THEME_ITEM(Theme::DATA_TYPE_STYLEBOX, GraphEditMinimap, panel);
+ BIND_THEME_ITEM_CUSTOM(Theme::DATA_TYPE_STYLEBOX, GraphEditMinimap, node_style, "node");
+ BIND_THEME_ITEM_CUSTOM(Theme::DATA_TYPE_STYLEBOX, GraphEditMinimap, camera_style, "camera");
+ BIND_THEME_ITEM(Theme::DATA_TYPE_ICON, GraphEditMinimap, resizer);
+ BIND_THEME_ITEM(Theme::DATA_TYPE_COLOR, GraphEditMinimap, resizer_color);
+}
+
+GraphEditMinimap::GraphEditMinimap(GraphEdit *p_edit) {
+ ge = p_edit;
+
+ minimap_padding = Vector2(MINIMAP_PADDING, MINIMAP_PADDING);
+ minimap_offset = minimap_padding + _convert_from_graph_position(graph_padding);
+}
+
Control::CursorShape GraphEdit::get_cursor_shape(const Point2 &p_pos) const {
if (moving_selection) {
return CURSOR_MOVE;
@@ -493,22 +493,25 @@ void GraphEdit::remove_child_notify(Node *p_child) {
}
}
+void GraphEdit::_update_theme_item_cache() {
+ Control::_update_theme_item_cache();
+
+ theme_cache.base_scale = get_theme_default_base_scale();
+}
+
void GraphEdit::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_THEME_CHANGED: {
- port_hotzone_inner_extent = get_theme_constant("port_hotzone_inner_extent");
- port_hotzone_outer_extent = get_theme_constant("port_hotzone_outer_extent");
-
- zoom_minus_button->set_icon(get_theme_icon(SNAME("zoom_out")));
- zoom_reset_button->set_icon(get_theme_icon(SNAME("zoom_reset")));
- zoom_plus_button->set_icon(get_theme_icon(SNAME("zoom_in")));
+ zoom_minus_button->set_icon(theme_cache.zoom_out);
+ zoom_reset_button->set_icon(theme_cache.zoom_reset);
+ zoom_plus_button->set_icon(theme_cache.zoom_in);
- toggle_snapping_button->set_icon(get_theme_icon(SNAME("snapping_toggle")));
- show_grid_button->set_icon(get_theme_icon(SNAME("grid_toggle")));
- minimap_button->set_icon(get_theme_icon(SNAME("minimap_toggle")));
- layout_button->set_icon(get_theme_icon(SNAME("layout")));
+ toggle_snapping_button->set_icon(theme_cache.snapping_toggle);
+ show_grid_button->set_icon(theme_cache.grid_toggle);
+ minimap_button->set_icon(theme_cache.minimap_toggle);
+ layout_button->set_icon(theme_cache.layout);
- zoom_label->set_custom_minimum_size(Size2(48, 0) * get_theme_default_base_scale());
+ zoom_label->set_custom_minimum_size(Size2(48, 0) * theme_cache.base_scale);
} break;
case NOTIFICATION_READY: {
@@ -528,7 +531,7 @@ void GraphEdit::_notification(int p_what) {
case NOTIFICATION_DRAW: {
// Draw background fill.
- draw_style_box(get_theme_stylebox(SNAME("panel")), Rect2(Point2(), get_size()));
+ draw_style_box(theme_cache.panel, Rect2(Point2(), get_size()));
// Draw background grid.
if (show_grid) {
@@ -538,16 +541,13 @@ void GraphEdit::_notification(int p_what) {
Point2i from_pos = (offset / float(snapping_distance)).floor();
Point2i len = (size / float(snapping_distance)).floor() + Vector2(1, 1);
- Color grid_minor = get_theme_color(SNAME("grid_minor"));
- Color grid_major = get_theme_color(SNAME("grid_major"));
-
for (int i = from_pos.x; i < from_pos.x + len.x; i++) {
Color color;
if (ABS(i) % GRID_MINOR_STEPS_PER_MAJOR_LINE == 0) {
- color = grid_major;
+ color = theme_cache.grid_major;
} else {
- color = grid_minor;
+ color = theme_cache.grid_minor;
}
float base_offset = i * snapping_distance * zoom - offset.x * zoom;
@@ -558,9 +558,9 @@ void GraphEdit::_notification(int p_what) {
Color color;
if (ABS(i) % GRID_MINOR_STEPS_PER_MAJOR_LINE == 0) {
- color = grid_major;
+ color = theme_cache.grid_major;
} else {
- color = grid_minor;
+ color = theme_cache.grid_minor;
}
float base_offset = i * snapping_distance * zoom - offset.y * zoom;
@@ -578,14 +578,14 @@ void GraphEdit::_notification(int p_what) {
}
bool GraphEdit::_filter_input(const Point2 &p_point) {
- Ref<Texture2D> port_icon = get_theme_icon(SNAME("port"), SNAME("GraphNode"));
-
for (int i = get_child_count() - 1; i >= 0; i--) {
GraphNode *graph_node = Object::cast_to<GraphNode>(get_child(i));
if (!graph_node || !graph_node->is_visible_in_tree()) {
continue;
}
+ Ref<Texture2D> port_icon = graph_node->theme_cache.port;
+
for (int j = 0; j < graph_node->get_input_port_count(); j++) {
Vector2i port_size = Vector2i(port_icon->get_width(), port_icon->get_height());
@@ -620,8 +620,6 @@ bool GraphEdit::_filter_input(const Point2 &p_point) {
void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) {
Ref<InputEventMouseButton> mb = p_ev;
if (mb.is_valid() && mb->get_button_index() == MouseButton::LEFT && mb->is_pressed()) {
- Ref<Texture2D> port_icon = get_theme_icon(SNAME("port"), SNAME("GraphNode"));
-
connecting_valid = false;
click_pos = mb->get_position() / zoom;
for (int i = get_child_count() - 1; i >= 0; i--) {
@@ -630,6 +628,8 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) {
continue;
}
+ Ref<Texture2D> port_icon = graph_node->theme_cache.port;
+
for (int j = 0; j < graph_node->get_output_port_count(); j++) {
Vector2 pos = graph_node->get_output_port_position(j) * zoom + graph_node->get_position();
Vector2i port_size = Vector2i(port_icon->get_width(), port_icon->get_height());
@@ -756,12 +756,13 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) {
if (connecting_valid) {
Vector2 mpos = mm->get_position() / zoom;
for (int i = get_child_count() - 1; i >= 0; i--) {
- Ref<Texture2D> port_icon = get_theme_icon(SNAME("port"), SNAME("GraphNode"));
GraphNode *graph_node = Object::cast_to<GraphNode>(get_child(i));
if (!graph_node || !graph_node->is_visible_in_tree()) {
continue;
}
+ Ref<Texture2D> port_icon = graph_node->theme_cache.port;
+
if (!connecting_out) {
for (int j = 0; j < graph_node->get_output_port_count(); j++) {
Vector2 pos = graph_node->get_output_port_position(j) * zoom + graph_node->get_position();
@@ -774,7 +775,7 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) {
int type = graph_node->get_output_port_type(j);
if ((type == connecting_type ||
- valid_connection_types.has(ConnectionType(connecting_type, type))) &&
+ valid_connection_types.has(ConnectionType(type, connecting_type))) &&
is_in_output_hotzone(graph_node, j, mpos, port_size)) {
if (!is_node_hover_valid(graph_node->get_name(), j, connecting_from, connecting_index)) {
continue;
@@ -877,7 +878,7 @@ bool GraphEdit::is_in_input_hotzone(GraphNode *p_graph_node, int p_port_idx, con
bool GraphEdit::is_in_output_hotzone(GraphNode *p_graph_node, int p_port_idx, const Vector2 &p_mouse_pos, const Vector2i &p_port_size) {
if (p_graph_node->is_resizable()) {
- Ref<Texture2D> resizer = p_graph_node->get_theme_icon(SNAME("resizer"));
+ Ref<Texture2D> resizer = p_graph_node->theme_cache.resizer;
Rect2 resizer_rect = Rect2(p_graph_node->get_position() / zoom + p_graph_node->get_size() - resizer->get_size(), resizer->get_size());
if (resizer_rect.has_point(p_mouse_pos)) {
return false;
@@ -895,9 +896,9 @@ bool GraphEdit::is_in_output_hotzone(GraphNode *p_graph_node, int p_port_idx, co
bool GraphEdit::is_in_port_hotzone(const Vector2 &p_pos, const Vector2 &p_mouse_pos, const Vector2i &p_port_size, bool p_left) {
Rect2 hotzone = Rect2(
- p_pos.x - (p_left ? port_hotzone_outer_extent : port_hotzone_inner_extent),
+ p_pos.x - (p_left ? theme_cache.port_hotzone_outer_extent : theme_cache.port_hotzone_inner_extent),
p_pos.y - p_port_size.height / 2.0,
- port_hotzone_inner_extent + port_hotzone_outer_extent,
+ theme_cache.port_hotzone_inner_extent + theme_cache.port_hotzone_outer_extent,
p_port_size.height);
if (!hotzone.has_point(p_mouse_pos)) {
@@ -965,12 +966,10 @@ void GraphEdit::_draw_connection_line(CanvasItem *p_where, const Vector2 &p_from
}
// Thickness below 0.5 doesn't look good on the graph or its minimap.
- p_where->draw_polyline_colors(scaled_points, colors, MAX(0.5, Math::floor(p_width * get_theme_default_base_scale())), lines_antialiased);
+ p_where->draw_polyline_colors(scaled_points, colors, MAX(0.5, Math::floor(p_width * theme_cache.base_scale)), lines_antialiased);
}
void GraphEdit::_connections_layer_draw() {
- Color activity_color = get_theme_color(SNAME("activity"));
-
// Draw connections.
List<List<Connection>::Element *> to_erase;
for (List<Connection>::Element *E = connections.front(); E; E = E->next()) {
@@ -998,8 +997,8 @@ void GraphEdit::_connections_layer_draw() {
Color tocolor = gnode_to->get_input_port_color(c.to_port);
if (c.activity > 0) {
- color = color.lerp(activity_color, c.activity);
- tocolor = tocolor.lerp(activity_color, c.activity);
+ color = color.lerp(theme_cache.activity_color, c.activity);
+ tocolor = tocolor.lerp(theme_cache.activity_color, c.activity);
}
_draw_connection_line(connections_layer, frompos, topos, color, tocolor, lines_thickness, zoom);
}
@@ -1042,8 +1041,8 @@ void GraphEdit::_top_layer_draw() {
}
if (box_selecting) {
- top_layer->draw_rect(box_selecting_rect, get_theme_color(SNAME("selection_fill")));
- top_layer->draw_rect(box_selecting_rect, get_theme_color(SNAME("selection_stroke")), false);
+ top_layer->draw_rect(box_selecting_rect, theme_cache.selection_fill);
+ top_layer->draw_rect(box_selecting_rect, theme_cache.selection_stroke, false);
}
}
@@ -1056,7 +1055,7 @@ void GraphEdit::_minimap_draw() {
// Draw the minimap background.
Rect2 minimap_rect = Rect2(Point2(), minimap->get_size());
- minimap->draw_style_box(minimap->get_theme_stylebox(SNAME("panel")), minimap_rect);
+ minimap->draw_style_box(minimap->theme_cache.panel, minimap_rect);
Vector2 graph_offset = minimap->_get_graph_offset();
Vector2 minimap_offset = minimap->minimap_offset;
@@ -1072,10 +1071,10 @@ void GraphEdit::_minimap_draw() {
Vector2 node_size = minimap->_convert_from_graph_position(graph_node->get_size() * zoom);
Rect2 node_rect = Rect2(node_position, node_size);
- Ref<StyleBoxFlat> sb_minimap = minimap->get_theme_stylebox(SNAME("node"))->duplicate();
+ Ref<StyleBoxFlat> sb_minimap = minimap->theme_cache.node_style->duplicate();
// Override default values with colors provided by the GraphNode's stylebox, if possible.
- Ref<StyleBoxFlat> sb_frame = graph_node->get_theme_stylebox(graph_node->is_selected() ? "panel_selected" : "panel");
+ Ref<StyleBoxFlat> sb_frame = graph_node->is_selected() ? graph_node->theme_cache.panel_selected : graph_node->theme_cache.panel;
if (sb_frame.is_valid()) {
Color node_color = sb_frame->get_bg_color();
sb_minimap->set_bg_color(node_color);
@@ -1085,7 +1084,6 @@ void GraphEdit::_minimap_draw() {
}
// Draw node connections.
- Color activity_color = get_theme_color(SNAME("activity"));
for (const Connection &E : connections) {
Node *from = get_node(NodePath(E.from_node));
GraphNode *graph_node_from = Object::cast_to<GraphNode>(from);
@@ -1107,19 +1105,19 @@ void GraphEdit::_minimap_draw() {
Color to_color = graph_node_to->get_input_port_color(E.to_port);
if (E.activity > 0) {
- from_color = from_color.lerp(activity_color, E.activity);
- to_color = to_color.lerp(activity_color, E.activity);
+ from_color = from_color.lerp(theme_cache.activity_color, E.activity);
+ to_color = to_color.lerp(theme_cache.activity_color, E.activity);
}
_draw_connection_line(minimap, from_position, to_position, from_color, to_color, 0.5, minimap->_convert_from_graph_position(Vector2(zoom, zoom)).length());
}
// Draw the "camera" viewport.
Rect2 camera_rect = minimap->get_camera_rect();
- minimap->draw_style_box(minimap->get_theme_stylebox(SNAME("camera")), camera_rect);
+ minimap->draw_style_box(minimap->theme_cache.camera_style, camera_rect);
// Draw the resizer control.
- Ref<Texture2D> resizer = minimap->get_theme_icon(SNAME("resizer"));
- Color resizer_color = minimap->get_theme_color(SNAME("resizer_color"));
+ Ref<Texture2D> resizer = minimap->theme_cache.resizer;
+ Color resizer_color = minimap->theme_cache.resizer_color;
minimap->draw_texture(resizer, Point2(), resizer_color);
}
@@ -1909,6 +1907,26 @@ void GraphEdit::_bind_methods() {
BIND_ENUM_CONSTANT(SCROLL_ZOOMS);
BIND_ENUM_CONSTANT(SCROLL_PANS);
+
+ BIND_THEME_ITEM(Theme::DATA_TYPE_STYLEBOX, GraphEdit, panel);
+ BIND_THEME_ITEM(Theme::DATA_TYPE_COLOR, GraphEdit, grid_major);
+ BIND_THEME_ITEM(Theme::DATA_TYPE_COLOR, GraphEdit, grid_minor);
+
+ BIND_THEME_ITEM_CUSTOM(Theme::DATA_TYPE_COLOR, GraphEdit, activity_color, "activity");
+ BIND_THEME_ITEM(Theme::DATA_TYPE_COLOR, GraphEdit, selection_fill);
+ BIND_THEME_ITEM(Theme::DATA_TYPE_COLOR, GraphEdit, selection_stroke);
+
+ BIND_THEME_ITEM(Theme::DATA_TYPE_ICON, GraphEdit, zoom_in);
+ BIND_THEME_ITEM(Theme::DATA_TYPE_ICON, GraphEdit, zoom_out);
+ BIND_THEME_ITEM(Theme::DATA_TYPE_ICON, GraphEdit, zoom_reset);
+
+ BIND_THEME_ITEM(Theme::DATA_TYPE_ICON, GraphEdit, snapping_toggle);
+ BIND_THEME_ITEM(Theme::DATA_TYPE_ICON, GraphEdit, grid_toggle);
+ BIND_THEME_ITEM(Theme::DATA_TYPE_ICON, GraphEdit, minimap_toggle);
+ BIND_THEME_ITEM(Theme::DATA_TYPE_ICON, GraphEdit, layout);
+
+ BIND_THEME_ITEM(Theme::DATA_TYPE_CONSTANT, GraphEdit, port_hotzone_inner_extent);
+ BIND_THEME_ITEM(Theme::DATA_TYPE_CONSTANT, GraphEdit, port_hotzone_outer_extent);
}
GraphEdit::GraphEdit() {
diff --git a/scene/gui/graph_edit.h b/scene/gui/graph_edit.h
index 5e97ea353d..6b5698ad41 100644
--- a/scene/gui/graph_edit.h
+++ b/scene/gui/graph_edit.h
@@ -47,6 +47,7 @@ class GraphEditFilter : public Control {
friend class GraphEdit;
friend class GraphEditMinimap;
+
GraphEdit *ge = nullptr;
virtual bool has_point(const Point2 &p_point) const override;
@@ -63,24 +64,24 @@ class GraphEditMinimap : public Control {
GraphEdit *ge = nullptr;
-public:
- GraphEditMinimap(GraphEdit *p_edit);
-
- virtual CursorShape get_cursor_shape(const Point2 &p_pos = Point2i()) const override;
-
- void update_minimap();
- Rect2 get_camera_rect();
-
-private:
Vector2 minimap_padding;
Vector2 minimap_offset;
- Vector2 graph_proportions;
- Vector2 graph_padding;
- Vector2 camera_position;
- Vector2 camera_size;
+ Vector2 graph_proportions = Vector2(1, 1);
+ Vector2 graph_padding = Vector2(0, 0);
+ Vector2 camera_position = Vector2(100, 50);
+ Vector2 camera_size = Vector2(200, 200);
+
+ bool is_pressing = false;
+ bool is_resizing = false;
+
+ struct ThemeCache {
+ Ref<StyleBox> panel;
+ Ref<StyleBox> node_style;
+ Ref<StyleBox> camera_style;
- bool is_pressing;
- bool is_resizing;
+ Ref<Texture2D> resizer;
+ Color resizer_color;
+ } theme_cache;
Vector2 _get_render_size();
Vector2 _get_graph_offset();
@@ -92,6 +93,17 @@ private:
virtual void gui_input(const Ref<InputEvent> &p_ev) override;
void _adjust_graph_scroll(const Vector2 &p_offset);
+
+protected:
+ static void _bind_methods();
+
+public:
+ virtual CursorShape get_cursor_shape(const Point2 &p_pos = Point2i()) const override;
+
+ void update_minimap();
+ Rect2 get_camera_rect();
+
+ GraphEditMinimap(GraphEdit *p_edit);
};
class GraphEdit : public Control {
@@ -150,9 +162,6 @@ private:
HScrollBar *h_scrollbar = nullptr;
VScrollBar *v_scrollbar = nullptr;
- float port_hotzone_inner_extent = 0.0;
- float port_hotzone_outer_extent = 0.0;
-
Ref<ViewPanner> panner;
bool warped_panning = true;
@@ -218,7 +227,30 @@ private:
HashSet<int> valid_left_disconnect_types;
HashSet<int> valid_right_disconnect_types;
- void _scroll_callback(Vector2 p_scroll_vec, bool p_alt);
+ struct ThemeCache {
+ float base_scale = 1.0;
+
+ Ref<StyleBox> panel;
+ Color grid_major;
+ Color grid_minor;
+
+ Color activity_color;
+ Color selection_fill;
+ Color selection_stroke;
+
+ Ref<Texture2D> zoom_in;
+ Ref<Texture2D> zoom_out;
+ Ref<Texture2D> zoom_reset;
+
+ Ref<Texture2D> snapping_toggle;
+ Ref<Texture2D> grid_toggle;
+ Ref<Texture2D> minimap_toggle;
+ Ref<Texture2D> layout;
+
+ float port_hotzone_inner_extent = 0.0;
+ float port_hotzone_outer_extent = 0.0;
+ } theme_cache;
+
void _pan_callback(Vector2 p_scroll_vec, Ref<InputEvent> p_event);
void _zoom_callback(float p_zoom_factor, Vector2 p_origin, Ref<InputEvent> p_event);
@@ -262,12 +294,13 @@ private:
bool _check_clickable_control(Control *p_control, const Vector2 &r_mouse_pos, const Vector2 &p_offset);
protected:
- static void _bind_methods();
+ virtual void _update_theme_item_cache() override;
virtual void add_child_notify(Node *p_child) override;
virtual void remove_child_notify(Node *p_child) override;
void _notification(int p_what);
+ static void _bind_methods();
virtual bool is_in_input_hotzone(GraphNode *p_graph_node, int p_port_idx, const Vector2 &p_mouse_pos, const Vector2i &p_port_size);
virtual bool is_in_output_hotzone(GraphNode *p_graph_node, int p_port_idx, const Vector2 &p_mouse_pos, const Vector2i &p_port_size);
diff --git a/scene/gui/graph_element.cpp b/scene/gui/graph_element.cpp
index 04c4aa6ce8..ac2cb8bd5d 100644
--- a/scene/gui/graph_element.cpp
+++ b/scene/gui/graph_element.cpp
@@ -32,6 +32,7 @@
#include "core/string/translation.h"
#include "scene/gui/graph_edit.h"
+#include "scene/theme/theme_db.h"
#ifdef TOOLS_ENABLED
void GraphElement::_edit_set_position(const Point2 &p_position) {
@@ -154,9 +155,7 @@ void GraphElement::gui_input(const Ref<InputEvent> &p_ev) {
if (mb->is_pressed() && mb->get_button_index() == MouseButton::LEFT) {
Vector2 mpos = mb->get_position();
- Ref<Texture2D> resizer = get_theme_icon(SNAME("resizer"));
-
- if (resizable && mpos.x > get_size().x - resizer->get_width() && mpos.y > get_size().y - resizer->get_height()) {
+ if (resizable && mpos.x > get_size().x - theme_cache.resizer->get_width() && mpos.y > get_size().y - theme_cache.resizer->get_height()) {
resizing = true;
resizing_from = mpos;
resizing_from_size = get_size();
@@ -241,4 +240,6 @@ void GraphElement::_bind_methods() {
ADD_SIGNAL(MethodInfo("raise_request"));
ADD_SIGNAL(MethodInfo("close_request"));
ADD_SIGNAL(MethodInfo("resize_request", PropertyInfo(Variant::VECTOR2, "new_minsize")));
+
+ BIND_THEME_ITEM(Theme::DATA_TYPE_ICON, GraphElement, resizer);
}
diff --git a/scene/gui/graph_element.h b/scene/gui/graph_element.h
index 2c0a4760d8..a50c2953fd 100644
--- a/scene/gui/graph_element.h
+++ b/scene/gui/graph_element.h
@@ -49,6 +49,10 @@ protected:
Vector2 position_offset;
+ struct ThemeCache {
+ Ref<Texture2D> resizer;
+ } theme_cache;
+
#ifdef TOOLS_ENABLED
void _edit_set_position(const Point2 &p_position) override;
#endif
diff --git a/scene/gui/graph_node.cpp b/scene/gui/graph_node.cpp
index 385b564b7c..fdebca3d28 100644
--- a/scene/gui/graph_node.cpp
+++ b/scene/gui/graph_node.cpp
@@ -33,6 +33,7 @@
#include "core/string/translation.h"
#include "scene/gui/box_container.h"
#include "scene/gui/label.h"
+#include "scene/theme/theme_db.h"
bool GraphNode::_set(const StringName &p_name, const Variant &p_value) {
String str = p_name;
@@ -151,8 +152,8 @@ void GraphNode::_get_property_list(List<PropertyInfo> *p_list) const {
void GraphNode::_resort() {
Size2 new_size = get_size();
- Ref<StyleBox> sb_panel = get_theme_stylebox(SNAME("panel"));
- Ref<StyleBox> sb_titlebar = get_theme_stylebox(SNAME("titlebar"));
+ Ref<StyleBox> sb_panel = theme_cache.panel;
+ Ref<StyleBox> sb_titlebar = theme_cache.titlebar;
// Resort titlebar first.
Size2 titlebar_size = Size2(new_size.width, titlebar_hbox->get_size().height);
@@ -164,8 +165,8 @@ void GraphNode::_resort() {
Size2i titlebar_min_size = titlebar_hbox->get_combined_minimum_size();
// First pass, determine minimum size AND amount of stretchable elements.
- Ref<StyleBox> sb_slot = get_theme_stylebox(SNAME("slot"));
- int separation = get_theme_constant(SNAME("separation"));
+ Ref<StyleBox> sb_slot = theme_cache.slot;
+ int separation = theme_cache.separation;
int children_count = 0;
int stretch_min = 0;
@@ -300,7 +301,7 @@ void GraphNode::draw_port(int p_slot_index, Point2i p_pos, bool p_left, const Co
Point2 icon_offset;
if (!port_icon.is_valid()) {
- port_icon = get_theme_icon(SNAME("port"));
+ port_icon = theme_cache.port;
}
icon_offset = -port_icon->get_size() * 0.5;
@@ -311,19 +312,15 @@ void GraphNode::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_DRAW: {
// Used for layout calculations.
- Ref<StyleBox> sb_panel = get_theme_stylebox(SNAME("panel"));
- Ref<StyleBox> sb_titlebar = get_theme_stylebox(SNAME("titlebar"));
+ Ref<StyleBox> sb_panel = theme_cache.panel;
+ Ref<StyleBox> sb_titlebar = theme_cache.titlebar;
// Used for drawing.
- Ref<StyleBox> sb_to_draw_panel = get_theme_stylebox(selected ? SNAME("panel_selected") : SNAME("panel"));
- Ref<StyleBox> sb_to_draw_titlebar = get_theme_stylebox(selected ? SNAME("titlebar_selected") : SNAME("titlebar"));
+ Ref<StyleBox> sb_to_draw_panel = selected ? theme_cache.panel_selected : theme_cache.panel;
+ Ref<StyleBox> sb_to_draw_titlebar = selected ? theme_cache.titlebar_selected : theme_cache.titlebar;
- Ref<StyleBox> sb_slot = get_theme_stylebox(SNAME("slot"));
+ Ref<StyleBox> sb_slot = theme_cache.slot;
- int port_h_offset = get_theme_constant(SNAME("port_h_offset"));
-
- Ref<Texture2D> resizer_icon = get_theme_icon(SNAME("resizer"));
-
- Color resizer_color = get_theme_color(SNAME("resizer_color"));
+ int port_h_offset = theme_cache.port_h_offset;
Rect2 titlebar_rect(Point2(), titlebar_hbox->get_size() + sb_titlebar->get_minimum_size());
Size2 body_size = get_size();
@@ -377,7 +374,7 @@ void GraphNode::_notification(int p_what) {
}
if (resizable) {
- draw_texture(resizer_icon, get_size() - resizer_icon->get_size(), resizer_color);
+ draw_texture(theme_cache.resizer, get_size() - theme_cache.resizer->get_size(), theme_cache.resizer_color);
}
} break;
}
@@ -566,11 +563,11 @@ void GraphNode::set_slot_draw_stylebox(int p_slot_index, bool p_enable) {
}
Size2 GraphNode::get_minimum_size() const {
- Ref<StyleBox> sb_panel = get_theme_stylebox(SNAME("panel"));
- Ref<StyleBox> sb_titlebar = get_theme_stylebox(SNAME("titlebar"));
- Ref<StyleBox> sb_slot = get_theme_stylebox(SNAME("slot"));
+ Ref<StyleBox> sb_panel = theme_cache.panel;
+ Ref<StyleBox> sb_titlebar = theme_cache.titlebar;
+ Ref<StyleBox> sb_slot = theme_cache.slot;
- int separation = get_theme_constant(SNAME("separation"));
+ int separation = theme_cache.separation;
Size2 minsize = titlebar_hbox->get_minimum_size() + sb_titlebar->get_minimum_size();
for (int i = 0; i < get_child_count(false); i++) {
@@ -599,11 +596,11 @@ Size2 GraphNode::get_minimum_size() const {
}
void GraphNode::_port_pos_update() {
- int edgeofs = get_theme_constant(SNAME("port_h_offset"));
- int separation = get_theme_constant(SNAME("separation"));
+ int edgeofs = theme_cache.port_h_offset;
+ int separation = theme_cache.separation;
- Ref<StyleBox> sb_panel = get_theme_stylebox(SNAME("panel"));
- Ref<StyleBox> sb_titlebar = get_theme_stylebox(SNAME("titlebar"));
+ Ref<StyleBox> sb_panel = theme_cache.panel;
+ Ref<StyleBox> sb_titlebar = theme_cache.titlebar;
left_port_cache.clear();
right_port_cache.clear();
@@ -754,9 +751,7 @@ HBoxContainer *GraphNode::get_titlebar_hbox() {
Control::CursorShape GraphNode::get_cursor_shape(const Point2 &p_pos) const {
if (resizable) {
- Ref<Texture2D> resizer = get_theme_icon(SNAME("resizer"));
-
- if (resizing || (p_pos.x > get_size().x - resizer->get_width() && p_pos.y > get_size().y - resizer->get_height())) {
+ if (resizing || (p_pos.x > get_size().x - theme_cache.resizer->get_width() && p_pos.y > get_size().y - theme_cache.resizer->get_height())) {
return CURSOR_FDIAGSIZE;
}
}
@@ -830,6 +825,19 @@ void GraphNode::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::STRING, "title"), "set_title", "get_title");
ADD_SIGNAL(MethodInfo("slot_updated", PropertyInfo(Variant::INT, "slot_index")));
+
+ BIND_THEME_ITEM(Theme::DATA_TYPE_STYLEBOX, GraphNode, panel);
+ BIND_THEME_ITEM(Theme::DATA_TYPE_STYLEBOX, GraphNode, panel_selected);
+ BIND_THEME_ITEM(Theme::DATA_TYPE_STYLEBOX, GraphNode, titlebar);
+ BIND_THEME_ITEM(Theme::DATA_TYPE_STYLEBOX, GraphNode, titlebar_selected);
+ BIND_THEME_ITEM(Theme::DATA_TYPE_STYLEBOX, GraphNode, slot);
+
+ BIND_THEME_ITEM(Theme::DATA_TYPE_CONSTANT, GraphNode, separation);
+ BIND_THEME_ITEM(Theme::DATA_TYPE_CONSTANT, GraphNode, port_h_offset);
+
+ BIND_THEME_ITEM(Theme::DATA_TYPE_ICON, GraphNode, port);
+ BIND_THEME_ITEM(Theme::DATA_TYPE_ICON, GraphNode, resizer);
+ BIND_THEME_ITEM(Theme::DATA_TYPE_COLOR, GraphNode, resizer_color);
}
GraphNode::GraphNode() {
diff --git a/scene/gui/graph_node.h b/scene/gui/graph_node.h
index 1178421819..04ca9e7cb4 100644
--- a/scene/gui/graph_node.h
+++ b/scene/gui/graph_node.h
@@ -38,6 +38,8 @@ class HBoxContainer;
class GraphNode : public GraphElement {
GDCLASS(GraphNode, GraphElement);
+ friend class GraphEdit;
+
struct Slot {
bool enable_left = false;
int type_left = 0;
@@ -74,9 +76,23 @@ class GraphNode : public GraphElement {
Vector<PortCache> right_port_cache;
HashMap<int, Slot> slot_table;
-
Vector<int> slot_y_cache;
+ struct ThemeCache {
+ Ref<StyleBox> panel;
+ Ref<StyleBox> panel_selected;
+ Ref<StyleBox> titlebar;
+ Ref<StyleBox> titlebar_selected;
+ Ref<StyleBox> slot;
+
+ int separation = 0;
+ int port_h_offset = 0;
+
+ Ref<Texture2D> port;
+ Ref<Texture2D> resizer;
+ Color resizer_color;
+ } theme_cache;
+
bool port_pos_dirty = true;
void _port_pos_update();
diff --git a/scene/gui/grid_container.cpp b/scene/gui/grid_container.cpp
index 1db51e45b7..a4baf3bb8d 100644
--- a/scene/gui/grid_container.cpp
+++ b/scene/gui/grid_container.cpp
@@ -259,6 +259,10 @@ int GridContainer::get_columns() const {
return columns;
}
+int GridContainer::get_h_separation() const {
+ return theme_cache.h_separation;
+}
+
void GridContainer::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_columns", "columns"), &GridContainer::set_columns);
ClassDB::bind_method(D_METHOD("get_columns"), &GridContainer::get_columns);
diff --git a/scene/gui/grid_container.h b/scene/gui/grid_container.h
index e98acef165..f6a51511a9 100644
--- a/scene/gui/grid_container.h
+++ b/scene/gui/grid_container.h
@@ -52,6 +52,8 @@ public:
int get_columns() const;
virtual Size2 get_minimum_size() const override;
+ int get_h_separation() const;
+
GridContainer();
};
diff --git a/scene/gui/margin_container.cpp b/scene/gui/margin_container.cpp
index 5688d8b8f3..6d331afbb5 100644
--- a/scene/gui/margin_container.cpp
+++ b/scene/gui/margin_container.cpp
@@ -80,6 +80,23 @@ Vector<int> MarginContainer::get_allowed_size_flags_vertical() const {
return flags;
}
+int MarginContainer::get_margin_size(Side p_side) const {
+ ERR_FAIL_INDEX_V((int)p_side, 4, 0);
+
+ switch (p_side) {
+ case SIDE_LEFT:
+ return theme_cache.margin_left;
+ case SIDE_RIGHT:
+ return theme_cache.margin_right;
+ case SIDE_TOP:
+ return theme_cache.margin_top;
+ case SIDE_BOTTOM:
+ return theme_cache.margin_bottom;
+ }
+
+ return 0;
+}
+
void MarginContainer::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_SORT_CHILDREN: {
diff --git a/scene/gui/margin_container.h b/scene/gui/margin_container.h
index 4ad9a56cf4..d57ab9b452 100644
--- a/scene/gui/margin_container.h
+++ b/scene/gui/margin_container.h
@@ -53,6 +53,8 @@ public:
virtual Vector<int> get_allowed_size_flags_horizontal() const override;
virtual Vector<int> get_allowed_size_flags_vertical() const override;
+ int get_margin_size(Side p_side) const;
+
MarginContainer();
};
diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp
index 1fd9030a86..1fac301f9a 100644
--- a/scene/gui/popup_menu.cpp
+++ b/scene/gui/popup_menu.cpp
@@ -559,8 +559,8 @@ void PopupMenu::_draw_items() {
RID ci = control->get_canvas_item();
Size2 margin_size;
- margin_size.width = margin_container->get_theme_constant(SNAME("margin_right")) + margin_container->get_theme_constant(SNAME("margin_left"));
- margin_size.height = margin_container->get_theme_constant(SNAME("margin_top")) + margin_container->get_theme_constant(SNAME("margin_bottom"));
+ margin_size.width = margin_container->get_margin_size(SIDE_LEFT) + margin_container->get_margin_size(SIDE_RIGHT);
+ margin_size.height = margin_container->get_margin_size(SIDE_TOP) + margin_container->get_margin_size(SIDE_BOTTOM);
// Space between the item content and the sides of popup menu.
bool rtl = control->is_layout_rtl();
diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp
index 58babee0a4..96e338544c 100644
--- a/scene/gui/rich_text_label.cpp
+++ b/scene/gui/rich_text_label.cpp
@@ -5817,6 +5817,9 @@ void RichTextLabel::_bind_methods() {
BIND_THEME_ITEM(Theme::DATA_TYPE_FONT, RichTextLabel, mono_font);
BIND_THEME_ITEM(Theme::DATA_TYPE_FONT_SIZE, RichTextLabel, mono_font_size);
+ BIND_THEME_ITEM(Theme::DATA_TYPE_CONSTANT, RichTextLabel, text_highlight_h_padding);
+ BIND_THEME_ITEM(Theme::DATA_TYPE_CONSTANT, RichTextLabel, text_highlight_v_padding);
+
BIND_THEME_ITEM(Theme::DATA_TYPE_CONSTANT, RichTextLabel, table_h_separation);
BIND_THEME_ITEM(Theme::DATA_TYPE_CONSTANT, RichTextLabel, table_v_separation);
BIND_THEME_ITEM(Theme::DATA_TYPE_COLOR, RichTextLabel, table_odd_row_bg);
@@ -6029,8 +6032,6 @@ void RichTextLabel::_draw_fbg_boxes(RID p_ci, RID p_rid, Vector2 line_off, Item
Vector2i fbg_index = Vector2i(end, start);
Color last_color = Color(0, 0, 0, 0);
bool draw_box = false;
- int hpad = get_theme_constant(SNAME("text_highlight_h_padding"));
- int vpad = get_theme_constant(SNAME("text_highlight_v_padding"));
// Draw a box based on color tags associated with glyphs
for (int i = start; i < end; i++) {
Item *it = _get_item_at_pos(it_from, it_to, i);
@@ -6060,8 +6061,8 @@ void RichTextLabel::_draw_fbg_boxes(RID p_ci, RID p_rid, Vector2 line_off, Item
if (draw_box) {
Vector<Vector2> sel = TS->shaped_text_get_selection(p_rid, fbg_index.x, fbg_index.y);
for (int j = 0; j < sel.size(); j++) {
- Vector2 rect_off = line_off + Vector2(sel[j].x - hpad, -TS->shaped_text_get_ascent(p_rid) - vpad);
- Vector2 rect_size = Vector2(sel[j].y - sel[j].x + 2 * hpad, TS->shaped_text_get_size(p_rid).y + 2 * vpad);
+ Vector2 rect_off = line_off + Vector2(sel[j].x - theme_cache.text_highlight_h_padding, -TS->shaped_text_get_ascent(p_rid) - theme_cache.text_highlight_v_padding);
+ Vector2 rect_size = Vector2(sel[j].y - sel[j].x + 2 * theme_cache.text_highlight_h_padding, TS->shaped_text_get_size(p_rid).y + 2 * theme_cache.text_highlight_v_padding);
RenderingServer::get_singleton()->canvas_item_add_rect(p_ci, Rect2(rect_off, rect_size), last_color);
}
fbg_index = Vector2i(end, start);
@@ -6079,8 +6080,8 @@ void RichTextLabel::_draw_fbg_boxes(RID p_ci, RID p_rid, Vector2 line_off, Item
if (last_color.a > 0) {
Vector<Vector2> sel = TS->shaped_text_get_selection(p_rid, fbg_index.x, end);
for (int i = 0; i < sel.size(); i++) {
- Vector2 rect_off = line_off + Vector2(sel[i].x - hpad, -TS->shaped_text_get_ascent(p_rid) - vpad);
- Vector2 rect_size = Vector2(sel[i].y - sel[i].x + 2 * hpad, TS->shaped_text_get_size(p_rid).y + 2 * vpad);
+ Vector2 rect_off = line_off + Vector2(sel[i].x - theme_cache.text_highlight_h_padding, -TS->shaped_text_get_ascent(p_rid) - theme_cache.text_highlight_v_padding);
+ Vector2 rect_size = Vector2(sel[i].y - sel[i].x + 2 * theme_cache.text_highlight_h_padding, TS->shaped_text_get_size(p_rid).y + 2 * theme_cache.text_highlight_v_padding);
RenderingServer::get_singleton()->canvas_item_add_rect(p_ci, Rect2(rect_off, rect_size), last_color);
}
}
diff --git a/scene/gui/rich_text_label.h b/scene/gui/rich_text_label.h
index af48e7efce..d88623073d 100644
--- a/scene/gui/rich_text_label.h
+++ b/scene/gui/rich_text_label.h
@@ -592,6 +592,9 @@ private:
Ref<Font> mono_font;
int mono_font_size;
+ int text_highlight_h_padding;
+ int text_highlight_v_padding;
+
int table_h_separation;
int table_v_separation;
Color table_odd_row_bg;
diff --git a/scene/gui/split_container.cpp b/scene/gui/split_container.cpp
index 4a76c341e2..06b32b548f 100644
--- a/scene/gui/split_container.cpp
+++ b/scene/gui/split_container.cpp
@@ -97,7 +97,7 @@ void SplitContainerDragger::_notification(int p_what) {
case NOTIFICATION_MOUSE_ENTER: {
mouse_inside = true;
SplitContainer *sc = Object::cast_to<SplitContainer>(get_parent());
- if (sc->get_theme_constant(SNAME("autohide"))) {
+ if (sc->theme_cache.autohide) {
queue_redraw();
}
} break;
@@ -105,14 +105,14 @@ void SplitContainerDragger::_notification(int p_what) {
case NOTIFICATION_MOUSE_EXIT: {
mouse_inside = false;
SplitContainer *sc = Object::cast_to<SplitContainer>(get_parent());
- if (sc->get_theme_constant(SNAME("autohide"))) {
+ if (sc->theme_cache.autohide) {
queue_redraw();
}
} break;
case NOTIFICATION_DRAW: {
SplitContainer *sc = Object::cast_to<SplitContainer>(get_parent());
- if (!dragging && !mouse_inside && sc->get_theme_constant(SNAME("autohide"))) {
+ if (!dragging && !mouse_inside && sc->theme_cache.autohide) {
return;
}
diff --git a/scene/gui/split_container.h b/scene/gui/split_container.h
index 878560dd59..f008d2678b 100644
--- a/scene/gui/split_container.h
+++ b/scene/gui/split_container.h
@@ -73,7 +73,7 @@ private:
struct ThemeCache {
int separation = 0;
int minimum_grab_thickness = 0;
- int autohide = 0;
+ bool autohide = false;
Ref<Texture2D> grabber_icon;
Ref<Texture2D> grabber_icon_h;
Ref<Texture2D> grabber_icon_v;
@@ -85,8 +85,6 @@ private:
void _compute_middle_sep(bool p_clamp);
void _resort();
- void _dragging_area_gui_input(const Ref<InputEvent> &p_event);
-
protected:
bool is_fixed = false;
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index cc519ad38b..f28f20b584 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -1254,7 +1254,7 @@ void TextEdit::_notification(int p_what) {
if ((brace_matching[c].open_match_line == line && brace_matching[c].open_match_column == glyphs[j].start) ||
(get_caret_column(c) == glyphs[j].start && get_caret_line(c) == line && carets_wrap_index[c] == line_wrap_index && (brace_matching[c].open_matching || brace_matching[c].open_mismatch))) {
if (brace_matching[c].open_mismatch) {
- gl_color = theme_cache.brace_mismatch_color;
+ gl_color = _get_brace_mismatch_color();
}
Rect2 rect = Rect2(char_pos, ofs_y + theme_cache.font->get_underline_position(theme_cache.font_size), glyphs[j].advance * glyphs[j].repeat, MAX(theme_cache.font->get_underline_thickness(theme_cache.font_size) * theme_cache.base_scale, 1));
draw_rect(rect, gl_color);
@@ -1263,7 +1263,7 @@ void TextEdit::_notification(int p_what) {
if ((brace_matching[c].close_match_line == line && brace_matching[c].close_match_column == glyphs[j].start) ||
(get_caret_column(c) == glyphs[j].start + 1 && get_caret_line(c) == line && carets_wrap_index[c] == line_wrap_index && (brace_matching[c].close_matching || brace_matching[c].close_mismatch))) {
if (brace_matching[c].close_mismatch) {
- gl_color = theme_cache.brace_mismatch_color;
+ gl_color = _get_brace_mismatch_color();
}
Rect2 rect = Rect2(char_pos, ofs_y + theme_cache.font->get_underline_position(theme_cache.font_size), glyphs[j].advance * glyphs[j].repeat, MAX(theme_cache.font->get_underline_thickness(theme_cache.font_size) * theme_cache.base_scale, 1));
draw_rect(rect, gl_color);
@@ -1313,12 +1313,12 @@ void TextEdit::_notification(int p_what) {
// is_line_folded
if (line_wrap_index == line_wrap_amount && line < text.size() - 1 && _is_line_hidden(line + 1)) {
- int xofs = char_ofs + char_margin + ofs_x + (theme_cache.folded_eol_icon->get_width() / 2);
+ int xofs = char_ofs + char_margin + ofs_x + (_get_folded_eol_icon()->get_width() / 2);
if (xofs >= xmargin_beg && xofs < xmargin_end) {
- int yofs = (text_height - theme_cache.folded_eol_icon->get_height()) / 2 - ldata->get_line_ascent(line_wrap_index);
- Color eol_color = theme_cache.code_folding_color;
+ int yofs = (text_height - _get_folded_eol_icon()->get_height()) / 2 - ldata->get_line_ascent(line_wrap_index);
+ Color eol_color = _get_code_folding_color();
eol_color.a = 1;
- theme_cache.folded_eol_icon->draw(ci, Point2(xofs, ofs_y + yofs), eol_color);
+ _get_folded_eol_icon()->draw(ci, Point2(xofs, ofs_y + yofs), eol_color);
}
}
@@ -3000,7 +3000,6 @@ void TextEdit::_update_theme_item_cache() {
Control::_update_theme_item_cache();
theme_cache.base_scale = get_theme_default_base_scale();
- theme_cache.folded_code_region_color = get_theme_color(SNAME("folded_code_region_color"), SNAME("CodeEdit"));
use_selected_font_color = theme_cache.font_selected_color != Color(0, 0, 0, 0);
if (text.get_line_height() + theme_cache.line_spacing < 1) {
@@ -6474,12 +6473,6 @@ void TextEdit::_bind_methods() {
ADD_SIGNAL(MethodInfo("gutter_removed"));
/* Theme items */
- /* Internal API for CodeEdit */
- BIND_THEME_ITEM_EXT(Theme::DATA_TYPE_COLOR, TextEdit, brace_mismatch_color, "brace_mismatch_color", "CodeEdit");
- BIND_THEME_ITEM_EXT(Theme::DATA_TYPE_COLOR, TextEdit, code_folding_color, "code_folding_color", "CodeEdit");
- BIND_THEME_ITEM_EXT(Theme::DATA_TYPE_COLOR, TextEdit, folded_code_region_color, "folded_code_region_color", "CodeEdit");
- BIND_THEME_ITEM_EXT(Theme::DATA_TYPE_ICON, TextEdit, folded_eol_icon, "folded_eol_icon", "CodeEdit");
-
/* Search */
BIND_THEME_ITEM(Theme::DATA_TYPE_COLOR, TextEdit, search_result_color);
BIND_THEME_ITEM(Theme::DATA_TYPE_COLOR, TextEdit, search_result_border_color);
diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h
index d874db34bf..7be58bd927 100644
--- a/scene/gui/text_edit.h
+++ b/scene/gui/text_edit.h
@@ -41,6 +41,8 @@
class TextEdit : public Control {
GDCLASS(TextEdit, Control);
+ friend class CodeHighlighter;
+
public:
/* Edit Actions. */
enum EditAction {
@@ -543,12 +545,6 @@ private:
struct ThemeCache {
float base_scale = 1.0;
- /* Internal API for CodeEdit */
- Color brace_mismatch_color;
- Color code_folding_color = Color(1, 1, 1);
- Color folded_code_region_color = Color(1, 1, 1);
- Ref<Texture2D> folded_eol_icon;
-
/* Search */
Color search_result_color = Color(1, 1, 1);
Color search_result_border_color = Color(1, 1, 1);
@@ -633,7 +629,7 @@ protected:
virtual void _update_theme_item_cache() override;
/* Internal API for CodeEdit, pending public API. */
- // brace matching
+ // Brace matching.
struct BraceMatchingData {
int open_match_line = -1;
int open_match_column = -1;
@@ -662,6 +658,11 @@ protected:
String lookup_symbol_word;
void _set_symbol_lookup_word(const String &p_symbol);
+ // Theme items.
+ virtual Color _get_brace_mismatch_color() const { return Color(); };
+ virtual Color _get_code_folding_color() const { return Color(); };
+ virtual Ref<Texture2D> _get_folded_eol_icon() const { return Ref<Texture2D>(); };
+
/* Text manipulation */
// Overridable actions
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index 5f8f5225c9..518cc4b7c9 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -319,16 +319,16 @@ void Viewport::_sub_window_update(Window *p_window) {
Rect2i r = Rect2i(p_window->get_position(), sw.window->get_size());
if (!p_window->get_flag(Window::FLAG_BORDERLESS)) {
- Ref<StyleBox> panel = p_window->get_theme_stylebox(gui.subwindow_focused == p_window ? SNAME("embedded_border") : SNAME("embedded_unfocused_border"));
+ Ref<StyleBox> panel = gui.subwindow_focused == p_window ? p_window->theme_cache.embedded_border : p_window->theme_cache.embedded_unfocused_border;
panel->draw(sw.canvas_item, r);
// Draw the title bar text.
- Ref<Font> title_font = p_window->get_theme_font(SNAME("title_font"));
- int font_size = p_window->get_theme_font_size(SNAME("title_font_size"));
- Color title_color = p_window->get_theme_color(SNAME("title_color"));
- int title_height = p_window->get_theme_constant(SNAME("title_height"));
- int close_h_ofs = p_window->get_theme_constant(SNAME("close_h_offset"));
- int close_v_ofs = p_window->get_theme_constant(SNAME("close_v_offset"));
+ Ref<Font> title_font = p_window->theme_cache.title_font;
+ int font_size = p_window->theme_cache.title_font_size;
+ Color title_color = p_window->theme_cache.title_color;
+ int title_height = p_window->theme_cache.title_height;
+ int close_h_ofs = p_window->theme_cache.close_h_offset;
+ int close_v_ofs = p_window->theme_cache.close_v_offset;
TextLine title_text = TextLine(p_window->atr(p_window->get_title()), title_font, font_size);
title_text.set_width(r.size.width - panel->get_minimum_size().x - close_h_ofs);
@@ -336,15 +336,15 @@ void Viewport::_sub_window_update(Window *p_window) {
int x = (r.size.width - title_text.get_size().x) / 2;
int y = (-title_height - title_text.get_size().y) / 2;
- Color font_outline_color = p_window->get_theme_color(SNAME("title_outline_modulate"));
- int outline_size = p_window->get_theme_constant(SNAME("title_outline_size"));
+ Color font_outline_color = p_window->theme_cache.title_outline_modulate;
+ int outline_size = p_window->theme_cache.title_outline_size;
if (outline_size > 0 && font_outline_color.a > 0) {
title_text.draw_outline(sw.canvas_item, r.position + Point2(x, y), outline_size, font_outline_color);
}
title_text.draw(sw.canvas_item, r.position + Point2(x, y), title_color);
bool pressed = gui.subwindow_focused == sw.window && gui.subwindow_drag == SUB_WINDOW_DRAG_CLOSE && gui.subwindow_drag_close_inside;
- Ref<Texture2D> close_icon = p_window->get_theme_icon(pressed ? "close_pressed" : "close");
+ Ref<Texture2D> close_icon = pressed ? p_window->theme_cache.close_pressed : p_window->theme_cache.close;
close_icon->draw(sw.canvas_item, r.position + Vector2(r.size.width - close_h_ofs, -close_v_ofs));
}
@@ -2039,7 +2039,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
Window *sw = embedder->gui.sub_windows[i].window;
Rect2 swrect = Rect2i(sw->get_position(), sw->get_size());
if (!sw->get_flag(Window::FLAG_BORDERLESS)) {
- int title_height = sw->get_theme_constant(SNAME("title_height"));
+ int title_height = sw->theme_cache.title_height;
swrect.position.y -= title_height;
swrect.size.y += title_height;
}
@@ -2669,7 +2669,7 @@ Viewport::SubWindowResize Viewport::_sub_window_get_resize_margin(Window *p_subw
Rect2i r = Rect2i(p_subwindow->get_position(), p_subwindow->get_size());
- int title_height = p_subwindow->get_theme_constant(SNAME("title_height"));
+ int title_height = p_subwindow->theme_cache.title_height;
r.position.y -= title_height;
r.size.y += title_height;
@@ -2681,7 +2681,7 @@ Viewport::SubWindowResize Viewport::_sub_window_get_resize_margin(Window *p_subw
int dist_x = p_point.x < r.position.x ? (p_point.x - r.position.x) : (p_point.x > (r.position.x + r.size.x) ? (p_point.x - (r.position.x + r.size.x)) : 0);
int dist_y = p_point.y < r.position.y ? (p_point.y - r.position.y) : (p_point.y > (r.position.y + r.size.y) ? (p_point.y - (r.position.y + r.size.y)) : 0);
- int limit = p_subwindow->get_theme_constant(SNAME("resize_margin"));
+ int limit = p_subwindow->theme_cache.resize_margin;
if (ABS(dist_x) > limit) {
return SUB_WINDOW_RESIZE_DISABLED;
@@ -2866,7 +2866,7 @@ bool Viewport::_sub_windows_forward_input(const Ref<InputEvent> &p_event) {
if (!sw.window->get_flag(Window::FLAG_BORDERLESS)) {
// Check top bar.
- int title_height = sw.window->get_theme_constant(SNAME("title_height"));
+ int title_height = sw.window->theme_cache.title_height;
Rect2i title_bar = r;
title_bar.position.y -= title_height;
title_bar.size.y = title_height;
@@ -2874,9 +2874,9 @@ bool Viewport::_sub_windows_forward_input(const Ref<InputEvent> &p_event) {
if (title_bar.size.y > 0 && title_bar.has_point(mb->get_position())) {
click_on_window = sw.window;
- int close_h_ofs = sw.window->get_theme_constant(SNAME("close_h_offset"));
- int close_v_ofs = sw.window->get_theme_constant(SNAME("close_v_offset"));
- Ref<Texture2D> close_icon = sw.window->get_theme_icon(SNAME("close"));
+ int close_h_ofs = sw.window->theme_cache.close_h_offset;
+ int close_v_ofs = sw.window->theme_cache.close_v_offset;
+ Ref<Texture2D> close_icon = sw.window->theme_cache.close;
Rect2 close_rect;
close_rect.position = Vector2(r.position.x + r.size.x - close_h_ofs, r.position.y - close_v_ofs);
@@ -3016,8 +3016,8 @@ void Viewport::_update_mouse_over(Vector2 p_pos) {
Rect2 swrect_border = swrect;
if (!sw->get_flag(Window::FLAG_BORDERLESS)) {
- int title_height = sw->get_theme_constant(SNAME("title_height"));
- int margin = sw->get_theme_constant(SNAME("resize_margin"));
+ int title_height = sw->theme_cache.title_height;
+ int margin = sw->theme_cache.resize_margin;
swrect_border.position.y -= title_height + margin;
swrect_border.size.y += title_height + margin * 2;
swrect_border.position.x -= margin;
diff --git a/scene/main/window.cpp b/scene/main/window.cpp
index a34fda3065..c345c3d179 100644
--- a/scene/main/window.cpp
+++ b/scene/main/window.cpp
@@ -1804,7 +1804,7 @@ Rect2i Window::fit_rect_in_parent(Rect2i p_rect, const Rect2i &p_parent_rect) co
p_rect.position.x = 0;
}
- int title_height = get_flag(Window::FLAG_BORDERLESS) ? 0 : get_theme_constant(SNAME("title_height"));
+ int title_height = get_flag(Window::FLAG_BORDERLESS) ? 0 : theme_cache.title_height;
if (p_rect.position.y < title_height) {
p_rect.position.y = title_height;
@@ -2910,6 +2910,23 @@ void Window::_bind_methods() {
BIND_ENUM_CONSTANT(WINDOW_INITIAL_POSITION_CENTER_SCREEN_WITH_KEYBOARD_FOCUS);
GDVIRTUAL_BIND(_get_contents_minimum_size);
+
+ BIND_THEME_ITEM(Theme::DATA_TYPE_STYLEBOX, Window, embedded_border);
+ BIND_THEME_ITEM(Theme::DATA_TYPE_STYLEBOX, Window, embedded_unfocused_border);
+
+ BIND_THEME_ITEM(Theme::DATA_TYPE_FONT, Window, title_font);
+ BIND_THEME_ITEM(Theme::DATA_TYPE_FONT_SIZE, Window, title_font_size);
+ BIND_THEME_ITEM(Theme::DATA_TYPE_COLOR, Window, title_color);
+ BIND_THEME_ITEM(Theme::DATA_TYPE_CONSTANT, Window, title_height);
+ BIND_THEME_ITEM(Theme::DATA_TYPE_COLOR, Window, title_outline_modulate);
+ BIND_THEME_ITEM(Theme::DATA_TYPE_CONSTANT, Window, title_outline_size);
+
+ BIND_THEME_ITEM(Theme::DATA_TYPE_ICON, Window, close);
+ BIND_THEME_ITEM(Theme::DATA_TYPE_ICON, Window, close_pressed);
+ BIND_THEME_ITEM(Theme::DATA_TYPE_CONSTANT, Window, close_h_offset);
+ BIND_THEME_ITEM(Theme::DATA_TYPE_CONSTANT, Window, close_v_offset);
+
+ BIND_THEME_ITEM(Theme::DATA_TYPE_CONSTANT, Window, resize_margin);
}
Window::Window() {
diff --git a/scene/main/window.h b/scene/main/window.h
index 26b974a9c1..11b986239e 100644
--- a/scene/main/window.h
+++ b/scene/main/window.h
@@ -42,7 +42,8 @@ class ThemeOwner;
class ThemeContext;
class Window : public Viewport {
- GDCLASS(Window, Viewport)
+ GDCLASS(Window, Viewport);
+
public:
// Keep synced with enum hint for `mode` property.
enum Mode {
@@ -191,6 +192,25 @@ private:
void _notify_theme_override_changed();
void _invalidate_theme_cache();
+ struct ThemeCache {
+ Ref<StyleBox> embedded_border;
+ Ref<StyleBox> embedded_unfocused_border;
+
+ Ref<Font> title_font;
+ int title_font_size = 0;
+ Color title_color;
+ int title_height = 0;
+ Color title_outline_modulate;
+ int title_outline_size = 0;
+
+ Ref<Texture2D> close;
+ Ref<Texture2D> close_pressed;
+ int close_h_offset = 0;
+ int close_v_offset = 0;
+
+ int resize_margin = 0;
+ } theme_cache;
+
Viewport *embedder = nullptr;
Transform2D window_transform;
@@ -212,12 +232,12 @@ private:
protected:
virtual Rect2i _popup_adjust_rect() const { return Rect2i(); }
+ virtual void _post_popup() {}
virtual void _update_theme_item_cache();
- virtual void _post_popup() {}
- static void _bind_methods();
void _notification(int p_what);
+ static void _bind_methods();
bool _set(const StringName &p_name, const Variant &p_value);
bool _get(const StringName &p_name, Variant &r_ret) const;
diff --git a/scene/resources/syntax_highlighter.cpp b/scene/resources/syntax_highlighter.cpp
index 903be41c26..aa311baa43 100644
--- a/scene/resources/syntax_highlighter.cpp
+++ b/scene/resources/syntax_highlighter.cpp
@@ -419,7 +419,7 @@ void CodeHighlighter::_clear_highlighting_cache() {
}
void CodeHighlighter::_update_cache() {
- font_color = text_edit->get_theme_color(SNAME("font_color"));
+ font_color = text_edit->theme_cache.font_color;
}
void CodeHighlighter::add_keyword_color(const String &p_keyword, const Color &p_color) {
diff --git a/scene/resources/theme.h b/scene/resources/theme.h
index c7a76f4c5e..b26b5b5e84 100644
--- a/scene/resources/theme.h
+++ b/scene/resources/theme.h
@@ -69,15 +69,6 @@ private:
void _emit_theme_changed(bool p_notify_list_changed = false);
- HashMap<StringName, ThemeIconMap> icon_map;
- HashMap<StringName, ThemeStyleMap> style_map;
- HashMap<StringName, ThemeFontMap> font_map;
- HashMap<StringName, ThemeFontSizeMap> font_size_map;
- HashMap<StringName, ThemeColorMap> color_map;
- HashMap<StringName, ThemeConstantMap> constant_map;
- HashMap<StringName, StringName> variation_map;
- HashMap<StringName, List<StringName>> variation_base_map;
-
Vector<String> _get_icon_list(const String &p_theme_type) const;
Vector<String> _get_icon_type_list() const;
Vector<String> _get_stylebox_list(const String &p_theme_type) const;
@@ -107,6 +98,15 @@ protected:
Ref<Font> default_font;
int default_font_size = -1;
+ HashMap<StringName, ThemeIconMap> icon_map;
+ HashMap<StringName, ThemeStyleMap> style_map;
+ HashMap<StringName, ThemeFontMap> font_map;
+ HashMap<StringName, ThemeFontSizeMap> font_size_map;
+ HashMap<StringName, ThemeColorMap> color_map;
+ HashMap<StringName, ThemeConstantMap> constant_map;
+ HashMap<StringName, StringName> variation_map;
+ HashMap<StringName, List<StringName>> variation_base_map;
+
static void _bind_methods();
void _freeze_change_propagation();
@@ -131,7 +131,7 @@ public:
bool has_default_font_size() const;
void set_icon(const StringName &p_name, const StringName &p_theme_type, const Ref<Texture2D> &p_icon);
- Ref<Texture2D> get_icon(const StringName &p_name, const StringName &p_theme_type) const;
+ virtual Ref<Texture2D> get_icon(const StringName &p_name, const StringName &p_theme_type) const;
bool has_icon(const StringName &p_name, const StringName &p_theme_type) const;
bool has_icon_nocheck(const StringName &p_name, const StringName &p_theme_type) const;
void rename_icon(const StringName &p_old_name, const StringName &p_name, const StringName &p_theme_type);
@@ -142,7 +142,7 @@ public:
void get_icon_type_list(List<StringName> *p_list) const;
void set_stylebox(const StringName &p_name, const StringName &p_theme_type, const Ref<StyleBox> &p_style);
- Ref<StyleBox> get_stylebox(const StringName &p_name, const StringName &p_theme_type) const;
+ virtual Ref<StyleBox> get_stylebox(const StringName &p_name, const StringName &p_theme_type) const;
bool has_stylebox(const StringName &p_name, const StringName &p_theme_type) const;
bool has_stylebox_nocheck(const StringName &p_name, const StringName &p_theme_type) const;
void rename_stylebox(const StringName &p_old_name, const StringName &p_name, const StringName &p_theme_type);
@@ -153,7 +153,7 @@ public:
void get_stylebox_type_list(List<StringName> *p_list) const;
void set_font(const StringName &p_name, const StringName &p_theme_type, const Ref<Font> &p_font);
- Ref<Font> get_font(const StringName &p_name, const StringName &p_theme_type) const;
+ virtual Ref<Font> get_font(const StringName &p_name, const StringName &p_theme_type) const;
bool has_font(const StringName &p_name, const StringName &p_theme_type) const;
bool has_font_nocheck(const StringName &p_name, const StringName &p_theme_type) const;
void rename_font(const StringName &p_old_name, const StringName &p_name, const StringName &p_theme_type);
@@ -164,7 +164,7 @@ public:
void get_font_type_list(List<StringName> *p_list) const;
void set_font_size(const StringName &p_name, const StringName &p_theme_type, int p_font_size);
- int get_font_size(const StringName &p_name, const StringName &p_theme_type) const;
+ virtual int get_font_size(const StringName &p_name, const StringName &p_theme_type) const;
bool has_font_size(const StringName &p_name, const StringName &p_theme_type) const;
bool has_font_size_nocheck(const StringName &p_name, const StringName &p_theme_type) const;
void rename_font_size(const StringName &p_old_name, const StringName &p_name, const StringName &p_theme_type);
@@ -175,7 +175,7 @@ public:
void get_font_size_type_list(List<StringName> *p_list) const;
void set_color(const StringName &p_name, const StringName &p_theme_type, const Color &p_color);
- Color get_color(const StringName &p_name, const StringName &p_theme_type) const;
+ virtual Color get_color(const StringName &p_name, const StringName &p_theme_type) const;
bool has_color(const StringName &p_name, const StringName &p_theme_type) const;
bool has_color_nocheck(const StringName &p_name, const StringName &p_theme_type) const;
void rename_color(const StringName &p_old_name, const StringName &p_name, const StringName &p_theme_type);
@@ -186,7 +186,7 @@ public:
void get_color_type_list(List<StringName> *p_list) const;
void set_constant(const StringName &p_name, const StringName &p_theme_type, int p_constant);
- int get_constant(const StringName &p_name, const StringName &p_theme_type) const;
+ virtual int get_constant(const StringName &p_name, const StringName &p_theme_type) const;
bool has_constant(const StringName &p_name, const StringName &p_theme_type) const;
bool has_constant_nocheck(const StringName &p_name, const StringName &p_theme_type) const;
void rename_constant(const StringName &p_old_name, const StringName &p_name, const StringName &p_theme_type);
diff --git a/servers/xr/xr_interface.cpp b/servers/xr/xr_interface.cpp
index 416f08dbb6..9ced28fd52 100644
--- a/servers/xr/xr_interface.cpp
+++ b/servers/xr/xr_interface.cpp
@@ -79,6 +79,8 @@ void XRInterface::_bind_methods() {
/** environment blend mode. */
ClassDB::bind_method(D_METHOD("get_supported_environment_blend_modes"), &XRInterface::get_supported_environment_blend_modes);
ClassDB::bind_method(D_METHOD("set_environment_blend_mode", "mode"), &XRInterface::set_environment_blend_mode);
+ ClassDB::bind_method(D_METHOD("get_environment_blend_mode"), &XRInterface::get_environment_blend_mode);
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "environment_blend_mode"), "set_environment_blend_mode", "get_environment_blend_mode");
ADD_GROUP("AR", "ar_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "ar_is_anchor_detection_enabled"), "set_anchor_detection_is_enabled", "get_anchor_detection_is_enabled");
diff --git a/servers/xr/xr_interface.h b/servers/xr/xr_interface.h
index b42cb37234..c76d0fbf68 100644
--- a/servers/xr/xr_interface.h
+++ b/servers/xr/xr_interface.h
@@ -147,6 +147,7 @@ public:
/** environment blend mode. */
virtual Array get_supported_environment_blend_modes();
+ virtual XRInterface::EnvironmentBlendMode get_environment_blend_mode() const { return XR_ENV_BLEND_MODE_OPAQUE; }
virtual bool set_environment_blend_mode(EnvironmentBlendMode mode) { return false; }
XRInterface();
diff --git a/tests/core/io/test_resource.h b/tests/core/io/test_resource.h
index 8fc2a2f040..9ddb51220b 100644
--- a/tests/core/io/test_resource.h
+++ b/tests/core/io/test_resource.h
@@ -139,7 +139,7 @@ TEST_CASE("[Resource] Breaking circular references on save") {
loaded_resource_c_binary->get_name() == "C",
"The loaded child resource name should be equal to the expected value.");
CHECK_MESSAGE(
- !loaded_resource_c_binary->get_meta("next"),
+ !loaded_resource_c_binary->has_meta("next"),
"The loaded child resource circular reference should be NULL.");
const Ref<Resource> &loaded_resource_a_text = ResourceLoader::load(save_path_text);
@@ -155,7 +155,7 @@ TEST_CASE("[Resource] Breaking circular references on save") {
loaded_resource_c_text->get_name() == "C",
"The loaded child resource name should be equal to the expected value.");
CHECK_MESSAGE(
- !loaded_resource_c_text->get_meta("next"),
+ !loaded_resource_c_text->has_meta("next"),
"The loaded child resource circular reference should be NULL.");
// Break circular reference to avoid memory leak
diff --git a/thirdparty/README.md b/thirdparty/README.md
index bd3c626b65..f495ed112d 100644
--- a/thirdparty/README.md
+++ b/thirdparty/README.md
@@ -417,7 +417,7 @@ Files extracted from upstream source:
## libwebp
- Upstream: https://chromium.googlesource.com/webm/libwebp/
-- Version: 1.3.1 (fd7bb21c0cb56e8a82e9bfa376164b842f433f3b, 2023)
+- Version: 1.3.2 (ca332209cb5567c9b249c86788cb2dbf8847e760, 2023)
- License: BSD-3-Clause
Files extracted from upstream source:
diff --git a/thirdparty/libwebp/src/dec/vp8i_dec.h b/thirdparty/libwebp/src/dec/vp8i_dec.h
index 1ae4ff62f2..7929fd7506 100644
--- a/thirdparty/libwebp/src/dec/vp8i_dec.h
+++ b/thirdparty/libwebp/src/dec/vp8i_dec.h
@@ -32,7 +32,7 @@ extern "C" {
// version numbers
#define DEC_MAJ_VERSION 1
#define DEC_MIN_VERSION 3
-#define DEC_REV_VERSION 1
+#define DEC_REV_VERSION 2
// YUV-cache parameters. Cache is 32-bytes wide (= one cacheline).
// Constraints are: We need to store one 16x16 block of luma samples (y),
diff --git a/thirdparty/libwebp/src/dec/vp8l_dec.c b/thirdparty/libwebp/src/dec/vp8l_dec.c
index c0ea0181e5..7995313fa1 100644
--- a/thirdparty/libwebp/src/dec/vp8l_dec.c
+++ b/thirdparty/libwebp/src/dec/vp8l_dec.c
@@ -253,11 +253,11 @@ static int ReadHuffmanCodeLengths(
int symbol;
int max_symbol;
int prev_code_len = DEFAULT_CODE_LENGTH;
- HuffmanCode table[1 << LENGTHS_TABLE_BITS];
+ HuffmanTables tables;
- if (!VP8LBuildHuffmanTable(table, LENGTHS_TABLE_BITS,
- code_length_code_lengths,
- NUM_CODE_LENGTH_CODES)) {
+ if (!VP8LHuffmanTablesAllocate(1 << LENGTHS_TABLE_BITS, &tables) ||
+ !VP8LBuildHuffmanTable(&tables, LENGTHS_TABLE_BITS,
+ code_length_code_lengths, NUM_CODE_LENGTH_CODES)) {
goto End;
}
@@ -277,7 +277,7 @@ static int ReadHuffmanCodeLengths(
int code_len;
if (max_symbol-- == 0) break;
VP8LFillBitWindow(br);
- p = &table[VP8LPrefetchBits(br) & LENGTHS_TABLE_MASK];
+ p = &tables.curr_segment->start[VP8LPrefetchBits(br) & LENGTHS_TABLE_MASK];
VP8LSetBitPos(br, br->bit_pos_ + p->bits);
code_len = p->value;
if (code_len < kCodeLengthLiterals) {
@@ -300,6 +300,7 @@ static int ReadHuffmanCodeLengths(
ok = 1;
End:
+ VP8LHuffmanTablesDeallocate(&tables);
if (!ok) dec->status_ = VP8_STATUS_BITSTREAM_ERROR;
return ok;
}
@@ -307,7 +308,8 @@ static int ReadHuffmanCodeLengths(
// 'code_lengths' is pre-allocated temporary buffer, used for creating Huffman
// tree.
static int ReadHuffmanCode(int alphabet_size, VP8LDecoder* const dec,
- int* const code_lengths, HuffmanCode* const table) {
+ int* const code_lengths,
+ HuffmanTables* const table) {
int ok = 0;
int size = 0;
VP8LBitReader* const br = &dec->br_;
@@ -362,8 +364,7 @@ static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize,
VP8LMetadata* const hdr = &dec->hdr_;
uint32_t* huffman_image = NULL;
HTreeGroup* htree_groups = NULL;
- HuffmanCode* huffman_tables = NULL;
- HuffmanCode* huffman_table = NULL;
+ HuffmanTables* huffman_tables = &hdr->huffman_tables_;
int num_htree_groups = 1;
int num_htree_groups_max = 1;
int max_alphabet_size = 0;
@@ -372,6 +373,10 @@ static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize,
int* mapping = NULL;
int ok = 0;
+ // Check the table has been 0 initialized (through InitMetadata).
+ assert(huffman_tables->root.start == NULL);
+ assert(huffman_tables->curr_segment == NULL);
+
if (allow_recursion && VP8LReadBits(br, 1)) {
// use meta Huffman codes.
const int huffman_precision = VP8LReadBits(br, 3) + 2;
@@ -434,16 +439,15 @@ static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize,
code_lengths = (int*)WebPSafeCalloc((uint64_t)max_alphabet_size,
sizeof(*code_lengths));
- huffman_tables = (HuffmanCode*)WebPSafeMalloc(num_htree_groups * table_size,
- sizeof(*huffman_tables));
htree_groups = VP8LHtreeGroupsNew(num_htree_groups);
- if (htree_groups == NULL || code_lengths == NULL || huffman_tables == NULL) {
+ if (htree_groups == NULL || code_lengths == NULL ||
+ !VP8LHuffmanTablesAllocate(num_htree_groups * table_size,
+ huffman_tables)) {
dec->status_ = VP8_STATUS_OUT_OF_MEMORY;
goto Error;
}
- huffman_table = huffman_tables;
for (i = 0; i < num_htree_groups_max; ++i) {
// If the index "i" is unused in the Huffman image, just make sure the
// coefficients are valid but do not store them.
@@ -468,19 +472,20 @@ static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize,
int max_bits = 0;
for (j = 0; j < HUFFMAN_CODES_PER_META_CODE; ++j) {
int alphabet_size = kAlphabetSize[j];
- htrees[j] = huffman_table;
if (j == 0 && color_cache_bits > 0) {
alphabet_size += (1 << color_cache_bits);
}
- size = ReadHuffmanCode(alphabet_size, dec, code_lengths, huffman_table);
+ size =
+ ReadHuffmanCode(alphabet_size, dec, code_lengths, huffman_tables);
+ htrees[j] = huffman_tables->curr_segment->curr_table;
if (size == 0) {
goto Error;
}
if (is_trivial_literal && kLiteralMap[j] == 1) {
- is_trivial_literal = (huffman_table->bits == 0);
+ is_trivial_literal = (htrees[j]->bits == 0);
}
- total_size += huffman_table->bits;
- huffman_table += size;
+ total_size += htrees[j]->bits;
+ huffman_tables->curr_segment->curr_table += size;
if (j <= ALPHA) {
int local_max_bits = code_lengths[0];
int k;
@@ -515,14 +520,13 @@ static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize,
hdr->huffman_image_ = huffman_image;
hdr->num_htree_groups_ = num_htree_groups;
hdr->htree_groups_ = htree_groups;
- hdr->huffman_tables_ = huffman_tables;
Error:
WebPSafeFree(code_lengths);
WebPSafeFree(mapping);
if (!ok) {
WebPSafeFree(huffman_image);
- WebPSafeFree(huffman_tables);
+ VP8LHuffmanTablesDeallocate(huffman_tables);
VP8LHtreeGroupsFree(htree_groups);
}
return ok;
@@ -1358,7 +1362,7 @@ static void ClearMetadata(VP8LMetadata* const hdr) {
assert(hdr != NULL);
WebPSafeFree(hdr->huffman_image_);
- WebPSafeFree(hdr->huffman_tables_);
+ VP8LHuffmanTablesDeallocate(&hdr->huffman_tables_);
VP8LHtreeGroupsFree(hdr->htree_groups_);
VP8LColorCacheClear(&hdr->color_cache_);
VP8LColorCacheClear(&hdr->saved_color_cache_);
@@ -1673,7 +1677,7 @@ int VP8LDecodeImage(VP8LDecoder* const dec) {
if (dec == NULL) return 0;
- assert(dec->hdr_.huffman_tables_ != NULL);
+ assert(dec->hdr_.huffman_tables_.root.start != NULL);
assert(dec->hdr_.htree_groups_ != NULL);
assert(dec->hdr_.num_htree_groups_ > 0);
diff --git a/thirdparty/libwebp/src/dec/vp8li_dec.h b/thirdparty/libwebp/src/dec/vp8li_dec.h
index 72b2e86120..32540a4b88 100644
--- a/thirdparty/libwebp/src/dec/vp8li_dec.h
+++ b/thirdparty/libwebp/src/dec/vp8li_dec.h
@@ -51,7 +51,7 @@ typedef struct {
uint32_t* huffman_image_;
int num_htree_groups_;
HTreeGroup* htree_groups_;
- HuffmanCode* huffman_tables_;
+ HuffmanTables huffman_tables_;
} VP8LMetadata;
typedef struct VP8LDecoder VP8LDecoder;
diff --git a/thirdparty/libwebp/src/demux/demux.c b/thirdparty/libwebp/src/demux/demux.c
index fd45a2500e..4b0d3f59e9 100644
--- a/thirdparty/libwebp/src/demux/demux.c
+++ b/thirdparty/libwebp/src/demux/demux.c
@@ -25,7 +25,7 @@
#define DMUX_MAJ_VERSION 1
#define DMUX_MIN_VERSION 3
-#define DMUX_REV_VERSION 1
+#define DMUX_REV_VERSION 2
typedef struct {
size_t start_; // start location of the data
diff --git a/thirdparty/libwebp/src/enc/vp8i_enc.h b/thirdparty/libwebp/src/enc/vp8i_enc.h
index 19d9a6edb7..0864fbf1f5 100644
--- a/thirdparty/libwebp/src/enc/vp8i_enc.h
+++ b/thirdparty/libwebp/src/enc/vp8i_enc.h
@@ -32,7 +32,7 @@ extern "C" {
// version numbers
#define ENC_MAJ_VERSION 1
#define ENC_MIN_VERSION 3
-#define ENC_REV_VERSION 1
+#define ENC_REV_VERSION 2
enum { MAX_LF_LEVELS = 64, // Maximum loop filter level
MAX_VARIABLE_LEVEL = 67, // last (inclusive) level with variable cost
diff --git a/thirdparty/libwebp/src/mux/muxi.h b/thirdparty/libwebp/src/mux/muxi.h
index fc44d6f2fe..afc5954353 100644
--- a/thirdparty/libwebp/src/mux/muxi.h
+++ b/thirdparty/libwebp/src/mux/muxi.h
@@ -29,7 +29,7 @@ extern "C" {
#define MUX_MAJ_VERSION 1
#define MUX_MIN_VERSION 3
-#define MUX_REV_VERSION 1
+#define MUX_REV_VERSION 2
// Chunk object.
typedef struct WebPChunk WebPChunk;
diff --git a/thirdparty/libwebp/src/utils/huffman_utils.c b/thirdparty/libwebp/src/utils/huffman_utils.c
index 90c2fbf7c1..cf73abd437 100644
--- a/thirdparty/libwebp/src/utils/huffman_utils.c
+++ b/thirdparty/libwebp/src/utils/huffman_utils.c
@@ -177,21 +177,24 @@ static int BuildHuffmanTable(HuffmanCode* const root_table, int root_bits,
if (num_open < 0) {
return 0;
}
- if (root_table == NULL) continue;
for (; count[len] > 0; --count[len]) {
HuffmanCode code;
if ((key & mask) != low) {
- table += table_size;
+ if (root_table != NULL) table += table_size;
table_bits = NextTableBitSize(count, len, root_bits);
table_size = 1 << table_bits;
total_size += table_size;
low = key & mask;
- root_table[low].bits = (uint8_t)(table_bits + root_bits);
- root_table[low].value = (uint16_t)((table - root_table) - low);
+ if (root_table != NULL) {
+ root_table[low].bits = (uint8_t)(table_bits + root_bits);
+ root_table[low].value = (uint16_t)((table - root_table) - low);
+ }
+ }
+ if (root_table != NULL) {
+ code.bits = (uint8_t)(len - root_bits);
+ code.value = (uint16_t)sorted[symbol++];
+ ReplicateValue(&table[key >> root_bits], step, table_size, code);
}
- code.bits = (uint8_t)(len - root_bits);
- code.value = (uint16_t)sorted[symbol++];
- ReplicateValue(&table[key >> root_bits], step, table_size, code);
key = GetNextKey(key, len);
}
}
@@ -211,25 +214,83 @@ static int BuildHuffmanTable(HuffmanCode* const root_table, int root_bits,
((1 << MAX_CACHE_BITS) + NUM_LITERAL_CODES + NUM_LENGTH_CODES)
// Cut-off value for switching between heap and stack allocation.
#define SORTED_SIZE_CUTOFF 512
-int VP8LBuildHuffmanTable(HuffmanCode* const root_table, int root_bits,
+int VP8LBuildHuffmanTable(HuffmanTables* const root_table, int root_bits,
const int code_lengths[], int code_lengths_size) {
- int total_size;
+ const int total_size =
+ BuildHuffmanTable(NULL, root_bits, code_lengths, code_lengths_size, NULL);
assert(code_lengths_size <= MAX_CODE_LENGTHS_SIZE);
- if (root_table == NULL) {
- total_size = BuildHuffmanTable(NULL, root_bits,
- code_lengths, code_lengths_size, NULL);
- } else if (code_lengths_size <= SORTED_SIZE_CUTOFF) {
+ if (total_size == 0 || root_table == NULL) return total_size;
+
+ if (root_table->curr_segment->curr_table + total_size >=
+ root_table->curr_segment->start + root_table->curr_segment->size) {
+ // If 'root_table' does not have enough memory, allocate a new segment.
+ // The available part of root_table->curr_segment is left unused because we
+ // need a contiguous buffer.
+ const int segment_size = root_table->curr_segment->size;
+ struct HuffmanTablesSegment* next =
+ (HuffmanTablesSegment*)WebPSafeMalloc(1, sizeof(*next));
+ if (next == NULL) return 0;
+ // Fill the new segment.
+ // We need at least 'total_size' but if that value is small, it is better to
+ // allocate a big chunk to prevent more allocations later. 'segment_size' is
+ // therefore chosen (any other arbitrary value could be chosen).
+ next->size = total_size > segment_size ? total_size : segment_size;
+ next->start =
+ (HuffmanCode*)WebPSafeMalloc(next->size, sizeof(*next->start));
+ if (next->start == NULL) {
+ WebPSafeFree(next);
+ return 0;
+ }
+ next->curr_table = next->start;
+ next->next = NULL;
+ // Point to the new segment.
+ root_table->curr_segment->next = next;
+ root_table->curr_segment = next;
+ }
+ if (code_lengths_size <= SORTED_SIZE_CUTOFF) {
// use local stack-allocated array.
uint16_t sorted[SORTED_SIZE_CUTOFF];
- total_size = BuildHuffmanTable(root_table, root_bits,
- code_lengths, code_lengths_size, sorted);
- } else { // rare case. Use heap allocation.
+ BuildHuffmanTable(root_table->curr_segment->curr_table, root_bits,
+ code_lengths, code_lengths_size, sorted);
+ } else { // rare case. Use heap allocation.
uint16_t* const sorted =
(uint16_t*)WebPSafeMalloc(code_lengths_size, sizeof(*sorted));
if (sorted == NULL) return 0;
- total_size = BuildHuffmanTable(root_table, root_bits,
- code_lengths, code_lengths_size, sorted);
+ BuildHuffmanTable(root_table->curr_segment->curr_table, root_bits,
+ code_lengths, code_lengths_size, sorted);
WebPSafeFree(sorted);
}
return total_size;
}
+
+int VP8LHuffmanTablesAllocate(int size, HuffmanTables* huffman_tables) {
+ // Have 'segment' point to the first segment for now, 'root'.
+ HuffmanTablesSegment* const root = &huffman_tables->root;
+ huffman_tables->curr_segment = root;
+ // Allocate root.
+ root->start = (HuffmanCode*)WebPSafeMalloc(size, sizeof(*root->start));
+ if (root->start == NULL) return 0;
+ root->curr_table = root->start;
+ root->next = NULL;
+ root->size = size;
+ return 1;
+}
+
+void VP8LHuffmanTablesDeallocate(HuffmanTables* const huffman_tables) {
+ HuffmanTablesSegment *current, *next;
+ if (huffman_tables == NULL) return;
+ // Free the root node.
+ current = &huffman_tables->root;
+ next = current->next;
+ WebPSafeFree(current->start);
+ current->start = NULL;
+ current->next = NULL;
+ current = next;
+ // Free the following nodes.
+ while (current != NULL) {
+ next = current->next;
+ WebPSafeFree(current->start);
+ WebPSafeFree(current);
+ current = next;
+ }
+}
diff --git a/thirdparty/libwebp/src/utils/huffman_utils.h b/thirdparty/libwebp/src/utils/huffman_utils.h
index 13b7ad1ac4..98415c5328 100644
--- a/thirdparty/libwebp/src/utils/huffman_utils.h
+++ b/thirdparty/libwebp/src/utils/huffman_utils.h
@@ -43,6 +43,29 @@ typedef struct {
// or non-literal symbol otherwise
} HuffmanCode32;
+// Contiguous memory segment of HuffmanCodes.
+typedef struct HuffmanTablesSegment {
+ HuffmanCode* start;
+ // Pointer to where we are writing into the segment. Starts at 'start' and
+ // cannot go beyond 'start' + 'size'.
+ HuffmanCode* curr_table;
+ // Pointer to the next segment in the chain.
+ struct HuffmanTablesSegment* next;
+ int size;
+} HuffmanTablesSegment;
+
+// Chained memory segments of HuffmanCodes.
+typedef struct HuffmanTables {
+ HuffmanTablesSegment root;
+ // Currently processed segment. At first, this is 'root'.
+ HuffmanTablesSegment* curr_segment;
+} HuffmanTables;
+
+// Allocates a HuffmanTables with 'size' contiguous HuffmanCodes. Returns 0 on
+// memory allocation error, 1 otherwise.
+int VP8LHuffmanTablesAllocate(int size, HuffmanTables* huffman_tables);
+void VP8LHuffmanTablesDeallocate(HuffmanTables* const huffman_tables);
+
#define HUFFMAN_PACKED_BITS 6
#define HUFFMAN_PACKED_TABLE_SIZE (1u << HUFFMAN_PACKED_BITS)
@@ -78,9 +101,7 @@ void VP8LHtreeGroupsFree(HTreeGroup* const htree_groups);
// the huffman table.
// Returns built table size or 0 in case of error (invalid tree or
// memory error).
-// If root_table is NULL, it returns 0 if a lookup cannot be built, something
-// > 0 otherwise (but not the table size).
-int VP8LBuildHuffmanTable(HuffmanCode* const root_table, int root_bits,
+int VP8LBuildHuffmanTable(HuffmanTables* const root_table, int root_bits,
const int code_lengths[], int code_lengths_size);
#ifdef __cplusplus