diff options
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<Texture2D>("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=""0""> + 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=""0""> 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 |
