summaryrefslogtreecommitdiff
path: root/editor/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'editor/plugins')
-rw-r--r--editor/plugins/animation_blend_space_1d_editor.cpp12
-rw-r--r--editor/plugins/animation_blend_space_1d_editor.h2
-rw-r--r--editor/plugins/animation_blend_space_2d_editor.cpp15
-rw-r--r--editor/plugins/animation_blend_space_2d_editor.h4
-rw-r--r--editor/plugins/animation_blend_tree_editor_plugin.cpp24
-rw-r--r--editor/plugins/animation_blend_tree_editor_plugin.h5
-rw-r--r--editor/plugins/animation_library_editor.cpp25
-rw-r--r--editor/plugins/animation_player_editor_plugin.cpp60
-rw-r--r--editor/plugins/animation_player_editor_plugin.h2
-rw-r--r--editor/plugins/animation_state_machine_editor.cpp17
-rw-r--r--editor/plugins/animation_state_machine_editor.h3
-rw-r--r--editor/plugins/asset_library_editor_plugin.cpp1
-rw-r--r--editor/plugins/bit_map_editor_plugin.cpp2
-rw-r--r--editor/plugins/bone_map_editor_plugin.cpp4
-rw-r--r--editor/plugins/bone_map_editor_plugin.h3
-rw-r--r--editor/plugins/canvas_item_editor_plugin.cpp11
-rw-r--r--editor/plugins/canvas_item_editor_plugin.h17
-rw-r--r--editor/plugins/cast_2d_editor_plugin.cpp5
-rw-r--r--editor/plugins/cast_2d_editor_plugin.h4
-rw-r--r--editor/plugins/collision_shape_2d_editor_plugin.cpp3
-rw-r--r--editor/plugins/collision_shape_2d_editor_plugin.h2
-rw-r--r--editor/plugins/control_editor_plugin.cpp4
-rw-r--r--editor/plugins/control_editor_plugin.h2
-rw-r--r--editor/plugins/cpu_particles_2d_editor_plugin.cpp6
-rw-r--r--editor/plugins/cpu_particles_2d_editor_plugin.h2
-rw-r--r--editor/plugins/debugger_editor_plugin.cpp16
-rw-r--r--editor/plugins/debugger_editor_plugin.h1
-rw-r--r--editor/plugins/font_config_plugin.cpp1
-rw-r--r--editor/plugins/gdextension_export_plugin.h97
-rw-r--r--editor/plugins/gpu_particles_2d_editor_plugin.cpp3
-rw-r--r--editor/plugins/gpu_particles_2d_editor_plugin.h2
-rw-r--r--editor/plugins/gpu_particles_3d_editor_plugin.cpp2
-rw-r--r--editor/plugins/gradient_texture_2d_editor_plugin.cpp6
-rw-r--r--editor/plugins/gradient_texture_2d_editor_plugin.h4
-rw-r--r--editor/plugins/material_editor_plugin.h2
-rw-r--r--editor/plugins/mesh_editor_plugin.cpp2
-rw-r--r--editor/plugins/mesh_editor_plugin.h3
-rw-r--r--editor/plugins/mesh_instance_3d_editor_plugin.cpp13
-rw-r--r--editor/plugins/mesh_library_editor_plugin.cpp2
-rw-r--r--editor/plugins/multimesh_editor_plugin.cpp2
-rw-r--r--editor/plugins/navigation_link_2d_editor_plugin.cpp5
-rw-r--r--editor/plugins/navigation_link_2d_editor_plugin.h4
-rw-r--r--editor/plugins/node_3d_editor_gizmos.cpp68
-rw-r--r--editor/plugins/node_3d_editor_gizmos.h3
-rw-r--r--editor/plugins/node_3d_editor_plugin.cpp312
-rw-r--r--editor/plugins/node_3d_editor_plugin.h61
-rw-r--r--editor/plugins/path_2d_editor_plugin.cpp7
-rw-r--r--editor/plugins/path_2d_editor_plugin.h3
-rw-r--r--editor/plugins/path_3d_editor_plugin.cpp64
-rw-r--r--editor/plugins/physical_bone_3d_editor_plugin.cpp1
-rw-r--r--editor/plugins/polygon_2d_editor_plugin.cpp4
-rw-r--r--editor/plugins/polygon_3d_editor_plugin.cpp6
-rw-r--r--editor/plugins/polygon_3d_editor_plugin.h2
-rw-r--r--editor/plugins/resource_preloader_editor_plugin.cpp10
-rw-r--r--editor/plugins/resource_preloader_editor_plugin.h5
-rw-r--r--editor/plugins/root_motion_editor_plugin.cpp1
-rw-r--r--editor/plugins/script_editor_plugin.cpp2
-rw-r--r--editor/plugins/script_editor_plugin.h24
-rw-r--r--editor/plugins/script_text_editor.cpp102
-rw-r--r--editor/plugins/script_text_editor.h6
-rw-r--r--editor/plugins/shader_editor_plugin.cpp3
-rw-r--r--editor/plugins/shader_editor_plugin.h1
-rw-r--r--editor/plugins/shader_file_editor_plugin.cpp2
-rw-r--r--editor/plugins/skeleton_2d_editor_plugin.cpp1
-rw-r--r--editor/plugins/skeleton_3d_editor_plugin.cpp6
-rw-r--r--editor/plugins/skeleton_3d_editor_plugin.h6
-rw-r--r--editor/plugins/sprite_2d_editor_plugin.cpp1
-rw-r--r--editor/plugins/sprite_frames_editor_plugin.cpp22
-rw-r--r--editor/plugins/sprite_frames_editor_plugin.h5
-rw-r--r--editor/plugins/style_box_editor_plugin.cpp1
-rw-r--r--editor/plugins/style_box_editor_plugin.h2
-rw-r--r--editor/plugins/text_editor.cpp5
-rw-r--r--editor/plugins/text_editor.h2
-rw-r--r--editor/plugins/texture_3d_editor_plugin.cpp2
-rw-r--r--editor/plugins/texture_editor_plugin.cpp2
-rw-r--r--editor/plugins/texture_layered_editor_plugin.cpp2
-rw-r--r--editor/plugins/texture_region_editor_plugin.cpp4
-rw-r--r--editor/plugins/texture_region_editor_plugin.h4
-rw-r--r--editor/plugins/theme_editor_plugin.cpp2
-rw-r--r--editor/plugins/theme_editor_preview.cpp3
-rw-r--r--editor/plugins/tiles/atlas_merging_dialog.cpp6
-rw-r--r--editor/plugins/tiles/atlas_merging_dialog.h3
-rw-r--r--editor/plugins/tiles/tile_data_editors.cpp62
-rw-r--r--editor/plugins/tiles/tile_data_editors.h12
-rw-r--r--editor/plugins/tiles/tile_map_editor.cpp39
-rw-r--r--editor/plugins/tiles/tile_map_editor.h5
-rw-r--r--editor/plugins/tiles/tile_proxies_manager_dialog.cpp13
-rw-r--r--editor/plugins/tiles/tile_proxies_manager_dialog.h6
-rw-r--r--editor/plugins/tiles/tile_set_atlas_source_editor.cpp54
-rw-r--r--editor/plugins/tiles/tile_set_atlas_source_editor.h3
-rw-r--r--editor/plugins/tiles/tile_set_editor.cpp17
-rw-r--r--editor/plugins/tiles/tile_set_editor.h4
-rw-r--r--editor/plugins/tiles/tile_set_scenes_collection_source_editor.cpp1
-rw-r--r--editor/plugins/tiles/tiles_editor_plugin.cpp14
-rw-r--r--editor/plugins/tiles/tiles_editor_plugin.h2
-rw-r--r--editor/plugins/version_control_editor_plugin.cpp5
-rw-r--r--editor/plugins/visual_shader_editor_plugin.cpp341
-rw-r--r--editor/plugins/visual_shader_editor_plugin.h19
98 files changed, 1227 insertions, 536 deletions
diff --git a/editor/plugins/animation_blend_space_1d_editor.cpp b/editor/plugins/animation_blend_space_1d_editor.cpp
index d11217cc5e..e64b80abbd 100644
--- a/editor/plugins/animation_blend_space_1d_editor.cpp
+++ b/editor/plugins/animation_blend_space_1d_editor.cpp
@@ -37,6 +37,8 @@
#include "editor/editor_settings.h"
#include "editor/editor_undo_redo_manager.h"
#include "scene/animation/animation_blend_tree.h"
+#include "scene/gui/check_box.h"
+#include "scene/gui/panel_container.h"
StringName AnimationNodeBlendSpace1DEditor::get_blend_position_path() const {
StringName path = AnimationTreeEditor::get_singleton()->get_base_path() + "blend_position";
@@ -153,6 +155,7 @@ void AnimationNodeBlendSpace1DEditor::_blend_space_gui_input(const Ref<InputEven
}
updating = true;
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Move Node Point"));
undo_redo->add_do_method(blend_space.ptr(), "set_blend_point_position", selected_point, point);
undo_redo->add_undo_method(blend_space.ptr(), "set_blend_point_position", selected_point, blend_space->get_blend_point_position(selected_point));
@@ -341,6 +344,7 @@ void AnimationNodeBlendSpace1DEditor::_config_changed(double) {
}
updating = true;
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Change BlendSpace1D Config"));
undo_redo->add_do_method(blend_space.ptr(), "set_max_space", max_value->get_value());
undo_redo->add_undo_method(blend_space.ptr(), "set_max_space", blend_space->get_max_space());
@@ -364,6 +368,7 @@ void AnimationNodeBlendSpace1DEditor::_labels_changed(String) {
}
updating = true;
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Change BlendSpace1D Labels"), UndoRedo::MERGE_ENDS);
undo_redo->add_do_method(blend_space.ptr(), "set_value_label", label_value->get_text());
undo_redo->add_undo_method(blend_space.ptr(), "set_value_label", blend_space->get_value_label());
@@ -419,6 +424,7 @@ void AnimationNodeBlendSpace1DEditor::_add_menu_type(int p_index) {
}
updating = true;
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Add Node Point"));
undo_redo->add_do_method(blend_space.ptr(), "add_blend_point", node, add_point_pos);
undo_redo->add_undo_method(blend_space.ptr(), "remove_blend_point", blend_space->get_blend_point_count());
@@ -437,6 +443,7 @@ void AnimationNodeBlendSpace1DEditor::_add_animation_type(int p_index) {
anim->set_animation(animations_to_add[p_index]);
updating = true;
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Add Animation Point"));
undo_redo->add_do_method(blend_space.ptr(), "add_blend_point", anim, add_point_pos);
undo_redo->add_undo_method(blend_space.ptr(), "remove_blend_point", blend_space->get_blend_point_count());
@@ -510,6 +517,7 @@ void AnimationNodeBlendSpace1DEditor::_erase_selected() {
if (selected_point != -1) {
updating = true;
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Remove BlendSpace1D Point"));
undo_redo->add_do_method(blend_space.ptr(), "remove_blend_point", selected_point);
undo_redo->add_undo_method(blend_space.ptr(), "add_blend_point", blend_space->get_blend_point_node(selected_point), blend_space->get_blend_point_position(selected_point), selected_point);
@@ -529,6 +537,7 @@ void AnimationNodeBlendSpace1DEditor::_edit_point_pos(double) {
}
updating = true;
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Move BlendSpace1D Node Point"));
undo_redo->add_do_method(blend_space.ptr(), "set_blend_point_position", selected_point, edit_value->get_value());
undo_redo->add_undo_method(blend_space.ptr(), "set_blend_point_position", selected_point, blend_space->get_blend_point_position(selected_point));
@@ -762,8 +771,6 @@ AnimationNodeBlendSpace1DEditor::AnimationNodeBlendSpace1DEditor() {
error_panel->add_child(error_label);
error_label->set_text("hmmm");
- undo_redo = EditorNode::get_undo_redo();
-
menu = memnew(PopupMenu);
add_child(menu);
menu->connect("id_pressed", callable_mp(this, &AnimationNodeBlendSpace1DEditor::_add_menu_type));
@@ -778,7 +785,6 @@ AnimationNodeBlendSpace1DEditor::AnimationNodeBlendSpace1DEditor() {
open_file->set_title(TTR("Open Animation Node"));
open_file->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILE);
open_file->connect("file_selected", callable_mp(this, &AnimationNodeBlendSpace1DEditor::_file_opened));
- undo_redo = EditorNode::get_undo_redo();
set_custom_minimum_size(Size2(0, 150 * EDSCALE));
}
diff --git a/editor/plugins/animation_blend_space_1d_editor.h b/editor/plugins/animation_blend_space_1d_editor.h
index 54aa227c96..ec07678b27 100644
--- a/editor/plugins/animation_blend_space_1d_editor.h
+++ b/editor/plugins/animation_blend_space_1d_editor.h
@@ -80,8 +80,6 @@ class AnimationNodeBlendSpace1DEditor : public AnimationTreeNodeEditorPlugin {
bool updating = false;
- Ref<EditorUndoRedoManager> undo_redo;
-
static AnimationNodeBlendSpace1DEditor *singleton;
void _blend_space_gui_input(const Ref<InputEvent> &p_event);
diff --git a/editor/plugins/animation_blend_space_2d_editor.cpp b/editor/plugins/animation_blend_space_2d_editor.cpp
index 0adac598a6..4d8e972883 100644
--- a/editor/plugins/animation_blend_space_2d_editor.cpp
+++ b/editor/plugins/animation_blend_space_2d_editor.cpp
@@ -42,9 +42,12 @@
#include "editor/editor_undo_redo_manager.h"
#include "scene/animation/animation_blend_tree.h"
#include "scene/animation/animation_player.h"
+#include "scene/gui/check_box.h"
#include "scene/gui/grid_container.h"
#include "scene/gui/menu_button.h"
+#include "scene/gui/option_button.h"
#include "scene/gui/panel.h"
+#include "scene/gui/panel_container.h"
#include "scene/main/window.h"
bool AnimationNodeBlendSpace2DEditor::can_edit(const Ref<AnimationNode> &p_node) {
@@ -222,6 +225,7 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_gui_input(const Ref<InputEven
}
updating = true;
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Add Triangle"));
undo_redo->add_do_method(blend_space.ptr(), "add_triangle", making_triangle[0], making_triangle[1], making_triangle[2]);
undo_redo->add_undo_method(blend_space.ptr(), "remove_triangle", blend_space->get_triangle_count());
@@ -247,6 +251,7 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_gui_input(const Ref<InputEven
if (!read_only) {
updating = true;
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Move Node Point"));
undo_redo->add_do_method(blend_space.ptr(), "set_blend_point_position", selected_point, point);
undo_redo->add_undo_method(blend_space.ptr(), "set_blend_point_position", selected_point, blend_space->get_blend_point_position(selected_point));
@@ -354,6 +359,7 @@ void AnimationNodeBlendSpace2DEditor::_add_menu_type(int p_index) {
}
updating = true;
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Add Node Point"));
undo_redo->add_do_method(blend_space.ptr(), "add_blend_point", node, add_point_pos);
undo_redo->add_undo_method(blend_space.ptr(), "remove_blend_point", blend_space->get_blend_point_count());
@@ -372,6 +378,7 @@ void AnimationNodeBlendSpace2DEditor::_add_animation_type(int p_index) {
anim->set_animation(animations_to_add[p_index]);
updating = true;
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Add Animation Point"));
undo_redo->add_do_method(blend_space.ptr(), "add_blend_point", anim, add_point_pos);
undo_redo->add_undo_method(blend_space.ptr(), "remove_blend_point", blend_space->get_blend_point_count());
@@ -661,6 +668,7 @@ void AnimationNodeBlendSpace2DEditor::_config_changed(double) {
}
updating = true;
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Change BlendSpace2D Config"));
undo_redo->add_do_method(blend_space.ptr(), "set_max_space", Vector2(max_x_value->get_value(), max_y_value->get_value()));
undo_redo->add_undo_method(blend_space.ptr(), "set_max_space", blend_space->get_max_space());
@@ -686,6 +694,7 @@ void AnimationNodeBlendSpace2DEditor::_labels_changed(String) {
}
updating = true;
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Change BlendSpace2D Labels"), UndoRedo::MERGE_ENDS);
undo_redo->add_do_method(blend_space.ptr(), "set_x_label", label_x->get_text());
undo_redo->add_undo_method(blend_space.ptr(), "set_x_label", blend_space->get_x_label());
@@ -698,6 +707,7 @@ void AnimationNodeBlendSpace2DEditor::_labels_changed(String) {
}
void AnimationNodeBlendSpace2DEditor::_erase_selected() {
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
if (selected_point != -1) {
updating = true;
undo_redo->create_action(TTR("Remove BlendSpace2D Point"));
@@ -760,6 +770,7 @@ void AnimationNodeBlendSpace2DEditor::_edit_point_pos(double) {
return;
}
updating = true;
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Move Node Point"));
undo_redo->add_do_method(blend_space.ptr(), "set_blend_point_position", selected_point, Vector2(edit_x->get_value(), edit_y->get_value()));
undo_redo->add_undo_method(blend_space.ptr(), "set_blend_point_position", selected_point, blend_space->get_blend_point_position(selected_point));
@@ -836,6 +847,7 @@ void AnimationNodeBlendSpace2DEditor::_removed_from_graph() {
}
void AnimationNodeBlendSpace2DEditor::_auto_triangles_toggled() {
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Toggle Auto Triangles"));
undo_redo->add_do_method(blend_space.ptr(), "set_auto_triangles", auto_triangles->is_pressed());
undo_redo->add_undo_method(blend_space.ptr(), "set_auto_triangles", blend_space->get_auto_triangles());
@@ -1059,8 +1071,6 @@ AnimationNodeBlendSpace2DEditor::AnimationNodeBlendSpace2DEditor() {
error_panel->add_child(error_label);
error_label->set_text("eh");
- undo_redo = EditorNode::get_undo_redo();
-
set_custom_minimum_size(Size2(0, 300 * EDSCALE));
menu = memnew(PopupMenu);
@@ -1077,7 +1087,6 @@ AnimationNodeBlendSpace2DEditor::AnimationNodeBlendSpace2DEditor() {
open_file->set_title(TTR("Open Animation Node"));
open_file->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILE);
open_file->connect("file_selected", callable_mp(this, &AnimationNodeBlendSpace2DEditor::_file_opened));
- undo_redo = EditorNode::get_undo_redo();
selected_point = -1;
selected_triangle = -1;
diff --git a/editor/plugins/animation_blend_space_2d_editor.h b/editor/plugins/animation_blend_space_2d_editor.h
index e4512b78a3..60873e5473 100644
--- a/editor/plugins/animation_blend_space_2d_editor.h
+++ b/editor/plugins/animation_blend_space_2d_editor.h
@@ -44,8 +44,6 @@ class CheckBox;
class OptionButton;
class PanelContainer;
-class EditorUndoRedoManager;
-
class AnimationNodeBlendSpace2DEditor : public AnimationTreeNodeEditorPlugin {
GDCLASS(AnimationNodeBlendSpace2DEditor, AnimationTreeNodeEditorPlugin);
@@ -89,8 +87,6 @@ class AnimationNodeBlendSpace2DEditor : public AnimationTreeNodeEditorPlugin {
bool updating;
- Ref<EditorUndoRedoManager> undo_redo;
-
static AnimationNodeBlendSpace2DEditor *singleton;
void _blend_space_gui_input(const Ref<InputEvent> &p_event);
diff --git a/editor/plugins/animation_blend_tree_editor_plugin.cpp b/editor/plugins/animation_blend_tree_editor_plugin.cpp
index 1a4774b98b..dbd1b12a94 100644
--- a/editor/plugins/animation_blend_tree_editor_plugin.cpp
+++ b/editor/plugins/animation_blend_tree_editor_plugin.cpp
@@ -41,9 +41,11 @@
#include "editor/editor_settings.h"
#include "editor/editor_undo_redo_manager.h"
#include "scene/animation/animation_player.h"
+#include "scene/gui/check_box.h"
#include "scene/gui/menu_button.h"
#include "scene/gui/panel.h"
#include "scene/gui/progress_bar.h"
+#include "scene/gui/separator.h"
#include "scene/gui/view_panner.h"
#include "scene/main/window.h"
@@ -98,6 +100,7 @@ Size2 AnimationNodeBlendTreeEditor::get_minimum_size() const {
void AnimationNodeBlendTreeEditor::_property_changed(const StringName &p_property, const Variant &p_value, const String &p_field, bool p_changing) {
AnimationTree *tree = AnimationTreeEditor::get_singleton()->get_animation_tree();
updating = true;
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Parameter Changed:") + " " + String(p_property), UndoRedo::MERGE_ENDS);
undo_redo->add_do_property(tree, p_property, p_value);
undo_redo->add_undo_property(tree, p_property, tree->get(p_property));
@@ -353,6 +356,7 @@ void AnimationNodeBlendTreeEditor::_add_node(int p_idx) {
name = base_name + " " + itos(base);
}
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Add Node to BlendTree"));
undo_redo->add_do_method(blend_tree.ptr(), "add_node", name, anode, instance_pos / EDSCALE);
undo_redo->add_undo_method(blend_tree.ptr(), "remove_node", name);
@@ -372,11 +376,11 @@ void AnimationNodeBlendTreeEditor::_add_node(int p_idx) {
undo_redo->commit_action();
}
-void AnimationNodeBlendTreeEditor::_popup(bool p_has_input_ports, const Vector2 &p_popup_position, const Vector2 &p_node_position) {
+void AnimationNodeBlendTreeEditor::_popup(bool p_has_input_ports, const Vector2 &p_node_position) {
_update_options_menu(p_has_input_ports);
use_position_from_popup_menu = true;
position_from_popup_menu = p_node_position;
- add_node->get_popup()->set_position(p_popup_position);
+ add_node->get_popup()->set_position(graph->get_screen_position() + graph->get_local_mouse_position());
add_node->get_popup()->reset_size();
add_node->get_popup()->popup();
}
@@ -386,7 +390,7 @@ void AnimationNodeBlendTreeEditor::_popup_request(const Vector2 &p_position) {
return;
}
- _popup(false, graph->get_screen_position() + graph->get_local_mouse_position(), p_position);
+ _popup(false, p_position);
}
void AnimationNodeBlendTreeEditor::_connection_to_empty(const String &p_from, int p_from_slot, const Vector2 &p_release_position) {
@@ -397,7 +401,7 @@ void AnimationNodeBlendTreeEditor::_connection_to_empty(const String &p_from, in
Ref<AnimationNode> node = blend_tree->get_node(p_from);
if (node.is_valid()) {
from_node = p_from;
- _popup(true, p_release_position, graph->get_global_mouse_position());
+ _popup(true, p_release_position);
}
}
@@ -410,12 +414,13 @@ void AnimationNodeBlendTreeEditor::_connection_from_empty(const String &p_to, in
if (node.is_valid()) {
to_node = p_to;
to_slot = p_to_slot;
- _popup(false, p_release_position, graph->get_global_mouse_position());
+ _popup(false, p_release_position);
}
}
void AnimationNodeBlendTreeEditor::_node_dragged(const Vector2 &p_from, const Vector2 &p_to, const StringName &p_which) {
updating = true;
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Node Moved"));
undo_redo->add_do_method(blend_tree.ptr(), "set_node_position", p_which, p_to / EDSCALE);
undo_redo->add_undo_method(blend_tree.ptr(), "set_node_position", p_which, p_from / EDSCALE);
@@ -437,6 +442,7 @@ void AnimationNodeBlendTreeEditor::_connection_request(const String &p_from, int
return;
}
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Nodes Connected"));
undo_redo->add_do_method(blend_tree.ptr(), "connect_node", p_to, p_to_index, p_from);
undo_redo->add_undo_method(blend_tree.ptr(), "disconnect_node", p_to, p_to_index);
@@ -453,6 +459,7 @@ void AnimationNodeBlendTreeEditor::_disconnection_request(const String &p_from,
graph->disconnect_node(p_from, p_from_index, p_to, p_to_index);
updating = true;
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Nodes Disconnected"));
undo_redo->add_do_method(blend_tree.ptr(), "disconnect_node", p_to, p_to_index);
undo_redo->add_undo_method(blend_tree.ptr(), "connect_node", p_to, p_to_index, p_from);
@@ -468,6 +475,7 @@ void AnimationNodeBlendTreeEditor::_anim_selected(int p_index, Array p_options,
Ref<AnimationNodeAnimation> anim = blend_tree->get_node(p_node);
ERR_FAIL_COND(!anim.is_valid());
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Set Animation"));
undo_redo->add_do_method(anim.ptr(), "set_animation", option);
undo_redo->add_undo_method(anim.ptr(), "set_animation", anim->get_animation());
@@ -481,6 +489,7 @@ void AnimationNodeBlendTreeEditor::_delete_request(const String &p_which) {
return;
}
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Delete Node"));
undo_redo->add_do_method(blend_tree.ptr(), "remove_node", p_which);
undo_redo->add_undo_method(blend_tree.ptr(), "add_node", p_which, blend_tree->get_node(p_which), blend_tree.ptr()->get_node_position(p_which));
@@ -525,6 +534,7 @@ void AnimationNodeBlendTreeEditor::_delete_nodes_request(const TypedArray<String
return;
}
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Delete Node(s)"));
for (const StringName &F : to_erase) {
@@ -558,6 +568,7 @@ void AnimationNodeBlendTreeEditor::_open_in_editor(const String &p_which) {
void AnimationNodeBlendTreeEditor::_filter_toggled() {
updating = true;
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Toggle Filter On/Off"));
undo_redo->add_do_method(_filter_edit.ptr(), "set_filter_enabled", filter_enabled->is_pressed());
undo_redo->add_undo_method(_filter_edit.ptr(), "set_filter_enabled", _filter_edit->is_filter_enabled());
@@ -575,6 +586,7 @@ void AnimationNodeBlendTreeEditor::_filter_edited() {
bool filtered = edited->is_checked(0);
updating = true;
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Change Filter"));
undo_redo->add_do_method(_filter_edit.ptr(), "set_filter_path", edited_path, filtered);
undo_redo->add_undo_method(_filter_edit.ptr(), "set_filter_path", edited_path, _filter_edit->is_path_filtered(edited_path));
@@ -949,6 +961,7 @@ void AnimationNodeBlendTreeEditor::_node_renamed(const String &p_text, Ref<Anima
String base_path = AnimationTreeEditor::get_singleton()->get_base_path();
updating = true;
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Node Renamed"));
undo_redo->add_do_method(blend_tree.ptr(), "rename_node", prev_name, name);
undo_redo->add_undo_method(blend_tree.ptr(), "rename_node", name, prev_name);
@@ -1117,5 +1130,4 @@ AnimationNodeBlendTreeEditor::AnimationNodeBlendTreeEditor() {
open_file->set_title(TTR("Open Animation Node"));
open_file->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILE);
open_file->connect("file_selected", callable_mp(this, &AnimationNodeBlendTreeEditor::_file_opened));
- undo_redo = EditorNode::get_undo_redo();
}
diff --git a/editor/plugins/animation_blend_tree_editor_plugin.h b/editor/plugins/animation_blend_tree_editor_plugin.h
index 112c824d8e..4b55aa9b3f 100644
--- a/editor/plugins/animation_blend_tree_editor_plugin.h
+++ b/editor/plugins/animation_blend_tree_editor_plugin.h
@@ -44,7 +44,6 @@ class CheckBox;
class ProgressBar;
class EditorFileDialog;
class EditorProperty;
-class EditorUndoRedoManager;
class MenuButton;
class PanelContainer;
@@ -63,8 +62,6 @@ class AnimationNodeBlendTreeEditor : public AnimationTreeNodeEditorPlugin {
PanelContainer *error_panel = nullptr;
Label *error_label = nullptr;
- Ref<EditorUndoRedoManager> undo_redo;
-
AcceptDialog *filter_dialog = nullptr;
Tree *filters = nullptr;
CheckBox *filter_enabled = nullptr;
@@ -120,7 +117,7 @@ class AnimationNodeBlendTreeEditor : public AnimationTreeNodeEditorPlugin {
void _filter_toggled();
Ref<AnimationNode> _filter_edit;
- void _popup(bool p_has_input_ports, const Vector2 &p_popup_position, const Vector2 &p_node_position);
+ void _popup(bool p_has_input_ports, const Vector2 &p_node_position);
void _popup_request(const Vector2 &p_position);
void _connection_to_empty(const String &p_from, int p_from_slot, const Vector2 &p_release_position);
void _connection_from_empty(const String &p_to, int p_to_slot, const Vector2 &p_release_position);
diff --git a/editor/plugins/animation_library_editor.cpp b/editor/plugins/animation_library_editor.cpp
index 2d20c0cca7..10b5271fc8 100644
--- a/editor/plugins/animation_library_editor.cpp
+++ b/editor/plugins/animation_library_editor.cpp
@@ -32,6 +32,7 @@
#include "editor/editor_file_dialog.h"
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
+#include "editor/editor_settings.h"
#include "editor/editor_undo_redo_manager.h"
void AnimationLibraryEditor::set_animation_player(Object *p_player) {
@@ -93,7 +94,7 @@ void AnimationLibraryEditor::_add_library_validate(const String &p_name) {
void AnimationLibraryEditor::_add_library_confirm() {
if (adding_animation) {
String anim_name = add_library_name->get_text();
- Ref<EditorUndoRedoManager> undo_redo = EditorNode::get_singleton()->get_undo_redo();
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_singleton()->get_undo_redo();
Ref<AnimationLibrary> al = player->call("get_animation_library", adding_animation_to_library);
ERR_FAIL_COND(!al.is_valid());
@@ -110,7 +111,7 @@ void AnimationLibraryEditor::_add_library_confirm() {
} else {
String lib_name = add_library_name->get_text();
- Ref<EditorUndoRedoManager> undo_redo = EditorNode::get_singleton()->get_undo_redo();
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_singleton()->get_undo_redo();
Ref<AnimationLibrary> al;
al.instantiate();
@@ -210,7 +211,7 @@ void AnimationLibraryEditor::_file_popup_selected(int p_id) {
ald->add_animation(animation_name, animation);
}
- Ref<EditorUndoRedoManager> undo_redo = EditorNode::get_singleton()->get_undo_redo();
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_singleton()->get_undo_redo();
undo_redo->create_action(vformat(TTR("Make Animation Library Unique: %s"), lib_name));
undo_redo->add_do_method(player, "remove_animation_library", lib_name);
undo_redo->add_do_method(player, "add_animation_library", lib_name, ald);
@@ -279,7 +280,7 @@ void AnimationLibraryEditor::_file_popup_selected(int p_id) {
Ref<Animation> animd = anim->duplicate();
- Ref<EditorUndoRedoManager> undo_redo = EditorNode::get_singleton()->get_undo_redo();
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_singleton()->get_undo_redo();
undo_redo->create_action(vformat(TTR("Make Animation Unique: %s"), anim_name));
undo_redo->add_do_method(al.ptr(), "remove_animation", anim_name);
undo_redo->add_do_method(al.ptr(), "add_animation", anim_name, animd);
@@ -327,7 +328,7 @@ void AnimationLibraryEditor::_load_file(String p_path) {
name = p_path.get_file().get_basename() + " " + itos(attempt);
}
- Ref<EditorUndoRedoManager> undo_redo = EditorNode::get_singleton()->get_undo_redo();
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_singleton()->get_undo_redo();
undo_redo->create_action(vformat(TTR("Add Animation Library: %s"), name));
undo_redo->add_do_method(player, "add_animation_library", name, al);
@@ -365,7 +366,7 @@ void AnimationLibraryEditor::_load_file(String p_path) {
name = p_path.get_file().get_basename() + " " + itos(attempt);
}
- Ref<EditorUndoRedoManager> undo_redo = EditorNode::get_singleton()->get_undo_redo();
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_singleton()->get_undo_redo();
undo_redo->create_action(vformat(TTR("Load Animation into Library: %s"), name));
undo_redo->add_do_method(al.ptr(), "add_animation", name, anim);
@@ -381,7 +382,7 @@ void AnimationLibraryEditor::_load_file(String p_path) {
EditorNode::get_singleton()->save_resource_in_path(al, p_path);
if (al->get_path() != prev_path) { // Save successful.
- Ref<EditorUndoRedoManager> undo_redo = EditorNode::get_singleton()->get_undo_redo();
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_singleton()->get_undo_redo();
undo_redo->create_action(vformat(TTR("Save Animation library to File: %s"), file_dialog_library));
undo_redo->add_do_method(al.ptr(), "set_path", al->get_path());
@@ -402,7 +403,7 @@ void AnimationLibraryEditor::_load_file(String p_path) {
String prev_path = anim->get_path();
EditorNode::get_singleton()->save_resource_in_path(anim, p_path);
if (anim->get_path() != prev_path) { // Save successful.
- Ref<EditorUndoRedoManager> undo_redo = EditorNode::get_singleton()->get_undo_redo();
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_singleton()->get_undo_redo();
undo_redo->create_action(vformat(TTR("Save Animation to File: %s"), file_dialog_animation));
undo_redo->add_do_method(anim.ptr(), "set_path", anim->get_path());
@@ -420,7 +421,7 @@ void AnimationLibraryEditor::_item_renamed() {
String text = ti->get_text(0);
String old_text = ti->get_metadata(0);
bool restore_text = false;
- Ref<EditorUndoRedoManager> undo_redo = EditorNode::get_singleton()->get_undo_redo();
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_singleton()->get_undo_redo();
if (String(text).contains("/") || String(text).contains(":") || String(text).contains(",") || String(text).contains("[")) {
restore_text = true;
@@ -534,7 +535,7 @@ void AnimationLibraryEditor::_button_pressed(TreeItem *p_item, int p_column, int
name = base_name + " (" + itos(attempt) + ")";
}
- Ref<EditorUndoRedoManager> undo_redo = EditorNode::get_singleton()->get_undo_redo();
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_singleton()->get_undo_redo();
undo_redo->create_action(vformat(TTR("Add Animation to Library: %s"), name));
undo_redo->add_do_method(al.ptr(), "add_animation", name, anim);
@@ -560,7 +561,7 @@ void AnimationLibraryEditor::_button_pressed(TreeItem *p_item, int p_column, int
file_dialog_library = lib_name;
} break;
case LIB_BUTTON_DELETE: {
- Ref<EditorUndoRedoManager> undo_redo = EditorNode::get_singleton()->get_undo_redo();
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_singleton()->get_undo_redo();
undo_redo->create_action(vformat(TTR("Remove Animation Library: %s"), lib_name));
undo_redo->add_do_method(player, "remove_animation_library", lib_name);
undo_redo->add_undo_method(player, "add_animation_library", lib_name, al);
@@ -601,7 +602,7 @@ void AnimationLibraryEditor::_button_pressed(TreeItem *p_item, int p_column, int
} break;
case ANIM_BUTTON_DELETE: {
- Ref<EditorUndoRedoManager> undo_redo = EditorNode::get_singleton()->get_undo_redo();
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_singleton()->get_undo_redo();
undo_redo->create_action(vformat(TTR("Remove Animation from Library: %s"), anim_name));
undo_redo->add_do_method(al.ptr(), "remove_animation", anim_name);
undo_redo->add_undo_method(al.ptr(), "add_animation", anim_name, anim);
diff --git a/editor/plugins/animation_player_editor_plugin.cpp b/editor/plugins/animation_player_editor_plugin.cpp
index 85739d0d8f..5183a738ae 100644
--- a/editor/plugins/animation_player_editor_plugin.cpp
+++ b/editor/plugins/animation_player_editor_plugin.cpp
@@ -40,9 +40,11 @@
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
#include "editor/editor_undo_redo_manager.h"
+#include "editor/inspector_dock.h"
#include "editor/plugins/canvas_item_editor_plugin.h" // For onion skinning.
#include "editor/plugins/node_3d_editor_plugin.h" // For onion skinning.
#include "editor/scene_tree_dock.h"
+#include "scene/gui/separator.h"
#include "scene/main/window.h"
#include "scene/resources/animation.h"
#include "scene/scene_string_names.h"
@@ -197,6 +199,7 @@ void AnimationPlayerEditor::_play_pressed() {
if (current == player->get_assigned_animation()) {
player->stop(); //so it won't blend with itself
}
+ ERR_FAIL_COND_EDMSG(!_validate_tracks(player->get_animation(current)), "Animation tracks may have any invalid key, abort playing.");
player->play(current);
}
@@ -209,13 +212,12 @@ void AnimationPlayerEditor::_play_from_pressed() {
if (!current.is_empty()) {
float time = player->get_current_animation_position();
-
if (current == player->get_assigned_animation() && player->is_playing()) {
player->stop(); //so it won't blend with itself
}
-
- player->play(current);
+ ERR_FAIL_COND_EDMSG(!_validate_tracks(player->get_animation(current)), "Animation tracks may have any invalid key, abort playing.");
player->seek(time);
+ player->play(current);
}
//unstop
@@ -235,6 +237,7 @@ void AnimationPlayerEditor::_play_bw_pressed() {
if (current == player->get_assigned_animation()) {
player->stop(); //so it won't blend with itself
}
+ ERR_FAIL_COND_EDMSG(!_validate_tracks(player->get_animation(current)), "Animation tracks may have any invalid key, abort playing.");
player->play(current, -1, -1, true);
}
@@ -250,9 +253,9 @@ void AnimationPlayerEditor::_play_bw_from_pressed() {
if (current == player->get_assigned_animation()) {
player->stop(); //so it won't blend with itself
}
-
- player->play(current, -1, -1, true);
+ ERR_FAIL_COND_EDMSG(!_validate_tracks(player->get_animation(current)), "Animation tracks may have any invalid key, abort playing.");
player->seek(time);
+ player->play(current, -1, -1, true);
}
//unstop
@@ -1562,6 +1565,53 @@ void AnimationPlayerEditor::_pin_pressed() {
SceneTreeDock::get_singleton()->get_tree_editor()->update_tree();
}
+bool AnimationPlayerEditor::_validate_tracks(const Ref<Animation> p_anim) {
+ bool is_valid = true;
+ if (!p_anim.is_valid()) {
+ return true; // There is a problem outside of the animation track.
+ }
+ int len = p_anim->get_track_count();
+ for (int i = 0; i < len; i++) {
+ Animation::TrackType ttype = p_anim->track_get_type(i);
+ if (ttype == Animation::TYPE_ROTATION_3D) {
+ int key_len = p_anim->track_get_key_count(i);
+ for (int j = 0; j < key_len; j++) {
+ Quaternion q;
+ p_anim->rotation_track_get_key(i, j, &q);
+ ERR_BREAK_EDMSG(!q.is_normalized(), "AnimationPlayer: '" + player->get_name() + "', Animation: '" + player->get_current_animation() + "', rotation track: '" + p_anim->track_get_path(i) + "' contains unnormalized Quaternion key.");
+ }
+ } else if (ttype == Animation::TYPE_VALUE) {
+ int key_len = p_anim->track_get_key_count(i);
+ if (key_len == 0) {
+ continue;
+ }
+ switch (p_anim->track_get_key_value(i, 0).get_type()) {
+ case Variant::QUATERNION: {
+ for (int j = 0; j < key_len; j++) {
+ Quaternion q = Quaternion(p_anim->track_get_key_value(i, j));
+ if (!q.is_normalized()) {
+ is_valid = false;
+ ERR_BREAK_EDMSG(true, "AnimationPlayer: '" + player->get_name() + "', Animation: '" + player->get_current_animation() + "', value track: '" + p_anim->track_get_path(i) + "' contains unnormalized Quaternion key.");
+ }
+ }
+ } break;
+ case Variant::TRANSFORM3D: {
+ for (int j = 0; j < key_len; j++) {
+ Transform3D t = Transform3D(p_anim->track_get_key_value(i, j));
+ if (!t.basis.orthonormalized().is_rotation()) {
+ is_valid = false;
+ ERR_BREAK_EDMSG(true, "AnimationPlayer: '" + player->get_name() + "', Animation: '" + player->get_current_animation() + "', value track: '" + p_anim->track_get_path(i) + "' contains corrupted basis (some axes are too close other axis or scaled by zero) Transform3D key.");
+ }
+ }
+ } break;
+ default: {
+ } break;
+ }
+ }
+ }
+ return is_valid;
+}
+
void AnimationPlayerEditor::_bind_methods() {
ClassDB::bind_method(D_METHOD("_animation_new"), &AnimationPlayerEditor::_animation_new);
ClassDB::bind_method(D_METHOD("_animation_rename"), &AnimationPlayerEditor::_animation_rename);
diff --git a/editor/plugins/animation_player_editor_plugin.h b/editor/plugins/animation_player_editor_plugin.h
index 6370b00ea8..53d460fc9e 100644
--- a/editor/plugins/animation_player_editor_plugin.h
+++ b/editor/plugins/animation_player_editor_plugin.h
@@ -212,6 +212,8 @@ class AnimationPlayerEditor : public VBoxContainer {
void _start_onion_skinning();
void _stop_onion_skinning();
+ bool _validate_tracks(const Ref<Animation> p_anim);
+
void _pin_pressed();
String _get_current() const;
diff --git a/editor/plugins/animation_state_machine_editor.cpp b/editor/plugins/animation_state_machine_editor.cpp
index 060e9d0d10..ef9477abea 100644
--- a/editor/plugins/animation_state_machine_editor.cpp
+++ b/editor/plugins/animation_state_machine_editor.cpp
@@ -43,7 +43,10 @@
#include "scene/animation/animation_blend_tree.h"
#include "scene/animation/animation_player.h"
#include "scene/gui/menu_button.h"
+#include "scene/gui/option_button.h"
#include "scene/gui/panel.h"
+#include "scene/gui/panel_container.h"
+#include "scene/gui/separator.h"
#include "scene/gui/tree.h"
#include "scene/main/viewport.h"
#include "scene/main/window.h"
@@ -238,6 +241,7 @@ void AnimationNodeStateMachineEditor::_state_machine_gui_input(const Ref<InputEv
Ref<AnimationNode> an = state_machine->get_node(selected_node);
updating = true;
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Move Node"));
for (int i = 0; i < node_rects.size(); i++) {
@@ -534,6 +538,7 @@ void AnimationNodeStateMachineEditor::_group_selected_nodes() {
}
updating = true;
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action("Group");
// Move selected nodes to the new state machine
@@ -648,6 +653,7 @@ void AnimationNodeStateMachineEditor::_ungroup_selected_nodes() {
Vector<TransitionUR> transitions_ur;
updating = true;
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action("Ungroup");
// Move all child nodes to current state machine
@@ -921,6 +927,7 @@ void AnimationNodeStateMachineEditor::_stop_connecting() {
void AnimationNodeStateMachineEditor::_delete_selected() {
TreeItem *item = delete_tree->get_next_selected(nullptr);
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
while (item) {
if (!updating) {
updating = true;
@@ -948,6 +955,7 @@ void AnimationNodeStateMachineEditor::_delete_all() {
selected_multi_transition = TransitionLine();
updating = true;
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action("Transition(s) Removed");
_erase_selected(true);
for (int i = 0; i < multi_transitions.size(); i++) {
@@ -1027,6 +1035,7 @@ void AnimationNodeStateMachineEditor::_add_menu_type(int p_index) {
}
updating = true;
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Add Node and Transition"));
undo_redo->add_do_method(state_machine.ptr(), "add_node", name, node, add_node_pos);
undo_redo->add_undo_method(state_machine.ptr(), "remove_node", name);
@@ -1053,6 +1062,7 @@ void AnimationNodeStateMachineEditor::_add_animation_type(int p_index) {
}
updating = true;
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Add Node and Transition"));
undo_redo->add_do_method(state_machine.ptr(), "add_node", name, anim, add_node_pos);
undo_redo->add_undo_method(state_machine.ptr(), "remove_node", name);
@@ -1081,6 +1091,7 @@ void AnimationNodeStateMachineEditor::_add_transition(const bool p_nested_action
tr.instantiate();
tr->set_switch_mode(AnimationNodeStateMachineTransition::SwitchMode(transition_mode->get_selected()));
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
if (!p_nested_action) {
updating = true;
undo_redo->create_action(TTR("Add Transition"));
@@ -1745,6 +1756,7 @@ void AnimationNodeStateMachineEditor::_name_edited(const String &p_text) {
}
updating = true;
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Node Renamed"));
undo_redo->add_do_method(state_machine.ptr(), "rename_node", prev_name, name);
undo_redo->add_undo_method(state_machine.ptr(), "rename_node", name, prev_name);
@@ -1779,6 +1791,7 @@ void AnimationNodeStateMachineEditor::_erase_selected(const bool p_nested_action
if (!p_nested_action) {
updating = true;
}
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Node Removed"));
for (int i = 0; i < node_rects.size(); i++) {
@@ -1847,6 +1860,7 @@ void AnimationNodeStateMachineEditor::_erase_selected(const bool p_nested_action
if (!p_nested_action) {
updating = true;
}
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Transition Removed"));
undo_redo->add_do_method(state_machine.ptr(), "remove_transition", selected_transition_from, selected_transition_to);
undo_redo->add_undo_method(state_machine.ptr(), "add_transition", selected_transition_from, selected_transition_to, tr);
@@ -2013,8 +2027,6 @@ AnimationNodeStateMachineEditor::AnimationNodeStateMachineEditor() {
error_panel->add_child(error_label);
error_panel->hide();
- undo_redo = EditorNode::get_undo_redo();
-
set_custom_minimum_size(Size2(0, 300 * EDSCALE));
menu = memnew(PopupMenu);
@@ -2055,7 +2067,6 @@ AnimationNodeStateMachineEditor::AnimationNodeStateMachineEditor() {
open_file->set_title(TTR("Open Animation Node"));
open_file->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILE);
open_file->connect("file_selected", callable_mp(this, &AnimationNodeStateMachineEditor::_file_opened));
- undo_redo = EditorNode::get_undo_redo();
delete_window = memnew(ConfirmationDialog);
delete_window->set_flag(Window::FLAG_RESIZE_DISABLED, true);
diff --git a/editor/plugins/animation_state_machine_editor.h b/editor/plugins/animation_state_machine_editor.h
index 180f238834..5edf803c41 100644
--- a/editor/plugins/animation_state_machine_editor.h
+++ b/editor/plugins/animation_state_machine_editor.h
@@ -39,7 +39,6 @@
class ConfirmationDialog;
class EditorFileDialog;
-class EditorUndoRedoManager;
class OptionButton;
class PanelContainer;
@@ -80,8 +79,6 @@ class AnimationNodeStateMachineEditor : public AnimationTreeNodeEditorPlugin {
bool updating = false;
- Ref<EditorUndoRedoManager> undo_redo;
-
static AnimationNodeStateMachineEditor *singleton;
void _state_machine_gui_input(const Ref<InputEvent> &p_event);
diff --git a/editor/plugins/asset_library_editor_plugin.cpp b/editor/plugins/asset_library_editor_plugin.cpp
index 72bee901bf..7c3ecd5d4e 100644
--- a/editor/plugins/asset_library_editor_plugin.cpp
+++ b/editor/plugins/asset_library_editor_plugin.cpp
@@ -41,6 +41,7 @@
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
#include "editor/project_settings_editor.h"
+#include "scene/gui/menu_button.h"
static inline void setup_http_request(HTTPRequest *request) {
request->set_use_threads(EDITOR_DEF("asset_library/use_threads", true));
diff --git a/editor/plugins/bit_map_editor_plugin.cpp b/editor/plugins/bit_map_editor_plugin.cpp
index 657c5a36b6..8d9b3147a9 100644
--- a/editor/plugins/bit_map_editor_plugin.cpp
+++ b/editor/plugins/bit_map_editor_plugin.cpp
@@ -31,6 +31,8 @@
#include "bit_map_editor_plugin.h"
#include "editor/editor_scale.h"
+#include "scene/gui/label.h"
+#include "scene/gui/texture_rect.h"
void BitMapEditor::setup(const Ref<BitMap> &p_bitmap) {
texture_rect->set_texture(ImageTexture::create_from_image(p_bitmap->convert_to_image()));
diff --git a/editor/plugins/bone_map_editor_plugin.cpp b/editor/plugins/bone_map_editor_plugin.cpp
index 9ceedb18b3..4bf11f0627 100644
--- a/editor/plugins/bone_map_editor_plugin.cpp
+++ b/editor/plugins/bone_map_editor_plugin.cpp
@@ -31,10 +31,14 @@
#include "bone_map_editor_plugin.h"
#include "editor/editor_scale.h"
+#include "editor/editor_settings.h"
#include "editor/import/post_import_plugin_skeleton_renamer.h"
#include "editor/import/post_import_plugin_skeleton_rest_fixer.h"
#include "editor/import/post_import_plugin_skeleton_track_organizer.h"
#include "editor/import/scene_import_settings.h"
+#include "scene/gui/aspect_ratio_container.h"
+#include "scene/gui/separator.h"
+#include "scene/gui/texture_rect.h"
void BoneMapperButton::fetch_textures() {
if (selected) {
diff --git a/editor/plugins/bone_map_editor_plugin.h b/editor/plugins/bone_map_editor_plugin.h
index 16e5403978..e6a35d1120 100644
--- a/editor/plugins/bone_map_editor_plugin.h
+++ b/editor/plugins/bone_map_editor_plugin.h
@@ -41,11 +41,14 @@
#endif
#include "scene/3d/skeleton_3d.h"
+#include "scene/gui/box_container.h"
#include "scene/gui/color_rect.h"
#include "scene/gui/dialogs.h"
#include "scene/resources/bone_map.h"
#include "scene/resources/texture.h"
+class AspectRatioContainer;
+
class BoneMapperButton : public TextureButton {
GDCLASS(BoneMapperButton, TextureButton);
diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp
index 0fe77ec400..c08c9a83a7 100644
--- a/editor/plugins/canvas_item_editor_plugin.cpp
+++ b/editor/plugins/canvas_item_editor_plugin.cpp
@@ -32,15 +32,14 @@
#include "core/config/project_settings.h"
#include "core/input/input.h"
-#include "core/math/geometry_2d.h"
#include "core/os/keyboard.h"
-#include "core/string/print_string.h"
#include "editor/debugger/editor_debugger_node.h"
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
#include "editor/editor_toaster.h"
#include "editor/editor_undo_redo_manager.h"
+#include "editor/editor_zoom_widget.h"
#include "editor/plugins/animation_player_editor_plugin.h"
#include "editor/plugins/script_editor_plugin.h"
#include "editor/scene_tree_dock.h"
@@ -55,6 +54,7 @@
#include "scene/gui/grid_container.h"
#include "scene/gui/nine_patch_rect.h"
#include "scene/gui/separator.h"
+#include "scene/gui/split_container.h"
#include "scene/gui/subviewport_container.h"
#include "scene/gui/view_panner.h"
#include "scene/main/canvas_layer.h"
@@ -5596,7 +5596,7 @@ void CanvasItemEditorViewport::_create_nodes(Node *parent, Node *child, String &
// make visible for certain node type
if (Object::cast_to<Control>(child)) {
Size2 texture_size = texture->get_size();
- undo_redo->add_do_property(child, "rect_size", texture_size);
+ undo_redo->add_do_property(child, "size", texture_size);
} else if (Object::cast_to<Polygon2D>(child)) {
Size2 texture_size = texture->get_size();
Vector<Vector2> list = {
@@ -5612,6 +5612,11 @@ void CanvasItemEditorViewport::_create_nodes(Node *parent, Node *child, String &
Transform2D xform = canvas_item_editor->get_canvas_transform();
Point2 target_position = xform.affine_inverse().xform(p_point);
+ // Adjust position for Control and TouchScreenButton
+ if (Object::cast_to<Control>(child) || Object::cast_to<TouchScreenButton>(child)) {
+ target_position -= texture->get_size() / 2;
+ }
+
// there's nothing to be used as source position so snapping will work as absolute if enabled
target_position = canvas_item_editor->snap_point(target_position);
undo_redo->add_do_method(child, "set_global_position", target_position);
diff --git a/editor/plugins/canvas_item_editor_plugin.h b/editor/plugins/canvas_item_editor_plugin.h
index cc98aa8c51..9c7d0fbe6f 100644
--- a/editor/plugins/canvas_item_editor_plugin.h
+++ b/editor/plugins/canvas_item_editor_plugin.h
@@ -32,22 +32,21 @@
#define CANVAS_ITEM_EDITOR_PLUGIN_H
#include "editor/editor_plugin.h"
-#include "editor/editor_zoom_widget.h"
+#include "scene/gui/base_button.h"
#include "scene/gui/box_container.h"
-#include "scene/gui/check_box.h"
-#include "scene/gui/label.h"
-#include "scene/gui/panel_container.h"
-#include "scene/gui/spin_box.h"
-#include "scene/gui/split_container.h"
-#include "scene/gui/texture_rect.h"
-#include "scene/main/canvas_item.h"
class AcceptDialog;
+class CanvasItemEditorViewport;
class ConfirmationDialog;
class EditorData;
-class CanvasItemEditorViewport;
+class EditorZoomWidget;
+class HScrollBar;
+class HSplitContainer;
class MenuButton;
+class PanelContainer;
class ViewPanner;
+class VScrollBar;
+class VSplitContainer;
class CanvasItemEditorSelectedItem : public Object {
GDCLASS(CanvasItemEditorSelectedItem, Object);
diff --git a/editor/plugins/cast_2d_editor_plugin.cpp b/editor/plugins/cast_2d_editor_plugin.cpp
index a8d255f997..d991cdf27f 100644
--- a/editor/plugins/cast_2d_editor_plugin.cpp
+++ b/editor/plugins/cast_2d_editor_plugin.cpp
@@ -77,6 +77,7 @@ bool Cast2DEditor::forward_canvas_gui_input(const Ref<InputEvent> &p_event) {
return false;
}
} else if (pressed) {
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Set target_position"));
undo_redo->add_do_property(node, "target_position", target_position);
undo_redo->add_do_method(canvas_item_editor, "update_viewport");
@@ -130,10 +131,6 @@ void Cast2DEditor::edit(Node2D *p_node) {
canvas_item_editor->update_viewport();
}
-Cast2DEditor::Cast2DEditor() {
- undo_redo = EditorNode::get_singleton()->get_undo_redo();
-}
-
///////////////////////
void Cast2DEditorPlugin::edit(Object *p_object) {
diff --git a/editor/plugins/cast_2d_editor_plugin.h b/editor/plugins/cast_2d_editor_plugin.h
index ceed9b9111..1165a301f6 100644
--- a/editor/plugins/cast_2d_editor_plugin.h
+++ b/editor/plugins/cast_2d_editor_plugin.h
@@ -35,12 +35,10 @@
#include "scene/2d/node_2d.h"
class CanvasItemEditor;
-class EditorUndoRedoManager;
class Cast2DEditor : public Control {
GDCLASS(Cast2DEditor, Control);
- Ref<EditorUndoRedoManager> undo_redo;
CanvasItemEditor *canvas_item_editor = nullptr;
Node2D *node = nullptr;
@@ -55,8 +53,6 @@ public:
bool forward_canvas_gui_input(const Ref<InputEvent> &p_event);
void forward_canvas_draw_over_viewport(Control *p_overlay);
void edit(Node2D *p_node);
-
- Cast2DEditor();
};
class Cast2DEditorPlugin : public EditorPlugin {
diff --git a/editor/plugins/collision_shape_2d_editor_plugin.cpp b/editor/plugins/collision_shape_2d_editor_plugin.cpp
index 11992ad10e..a7f842aa66 100644
--- a/editor/plugins/collision_shape_2d_editor_plugin.cpp
+++ b/editor/plugins/collision_shape_2d_editor_plugin.cpp
@@ -219,6 +219,7 @@ void CollisionShape2DEditor::set_handle(int idx, Point2 &p_point) {
}
void CollisionShape2DEditor::commit_handle(int idx, Variant &p_org) {
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Set Handle"));
switch (shape_type) {
@@ -588,8 +589,6 @@ CollisionShape2DEditor::CollisionShape2DEditor() {
node = nullptr;
canvas_item_editor = nullptr;
- undo_redo = EditorNode::get_singleton()->get_undo_redo();
-
edit_handle = -1;
pressed = false;
diff --git a/editor/plugins/collision_shape_2d_editor_plugin.h b/editor/plugins/collision_shape_2d_editor_plugin.h
index 49e0820ae9..51cdab7396 100644
--- a/editor/plugins/collision_shape_2d_editor_plugin.h
+++ b/editor/plugins/collision_shape_2d_editor_plugin.h
@@ -35,7 +35,6 @@
#include "scene/2d/collision_shape_2d.h"
class CanvasItemEditor;
-class EditorUndoRedoManager;
class CollisionShape2DEditor : public Control {
GDCLASS(CollisionShape2DEditor, Control);
@@ -62,7 +61,6 @@ class CollisionShape2DEditor : public Control {
Point2(1, -1),
};
- Ref<EditorUndoRedoManager> undo_redo;
CanvasItemEditor *canvas_item_editor = nullptr;
CollisionShape2D *node = nullptr;
diff --git a/editor/plugins/control_editor_plugin.cpp b/editor/plugins/control_editor_plugin.cpp
index 00b7845cee..c18876b9ef 100644
--- a/editor/plugins/control_editor_plugin.cpp
+++ b/editor/plugins/control_editor_plugin.cpp
@@ -721,6 +721,7 @@ void ControlEditorToolbar::_anchors_preset_selected(int p_preset) {
LayoutPreset preset = (LayoutPreset)p_preset;
List<Node *> selection = editor_selection->get_selected_node_list();
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Change Anchors, Offsets, Grow Direction"));
for (Node *E : selection) {
@@ -740,6 +741,7 @@ void ControlEditorToolbar::_anchors_preset_selected(int p_preset) {
void ControlEditorToolbar::_anchors_to_current_ratio() {
List<Node *> selection = editor_selection->get_selected_node_list();
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Change Anchors, Offsets (Keep Ratio)"));
for (Node *E : selection) {
@@ -790,6 +792,7 @@ void ControlEditorToolbar::_anchor_mode_toggled(bool p_status) {
void ControlEditorToolbar::_container_flags_selected(int p_flags, bool p_vertical) {
List<Node *> selection = editor_selection->get_selected_node_list();
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
if (p_vertical) {
undo_redo->create_action(TTR("Change Vertical Size Flags"));
} else {
@@ -1025,7 +1028,6 @@ ControlEditorToolbar::ControlEditorToolbar() {
container_v_picker->connect("size_flags_selected", callable_mp(this, &ControlEditorToolbar::_container_flags_selected).bind(true));
// Editor connections.
- undo_redo = EditorNode::get_singleton()->get_undo_redo();
editor_selection = EditorNode::get_singleton()->get_editor_selection();
editor_selection->add_editor_plugin(this);
editor_selection->connect("selection_changed", callable_mp(this, &ControlEditorToolbar::_selection_changed));
diff --git a/editor/plugins/control_editor_plugin.h b/editor/plugins/control_editor_plugin.h
index 14886e77a4..cf2c6f4e20 100644
--- a/editor/plugins/control_editor_plugin.h
+++ b/editor/plugins/control_editor_plugin.h
@@ -45,7 +45,6 @@
#include "scene/gui/separator.h"
#include "scene/gui/texture_rect.h"
-class EditorUndoRedoManager;
class GridContainer;
// Inspector controls.
@@ -207,7 +206,6 @@ public:
class ControlEditorToolbar : public HBoxContainer {
GDCLASS(ControlEditorToolbar, HBoxContainer);
- Ref<EditorUndoRedoManager> undo_redo;
EditorSelection *editor_selection = nullptr;
ControlEditorPopupButton *anchors_button = nullptr;
diff --git a/editor/plugins/cpu_particles_2d_editor_plugin.cpp b/editor/plugins/cpu_particles_2d_editor_plugin.cpp
index a0e6771768..36b51e0e0c 100644
--- a/editor/plugins/cpu_particles_2d_editor_plugin.cpp
+++ b/editor/plugins/cpu_particles_2d_editor_plugin.cpp
@@ -34,9 +34,12 @@
#include "core/io/image_loader.h"
#include "editor/editor_file_dialog.h"
#include "editor/editor_node.h"
-#include "editor/editor_undo_redo_manager.h"
#include "scene/2d/cpu_particles_2d.h"
+#include "scene/gui/check_box.h"
+#include "scene/gui/menu_button.h"
+#include "scene/gui/option_button.h"
#include "scene/gui/separator.h"
+#include "scene/gui/spin_box.h"
#include "scene/resources/particle_process_material.h"
void CPUParticles2DEditorPlugin::edit(Object *p_object) {
@@ -239,7 +242,6 @@ void CPUParticles2DEditorPlugin::_bind_methods() {
CPUParticles2DEditorPlugin::CPUParticles2DEditorPlugin() {
particles = nullptr;
- undo_redo = EditorNode::get_singleton()->get_undo_redo();
toolbar = memnew(HBoxContainer);
add_control_to_container(CONTAINER_CANVAS_EDITOR_MENU, toolbar);
diff --git a/editor/plugins/cpu_particles_2d_editor_plugin.h b/editor/plugins/cpu_particles_2d_editor_plugin.h
index 694162588b..1fc9ed763c 100644
--- a/editor/plugins/cpu_particles_2d_editor_plugin.h
+++ b/editor/plugins/cpu_particles_2d_editor_plugin.h
@@ -40,7 +40,6 @@ class CheckBox;
class ConfirmationDialog;
class SpinBox;
class EditorFileDialog;
-class EditorUndoRedoManager;
class MenuButton;
class OptionButton;
@@ -74,7 +73,6 @@ class CPUParticles2DEditorPlugin : public EditorPlugin {
String source_emission_file;
- Ref<EditorUndoRedoManager> undo_redo;
void _file_selected(const String &p_file);
void _menu_callback(int p_idx);
void _generate_emission_mask();
diff --git a/editor/plugins/debugger_editor_plugin.cpp b/editor/plugins/debugger_editor_plugin.cpp
index dd6187c264..7d04880fb7 100644
--- a/editor/plugins/debugger_editor_plugin.cpp
+++ b/editor/plugins/debugger_editor_plugin.cpp
@@ -47,7 +47,6 @@ DebuggerEditorPlugin::DebuggerEditorPlugin(PopupMenu *p_debug_menu) {
ED_SHORTCUT("debugger/step_over", TTR("Step Over"), Key::F10);
ED_SHORTCUT("debugger/break", TTR("Break"));
ED_SHORTCUT("debugger/continue", TTR("Continue"), Key::F12);
- ED_SHORTCUT("debugger/keep_debugger_open", TTR("Keep Debugger Open"));
ED_SHORTCUT("debugger/debug_with_external_editor", TTR("Debug with External Editor"));
// File Server for deploy with remote filesystem.
@@ -85,6 +84,9 @@ DebuggerEditorPlugin::DebuggerEditorPlugin(PopupMenu *p_debug_menu) {
debug_menu->add_check_shortcut(ED_SHORTCUT("editor/sync_script_changes", TTR("Synchronize Script Changes")), RUN_RELOAD_SCRIPTS);
debug_menu->set_item_tooltip(-1,
TTR("When this option is enabled, any script that is saved will be reloaded in the running project.\nWhen used remotely on a device, this is more efficient when the network filesystem option is enabled."));
+ debug_menu->add_check_shortcut(ED_SHORTCUT("editor/keep_server_open", TTR("Keep Debug Server Open")), SERVER_KEEP_OPEN);
+ debug_menu->set_item_tooltip(-1,
+ TTR("When this option is enabled, the editor debug server will stay open and listen for new sessions started outside of the editor itself."));
// Multi-instance, start/stop
instances_menu = memnew(PopupMenu);
@@ -176,6 +178,14 @@ void DebuggerEditorPlugin::_menu_option(int p_option) {
EditorSettings::get_singleton()->set_project_metadata("debug_options", "run_reload_scripts", !ischecked);
} break;
+ case SERVER_KEEP_OPEN: {
+ bool ischecked = debug_menu->is_item_checked(debug_menu->get_item_index(SERVER_KEEP_OPEN));
+ debug_menu->set_item_checked(debug_menu->get_item_index(SERVER_KEEP_OPEN), !ischecked);
+
+ EditorDebuggerNode::get_singleton()->set_keep_open(!ischecked);
+ EditorSettings::get_singleton()->set_project_metadata("debug_options", "server_keep_open", !ischecked);
+
+ } break;
}
}
@@ -195,6 +205,7 @@ void DebuggerEditorPlugin::_update_debug_options() {
bool check_debug_navigation = EditorSettings::get_singleton()->get_project_metadata("debug_options", "run_debug_navigation", false);
bool check_live_debug = EditorSettings::get_singleton()->get_project_metadata("debug_options", "run_live_debug", true);
bool check_reload_scripts = EditorSettings::get_singleton()->get_project_metadata("debug_options", "run_reload_scripts", true);
+ bool check_server_keep_open = EditorSettings::get_singleton()->get_project_metadata("debug_options", "server_keep_open", false);
int instances = EditorSettings::get_singleton()->get_project_metadata("debug_options", "run_debug_instances", 1);
if (check_deploy_remote) {
@@ -218,6 +229,9 @@ void DebuggerEditorPlugin::_update_debug_options() {
if (check_reload_scripts) {
_menu_option(RUN_RELOAD_SCRIPTS);
}
+ if (check_server_keep_open) {
+ _menu_option(SERVER_KEEP_OPEN);
+ }
int len = instances_menu->get_item_count();
for (int idx = 0; idx < len; idx++) {
diff --git a/editor/plugins/debugger_editor_plugin.h b/editor/plugins/debugger_editor_plugin.h
index c706acdb5c..5f682ed5e0 100644
--- a/editor/plugins/debugger_editor_plugin.h
+++ b/editor/plugins/debugger_editor_plugin.h
@@ -53,6 +53,7 @@ private:
RUN_DEBUG_NAVIGATION,
RUN_DEPLOY_REMOTE_DEBUG,
RUN_RELOAD_SCRIPTS,
+ SERVER_KEEP_OPEN,
};
void _update_debug_options();
diff --git a/editor/plugins/font_config_plugin.cpp b/editor/plugins/font_config_plugin.cpp
index 33992314b0..4370d013be 100644
--- a/editor/plugins/font_config_plugin.cpp
+++ b/editor/plugins/font_config_plugin.cpp
@@ -31,6 +31,7 @@
#include "font_config_plugin.h"
#include "editor/editor_scale.h"
+#include "editor/editor_settings.h"
#include "editor/import/dynamic_font_import_settings.h"
/*************************************************************************/
diff --git a/editor/plugins/gdextension_export_plugin.h b/editor/plugins/gdextension_export_plugin.h
index c5f7d2a047..586cd2bd59 100644
--- a/editor/plugins/gdextension_export_plugin.h
+++ b/editor/plugins/gdextension_export_plugin.h
@@ -54,60 +54,38 @@ void GDExtensionExportPlugin::_export_file(const String &p_path, const String &p
String entry_symbol = config->get_value("configuration", "entry_symbol");
- List<String> libraries;
-
- config->get_section_keys("libraries", &libraries);
-
- bool could_export = false;
- for (const String &E : libraries) {
- Vector<String> tags = E.split(".");
- bool all_tags_met = true;
- for (int i = 0; i < tags.size(); i++) {
- String tag = tags[i].strip_edges();
- if (!p_features.has(tag)) {
- all_tags_met = false;
- break;
- }
- }
-
- if (all_tags_met) {
- String library_path = config->get_value("libraries", E);
- if (!library_path.begins_with("res://")) {
- print_line("Skipping export of out-of-project library " + library_path);
- continue;
- }
- add_shared_object(library_path, tags);
-
- if (p_features.has("iOS") && (library_path.ends_with(".a") || library_path.ends_with(".xcframework"))) {
- String additional_code = "extern void register_dynamic_symbol(char *name, void *address);\n"
- "extern void add_ios_init_callback(void (*cb)());\n"
- "\n"
- "extern \"C\" void $ENTRY();\n"
- "void $ENTRY_init() {\n"
- " if (&$ENTRY) register_dynamic_symbol((char *)\"$ENTRY\", (void *)$ENTRY);\n"
- "}\n"
- "struct $ENTRY_struct {\n"
- " $ENTRY_struct() {\n"
- " add_ios_init_callback($ENTRY_init);\n"
- " }\n"
- "};\n"
- "$ENTRY_struct $ENTRY_struct_instance;\n\n";
- additional_code = additional_code.replace("$ENTRY", entry_symbol);
- add_ios_cpp_code(additional_code);
-
- String linker_flags = "-Wl,-U,_" + entry_symbol;
- add_ios_linker_flags(linker_flags);
- }
- could_export = true;
- break;
+ PackedStringArray tags;
+ String library_path = NativeExtension::find_extension_library(
+ p_path, config, [p_features](String p_feature) { return p_features.has(p_feature); }, &tags);
+ if (!library_path.is_empty()) {
+ add_shared_object(library_path, tags);
+
+ if (p_features.has("iOS") && (library_path.ends_with(".a") || library_path.ends_with(".xcframework"))) {
+ String additional_code = "extern void register_dynamic_symbol(char *name, void *address);\n"
+ "extern void add_ios_init_callback(void (*cb)());\n"
+ "\n"
+ "extern \"C\" void $ENTRY();\n"
+ "void $ENTRY_init() {\n"
+ " if (&$ENTRY) register_dynamic_symbol((char *)\"$ENTRY\", (void *)$ENTRY);\n"
+ "}\n"
+ "struct $ENTRY_struct {\n"
+ " $ENTRY_struct() {\n"
+ " add_ios_init_callback($ENTRY_init);\n"
+ " }\n"
+ "};\n"
+ "$ENTRY_struct $ENTRY_struct_instance;\n\n";
+ additional_code = additional_code.replace("$ENTRY", entry_symbol);
+ add_ios_cpp_code(additional_code);
+
+ String linker_flags = "-Wl,-U,_" + entry_symbol;
+ add_ios_linker_flags(linker_flags);
}
- }
- if (!could_export) {
- Vector<String> tags;
+ } else {
+ Vector<String> features_vector;
for (const String &E : p_features) {
- tags.append(E);
+ features_vector.append(E);
}
- ERR_FAIL_MSG(vformat("No suitable library found. The libraries' tags referred to an invalid feature flag. Possible feature flags for your platform: %s", p_path, String(", ").join(tags)));
+ ERR_FAIL_MSG(vformat("No suitable library found for GDExtension: %s. Possible feature flags for your platform: %s", p_path, String(", ").join(features_vector)));
}
List<String> dependencies;
@@ -115,11 +93,11 @@ void GDExtensionExportPlugin::_export_file(const String &p_path, const String &p
config->get_section_keys("dependencies", &dependencies);
}
- for (const String &E : libraries) {
- Vector<String> tags = E.split(".");
+ for (const String &E : dependencies) {
+ Vector<String> dependency_tags = E.split(".");
bool all_tags_met = true;
- for (int i = 0; i < tags.size(); i++) {
- String tag = tags[i].strip_edges();
+ for (int i = 0; i < dependency_tags.size(); i++) {
+ String tag = dependency_tags[i].strip_edges();
if (!p_features.has(tag)) {
all_tags_met = false;
break;
@@ -129,13 +107,12 @@ void GDExtensionExportPlugin::_export_file(const String &p_path, const String &p
if (all_tags_met) {
Dictionary dependency = config->get_value("dependencies", E);
for (const Variant *key = dependency.next(nullptr); key; key = dependency.next(key)) {
- String library_path = *key;
+ String dependency_path = *key;
String target_path = dependency[*key];
- if (!library_path.begins_with("res://")) {
- print_line("Skipping export of out-of-project library " + library_path);
- continue;
+ if (dependency_path.is_relative_path()) {
+ dependency_path = p_path.get_base_dir().path_join(dependency_path);
}
- add_shared_object(library_path, tags, target_path);
+ add_shared_object(dependency_path, dependency_tags, target_path);
}
break;
}
diff --git a/editor/plugins/gpu_particles_2d_editor_plugin.cpp b/editor/plugins/gpu_particles_2d_editor_plugin.cpp
index 891b9efa4f..0fa3efba9a 100644
--- a/editor/plugins/gpu_particles_2d_editor_plugin.cpp
+++ b/editor/plugins/gpu_particles_2d_editor_plugin.cpp
@@ -37,6 +37,7 @@
#include "editor/editor_undo_redo_manager.h"
#include "editor/scene_tree_dock.h"
#include "scene/2d/cpu_particles_2d.h"
+#include "scene/gui/menu_button.h"
#include "scene/gui/separator.h"
#include "scene/resources/particle_process_material.h"
@@ -160,6 +161,7 @@ void GPUParticles2DEditorPlugin::_generate_visibility_rect() {
particles->set_emitting(false);
}
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Generate Visibility Rect"));
undo_redo->add_do_method(particles, "set_visibility_rect", rect);
undo_redo->add_undo_method(particles, "set_visibility_rect", particles->get_visibility_rect());
@@ -359,7 +361,6 @@ void GPUParticles2DEditorPlugin::_bind_methods() {
GPUParticles2DEditorPlugin::GPUParticles2DEditorPlugin() {
particles = nullptr;
- undo_redo = EditorNode::get_singleton()->get_undo_redo();
toolbar = memnew(HBoxContainer);
add_control_to_container(CONTAINER_CANVAS_EDITOR_MENU, toolbar);
diff --git a/editor/plugins/gpu_particles_2d_editor_plugin.h b/editor/plugins/gpu_particles_2d_editor_plugin.h
index 0a0ea21c1f..34cadaf7de 100644
--- a/editor/plugins/gpu_particles_2d_editor_plugin.h
+++ b/editor/plugins/gpu_particles_2d_editor_plugin.h
@@ -40,7 +40,6 @@
class CheckBox;
class ConfirmationDialog;
class EditorFileDialog;
-class EditorUndoRedoManager;
class MenuButton;
class OptionButton;
@@ -80,7 +79,6 @@ class GPUParticles2DEditorPlugin : public EditorPlugin {
String source_emission_file;
- Ref<EditorUndoRedoManager> undo_redo;
void _file_selected(const String &p_file);
void _menu_callback(int p_idx);
void _generate_visibility_rect();
diff --git a/editor/plugins/gpu_particles_3d_editor_plugin.cpp b/editor/plugins/gpu_particles_3d_editor_plugin.cpp
index db3a46d1f1..b2878244d0 100644
--- a/editor/plugins/gpu_particles_3d_editor_plugin.cpp
+++ b/editor/plugins/gpu_particles_3d_editor_plugin.cpp
@@ -36,6 +36,8 @@
#include "editor/plugins/node_3d_editor_plugin.h"
#include "editor/scene_tree_dock.h"
#include "scene/3d/cpu_particles_3d.h"
+#include "scene/3d/mesh_instance_3d.h"
+#include "scene/gui/menu_button.h"
#include "scene/resources/particle_process_material.h"
bool GPUParticles3DEditorBase::_generate(Vector<Vector3> &points, Vector<Vector3> &normals) {
diff --git a/editor/plugins/gradient_texture_2d_editor_plugin.cpp b/editor/plugins/gradient_texture_2d_editor_plugin.cpp
index 561dca4fc6..0591288c6e 100644
--- a/editor/plugins/gradient_texture_2d_editor_plugin.cpp
+++ b/editor/plugins/gradient_texture_2d_editor_plugin.cpp
@@ -55,6 +55,7 @@ void GradientTexture2DEditorRect::_update_fill_position() {
String property_name = handle == HANDLE_FILL_FROM ? "fill_from" : "fill_to";
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(vformat(TTR("Set %s"), property_name), UndoRedo::MERGE_ENDS);
undo_redo->add_do_property(texture.ptr(), property_name, percent);
undo_redo->add_undo_property(texture.ptr(), property_name, handle == HANDLE_FILL_FROM ? texture->get_fill_from() : texture->get_fill_to());
@@ -175,8 +176,6 @@ void GradientTexture2DEditorRect::_notification(int p_what) {
}
GradientTexture2DEditorRect::GradientTexture2DEditorRect() {
- undo_redo = EditorNode::get_undo_redo();
-
checkerboard = memnew(TextureRect);
checkerboard->set_stretch_mode(TextureRect::STRETCH_TILE);
checkerboard->set_ignore_texture_size(true);
@@ -189,6 +188,7 @@ GradientTexture2DEditorRect::GradientTexture2DEditorRect() {
///////////////////////
void GradientTexture2DEditor::_reverse_button_pressed() {
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Swap GradientTexture2D Fill Points"));
undo_redo->add_do_property(texture.ptr(), "fill_from", texture->get_fill_to());
undo_redo->add_do_property(texture.ptr(), "fill_to", texture->get_fill_from());
@@ -223,8 +223,6 @@ void GradientTexture2DEditor::_notification(int p_what) {
}
GradientTexture2DEditor::GradientTexture2DEditor() {
- undo_redo = EditorNode::get_undo_redo();
-
HFlowContainer *toolbar = memnew(HFlowContainer);
add_child(toolbar);
diff --git a/editor/plugins/gradient_texture_2d_editor_plugin.h b/editor/plugins/gradient_texture_2d_editor_plugin.h
index 0737300498..3172944ea8 100644
--- a/editor/plugins/gradient_texture_2d_editor_plugin.h
+++ b/editor/plugins/gradient_texture_2d_editor_plugin.h
@@ -35,8 +35,6 @@
#include "editor/editor_plugin.h"
#include "editor/editor_spin_slider.h"
-class EditorUndoRedoManager;
-
class GradientTexture2DEditorRect : public Control {
GDCLASS(GradientTexture2DEditorRect, Control);
@@ -47,7 +45,6 @@ class GradientTexture2DEditorRect : public Control {
};
Ref<GradientTexture2D> texture;
- Ref<EditorUndoRedoManager> undo_redo;
bool snap_enabled = false;
float snap_size = 0;
@@ -77,7 +74,6 @@ class GradientTexture2DEditor : public VBoxContainer {
GDCLASS(GradientTexture2DEditor, VBoxContainer);
Ref<GradientTexture2D> texture;
- Ref<EditorUndoRedoManager> undo_redo;
Button *reverse_button = nullptr;
Button *snap_button = nullptr;
diff --git a/editor/plugins/material_editor_plugin.h b/editor/plugins/material_editor_plugin.h
index 076fd5e537..7d7d41785b 100644
--- a/editor/plugins/material_editor_plugin.h
+++ b/editor/plugins/material_editor_plugin.h
@@ -41,7 +41,9 @@
#include "scene/resources/material.h"
#include "scene/resources/primitive_meshes.h"
+class SubViewport;
class SubViewportContainer;
+class TextureButton;
class MaterialEditor : public Control {
GDCLASS(MaterialEditor, Control);
diff --git a/editor/plugins/mesh_editor_plugin.cpp b/editor/plugins/mesh_editor_plugin.cpp
index 57dc92a9ee..79fbf19f89 100644
--- a/editor/plugins/mesh_editor_plugin.cpp
+++ b/editor/plugins/mesh_editor_plugin.cpp
@@ -32,6 +32,8 @@
#include "core/config/project_settings.h"
#include "editor/editor_scale.h"
+#include "scene/gui/texture_button.h"
+#include "scene/main/viewport.h"
void MeshEditor::gui_input(const Ref<InputEvent> &p_event) {
ERR_FAIL_COND(p_event.is_null());
diff --git a/editor/plugins/mesh_editor_plugin.h b/editor/plugins/mesh_editor_plugin.h
index b8d6562c5c..8eecc909b6 100644
--- a/editor/plugins/mesh_editor_plugin.h
+++ b/editor/plugins/mesh_editor_plugin.h
@@ -40,6 +40,9 @@
#include "scene/resources/camera_attributes.h"
#include "scene/resources/material.h"
+class SubViewport;
+class TextureButton;
+
class MeshEditor : public SubViewportContainer {
GDCLASS(MeshEditor, SubViewportContainer);
diff --git a/editor/plugins/mesh_instance_3d_editor_plugin.cpp b/editor/plugins/mesh_instance_3d_editor_plugin.cpp
index d5cdb70ccf..57e8046f32 100644
--- a/editor/plugins/mesh_instance_3d_editor_plugin.cpp
+++ b/editor/plugins/mesh_instance_3d_editor_plugin.cpp
@@ -38,6 +38,9 @@
#include "scene/3d/navigation_region_3d.h"
#include "scene/3d/physics_body_3d.h"
#include "scene/gui/box_container.h"
+#include "scene/gui/menu_button.h"
+#include "scene/resources/concave_polygon_shape_3d.h"
+#include "scene/resources/convex_polygon_shape_3d.h"
void MeshInstance3DEditor::_node_removed(Node *p_node) {
if (p_node == node) {
@@ -66,7 +69,7 @@ void MeshInstance3DEditor::_menu_option(int p_option) {
List<Node *> selection = editor_selection->get_selected_node_list();
if (selection.is_empty()) {
- Ref<Shape3D> shape = mesh->create_trimesh_shape();
+ Ref<ConcavePolygonShape3D> shape = mesh->create_trimesh_shape();
if (shape.is_null()) {
err_dialog->set_text(TTR("Couldn't create a Trimesh collision shape."));
err_dialog->popup_centered();
@@ -105,7 +108,7 @@ void MeshInstance3DEditor::_menu_option(int p_option) {
continue;
}
- Ref<Shape3D> shape = m->create_trimesh_shape();
+ Ref<ConcavePolygonShape3D> shape = m->create_trimesh_shape();
if (shape.is_null()) {
continue;
}
@@ -137,7 +140,7 @@ void MeshInstance3DEditor::_menu_option(int p_option) {
return;
}
- Ref<Shape3D> shape = mesh->create_trimesh_shape();
+ Ref<ConcavePolygonShape3D> shape = mesh->create_trimesh_shape();
if (shape.is_null()) {
return;
}
@@ -171,7 +174,7 @@ void MeshInstance3DEditor::_menu_option(int p_option) {
bool simplify = (p_option == MENU_OPTION_CREATE_SIMPLIFIED_CONVEX_COLLISION_SHAPE);
- Ref<Shape3D> shape = mesh->create_convex_shape(true, simplify);
+ Ref<ConvexPolygonShape3D> shape = mesh->create_convex_shape(true, simplify);
if (shape.is_null()) {
err_dialog->set_text(TTR("Couldn't create a single convex collision shape."));
@@ -271,7 +274,7 @@ void MeshInstance3DEditor::_menu_option(int p_option) {
outline_dialog->popup_centered(Vector2(200, 90));
} break;
case MENU_OPTION_CREATE_DEBUG_TANGENTS: {
- Ref<EditorUndoRedoManager> ur = EditorNode::get_singleton()->get_undo_redo();
+ Ref<EditorUndoRedoManager> &ur = EditorNode::get_singleton()->get_undo_redo();
ur->create_action(TTR("Create Debug Tangents"));
MeshInstance3D *tangents = node->create_debug_tangents_node();
diff --git a/editor/plugins/mesh_library_editor_plugin.cpp b/editor/plugins/mesh_library_editor_plugin.cpp
index 6654b03a0d..4a8e5d9979 100644
--- a/editor/plugins/mesh_library_editor_plugin.cpp
+++ b/editor/plugins/mesh_library_editor_plugin.cpp
@@ -33,11 +33,13 @@
#include "editor/editor_file_dialog.h"
#include "editor/editor_node.h"
#include "editor/editor_settings.h"
+#include "editor/inspector_dock.h"
#include "main/main.h"
#include "node_3d_editor_plugin.h"
#include "scene/3d/mesh_instance_3d.h"
#include "scene/3d/navigation_region_3d.h"
#include "scene/3d/physics_body_3d.h"
+#include "scene/gui/menu_button.h"
#include "scene/main/window.h"
#include "scene/resources/packed_scene.h"
diff --git a/editor/plugins/multimesh_editor_plugin.cpp b/editor/plugins/multimesh_editor_plugin.cpp
index b0e206b020..40fac060cd 100644
--- a/editor/plugins/multimesh_editor_plugin.cpp
+++ b/editor/plugins/multimesh_editor_plugin.cpp
@@ -35,6 +35,8 @@
#include "node_3d_editor_plugin.h"
#include "scene/3d/mesh_instance_3d.h"
#include "scene/gui/box_container.h"
+#include "scene/gui/menu_button.h"
+#include "scene/gui/option_button.h"
void MultiMeshEditor::_node_removed(Node *p_node) {
if (p_node == node) {
diff --git a/editor/plugins/navigation_link_2d_editor_plugin.cpp b/editor/plugins/navigation_link_2d_editor_plugin.cpp
index b72f639fbf..560454e5d3 100644
--- a/editor/plugins/navigation_link_2d_editor_plugin.cpp
+++ b/editor/plugins/navigation_link_2d_editor_plugin.cpp
@@ -85,6 +85,7 @@ bool NavigationLink2DEditor::forward_canvas_gui_input(const Ref<InputEvent> &p_e
end_grabbed = false;
}
} else {
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
if (start_grabbed) {
undo_redo->create_action(TTR("Set start_location"));
undo_redo->add_do_method(node, "set_start_location", node->get_start_location());
@@ -165,10 +166,6 @@ void NavigationLink2DEditor::edit(NavigationLink2D *p_node) {
canvas_item_editor->update_viewport();
}
-NavigationLink2DEditor::NavigationLink2DEditor() {
- undo_redo = EditorNode::get_undo_redo();
-}
-
///////////////////////
void NavigationLink2DEditorPlugin::edit(Object *p_object) {
diff --git a/editor/plugins/navigation_link_2d_editor_plugin.h b/editor/plugins/navigation_link_2d_editor_plugin.h
index 0a3d9b8810..fea9f58a40 100644
--- a/editor/plugins/navigation_link_2d_editor_plugin.h
+++ b/editor/plugins/navigation_link_2d_editor_plugin.h
@@ -35,12 +35,10 @@
#include "scene/2d/navigation_link_2d.h"
class CanvasItemEditor;
-class EditorUndoRedoManager;
class NavigationLink2DEditor : public Control {
GDCLASS(NavigationLink2DEditor, Control);
- Ref<EditorUndoRedoManager> undo_redo;
CanvasItemEditor *canvas_item_editor = nullptr;
NavigationLink2D *node = nullptr;
@@ -58,8 +56,6 @@ public:
bool forward_canvas_gui_input(const Ref<InputEvent> &p_event);
void forward_canvas_draw_over_viewport(Control *p_overlay);
void edit(NavigationLink2D *p_node);
-
- NavigationLink2DEditor();
};
class NavigationLink2DEditorPlugin : public EditorPlugin {
diff --git a/editor/plugins/node_3d_editor_gizmos.cpp b/editor/plugins/node_3d_editor_gizmos.cpp
index 0af2a13df2..c8b80db334 100644
--- a/editor/plugins/node_3d_editor_gizmos.cpp
+++ b/editor/plugins/node_3d_editor_gizmos.cpp
@@ -30,6 +30,7 @@
#include "node_3d_editor_gizmos.h"
+#include "core/config/project_settings.h"
#include "core/math/convex_hull.h"
#include "core/math/geometry_2d.h"
#include "core/math/geometry_3d.h"
@@ -1732,6 +1733,24 @@ Camera3DGizmoPlugin::Camera3DGizmoPlugin() {
create_handle_material("handles");
}
+Size2i Camera3DGizmoPlugin::_get_viewport_size(Camera3D *p_camera) {
+ Viewport *viewport = p_camera->get_viewport();
+
+ Window *window = Object::cast_to<Window>(viewport);
+ if (window) {
+ return window->get_size();
+ }
+
+ SubViewport *sub_viewport = Object::cast_to<SubViewport>(viewport);
+ ERR_FAIL_NULL_V(sub_viewport, Size2i());
+
+ if (sub_viewport == EditorNode::get_singleton()->get_scene_root()) {
+ return Size2(GLOBAL_GET("display/window/size/viewport_width"), GLOBAL_GET("display/window/size/viewport_height"));
+ }
+
+ return sub_viewport->get_size();
+}
+
bool Camera3DGizmoPlugin::has_gizmo(Node3D *p_spatial) {
return Object::cast_to<Camera3D>(p_spatial) != nullptr;
}
@@ -1830,6 +1849,10 @@ void Camera3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
Ref<Material> material = get_material("camera_material", p_gizmo);
+ const Size2i viewport_size = _get_viewport_size(camera);
+ const real_t viewport_aspect = viewport_size.x > 0 && viewport_size.y > 0 ? viewport_size.aspect() : 1.0;
+ const Size2 size_factor = viewport_aspect > 1.0 ? Size2(1.0, 1.0 / viewport_aspect) : Size2(viewport_aspect, 1.0);
+
#define ADD_TRIANGLE(m_a, m_b, m_c) \
{ \
lines.push_back(m_a); \
@@ -1857,10 +1880,11 @@ void Camera3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
// The real FOV is halved for accurate representation
float fov = camera->get_fov() / 2.0;
- Vector3 side = Vector3(Math::sin(Math::deg_to_rad(fov)), 0, -Math::cos(Math::deg_to_rad(fov)));
- Vector3 nside = side;
- nside.x = -nside.x;
- Vector3 up = Vector3(0, side.x, 0);
+ const float hsize = Math::sin(Math::deg_to_rad(fov));
+ const float depth = -Math::cos(Math::deg_to_rad(fov));
+ Vector3 side = Vector3(hsize * size_factor.x, 0, depth);
+ Vector3 nside = Vector3(-side.x, side.y, side.z);
+ Vector3 up = Vector3(0, hsize * size_factor.y, 0);
ADD_TRIANGLE(Vector3(), side + up, side - up);
ADD_TRIANGLE(Vector3(), nside + up, nside - up);
@@ -1868,18 +1892,18 @@ void Camera3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
ADD_TRIANGLE(Vector3(), side - up, nside - up);
handles.push_back(side);
- side.x *= 0.25;
- nside.x *= 0.25;
- Vector3 tup(0, up.y * 3 / 2, side.z);
+ side.x = MIN(side.x, hsize * 0.25);
+ nside.x = -side.x;
+ Vector3 tup(0, up.y + hsize / 2, side.z);
ADD_TRIANGLE(tup, side + up, nside + up);
-
} break;
+
case Camera3D::PROJECTION_ORTHOGONAL: {
float size = camera->get_size();
float hsize = size * 0.5;
- Vector3 right(hsize, 0, 0);
- Vector3 up(0, hsize, 0);
+ Vector3 right(hsize * size_factor.x, 0, 0);
+ Vector3 up(0, hsize * size_factor.y, 0);
Vector3 back(0, 0, -1.0);
Vector3 front(0, 0, 0);
@@ -1890,18 +1914,19 @@ void Camera3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
handles.push_back(right + back);
- right.x *= 0.25;
- Vector3 tup(0, up.y * 3 / 2, back.z);
+ right.x = MIN(right.x, hsize * 0.25);
+ Vector3 tup(0, up.y + hsize / 2, back.z);
ADD_TRIANGLE(tup, right + up + back, -right + up + back);
} break;
+
case Camera3D::PROJECTION_FRUSTUM: {
float hsize = camera->get_size() / 2.0;
Vector3 side = Vector3(hsize, 0, -camera->get_near()).normalized();
- Vector3 nside = side;
- nside.x = -nside.x;
- Vector3 up = Vector3(0, side.x, 0);
+ side.x *= size_factor.x;
+ Vector3 nside = Vector3(-side.x, side.y, side.z);
+ Vector3 up = Vector3(0, hsize * size_factor.y, 0);
Vector3 offset = Vector3(camera->get_frustum_offset().x, camera->get_frustum_offset().y, 0.0);
ADD_TRIANGLE(Vector3(), side + up + offset, side - up + offset);
@@ -1909,11 +1934,11 @@ void Camera3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
ADD_TRIANGLE(Vector3(), side + up + offset, nside + up + offset);
ADD_TRIANGLE(Vector3(), side - up + offset, nside - up + offset);
- side.x *= 0.25;
- nside.x *= 0.25;
- Vector3 tup(0, up.y * 3 / 2, side.z);
+ side.x = MIN(side.x, hsize * 0.25);
+ nside.x = -side.x;
+ Vector3 tup(0, up.y + hsize / 2, side.z);
ADD_TRIANGLE(tup + offset, side + up + offset, nside + up + offset);
- }
+ } break;
}
#undef ADD_TRIANGLE
@@ -1921,7 +1946,10 @@ void Camera3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
p_gizmo->add_lines(lines, material);
p_gizmo->add_collision_segments(lines);
- p_gizmo->add_handles(handles, get_material("handles"));
+
+ if (!handles.is_empty()) {
+ p_gizmo->add_handles(handles, get_material("handles"));
+ }
}
//////
diff --git a/editor/plugins/node_3d_editor_gizmos.h b/editor/plugins/node_3d_editor_gizmos.h
index d7e3e03f61..60d44ad787 100644
--- a/editor/plugins/node_3d_editor_gizmos.h
+++ b/editor/plugins/node_3d_editor_gizmos.h
@@ -264,6 +264,9 @@ public:
class Camera3DGizmoPlugin : public EditorNode3DGizmoPlugin {
GDCLASS(Camera3DGizmoPlugin, EditorNode3DGizmoPlugin);
+private:
+ static Size2i _get_viewport_size(Camera3D *p_camera);
+
public:
bool has_gizmo(Node3D *p_spatial) override;
String get_gizmo_name() const override;
diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp
index ca6d65bd57..112a3fa51b 100644
--- a/editor/plugins/node_3d_editor_plugin.cpp
+++ b/editor/plugins/node_3d_editor_plugin.cpp
@@ -36,14 +36,12 @@
#include "core/math/math_funcs.h"
#include "core/math/projection.h"
#include "core/os/keyboard.h"
-#include "core/templates/sort_array.h"
#include "editor/debugger/editor_debugger_node.h"
#include "editor/editor_node.h"
#include "editor/editor_settings.h"
#include "editor/editor_undo_redo_manager.h"
#include "editor/plugins/animation_player_editor_plugin.h"
#include "editor/plugins/node_3d_editor_gizmos.h"
-#include "editor/plugins/script_editor_plugin.h"
#include "editor/scene_tree_dock.h"
#include "scene/3d/camera_3d.h"
#include "scene/3d/collision_shape_3d.h"
@@ -54,9 +52,12 @@
#include "scene/3d/visual_instance_3d.h"
#include "scene/3d/world_environment.h"
#include "scene/gui/center_container.h"
+#include "scene/gui/color_picker.h"
#include "scene/gui/flow_container.h"
+#include "scene/gui/split_container.h"
#include "scene/gui/subviewport_container.h"
#include "scene/resources/packed_scene.h"
+#include "scene/resources/sky_material.h"
#include "scene/resources/surface_tool.h"
constexpr real_t DISTANCE_DEFAULT = 4;
@@ -85,6 +86,177 @@ constexpr real_t MAX_Z = 1000000.0;
constexpr real_t MIN_FOV = 0.01;
constexpr real_t MAX_FOV = 179;
+void ViewportNavigationControl::_notification(int p_what) {
+ switch (p_what) {
+ case NOTIFICATION_ENTER_TREE: {
+ if (!is_connected("mouse_exited", callable_mp(this, &ViewportNavigationControl::_on_mouse_exited))) {
+ connect("mouse_exited", callable_mp(this, &ViewportNavigationControl::_on_mouse_exited));
+ }
+ if (!is_connected("mouse_entered", callable_mp(this, &ViewportNavigationControl::_on_mouse_entered))) {
+ connect("mouse_entered", callable_mp(this, &ViewportNavigationControl::_on_mouse_entered));
+ }
+ } break;
+
+ case NOTIFICATION_DRAW: {
+ if (viewport != nullptr) {
+ _draw();
+ _update_navigation();
+ }
+ } break;
+ }
+}
+
+void ViewportNavigationControl::_draw() {
+ if (nav_mode == Node3DEditorViewport::NAVIGATION_NONE) {
+ return;
+ }
+
+ Vector2 center = get_size() / 2.0;
+ float radius = get_size().x / 2.0;
+
+ const bool focused = focused_index != -1;
+ draw_circle(center, radius, Color(0.5, 0.5, 0.5, focused || hovered ? 0.35 : 0.15));
+
+ const Color c = focused ? Color(0.9, 0.9, 0.9, 0.9) : Color(0.5, 0.5, 0.5, 0.25);
+
+ Vector2 circle_pos = focused ? center.move_toward(focused_pos, radius) : center;
+
+ draw_circle(circle_pos, AXIS_CIRCLE_RADIUS, c);
+ draw_circle(circle_pos, AXIS_CIRCLE_RADIUS * 0.8, c.darkened(0.4));
+}
+
+void ViewportNavigationControl::_process_click(int p_index, Vector2 p_position, bool p_pressed) {
+ hovered = false;
+ queue_redraw();
+
+ if (focused_index != -1 && focused_index != p_index) {
+ return;
+ }
+ if (p_pressed) {
+ if (p_position.distance_to(get_size() / 2.0) < get_size().x / 2.0) {
+ focused_pos = p_position;
+ focused_index = p_index;
+ queue_redraw();
+ }
+ } else {
+ focused_index = -1;
+ if (Input::get_singleton()->get_mouse_mode() == Input::MOUSE_MODE_CAPTURED) {
+ Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_VISIBLE);
+ Input::get_singleton()->warp_mouse(focused_mouse_start);
+ }
+ }
+}
+
+void ViewportNavigationControl::_process_drag(int p_index, Vector2 p_position, Vector2 p_relative_position) {
+ if (focused_index == p_index) {
+ if (Input::get_singleton()->get_mouse_mode() == Input::MOUSE_MODE_VISIBLE) {
+ Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_CAPTURED);
+ focused_mouse_start = p_position;
+ }
+ focused_pos += p_relative_position;
+ queue_redraw();
+ }
+}
+
+void ViewportNavigationControl::gui_input(const Ref<InputEvent> &p_event) {
+ // Mouse events
+ const Ref<InputEventMouseButton> mouse_button = p_event;
+ if (mouse_button.is_valid() && mouse_button->get_button_index() == MouseButton::LEFT) {
+ _process_click(100, mouse_button->get_position(), mouse_button->is_pressed());
+ }
+
+ const Ref<InputEventMouseMotion> mouse_motion = p_event;
+ if (mouse_motion.is_valid()) {
+ _process_drag(100, mouse_motion->get_global_position(), viewport->_get_warped_mouse_motion(mouse_motion));
+ }
+
+ // Touch events
+ const Ref<InputEventScreenTouch> screen_touch = p_event;
+ if (screen_touch.is_valid()) {
+ _process_click(screen_touch->get_index(), screen_touch->get_position(), screen_touch->is_pressed());
+ }
+
+ const Ref<InputEventScreenDrag> screen_drag = p_event;
+ if (screen_drag.is_valid()) {
+ _process_drag(screen_drag->get_index(), screen_drag->get_position(), screen_drag->get_relative());
+ }
+}
+
+void ViewportNavigationControl::_update_navigation() {
+ if (focused_index == -1) {
+ return;
+ }
+
+ Vector2 delta = focused_pos - (get_size() / 2.0);
+ Vector2 delta_normalized = delta.normalized();
+ switch (nav_mode) {
+ case Node3DEditorViewport::NavigationMode::NAVIGATION_MOVE: {
+ real_t speed_multiplier = MIN(delta.length() / (get_size().x * 100.0), 3.0);
+ real_t speed = viewport->freelook_speed * speed_multiplier;
+
+ const Node3DEditorViewport::FreelookNavigationScheme navigation_scheme = (Node3DEditorViewport::FreelookNavigationScheme)EditorSettings::get_singleton()->get("editors/3d/freelook/freelook_navigation_scheme").operator int();
+
+ Vector3 forward;
+ if (navigation_scheme == Node3DEditorViewport::FreelookNavigationScheme::FREELOOK_FULLY_AXIS_LOCKED) {
+ // Forward/backward keys will always go straight forward/backward, never moving on the Y axis.
+ forward = Vector3(0, 0, delta_normalized.y).rotated(Vector3(0, 1, 0), viewport->camera->get_rotation().y);
+ } else {
+ // Forward/backward keys will be relative to the camera pitch.
+ forward = viewport->camera->get_transform().basis.xform(Vector3(0, 0, delta_normalized.y));
+ }
+
+ const Vector3 right = viewport->camera->get_transform().basis.xform(Vector3(delta_normalized.x, 0, 0));
+
+ const Vector3 direction = forward + right;
+ const Vector3 motion = direction * speed;
+ viewport->cursor.pos += motion;
+ viewport->cursor.eye_pos += motion;
+ } break;
+
+ case Node3DEditorViewport::NavigationMode::NAVIGATION_LOOK: {
+ real_t speed_multiplier = MIN(delta.length() / (get_size().x * 2.5), 3.0);
+ real_t speed = viewport->freelook_speed * speed_multiplier;
+ viewport->_nav_look(nullptr, delta_normalized * speed);
+ } break;
+
+ case Node3DEditorViewport::NAVIGATION_PAN: {
+ real_t speed_multiplier = MIN(delta.length() / (get_size().x), 3.0);
+ real_t speed = viewport->freelook_speed * speed_multiplier;
+ viewport->_nav_pan(nullptr, -delta_normalized * speed);
+ } break;
+ case Node3DEditorViewport::NAVIGATION_ZOOM: {
+ real_t speed_multiplier = MIN(delta.length() / (get_size().x), 3.0);
+ real_t speed = viewport->freelook_speed * speed_multiplier;
+ viewport->_nav_zoom(nullptr, delta_normalized * speed);
+ } break;
+ case Node3DEditorViewport::NAVIGATION_ORBIT: {
+ real_t speed_multiplier = MIN(delta.length() / (get_size().x), 3.0);
+ real_t speed = viewport->freelook_speed * speed_multiplier;
+ viewport->_nav_orbit(nullptr, delta_normalized * speed);
+ } break;
+ case Node3DEditorViewport::NAVIGATION_NONE: {
+ } break;
+ }
+}
+
+void ViewportNavigationControl::_on_mouse_entered() {
+ hovered = true;
+ queue_redraw();
+}
+
+void ViewportNavigationControl::_on_mouse_exited() {
+ hovered = false;
+ queue_redraw();
+}
+
+void ViewportNavigationControl::set_navigation_mode(Node3DEditorViewport::NavigationMode p_nav_mode) {
+ nav_mode = p_nav_mode;
+}
+
+void ViewportNavigationControl::set_viewport(Node3DEditorViewport *p_viewport) {
+ viewport = p_viewport;
+}
+
void ViewportRotationControl::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
@@ -119,7 +291,7 @@ void ViewportRotationControl::_draw() {
const Vector2i center = get_size() / 2.0;
const real_t radius = get_size().x / 2.0;
- if (focused_axis > -2 || orbiting) {
+ if (focused_axis > -2 || orbiting_index != -1) {
draw_circle(center, radius, Color(0.5, 0.5, 0.5, 0.25));
}
@@ -190,41 +362,63 @@ void ViewportRotationControl::_get_sorted_axis(Vector<Axis2D> &r_axis) {
r_axis.sort_custom<Axis2DCompare>();
}
+void ViewportRotationControl::_process_click(int p_index, Vector2 p_position, bool p_pressed) {
+ if (orbiting_index != -1 && orbiting_index != p_index) {
+ return;
+ }
+ if (p_pressed) {
+ if (p_position.distance_to(get_size() / 2.0) < get_size().x / 2.0) {
+ orbiting_index = p_index;
+ }
+ } else {
+ if (focused_axis > -1) {
+ viewport->_menu_option(axis_menu_options[focused_axis]);
+ _update_focus();
+ }
+ orbiting_index = -1;
+ if (Input::get_singleton()->get_mouse_mode() == Input::MOUSE_MODE_CAPTURED) {
+ Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_VISIBLE);
+ Input::get_singleton()->warp_mouse(orbiting_mouse_start);
+ }
+ }
+}
+
+void ViewportRotationControl::_process_drag(Ref<InputEventWithModifiers> p_event, int p_index, Vector2 p_position, Vector2 p_relative_position) {
+ if (orbiting_index == p_index) {
+ if (Input::get_singleton()->get_mouse_mode() == Input::MOUSE_MODE_VISIBLE) {
+ Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_CAPTURED);
+ orbiting_mouse_start = p_position;
+ }
+ viewport->_nav_orbit(p_event, p_relative_position);
+ focused_axis = -1;
+ } else {
+ _update_focus();
+ }
+}
+
void ViewportRotationControl::gui_input(const Ref<InputEvent> &p_event) {
ERR_FAIL_COND(p_event.is_null());
+ // Mouse events
const Ref<InputEventMouseButton> mb = p_event;
if (mb.is_valid() && mb->get_button_index() == MouseButton::LEFT) {
- Vector2 pos = mb->get_position();
- if (mb->is_pressed()) {
- if (pos.distance_to(get_size() / 2.0) < get_size().x / 2.0) {
- orbiting = true;
- }
- } else {
- if (focused_axis > -1) {
- viewport->_menu_option(axis_menu_options[focused_axis]);
- _update_focus();
- }
- orbiting = false;
- if (Input::get_singleton()->get_mouse_mode() == Input::MOUSE_MODE_CAPTURED) {
- Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_VISIBLE);
- Input::get_singleton()->warp_mouse(orbiting_mouse_start);
- }
- }
+ _process_click(100, mb->get_position(), mb->is_pressed());
}
const Ref<InputEventMouseMotion> mm = p_event;
if (mm.is_valid()) {
- if (orbiting) {
- if (Input::get_singleton()->get_mouse_mode() == Input::MOUSE_MODE_VISIBLE) {
- Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_CAPTURED);
- orbiting_mouse_start = mm->get_global_position();
- }
- viewport->_nav_orbit(mm, viewport->_get_warped_mouse_motion(mm));
- focused_axis = -1;
- } else {
- _update_focus();
- }
+ _process_drag(mm, 100, mm->get_global_position(), viewport->_get_warped_mouse_motion(mm));
+ }
+
+ // Touch events
+ const Ref<InputEventScreenTouch> screen_touch = p_event;
+ if (screen_touch.is_valid()) {
+ _process_click(screen_touch->get_index(), screen_touch->get_position(), screen_touch->is_pressed());
+ }
+
+ const Ref<InputEventScreenDrag> screen_drag = p_event;
+ if (screen_drag.is_valid()) {
+ _process_drag(screen_drag, screen_drag->get_index(), screen_drag->get_position(), screen_drag->get_relative());
}
}
@@ -352,6 +546,8 @@ void Node3DEditorViewport::_update_camera(real_t p_interp_delta) {
update_transform_gizmo_view();
rotation_control->queue_redraw();
+ position_control->queue_redraw();
+ look_control->queue_redraw();
spatial_editor->update_grid();
}
}
@@ -2090,7 +2286,7 @@ void Node3DEditorViewport::_nav_pan(Ref<InputEventWithModifiers> p_event, const
const NavigationScheme nav_scheme = (NavigationScheme)EDITOR_GET("editors/3d/navigation/navigation_scheme").operator int();
real_t pan_speed = 1 / 150.0;
- if (nav_scheme == NAVIGATION_MAYA && p_event->is_shift_pressed()) {
+ if (p_event.is_valid() && nav_scheme == NAVIGATION_MAYA && p_event->is_shift_pressed()) {
pan_speed *= 10;
}
@@ -2114,7 +2310,7 @@ void Node3DEditorViewport::_nav_zoom(Ref<InputEventWithModifiers> p_event, const
const NavigationScheme nav_scheme = (NavigationScheme)EDITOR_GET("editors/3d/navigation/navigation_scheme").operator int();
real_t zoom_speed = 1 / 80.0;
- if (nav_scheme == NAVIGATION_MAYA && p_event->is_shift_pressed()) {
+ if (p_event.is_valid() && nav_scheme == NAVIGATION_MAYA && p_event->is_shift_pressed()) {
zoom_speed *= 10;
}
@@ -2447,6 +2643,8 @@ void Node3DEditorViewport::_notification(int p_what) {
}
call_deferred(SNAME("update_transform_gizmo_view"));
rotation_control->set_visible(EDITOR_GET("editors/3d/navigation/show_viewport_rotation_gizmo"));
+ position_control->set_visible(EDITOR_GET("editors/3d/navigation/show_viewport_navigation_gizmo"));
+ look_control->set_visible(EDITOR_GET("editors/3d/navigation/show_viewport_navigation_gizmo"));
} break;
case NOTIFICATION_RESIZED: {
@@ -3369,6 +3567,8 @@ void Node3DEditorViewport::_toggle_camera_preview(bool p_activate) {
ERR_FAIL_COND(!p_activate && !previewing);
rotation_control->set_visible(!p_activate);
+ position_control->set_visible(!p_activate);
+ look_control->set_visible(!p_activate);
if (!p_activate) {
previewing->disconnect("tree_exiting", callable_mp(this, &Node3DEditorViewport::_preview_exited_scene));
@@ -3390,6 +3590,8 @@ void Node3DEditorViewport::_toggle_camera_preview(bool p_activate) {
void Node3DEditorViewport::_toggle_cinema_preview(bool p_activate) {
previewing_cinema = p_activate;
rotation_control->set_visible(!p_activate);
+ position_control->set_visible(!p_activate);
+ look_control->set_visible(!p_activate);
if (!previewing_cinema) {
if (previewing != nullptr) {
@@ -4873,6 +5075,14 @@ Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, int p
preview_node = nullptr;
+ bottom_center_vbox = memnew(VBoxContainer);
+ bottom_center_vbox->set_anchors_preset(LayoutPreset::PRESET_CENTER);
+ bottom_center_vbox->set_anchor_and_offset(SIDE_TOP, ANCHOR_END, -20 * EDSCALE);
+ bottom_center_vbox->set_anchor_and_offset(SIDE_BOTTOM, ANCHOR_END, -10 * EDSCALE);
+ bottom_center_vbox->set_h_grow_direction(GROW_DIRECTION_BOTH);
+ bottom_center_vbox->set_v_grow_direction(GROW_DIRECTION_BEGIN);
+ surface->add_child(bottom_center_vbox);
+
info_label = memnew(Label);
info_label->set_anchor_and_offset(SIDE_LEFT, ANCHOR_END, -90 * EDSCALE);
info_label->set_anchor_and_offset(SIDE_TOP, ANCHOR_END, -90 * EDSCALE);
@@ -4893,23 +5103,18 @@ Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, int p
previewing_cinema = false;
locked_label = memnew(Label);
- locked_label->set_anchor_and_offset(SIDE_TOP, ANCHOR_END, -20 * EDSCALE);
- locked_label->set_anchor_and_offset(SIDE_BOTTOM, ANCHOR_END, -10 * EDSCALE);
- locked_label->set_h_grow_direction(GROW_DIRECTION_END);
- locked_label->set_v_grow_direction(GROW_DIRECTION_BEGIN);
locked_label->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
- surface->add_child(locked_label);
+ locked_label->set_h_size_flags(SIZE_SHRINK_CENTER);
+ bottom_center_vbox->add_child(locked_label);
locked_label->set_text(TTR("View Rotation Locked"));
locked_label->hide();
zoom_limit_label = memnew(Label);
- zoom_limit_label->set_anchors_and_offsets_preset(LayoutPreset::PRESET_BOTTOM_LEFT);
- zoom_limit_label->set_offset(Side::SIDE_TOP, -28 * EDSCALE);
zoom_limit_label->set_text(TTR("To zoom further, change the camera's clipping planes (View -> Settings...)"));
zoom_limit_label->set_name("ZoomLimitMessageLabel");
zoom_limit_label->add_theme_color_override("font_color", Color(1, 1, 1, 1));
zoom_limit_label->hide();
- surface->add_child(zoom_limit_label);
+ bottom_center_vbox->add_child(zoom_limit_label);
preview_material_label = memnew(Label);
preview_material_label->set_anchors_and_offsets_preset(LayoutPreset::PRESET_BOTTOM_LEFT);
@@ -4940,6 +5145,30 @@ Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, int p
// Prevent visible spacing between frame time labels.
top_right_vbox->add_theme_constant_override("separation", 0);
+ const int navigation_control_size = 150;
+
+ position_control = memnew(ViewportNavigationControl);
+ position_control->set_navigation_mode(Node3DEditorViewport::NAVIGATION_MOVE);
+ position_control->set_custom_minimum_size(Size2(navigation_control_size, navigation_control_size) * EDSCALE);
+ position_control->set_h_size_flags(SIZE_SHRINK_END);
+ position_control->set_anchor_and_offset(SIDE_LEFT, ANCHOR_BEGIN, 0 * EDSCALE);
+ position_control->set_anchor_and_offset(SIDE_TOP, ANCHOR_END, -navigation_control_size * EDSCALE);
+ position_control->set_anchor_and_offset(SIDE_RIGHT, ANCHOR_BEGIN, navigation_control_size * EDSCALE);
+ position_control->set_anchor_and_offset(SIDE_BOTTOM, ANCHOR_END, 0 * EDSCALE);
+ position_control->set_viewport(this);
+ surface->add_child(position_control);
+
+ look_control = memnew(ViewportNavigationControl);
+ look_control->set_navigation_mode(Node3DEditorViewport::NAVIGATION_LOOK);
+ look_control->set_custom_minimum_size(Size2(navigation_control_size, navigation_control_size) * EDSCALE);
+ look_control->set_h_size_flags(SIZE_SHRINK_END);
+ look_control->set_anchor_and_offset(SIDE_LEFT, ANCHOR_END, -navigation_control_size * EDSCALE);
+ look_control->set_anchor_and_offset(SIDE_TOP, ANCHOR_END, -navigation_control_size * EDSCALE);
+ look_control->set_anchor_and_offset(SIDE_RIGHT, ANCHOR_END, 0 * EDSCALE);
+ look_control->set_anchor_and_offset(SIDE_BOTTOM, ANCHOR_END, 0 * EDSCALE);
+ look_control->set_viewport(this);
+ surface->add_child(look_control);
+
rotation_control = memnew(ViewportRotationControl);
rotation_control->set_custom_minimum_size(Size2(80, 80) * EDSCALE);
rotation_control->set_h_size_flags(SIZE_SHRINK_END);
@@ -7248,6 +7477,8 @@ void Node3DEditor::_notification(int p_what) {
sun_state->set_custom_minimum_size(sun_vb->get_combined_minimum_size());
environ_state->set_custom_minimum_size(environ_vb->get_combined_minimum_size());
+
+ EditorNode::get_singleton()->connect("project_settings_changed", callable_mp(this, &Node3DEditor::update_all_gizmos).bind(Variant()));
} break;
case NOTIFICATION_ENTER_TREE: {
@@ -8190,7 +8421,8 @@ Node3DEditor::Node3DEditor() {
EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::INT, "editors/3d/manipulator_gizmo_size", PROPERTY_HINT_RANGE, "16,160,1"));
EDITOR_DEF("editors/3d/manipulator_gizmo_opacity", 0.9);
EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::FLOAT, "editors/3d/manipulator_gizmo_opacity", PROPERTY_HINT_RANGE, "0,1,0.01"));
- EDITOR_DEF("editors/3d/navigation/show_viewport_rotation_gizmo", true);
+ EDITOR_DEF_RST("editors/3d/navigation/show_viewport_rotation_gizmo", true);
+ EDITOR_DEF_RST("editors/3d/navigation/show_viewport_navigation_gizmo", DisplayServer::get_singleton()->is_touchscreen_available());
current_hover_gizmo_handle = -1;
current_hover_gizmo_handle_secondary = false;
diff --git a/editor/plugins/node_3d_editor_plugin.h b/editor/plugins/node_3d_editor_plugin.h
index a8d3bfb70c..ed555d86c3 100644
--- a/editor/plugins/node_3d_editor_plugin.h
+++ b/editor/plugins/node_3d_editor_plugin.h
@@ -33,32 +33,31 @@
#include "editor/editor_plugin.h"
#include "editor/editor_scale.h"
-#include "editor/editor_spin_slider.h"
#include "editor/plugins/node_3d_editor_gizmos.h"
-#include "scene/3d/camera_3d.h"
-#include "scene/3d/light_3d.h"
-#include "scene/3d/visual_instance_3d.h"
-#include "scene/3d/world_environment.h"
#include "scene/gui/box_container.h"
-#include "scene/gui/color_picker.h"
-#include "scene/gui/panel_container.h"
+#include "scene/gui/button.h"
#include "scene/gui/spin_box.h"
-#include "scene/gui/split_container.h"
-#include "scene/resources/environment.h"
-#include "scene/resources/fog_material.h"
-#include "scene/resources/sky_material.h"
class AcceptDialog;
class CheckBox;
+class ColorPickerButton;
class ConfirmationDialog;
+class DirectionalLight3D;
class EditorData;
+class EditorSpinSlider;
+class HSplitContainer;
+class LineEdit;
class MenuButton;
class Node3DEditor;
class Node3DEditorViewport;
class OptionButton;
+class PanelContainer;
+class ProceduralSkyMaterial;
+class SubViewport;
class SubViewportContainer;
-class DirectionalLight3D;
+class VSplitContainer;
class WorldEnvironment;
+class ViewportNavigationControl;
class ViewportRotationControl : public Control {
GDCLASS(ViewportRotationControl, Control);
@@ -79,7 +78,7 @@ class ViewportRotationControl : public Control {
Vector<Color> axis_colors;
Vector<int> axis_menu_options;
Vector2i orbiting_mouse_start;
- bool orbiting = false;
+ int orbiting_index = -1;
int focused_axis = -2;
const float AXIS_CIRCLE_RADIUS = 8.0f * EDSCALE;
@@ -92,6 +91,8 @@ protected:
void _get_sorted_axis(Vector<Axis2D> &r_axis);
void _update_focus();
void _on_mouse_exited();
+ void _process_click(int p_index, Vector2 p_position, bool p_pressed);
+ void _process_drag(Ref<InputEventWithModifiers> p_event, int p_index, Vector2 p_position, Vector2 p_relative_position);
public:
void set_viewport(Node3DEditorViewport *p_viewport);
@@ -100,6 +101,7 @@ public:
class Node3DEditorViewport : public Control {
GDCLASS(Node3DEditorViewport, Control);
friend class Node3DEditor;
+ friend class ViewportNavigationControl;
friend class ViewportRotationControl;
enum {
VIEW_TOP,
@@ -238,6 +240,9 @@ private:
Label *preview_material_label_desc = nullptr;
VBoxContainer *top_right_vbox = nullptr;
+ VBoxContainer *bottom_center_vbox = nullptr;
+ ViewportNavigationControl *position_control = nullptr;
+ ViewportNavigationControl *look_control = nullptr;
ViewportRotationControl *rotation_control = nullptr;
Gradient *frame_time_gradient = nullptr;
Label *cpu_time_label = nullptr;
@@ -299,7 +304,8 @@ private:
NAVIGATION_PAN,
NAVIGATION_ZOOM,
NAVIGATION_ORBIT,
- NAVIGATION_LOOK
+ NAVIGATION_LOOK,
+ NAVIGATION_MOVE
};
enum TransformMode {
TRANSFORM_NONE,
@@ -918,4 +924,31 @@ public:
~Node3DEditorPlugin();
};
+class ViewportNavigationControl : public Control {
+ GDCLASS(ViewportNavigationControl, Control);
+
+ Node3DEditorViewport *viewport = nullptr;
+ Vector2i focused_mouse_start;
+ Vector2 focused_pos;
+ bool hovered = false;
+ int focused_index = -1;
+ Node3DEditorViewport::NavigationMode nav_mode = Node3DEditorViewport::NavigationMode::NAVIGATION_NONE;
+
+ const float AXIS_CIRCLE_RADIUS = 30.0f * EDSCALE;
+
+protected:
+ void _notification(int p_what);
+ virtual void gui_input(const Ref<InputEvent> &p_event) override;
+ void _draw();
+ void _on_mouse_entered();
+ void _on_mouse_exited();
+ void _process_click(int p_index, Vector2 p_position, bool p_pressed);
+ void _process_drag(int p_index, Vector2 p_position, Vector2 p_relative_position);
+ void _update_navigation();
+
+public:
+ void set_navigation_mode(Node3DEditorViewport::NavigationMode p_nav_mode);
+ void set_viewport(Node3DEditorViewport *p_viewport);
+};
+
#endif // NODE_3D_EDITOR_PLUGIN_H
diff --git a/editor/plugins/path_2d_editor_plugin.cpp b/editor/plugins/path_2d_editor_plugin.cpp
index c8bd4c1d05..3204cc8d0f 100644
--- a/editor/plugins/path_2d_editor_plugin.cpp
+++ b/editor/plugins/path_2d_editor_plugin.cpp
@@ -37,6 +37,7 @@
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
#include "editor/editor_undo_redo_manager.h"
+#include "scene/gui/menu_button.h"
void Path2DEditor::_notification(int p_what) {
switch (p_what) {
@@ -119,6 +120,7 @@ bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
}
// Check for point deletion.
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
if ((mb->get_button_index() == MouseButton::RIGHT && mode == MODE_EDIT) || (mb->get_button_index() == MouseButton::LEFT && mode == MODE_DELETE)) {
if (dist_to_p < grab_threshold) {
undo_redo->create_action(TTR("Remove Point from Curve"));
@@ -153,6 +155,7 @@ bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
if (mb->is_pressed() && mb->get_button_index() == MouseButton::LEFT && ((mb->is_command_or_control_pressed() && mode == MODE_EDIT) || mode == MODE_CREATE)) {
Ref<Curve2D> curve = node->get_curve();
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Add Point to Curve"));
undo_redo->add_do_method(curve.ptr(), "add_point", cpoint);
undo_redo->add_undo_method(curve.ptr(), "remove_point", curve->get_point_count());
@@ -188,6 +191,7 @@ bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
insertion_point = curve->get_point_count() - 2;
}
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Split Curve"));
undo_redo->add_do_method(curve.ptr(), "add_point", xform.affine_inverse().xform(gpoint2), Vector2(0, 0), Vector2(0, 0), insertion_point + 1);
undo_redo->add_undo_method(curve.ptr(), "remove_point", insertion_point + 1);
@@ -211,6 +215,7 @@ bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
if (!mb->is_pressed() && mb->get_button_index() == MouseButton::LEFT && action != ACTION_NONE) {
Ref<Curve2D> curve = node->get_curve();
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
Vector2 new_pos = moving_from + xform.affine_inverse().basis_xform(gpoint - moving_screen_from);
switch (action) {
case ACTION_NONE:
@@ -486,6 +491,7 @@ void Path2DEditor::_mode_selected(int p_mode) {
return;
}
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Remove Point from Curve"));
undo_redo->add_do_method(node->get_curve().ptr(), "add_point", begin);
undo_redo->add_undo_method(node->get_curve().ptr(), "remove_point", node->get_curve()->get_point_count());
@@ -519,7 +525,6 @@ void Path2DEditor::_handle_option_pressed(int p_option) {
Path2DEditor::Path2DEditor() {
canvas_item_editor = nullptr;
- undo_redo = EditorNode::get_singleton()->get_undo_redo();
mirror_handle_angle = true;
mirror_handle_length = true;
on_edge = false;
diff --git a/editor/plugins/path_2d_editor_plugin.h b/editor/plugins/path_2d_editor_plugin.h
index d2015b2bb8..c6ed257540 100644
--- a/editor/plugins/path_2d_editor_plugin.h
+++ b/editor/plugins/path_2d_editor_plugin.h
@@ -37,14 +37,11 @@
#include "scene/gui/separator.h"
class CanvasItemEditor;
-class EditorUndoRedoManager;
class MenuButton;
class Path2DEditor : public HBoxContainer {
GDCLASS(Path2DEditor, HBoxContainer);
- Ref<EditorUndoRedoManager> undo_redo;
-
CanvasItemEditor *canvas_item_editor = nullptr;
Panel *panel = nullptr;
Path2D *node = nullptr;
diff --git a/editor/plugins/path_3d_editor_plugin.cpp b/editor/plugins/path_3d_editor_plugin.cpp
index d7953bf4e0..63ca78d6c0 100644
--- a/editor/plugins/path_3d_editor_plugin.cpp
+++ b/editor/plugins/path_3d_editor_plugin.cpp
@@ -37,6 +37,7 @@
#include "editor/editor_settings.h"
#include "editor/editor_undo_redo_manager.h"
#include "node_3d_editor_plugin.h"
+#include "scene/gui/menu_button.h"
#include "scene/resources/curve.h"
static bool _is_in_handle(int p_id, int p_num_points) {
@@ -239,38 +240,63 @@ void Path3DGizmo::redraw() {
return;
}
- Vector<Vector3> v3a = c->tessellate();
- //Vector<Vector3> v3a=c->get_baked_points();
+ real_t interval = 0.1;
+ const real_t length = c->get_baked_length();
- int v3s = v3a.size();
- if (v3s == 0) {
- return;
- }
- Vector<Vector3> v3p;
- const Vector3 *r = v3a.ptr();
-
- // BUG: the following won't work when v3s, avoid drawing as a temporary workaround.
- for (int i = 0; i < v3s - 1; i++) {
- v3p.push_back(r[i]);
- v3p.push_back(r[i + 1]);
- //v3p.push_back(r[i]);
- //v3p.push_back(r[i]+Vector3(0,0.2,0));
- }
+ // 1. Draw curve and bones.
+ if (length > CMP_EPSILON) {
+ const int sample_count = int(length / interval) + 2;
+ interval = length / (sample_count - 1); // Recalculate real interval length.
+
+ Vector<Transform3D> frames;
+ frames.resize(sample_count);
+
+ {
+ Transform3D *w = frames.ptrw();
+
+ for (int i = 0; i < sample_count; i++) {
+ w[i] = c->sample_baked_with_rotation(i * interval, true, true);
+ }
+ }
+
+ const Transform3D *r = frames.ptr();
+ Vector<Vector3> v3p;
+ for (int i = 0; i < sample_count - 1; i++) {
+ const Vector3 p1 = r[i].origin;
+ const Vector3 p2 = r[i + 1].origin;
+ const Vector3 side = r[i].basis.get_column(0);
+ const Vector3 up = r[i].basis.get_column(1);
+ const Vector3 forward = r[i].basis.get_column(2);
+
+ // Curve segment.
+ v3p.push_back(p1);
+ v3p.push_back(p2);
+
+ // Fish Bone.
+ v3p.push_back(p1);
+ v3p.push_back(p1 + (side - forward) * 0.06);
+
+ v3p.push_back(p1);
+ v3p.push_back(p1 + (-side - forward) * 0.06);
+
+ v3p.push_back(p1);
+ v3p.push_back(p1 + up * 0.03);
+ }
- if (v3p.size() > 1) {
add_lines(v3p, path_material);
add_collision_segments(v3p);
}
+ // 2. Draw handles.
if (Path3DEditorPlugin::singleton->get_edited_path() == path) {
- v3p.clear();
+ Vector<Vector3> v3p;
Vector<Vector3> handle_points;
Vector<Vector3> sec_handle_points;
for (int i = 0; i < c->get_point_count(); i++) {
Vector3 p = c->get_point_position(i);
handle_points.push_back(p);
- // push Out points first so they get selected if the In and Out points are on top of each other.
+ // Push out points first so they get selected if the In and Out points are on top of each other.
if (i < c->get_point_count() - 1) {
v3p.push_back(p);
v3p.push_back(p + c->get_point_out(i));
diff --git a/editor/plugins/physical_bone_3d_editor_plugin.cpp b/editor/plugins/physical_bone_3d_editor_plugin.cpp
index 9dc89133c4..2b59e4cf08 100644
--- a/editor/plugins/physical_bone_3d_editor_plugin.cpp
+++ b/editor/plugins/physical_bone_3d_editor_plugin.cpp
@@ -31,6 +31,7 @@
#include "physical_bone_3d_editor_plugin.h"
#include "editor/plugins/node_3d_editor_plugin.h"
+#include "scene/gui/separator.h"
void PhysicalBone3DEditor::_bind_methods() {
}
diff --git a/editor/plugins/polygon_2d_editor_plugin.cpp b/editor/plugins/polygon_2d_editor_plugin.cpp
index 6218c887fb..a19a42f951 100644
--- a/editor/plugins/polygon_2d_editor_plugin.cpp
+++ b/editor/plugins/polygon_2d_editor_plugin.cpp
@@ -38,10 +38,14 @@
#include "editor/editor_undo_redo_manager.h"
#include "editor/plugins/canvas_item_editor_plugin.h"
#include "scene/2d/skeleton_2d.h"
+#include "scene/gui/check_box.h"
#include "scene/gui/menu_button.h"
#include "scene/gui/scroll_container.h"
#include "scene/gui/separator.h"
#include "scene/gui/slider.h"
+#include "scene/gui/spin_box.h"
+#include "scene/gui/split_container.h"
+#include "scene/gui/texture_rect.h"
#include "scene/gui/view_panner.h"
Node2D *Polygon2DEditor::_get_node() const {
diff --git a/editor/plugins/polygon_3d_editor_plugin.cpp b/editor/plugins/polygon_3d_editor_plugin.cpp
index dc6ae6be96..dde44d31fa 100644
--- a/editor/plugins/polygon_3d_editor_plugin.cpp
+++ b/editor/plugins/polygon_3d_editor_plugin.cpp
@@ -41,6 +41,7 @@
#include "editor/editor_undo_redo_manager.h"
#include "node_3d_editor_plugin.h"
#include "scene/3d/camera_3d.h"
+#include "scene/gui/separator.h"
void Polygon3DEditor::_notification(int p_what) {
switch (p_what) {
@@ -95,6 +96,7 @@ void Polygon3DEditor::_menu_option(int p_option) {
void Polygon3DEditor::_wip_close() {
Object *obj = node_resource.is_valid() ? (Object *)node_resource.ptr() : node;
ERR_FAIL_COND_MSG(!obj, "Edited object is not valid.");
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Create Polygon3D"));
undo_redo->add_undo_method(obj, "set_polygon", obj->call("get_polygon"));
undo_redo->add_do_method(obj, "set_polygon", wip);
@@ -184,6 +186,7 @@ EditorPlugin::AfterGUIInput Polygon3DEditor::forward_3d_gui_input(Camera3D *p_ca
if (mb->is_pressed()) {
if (mb->is_ctrl_pressed()) {
if (poly.size() < 3) {
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Edit Poly"));
undo_redo->add_undo_method(obj, "set_polygon", poly);
poly.push_back(cpoint);
@@ -262,6 +265,7 @@ EditorPlugin::AfterGUIInput Polygon3DEditor::forward_3d_gui_input(Camera3D *p_ca
ERR_FAIL_INDEX_V(edited_point, poly.size(), EditorPlugin::AFTER_GUI_INPUT_PASS);
poly.write[edited_point] = edited_point_pos;
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Edit Poly"));
undo_redo->add_do_method(obj, "set_polygon", poly);
undo_redo->add_undo_method(obj, "set_polygon", pre_move_edit);
@@ -290,6 +294,7 @@ EditorPlugin::AfterGUIInput Polygon3DEditor::forward_3d_gui_input(Camera3D *p_ca
}
if (closest_idx >= 0) {
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Edit Poly (Remove Point)"));
undo_redo->add_undo_method(obj, "set_polygon", poly);
poly.remove_at(closest_idx);
@@ -527,7 +532,6 @@ void Polygon3DEditor::_bind_methods() {
Polygon3DEditor::Polygon3DEditor() {
node = nullptr;
- undo_redo = EditorNode::get_undo_redo();
add_child(memnew(VSeparator));
button_create = memnew(Button);
diff --git a/editor/plugins/polygon_3d_editor_plugin.h b/editor/plugins/polygon_3d_editor_plugin.h
index fe8e2ce36d..2fa9820aa6 100644
--- a/editor/plugins/polygon_3d_editor_plugin.h
+++ b/editor/plugins/polygon_3d_editor_plugin.h
@@ -38,13 +38,11 @@
#include "scene/resources/immediate_mesh.h"
class CanvasItemEditor;
-class EditorUndoRedoManager;
class MenuButton;
class Polygon3DEditor : public HBoxContainer {
GDCLASS(Polygon3DEditor, HBoxContainer);
- Ref<EditorUndoRedoManager> undo_redo;
enum Mode {
MODE_CREATE,
MODE_EDIT,
diff --git a/editor/plugins/resource_preloader_editor_plugin.cpp b/editor/plugins/resource_preloader_editor_plugin.cpp
index e35e794b24..2794b02ba6 100644
--- a/editor/plugins/resource_preloader_editor_plugin.cpp
+++ b/editor/plugins/resource_preloader_editor_plugin.cpp
@@ -71,6 +71,7 @@ void ResourcePreloaderEditor::_files_load_request(const Vector<String> &p_paths)
name = basename + " " + itos(counter);
}
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Add Resource"));
undo_redo->add_do_method(preloader, "add_resource", name, resource);
undo_redo->add_undo_method(preloader, "remove_resource", name);
@@ -115,6 +116,7 @@ void ResourcePreloaderEditor::_item_edited() {
}
Ref<Resource> samp = preloader->get_resource(old_name);
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Rename Resource"));
undo_redo->add_do_method(preloader, "remove_resource", old_name);
undo_redo->add_do_method(preloader, "add_resource", new_name, samp);
@@ -127,6 +129,7 @@ void ResourcePreloaderEditor::_item_edited() {
}
void ResourcePreloaderEditor::_remove_resource(const String &p_to_remove) {
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Delete Resource"));
undo_redo->add_do_method(preloader, "remove_resource", p_to_remove);
undo_redo->add_undo_method(preloader, "add_resource", p_to_remove, preloader->get_resource(p_to_remove));
@@ -160,6 +163,7 @@ void ResourcePreloaderEditor::_paste_pressed() {
name = basename + " " + itos(counter);
}
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Paste Resource"));
undo_redo->add_do_method(preloader, "add_resource", name, r);
undo_redo->add_undo_method(preloader, "remove_resource", name);
@@ -235,10 +239,6 @@ void ResourcePreloaderEditor::_cell_button_pressed(Object *p_item, int p_column,
}
}
-void ResourcePreloaderEditor::set_undo_redo(Ref<EditorUndoRedoManager> p_undo_redo) {
- undo_redo = p_undo_redo;
-}
-
void ResourcePreloaderEditor::edit(ResourcePreloader *p_preloader) {
preloader = p_preloader;
@@ -322,6 +322,7 @@ void ResourcePreloaderEditor::drop_data_fw(const Point2 &p_point, const Variant
name = basename + "_" + itos(counter);
}
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Add Resource"));
undo_redo->add_do_method(preloader, "add_resource", name, r);
undo_redo->add_undo_method(preloader, "remove_resource", name);
@@ -392,7 +393,6 @@ ResourcePreloaderEditor::ResourcePreloaderEditor() {
}
void ResourcePreloaderEditorPlugin::edit(Object *p_object) {
- preloader_editor->set_undo_redo(EditorNode::get_undo_redo());
ResourcePreloader *s = Object::cast_to<ResourcePreloader>(p_object);
if (!s) {
return;
diff --git a/editor/plugins/resource_preloader_editor_plugin.h b/editor/plugins/resource_preloader_editor_plugin.h
index 59641e2561..7c1be9114d 100644
--- a/editor/plugins/resource_preloader_editor_plugin.h
+++ b/editor/plugins/resource_preloader_editor_plugin.h
@@ -38,7 +38,6 @@
#include "scene/main/resource_preloader.h"
class EditorFileDialog;
-class EditorUndoRedoManager;
class ResourcePreloaderEditor : public PanelContainer {
GDCLASS(ResourcePreloaderEditor, PanelContainer);
@@ -68,8 +67,6 @@ class ResourcePreloaderEditor : public PanelContainer {
void _cell_button_pressed(Object *p_item, int p_column, int p_id, MouseButton p_button);
void _item_edited();
- Ref<EditorUndoRedoManager> undo_redo;
-
Variant get_drag_data_fw(const Point2 &p_point, Control *p_from);
bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const;
void drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from);
@@ -80,8 +77,6 @@ protected:
static void _bind_methods();
public:
- void set_undo_redo(Ref<EditorUndoRedoManager> p_undo_redo);
-
void edit(ResourcePreloader *p_preloader);
ResourcePreloaderEditor();
};
diff --git a/editor/plugins/root_motion_editor_plugin.cpp b/editor/plugins/root_motion_editor_plugin.cpp
index 596b2c0edb..93a64a8f3d 100644
--- a/editor/plugins/root_motion_editor_plugin.cpp
+++ b/editor/plugins/root_motion_editor_plugin.cpp
@@ -32,6 +32,7 @@
#include "editor/editor_node.h"
#include "scene/animation/animation_player.h"
#include "scene/animation/animation_tree.h"
+#include "scene/gui/tree.h"
#include "scene/main/window.h"
void EditorPropertyRootMotion::_confirmed() {
diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp
index 4ff3919e9b..bb5491fcb5 100644
--- a/editor/plugins/script_editor_plugin.cpp
+++ b/editor/plugins/script_editor_plugin.cpp
@@ -40,6 +40,7 @@
#include "editor/debugger/editor_debugger_node.h"
#include "editor/debugger/script_editor_debugger.h"
#include "editor/editor_file_dialog.h"
+#include "editor/editor_help_search.h"
#include "editor/editor_node.h"
#include "editor/editor_paths.h"
#include "editor/editor_run_script.h"
@@ -47,6 +48,7 @@
#include "editor/editor_settings.h"
#include "editor/filesystem_dock.h"
#include "editor/find_in_files.h"
+#include "editor/inspector_dock.h"
#include "editor/node_dock.h"
#include "editor/plugins/shader_editor_plugin.h"
#include "editor/plugins/text_shader_editor.h"
diff --git a/editor/plugins/script_editor_plugin.h b/editor/plugins/script_editor_plugin.h
index 3f84ded0a2..213fbdc22a 100644
--- a/editor/plugins/script_editor_plugin.h
+++ b/editor/plugins/script_editor_plugin.h
@@ -31,24 +31,22 @@
#ifndef SCRIPT_EDITOR_PLUGIN_H
#define SCRIPT_EDITOR_PLUGIN_H
-#include "core/object/script_language.h"
-#include "editor/code_editor.h"
-#include "editor/editor_help.h"
-#include "editor/editor_help_search.h"
#include "editor/editor_plugin.h"
-#include "editor/script_create_dialog.h"
-#include "scene/gui/item_list.h"
-#include "scene/gui/line_edit.h"
-#include "scene/gui/menu_button.h"
-#include "scene/gui/split_container.h"
-#include "scene/gui/tab_container.h"
-#include "scene/gui/text_edit.h"
-#include "scene/gui/tree.h"
-#include "scene/main/timer.h"
+#include "scene/gui/dialogs.h"
+#include "scene/gui/panel_container.h"
+#include "scene/resources/syntax_highlighter.h"
#include "scene/resources/text_file.h"
class EditorFileDialog;
+class EditorHelpSearch;
+class FindReplaceBar;
+class HSplitContainer;
+class ItemList;
+class MenuButton;
+class TabContainer;
class TextureRect;
+class Tree;
+class VSplitContainer;
class EditorSyntaxHighlighter : public SyntaxHighlighter {
GDCLASS(EditorSyntaxHighlighter, SyntaxHighlighter)
diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp
index 4e66dc3d7e..38639ac811 100644
--- a/editor/plugins/script_text_editor.cpp
+++ b/editor/plugins/script_text_editor.cpp
@@ -38,6 +38,7 @@
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "scene/gui/split_container.h"
void ConnectionInfoDialog::ok_pressed() {
}
@@ -1222,7 +1223,9 @@ void ScriptTextEditor::_edit_option(int p_op) {
code_editor->duplicate_selection();
} break;
case EDIT_TOGGLE_FOLD_LINE: {
- tx->toggle_foldable_line(tx->get_caret_line());
+ for (int caret_idx = 0; caret_idx < tx->get_caret_count(); caret_idx++) {
+ tx->toggle_foldable_line(tx->get_caret_line(caret_idx));
+ }
tx->queue_redraw();
} break;
case EDIT_FOLD_ALL_LINES: {
@@ -1290,28 +1293,28 @@ void ScriptTextEditor::_edit_option(int p_op) {
} break;
case EDIT_EVALUATE: {
Expression expression;
- Vector<String> lines = code_editor->get_text_editor()->get_selected_text().split("\n");
- PackedStringArray results;
-
- for (int i = 0; i < lines.size(); i++) {
- String line = lines[i];
- String whitespace = line.substr(0, line.size() - line.strip_edges(true, false).size()); //extract the whitespace at the beginning
-
- if (expression.parse(line) == OK) {
- Variant result = expression.execute(Array(), Variant(), false, true);
- if (expression.get_error_text().is_empty()) {
- results.push_back(whitespace + result.get_construct_string());
+ tx->begin_complex_operation();
+ for (int caret_idx = 0; caret_idx < tx->get_caret_count(); caret_idx++) {
+ Vector<String> lines = tx->get_selected_text(caret_idx).split("\n");
+ PackedStringArray results;
+
+ for (int i = 0; i < lines.size(); i++) {
+ String line = lines[i];
+ String whitespace = line.substr(0, line.size() - line.strip_edges(true, false).size()); // Extract the whitespace at the beginning.
+ if (expression.parse(line) == OK) {
+ Variant result = expression.execute(Array(), Variant(), false, true);
+ if (expression.get_error_text().is_empty()) {
+ results.push_back(whitespace + result.get_construct_string());
+ } else {
+ results.push_back(line);
+ }
} else {
results.push_back(line);
}
- } else {
- results.push_back(line);
}
+ tx->insert_text_at_caret(String("\n").join(results), caret_idx);
}
-
- code_editor->get_text_editor()->begin_complex_operation(); //prevents creating a two-step undo
- code_editor->get_text_editor()->insert_text_at_caret(String("\n").join(results));
- code_editor->get_text_editor()->end_complex_operation();
+ tx->end_complex_operation();
} break;
case SEARCH_FIND: {
code_editor->get_find_replace_bar()->popup_search();
@@ -1326,14 +1329,14 @@ void ScriptTextEditor::_edit_option(int p_op) {
code_editor->get_find_replace_bar()->popup_replace();
} break;
case SEARCH_IN_FILES: {
- String selected_text = code_editor->get_text_editor()->get_selected_text();
+ String selected_text = tx->get_selected_text();
// Yep, because it doesn't make sense to instance this dialog for every single script open...
// So this will be delegated to the ScriptEditor.
emit_signal(SNAME("search_in_files_requested"), selected_text);
} break;
case REPLACE_IN_FILES: {
- String selected_text = code_editor->get_text_editor()->get_selected_text();
+ String selected_text = tx->get_selected_text();
emit_signal(SNAME("replace_in_files_requested"), selected_text);
} break;
@@ -1357,10 +1360,12 @@ void ScriptTextEditor::_edit_option(int p_op) {
code_editor->remove_all_bookmarks();
} break;
case DEBUG_TOGGLE_BREAKPOINT: {
- int line = tx->get_caret_line();
- bool dobreak = !tx->is_line_breakpointed(line);
- tx->set_line_as_breakpoint(line, dobreak);
- EditorDebuggerNode::get_singleton()->set_breakpoint(script->get_path(), line + 1, dobreak);
+ for (int caret_idx = 0; caret_idx < tx->get_caret_count(); caret_idx++) {
+ int line = tx->get_caret_line(caret_idx);
+ bool dobreak = !tx->is_line_breakpointed(line);
+ tx->set_line_as_breakpoint(line, dobreak);
+ EditorDebuggerNode::get_singleton()->set_breakpoint(script->get_path(), line + 1, dobreak);
+ }
} break;
case DEBUG_REMOVE_ALL_BREAKPOINTS: {
PackedInt32Array bpoints = tx->get_breakpointed_lines();
@@ -1378,26 +1383,14 @@ void ScriptTextEditor::_edit_option(int p_op) {
return;
}
- tx->remove_secondary_carets();
- int line = tx->get_caret_line();
-
- // wrap around
- if (line >= (int)bpoints[bpoints.size() - 1]) {
- tx->unfold_line(bpoints[0]);
- tx->set_caret_line(bpoints[0]);
- tx->center_viewport_to_caret();
- } else {
- for (int i = 0; i < bpoints.size(); i++) {
- int bline = bpoints[i];
- if (bline > line) {
- tx->unfold_line(bline);
- tx->set_caret_line(bline);
- tx->center_viewport_to_caret();
- return;
- }
+ int current_line = tx->get_caret_line();
+ int bpoint_idx = 0;
+ if (current_line < (int)bpoints[bpoints.size() - 1]) {
+ while (bpoint_idx < bpoints.size() && bpoints[bpoint_idx] <= current_line) {
+ bpoint_idx++;
}
}
-
+ code_editor->goto_line_centered(bpoints[bpoint_idx]);
} break;
case DEBUG_GOTO_PREV_BREAKPOINT: {
PackedInt32Array bpoints = tx->get_breakpointed_lines();
@@ -1405,25 +1398,14 @@ void ScriptTextEditor::_edit_option(int p_op) {
return;
}
- tx->remove_secondary_carets();
- int line = tx->get_caret_line();
- // wrap around
- if (line <= (int)bpoints[0]) {
- tx->unfold_line(bpoints[bpoints.size() - 1]);
- tx->set_caret_line(bpoints[bpoints.size() - 1]);
- tx->center_viewport_to_caret();
- } else {
- for (int i = bpoints.size() - 1; i >= 0; i--) {
- int bline = bpoints[i];
- if (bline < line) {
- tx->unfold_line(bline);
- tx->set_caret_line(bline);
- tx->center_viewport_to_caret();
- return;
- }
+ int current_line = tx->get_caret_line();
+ int bpoint_idx = bpoints.size() - 1;
+ if (current_line > (int)bpoints[0]) {
+ while (bpoint_idx >= 0 && bpoints[bpoint_idx] >= current_line) {
+ bpoint_idx--;
}
}
-
+ code_editor->goto_line_centered(bpoints[bpoint_idx]);
} break;
case HELP_CONTEXTUAL: {
String text = tx->get_selected_text(0);
@@ -1834,7 +1816,7 @@ void ScriptTextEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) {
base = _find_node_for_script(base, base, script);
}
ScriptLanguage::LookupResult result;
- if (script->get_language()->lookup_code(code_editor->get_text_editor()->get_text_for_symbol_lookup(), word_at_pos, script->get_path(), base, result) == OK) {
+ if (script->get_language()->lookup_code(tx->get_text_for_symbol_lookup(), word_at_pos, script->get_path(), base, result) == OK) {
open_docs = true;
}
}
diff --git a/editor/plugins/script_text_editor.h b/editor/plugins/script_text_editor.h
index 5fd12674b3..cbc4153e12 100644
--- a/editor/plugins/script_text_editor.h
+++ b/editor/plugins/script_text_editor.h
@@ -31,10 +31,14 @@
#ifndef SCRIPT_TEXT_EDITOR_H
#define SCRIPT_TEXT_EDITOR_H
+#include "script_editor_plugin.h"
+
+#include "editor/code_editor.h"
#include "scene/gui/color_picker.h"
#include "scene/gui/dialogs.h"
#include "scene/gui/tree.h"
-#include "script_editor_plugin.h"
+
+class RichTextLabel;
class ConnectionInfoDialog : public AcceptDialog {
GDCLASS(ConnectionInfoDialog, AcceptDialog);
diff --git a/editor/plugins/shader_editor_plugin.cpp b/editor/plugins/shader_editor_plugin.cpp
index 2f80e41dd4..fbc94c70f8 100644
--- a/editor/plugins/shader_editor_plugin.cpp
+++ b/editor/plugins/shader_editor_plugin.cpp
@@ -34,9 +34,12 @@
#include "editor/editor_scale.h"
#include "editor/editor_undo_redo_manager.h"
#include "editor/filesystem_dock.h"
+#include "editor/inspector_dock.h"
#include "editor/plugins/text_shader_editor.h"
#include "editor/plugins/visual_shader_editor_plugin.h"
#include "editor/shader_create_dialog.h"
+#include "scene/gui/item_list.h"
+#include "scene/gui/texture_rect.h"
void ShaderEditorPlugin::_update_shader_list() {
shader_list->clear();
diff --git a/editor/plugins/shader_editor_plugin.h b/editor/plugins/shader_editor_plugin.h
index 1ae419053e..4f0894a1a9 100644
--- a/editor/plugins/shader_editor_plugin.h
+++ b/editor/plugins/shader_editor_plugin.h
@@ -96,6 +96,7 @@ protected:
static void _bind_methods();
public:
+ virtual String get_name() const override { return "Shader"; }
virtual void edit(Object *p_object) override;
virtual bool handles(Object *p_object) const override;
virtual void make_visible(bool p_visible) override;
diff --git a/editor/plugins/shader_file_editor_plugin.cpp b/editor/plugins/shader_file_editor_plugin.cpp
index dd644cb369..4e33c421ae 100644
--- a/editor/plugins/shader_file_editor_plugin.cpp
+++ b/editor/plugins/shader_file_editor_plugin.cpp
@@ -37,6 +37,8 @@
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "scene/gui/item_list.h"
+#include "scene/gui/split_container.h"
#include "servers/display_server.h"
#include "servers/rendering/shader_types.h"
diff --git a/editor/plugins/skeleton_2d_editor_plugin.cpp b/editor/plugins/skeleton_2d_editor_plugin.cpp
index dbad81d743..5ae21a430d 100644
--- a/editor/plugins/skeleton_2d_editor_plugin.cpp
+++ b/editor/plugins/skeleton_2d_editor_plugin.cpp
@@ -35,6 +35,7 @@
#include "editor/editor_undo_redo_manager.h"
#include "scene/2d/mesh_instance_2d.h"
#include "scene/gui/box_container.h"
+#include "scene/gui/menu_button.h"
#include "thirdparty/misc/clipper.hpp"
void Skeleton2DEditor::_node_removed(Node *p_node) {
diff --git a/editor/plugins/skeleton_3d_editor_plugin.cpp b/editor/plugins/skeleton_3d_editor_plugin.cpp
index fd6c9b761e..e8bbfd1b91 100644
--- a/editor/plugins/skeleton_3d_editor_plugin.cpp
+++ b/editor/plugins/skeleton_3d_editor_plugin.cpp
@@ -34,6 +34,7 @@
#include "editor/editor_node.h"
#include "editor/editor_properties.h"
#include "editor/editor_scale.h"
+#include "editor/editor_settings.h"
#include "editor/editor_undo_redo_manager.h"
#include "editor/plugins/animation_player_editor_plugin.h"
#include "node_3d_editor_plugin.h"
@@ -41,6 +42,7 @@
#include "scene/3d/joint_3d.h"
#include "scene/3d/mesh_instance_3d.h"
#include "scene/3d/physics_body_3d.h"
+#include "scene/gui/separator.h"
#include "scene/resources/capsule_shape_3d.h"
#include "scene/resources/skeleton_profile.h"
#include "scene/resources/sphere_shape_3d.h"
@@ -113,6 +115,7 @@ void BoneTransformEditor::_value_changed(const String &p_property, Variant p_val
return;
}
if (skeleton) {
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Set Bone Transform"), UndoRedo::MERGE_ENDS);
undo_redo->add_undo_property(skeleton, p_property, skeleton->get(p_property));
undo_redo->add_do_property(skeleton, p_property, p_value);
@@ -122,7 +125,6 @@ void BoneTransformEditor::_value_changed(const String &p_property, Variant p_val
BoneTransformEditor::BoneTransformEditor(Skeleton3D *p_skeleton) :
skeleton(p_skeleton) {
- undo_redo = EditorNode::get_undo_redo();
}
void BoneTransformEditor::set_keyable(const bool p_keyable) {
@@ -1239,7 +1241,7 @@ int Skeleton3DGizmoPlugin::subgizmos_intersect_ray(const EditorNode3DGizmo *p_gi
Skeleton3DEditor *se = Skeleton3DEditor::get_singleton();
- if (!se->is_edit_mode()) {
+ if (!se || !se->is_edit_mode()) {
return -1;
}
diff --git a/editor/plugins/skeleton_3d_editor_plugin.h b/editor/plugins/skeleton_3d_editor_plugin.h
index 9f02d144ed..8ef61861d0 100644
--- a/editor/plugins/skeleton_3d_editor_plugin.h
+++ b/editor/plugins/skeleton_3d_editor_plugin.h
@@ -41,11 +41,13 @@
#include "scene/resources/immediate_mesh.h"
class EditorInspectorPluginSkeleton;
-class EditorUndoRedoManager;
class Joint;
class PhysicalBone3D;
class Skeleton3DEditorPlugin;
class Button;
+class Tree;
+class TreeItem;
+class VSeparator;
class BoneTransformEditor : public VBoxContainer {
GDCLASS(BoneTransformEditor, VBoxContainer);
@@ -65,8 +67,6 @@ class BoneTransformEditor : public VBoxContainer {
Skeleton3D *skeleton = nullptr;
// String property;
- Ref<EditorUndoRedoManager> undo_redo;
-
bool toggle_enabled = false;
bool updating = false;
diff --git a/editor/plugins/sprite_2d_editor_plugin.cpp b/editor/plugins/sprite_2d_editor_plugin.cpp
index b78b70cd5c..110ad7cac0 100644
--- a/editor/plugins/sprite_2d_editor_plugin.cpp
+++ b/editor/plugins/sprite_2d_editor_plugin.cpp
@@ -41,6 +41,7 @@
#include "scene/2d/mesh_instance_2d.h"
#include "scene/2d/polygon_2d.h"
#include "scene/gui/box_container.h"
+#include "scene/gui/menu_button.h"
#include "thirdparty/misc/clipper.hpp"
void Sprite2DEditor::_node_removed(Node *p_node) {
diff --git a/editor/plugins/sprite_frames_editor_plugin.cpp b/editor/plugins/sprite_frames_editor_plugin.cpp
index cf8cc71db7..64e899b121 100644
--- a/editor/plugins/sprite_frames_editor_plugin.cpp
+++ b/editor/plugins/sprite_frames_editor_plugin.cpp
@@ -34,6 +34,7 @@
#include "core/io/resource_loader.h"
#include "core/os/keyboard.h"
#include "editor/editor_file_dialog.h"
+#include "editor/editor_file_system.h"
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
@@ -43,6 +44,7 @@
#include "scene/gui/center_container.h"
#include "scene/gui/margin_container.h"
#include "scene/gui/panel_container.h"
+#include "scene/gui/separator.h"
static void _draw_shadowed_line(Control *p_control, const Point2 &p_from, const Size2 &p_size, const Size2 &p_shadow_offset, Color p_color, Color p_shadow_color) {
p_control->draw_line(p_from, p_from + p_size, p_color);
@@ -249,6 +251,7 @@ void SpriteFramesEditor::_sheet_add_frames() {
const Size2i offset = _get_offset();
const Size2i separation = _get_separation();
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Add Frame"));
int fc = frames->get_frame_count(edited_anim);
@@ -467,6 +470,7 @@ void SpriteFramesEditor::_file_load_request(const Vector<String> &p_path, int p_
return;
}
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Add Frame"));
int fc = frames->get_frame_count(edited_anim);
@@ -527,6 +531,7 @@ void SpriteFramesEditor::_paste_pressed() {
return; ///beh should show an error i guess
}
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Paste Frame"));
undo_redo->add_do_method(frames, "add_frame", edited_anim, r);
undo_redo->add_undo_method(frames, "remove_frame", edited_anim, frames->get_frame_count(edited_anim));
@@ -564,6 +569,7 @@ void SpriteFramesEditor::_empty_pressed() {
Ref<Texture2D> r;
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Add Empty"));
undo_redo->add_do_method(frames, "add_frame", edited_anim, r, from);
undo_redo->add_undo_method(frames, "remove_frame", edited_anim, from);
@@ -587,6 +593,7 @@ void SpriteFramesEditor::_empty2_pressed() {
Ref<Texture2D> r;
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Add Empty"));
undo_redo->add_do_method(frames, "add_frame", edited_anim, r, from + 1);
undo_redo->add_undo_method(frames, "remove_frame", edited_anim, from + 1);
@@ -610,6 +617,7 @@ void SpriteFramesEditor::_up_pressed() {
sel = to_move;
sel -= 1;
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Delete Resource"));
undo_redo->add_do_method(frames, "set_frame", edited_anim, to_move, frames->get_frame(edited_anim, to_move - 1));
undo_redo->add_do_method(frames, "set_frame", edited_anim, to_move - 1, frames->get_frame(edited_anim, to_move));
@@ -635,6 +643,7 @@ void SpriteFramesEditor::_down_pressed() {
sel = to_move;
sel += 1;
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Delete Resource"));
undo_redo->add_do_method(frames, "set_frame", edited_anim, to_move, frames->get_frame(edited_anim, to_move + 1));
undo_redo->add_do_method(frames, "set_frame", edited_anim, to_move + 1, frames->get_frame(edited_anim, to_move));
@@ -657,6 +666,7 @@ void SpriteFramesEditor::_delete_pressed() {
return;
}
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Delete Resource"));
undo_redo->add_do_method(frames, "remove_frame", edited_anim, to_delete);
undo_redo->add_undo_method(frames, "add_frame", edited_anim, frames->get_frame(edited_anim, to_delete), to_delete);
@@ -743,6 +753,7 @@ void SpriteFramesEditor::_animation_name_edited() {
List<Node *> nodes;
_find_anim_sprites(EditorNode::get_singleton()->get_edited_scene(), &nodes, Ref<SpriteFrames>(frames));
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Rename Animation"));
undo_redo->add_do_method(frames, "rename_animation", edited_anim, name);
undo_redo->add_undo_method(frames, "rename_animation", name, edited_anim);
@@ -772,6 +783,7 @@ void SpriteFramesEditor::_animation_add() {
List<Node *> nodes;
_find_anim_sprites(EditorNode::get_singleton()->get_edited_scene(), &nodes, Ref<SpriteFrames>(frames));
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Add Animation"));
undo_redo->add_do_method(frames, "add_animation", name);
undo_redo->add_undo_method(frames, "remove_animation", name);
@@ -804,6 +816,7 @@ void SpriteFramesEditor::_animation_remove() {
}
void SpriteFramesEditor::_animation_remove_confirmed() {
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Remove Animation"));
undo_redo->add_do_method(frames, "remove_animation", edited_anim);
undo_redo->add_undo_method(frames, "add_animation", edited_anim);
@@ -831,6 +844,7 @@ void SpriteFramesEditor::_animation_loop_changed() {
return;
}
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Change Animation Loop"));
undo_redo->add_do_method(frames, "set_animation_loop", edited_anim, anim_loop->is_pressed());
undo_redo->add_undo_method(frames, "set_animation_loop", edited_anim, frames->get_animation_loop(edited_anim));
@@ -844,6 +858,7 @@ void SpriteFramesEditor::_animation_fps_changed(double p_value) {
return;
}
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Change Animation FPS"), UndoRedo::MERGE_ENDS);
undo_redo->add_do_method(frames, "set_animation_speed", edited_anim, p_value);
undo_redo->add_undo_method(frames, "set_animation_speed", edited_anim, frames->get_animation_speed(edited_anim));
@@ -1035,10 +1050,6 @@ void SpriteFramesEditor::edit(SpriteFrames *p_frames) {
delete_frame->set_disabled(read_only);
}
-void SpriteFramesEditor::set_undo_redo(Ref<EditorUndoRedoManager> p_undo_redo) {
- undo_redo = p_undo_redo;
-}
-
Variant SpriteFramesEditor::get_drag_data_fw(const Point2 &p_point, Control *p_from) {
if (read_only) {
return false;
@@ -1136,6 +1147,7 @@ void SpriteFramesEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da
reorder = true;
}
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
if (reorder) { //drop is from reordering frames
int from_frame = -1;
if (d.has("frame")) {
@@ -1530,8 +1542,6 @@ SpriteFramesEditor::SpriteFramesEditor() {
}
void SpriteFramesEditorPlugin::edit(Object *p_object) {
- frames_editor->set_undo_redo(get_undo_redo());
-
SpriteFrames *s;
AnimatedSprite2D *animated_sprite = Object::cast_to<AnimatedSprite2D>(p_object);
if (animated_sprite) {
diff --git a/editor/plugins/sprite_frames_editor_plugin.h b/editor/plugins/sprite_frames_editor_plugin.h
index 5fc3fe4481..64245ee1e0 100644
--- a/editor/plugins/sprite_frames_editor_plugin.h
+++ b/editor/plugins/sprite_frames_editor_plugin.h
@@ -45,7 +45,6 @@
#include "scene/gui/tree.h"
class EditorFileDialog;
-class EditorUndoRedoManager;
class SpriteFramesEditor : public HSplitContainer {
GDCLASS(SpriteFramesEditor, HSplitContainer);
@@ -154,8 +153,6 @@ class SpriteFramesEditor : public HSplitContainer {
bool updating;
bool updating_split_settings = false; // Skip SpinBox/Range callback when setting value by code.
- Ref<EditorUndoRedoManager> undo_redo;
-
Variant get_drag_data_fw(const Point2 &p_point, Control *p_from);
bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const;
void drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from);
@@ -179,8 +176,6 @@ protected:
static void _bind_methods();
public:
- void set_undo_redo(Ref<EditorUndoRedoManager> p_undo_redo);
-
void edit(SpriteFrames *p_frames);
SpriteFramesEditor();
};
diff --git a/editor/plugins/style_box_editor_plugin.cpp b/editor/plugins/style_box_editor_plugin.cpp
index 16a6a48df9..afc54a2b83 100644
--- a/editor/plugins/style_box_editor_plugin.cpp
+++ b/editor/plugins/style_box_editor_plugin.cpp
@@ -31,6 +31,7 @@
#include "style_box_editor_plugin.h"
#include "editor/editor_scale.h"
+#include "scene/gui/texture_button.h"
bool StyleBoxPreview::grid_preview_enabled = true;
diff --git a/editor/plugins/style_box_editor_plugin.h b/editor/plugins/style_box_editor_plugin.h
index a072745d8f..d5351d3f34 100644
--- a/editor/plugins/style_box_editor_plugin.h
+++ b/editor/plugins/style_box_editor_plugin.h
@@ -37,6 +37,8 @@
#include "scene/gui/texture_rect.h"
#include "scene/resources/style_box.h"
+class TextureButton;
+
class StyleBoxPreview : public VBoxContainer {
GDCLASS(StyleBoxPreview, VBoxContainer);
diff --git a/editor/plugins/text_editor.cpp b/editor/plugins/text_editor.cpp
index 03cff74bdb..d6079d6285 100644
--- a/editor/plugins/text_editor.cpp
+++ b/editor/plugins/text_editor.cpp
@@ -33,6 +33,7 @@
#include "core/os/keyboard.h"
#include "editor/editor_node.h"
#include "editor/editor_settings.h"
+#include "scene/gui/menu_button.h"
void TextEditor::add_syntax_highlighter(Ref<EditorSyntaxHighlighter> p_highlighter) {
ERR_FAIL_COND(p_highlighter.is_null());
@@ -352,7 +353,9 @@ void TextEditor::_edit_option(int p_op) {
code_editor->duplicate_selection();
} break;
case EDIT_TOGGLE_FOLD_LINE: {
- tx->toggle_foldable_line(tx->get_caret_line());
+ for (int caret_idx = 0; caret_idx < tx->get_caret_count(); caret_idx++) {
+ tx->toggle_foldable_line(tx->get_caret_line(caret_idx));
+ }
tx->queue_redraw();
} break;
case EDIT_FOLD_ALL_LINES: {
diff --git a/editor/plugins/text_editor.h b/editor/plugins/text_editor.h
index 486a0f2c23..9f2132bc0b 100644
--- a/editor/plugins/text_editor.h
+++ b/editor/plugins/text_editor.h
@@ -33,6 +33,8 @@
#include "script_editor_plugin.h"
+#include "editor/code_editor.h"
+
class TextEditor : public ScriptEditorBase {
GDCLASS(TextEditor, ScriptEditorBase);
diff --git a/editor/plugins/texture_3d_editor_plugin.cpp b/editor/plugins/texture_3d_editor_plugin.cpp
index 4b2f28658a..bdea12c2cb 100644
--- a/editor/plugins/texture_3d_editor_plugin.cpp
+++ b/editor/plugins/texture_3d_editor_plugin.cpp
@@ -30,6 +30,8 @@
#include "texture_3d_editor_plugin.h"
+#include "scene/gui/label.h"
+
void Texture3DEditor::_texture_rect_draw() {
texture_rect->draw_rect(Rect2(Point2(), texture_rect->get_size()), Color(1, 1, 1, 1));
}
diff --git a/editor/plugins/texture_editor_plugin.cpp b/editor/plugins/texture_editor_plugin.cpp
index 4aed7a92a2..5783912c96 100644
--- a/editor/plugins/texture_editor_plugin.cpp
+++ b/editor/plugins/texture_editor_plugin.cpp
@@ -30,6 +30,8 @@
#include "texture_editor_plugin.h"
#include "editor/editor_scale.h"
+#include "scene/gui/label.h"
+#include "scene/gui/texture_rect.h"
TextureRect *TexturePreview::get_texture_display() {
return texture_display;
diff --git a/editor/plugins/texture_layered_editor_plugin.cpp b/editor/plugins/texture_layered_editor_plugin.cpp
index b0a174c1bc..479e84682b 100644
--- a/editor/plugins/texture_layered_editor_plugin.cpp
+++ b/editor/plugins/texture_layered_editor_plugin.cpp
@@ -30,6 +30,8 @@
#include "texture_layered_editor_plugin.h"
+#include "scene/gui/label.h"
+
void TextureLayeredEditor::gui_input(const Ref<InputEvent> &p_event) {
ERR_FAIL_COND(p_event.is_null());
diff --git a/editor/plugins/texture_region_editor_plugin.cpp b/editor/plugins/texture_region_editor_plugin.cpp
index b0c8597adf..fdfa3f8d0a 100644
--- a/editor/plugins/texture_region_editor_plugin.cpp
+++ b/editor/plugins/texture_region_editor_plugin.cpp
@@ -38,7 +38,9 @@
#include "editor/editor_settings.h"
#include "editor/editor_undo_redo_manager.h"
#include "scene/gui/check_box.h"
+#include "scene/gui/option_button.h"
#include "scene/gui/separator.h"
+#include "scene/gui/spin_box.h"
#include "scene/gui/view_panner.h"
#include "scene/resources/texture.h"
@@ -298,6 +300,7 @@ void TextureRegionEditor::_region_input(const Ref<InputEvent> &p_input) {
mtx.xform(rect.position + Vector2(0, rect.size.y / 2)) + Vector2(-handle_offset, 0)
};
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
Ref<InputEventMouseButton> mb = p_input;
if (mb.is_valid()) {
if (mb->get_button_index() == MouseButton::LEFT) {
@@ -1065,7 +1068,6 @@ TextureRegionEditor::TextureRegionEditor() {
node_ninepatch = nullptr;
obj_styleBox = Ref<StyleBoxTexture>(nullptr);
atlas_tex = Ref<AtlasTexture>(nullptr);
- undo_redo = EditorNode::get_singleton()->get_undo_redo();
preview_tex = Ref<CanvasTexture>(memnew(CanvasTexture));
diff --git a/editor/plugins/texture_region_editor_plugin.h b/editor/plugins/texture_region_editor_plugin.h
index 48cbb6b70e..90a5b20e14 100644
--- a/editor/plugins/texture_region_editor_plugin.h
+++ b/editor/plugins/texture_region_editor_plugin.h
@@ -36,12 +36,12 @@
#include "editor/editor_plugin.h"
#include "scene/2d/sprite_2d.h"
#include "scene/3d/sprite_3d.h"
+#include "scene/gui/dialogs.h"
#include "scene/gui/nine_patch_rect.h"
#include "scene/resources/style_box.h"
#include "scene/resources/texture.h"
class ViewPanner;
-class EditorUndoRedoManager;
class OptionButton;
class TextureRegionEditor : public AcceptDialog {
@@ -71,8 +71,6 @@ class TextureRegionEditor : public AcceptDialog {
VScrollBar *vscroll = nullptr;
HScrollBar *hscroll = nullptr;
- Ref<EditorUndoRedoManager> undo_redo;
-
Vector2 draw_ofs;
float draw_zoom = 0.0;
bool updating_scroll = false;
diff --git a/editor/plugins/theme_editor_plugin.cpp b/editor/plugins/theme_editor_plugin.cpp
index 5d02e4e437..135b218768 100644
--- a/editor/plugins/theme_editor_plugin.cpp
+++ b/editor/plugins/theme_editor_plugin.cpp
@@ -38,6 +38,8 @@
#include "editor/editor_undo_redo_manager.h"
#include "editor/progress_dialog.h"
#include "scene/gui/color_picker.h"
+#include "scene/gui/panel_container.h"
+#include "scene/gui/split_container.h"
#include "scene/theme/theme_db.h"
void ThemeItemImportTree::_update_items_tree() {
diff --git a/editor/plugins/theme_editor_preview.cpp b/editor/plugins/theme_editor_preview.cpp
index fdd8a80ad3..082b21bbe5 100644
--- a/editor/plugins/theme_editor_preview.cpp
+++ b/editor/plugins/theme_editor_preview.cpp
@@ -36,9 +36,12 @@
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "scene/gui/button.h"
+#include "scene/gui/check_box.h"
#include "scene/gui/check_button.h"
#include "scene/gui/color_picker.h"
#include "scene/gui/progress_bar.h"
+#include "scene/gui/text_edit.h"
+#include "scene/gui/tree.h"
#include "scene/resources/packed_scene.h"
#include "scene/theme/theme_db.h"
diff --git a/editor/plugins/tiles/atlas_merging_dialog.cpp b/editor/plugins/tiles/atlas_merging_dialog.cpp
index 167c6d169b..f892f3637d 100644
--- a/editor/plugins/tiles/atlas_merging_dialog.cpp
+++ b/editor/plugins/tiles/atlas_merging_dialog.cpp
@@ -154,6 +154,7 @@ void AtlasMergingDialog::_merge_confirmed(String p_path) {
Ref<Texture2D> new_texture_resource = ResourceLoader::load(p_path, "Texture2D");
merged->set_texture(new_texture_resource);
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Merge TileSetAtlasSource"));
int next_id = tile_set->get_next_source_id();
undo_redo->add_do_method(*tile_set, "add_source", merged, next_id);
@@ -193,6 +194,7 @@ void AtlasMergingDialog::ok_pressed() {
}
void AtlasMergingDialog::cancel_pressed() {
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
for (int i = 0; i < commited_actions_count; i++) {
undo_redo->undo();
}
@@ -234,7 +236,7 @@ void AtlasMergingDialog::update_tile_set(Ref<TileSet> p_tile_set) {
if (atlas_source.is_valid()) {
Ref<Texture2D> texture = atlas_source->get_texture();
if (texture.is_valid()) {
- String item_text = vformat("%s (id:%d)", texture->get_path().get_file(), source_id);
+ String item_text = vformat(TTR("%s (ID: %d)"), texture->get_path().get_file(), source_id);
atlas_merging_atlases_list->add_item(item_text, texture);
atlas_merging_atlases_list->set_item_metadata(-1, source_id);
}
@@ -248,8 +250,6 @@ void AtlasMergingDialog::update_tile_set(Ref<TileSet> p_tile_set) {
}
AtlasMergingDialog::AtlasMergingDialog() {
- undo_redo = EditorNode::get_singleton()->get_undo_redo();
-
// Atlas merging window.
set_title(TTR("Atlas Merging"));
set_hide_on_ok(false);
diff --git a/editor/plugins/tiles/atlas_merging_dialog.h b/editor/plugins/tiles/atlas_merging_dialog.h
index c7e4635d16..228c188817 100644
--- a/editor/plugins/tiles/atlas_merging_dialog.h
+++ b/editor/plugins/tiles/atlas_merging_dialog.h
@@ -38,7 +38,6 @@
#include "scene/resources/tile_set.h"
class EditorFileDialog;
-class EditorUndoRedoManager;
class AtlasMergingDialog : public ConfirmationDialog {
GDCLASS(AtlasMergingDialog, ConfirmationDialog);
@@ -50,8 +49,6 @@ private:
LocalVector<HashMap<Vector2i, Vector2i>> merged_mapping;
Ref<TileSet> tile_set;
- Ref<EditorUndoRedoManager> undo_redo;
-
// Settings.
int next_line_after_column = 30;
diff --git a/editor/plugins/tiles/tile_data_editors.cpp b/editor/plugins/tiles/tile_data_editors.cpp
index 42eceb82ab..147bb5f4e9 100644
--- a/editor/plugins/tiles/tile_data_editors.cpp
+++ b/editor/plugins/tiles/tile_data_editors.cpp
@@ -38,8 +38,13 @@
#include "editor/editor_node.h"
#include "editor/editor_properties.h"
#include "editor/editor_scale.h"
+#include "editor/editor_settings.h"
#include "editor/editor_undo_redo_manager.h"
+#include "scene/gui/menu_button.h"
+#include "scene/gui/option_button.h"
+#include "scene/gui/separator.h"
+
#ifdef DEBUG_ENABLED
#include "servers/navigation_server_3d.h"
#endif // DEBUG_ENABLED
@@ -153,7 +158,14 @@ void GenericTilePolygonEditor::_base_control_draw() {
// Draw the background.
if (background_texture.is_valid()) {
- base_control->draw_texture_rect_region(background_texture, Rect2(-background_region.size / 2 - background_offset, background_region.size), background_region, background_modulate, background_transpose);
+ Size2 region_size = background_region.size;
+ if (background_h_flip) {
+ region_size.x = -region_size.x;
+ }
+ if (background_v_flip) {
+ region_size.y = -region_size.y;
+ }
+ base_control->draw_texture_rect_region(background_texture, Rect2(-background_region.size / 2 - background_offset, region_size), background_region, background_modulate, background_transpose);
}
// Draw the polygons.
@@ -255,7 +267,7 @@ void GenericTilePolygonEditor::_zoom_changed() {
void GenericTilePolygonEditor::_advanced_menu_item_pressed(int p_item_pressed) {
Ref<EditorUndoRedoManager> undo_redo;
if (use_undo_redo) {
- undo_redo = editor_undo_redo;
+ undo_redo = EditorNode::get_undo_redo();
} else {
// This nice hack allows for discarding undo actions without making code too complex.
undo_redo.instantiate();
@@ -420,7 +432,7 @@ void GenericTilePolygonEditor::_snap_to_half_pixel(Point2 &r_point) {
void GenericTilePolygonEditor::_base_control_gui_input(Ref<InputEvent> p_event) {
Ref<EditorUndoRedoManager> undo_redo;
if (use_undo_redo) {
- undo_redo = editor_undo_redo;
+ undo_redo = EditorNode::get_undo_redo();
} else {
// This nice hack allows for discarding undo actions without making code too complex.
undo_redo.instantiate();
@@ -756,8 +768,6 @@ void GenericTilePolygonEditor::_bind_methods() {
}
GenericTilePolygonEditor::GenericTilePolygonEditor() {
- editor_undo_redo = EditorNode::get_undo_redo();
-
toolbar = memnew(HBoxContainer);
add_child(toolbar);
@@ -846,6 +856,7 @@ GenericTilePolygonEditor::GenericTilePolygonEditor() {
void TileDataDefaultEditor::_property_value_changed(StringName p_property, Variant p_value, StringName p_field) {
ERR_FAIL_COND(!dummy_object);
dummy_object->set(p_property, p_value);
+ emit_signal(SNAME("needs_redraw"));
}
Variant TileDataDefaultEditor::_get_painted_value() {
@@ -876,6 +887,7 @@ Variant TileDataDefaultEditor::_get_value(TileSetAtlasSource *p_tile_set_atlas_s
}
void TileDataDefaultEditor::_setup_undo_redo_action(TileSetAtlasSource *p_tile_set_atlas_source, HashMap<TileMapCell, Variant, TileMapCell> p_previous_values, Variant p_new_value) {
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
for (const KeyValue<TileMapCell, Variant> &E : p_previous_values) {
Vector2i coords = E.key.get_atlas_coords();
undo_redo->add_undo_property(p_tile_set_atlas_source, vformat("%d:%d/%d/%s", coords.x, coords.y, E.key.alternative_tile, property), E.value);
@@ -944,6 +956,7 @@ void TileDataDefaultEditor::forward_painting_atlas_gui_input(TileAtlasView *p_ti
}
}
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
Ref<InputEventMouseButton> mb = p_event;
if (mb.is_valid()) {
if (mb->get_button_index() == MouseButton::LEFT) {
@@ -1067,6 +1080,7 @@ void TileDataDefaultEditor::forward_painting_alternatives_gui_input(TileAtlasVie
drag_last_pos = mb->get_position();
}
} else {
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Painting Tiles Property"));
_setup_undo_redo_action(p_tile_set_atlas_source, drag_modified, drag_painted_value);
undo_redo->commit_action(false);
@@ -1188,8 +1202,6 @@ Variant::Type TileDataDefaultEditor::get_property_type() {
}
TileDataDefaultEditor::TileDataDefaultEditor() {
- undo_redo = EditorNode::get_undo_redo();
-
label = memnew(Label);
label->set_text(TTR("Painting:"));
label->set_theme_type_variation("HeaderSmall");
@@ -1320,6 +1332,7 @@ Variant TileDataOcclusionShapeEditor::_get_value(TileSetAtlasSource *p_tile_set_
}
void TileDataOcclusionShapeEditor::_setup_undo_redo_action(TileSetAtlasSource *p_tile_set_atlas_source, HashMap<TileMapCell, Variant, TileMapCell> p_previous_values, Variant p_new_value) {
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
for (const KeyValue<TileMapCell, Variant> &E : p_previous_values) {
Vector2i coords = E.key.get_atlas_coords();
undo_redo->add_undo_property(p_tile_set_atlas_source, vformat("%d:%d/%d/occlusion_layer_%d/polygon", coords.x, coords.y, E.key.alternative_tile, occlusion_layer), E.value);
@@ -1340,8 +1353,6 @@ void TileDataOcclusionShapeEditor::_notification(int p_what) {
}
TileDataOcclusionShapeEditor::TileDataOcclusionShapeEditor() {
- undo_redo = EditorNode::get_undo_redo();
-
polygon_editor = memnew(GenericTilePolygonEditor);
add_child(polygon_editor);
}
@@ -1501,6 +1512,7 @@ Variant TileDataCollisionEditor::_get_value(TileSetAtlasSource *p_tile_set_atlas
void TileDataCollisionEditor::_setup_undo_redo_action(TileSetAtlasSource *p_tile_set_atlas_source, HashMap<TileMapCell, Variant, TileMapCell> p_previous_values, Variant p_new_value) {
Array new_array = p_new_value;
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
for (KeyValue<TileMapCell, Variant> &E : p_previous_values) {
Array old_array = E.value;
@@ -1537,8 +1549,6 @@ void TileDataCollisionEditor::_notification(int p_what) {
}
TileDataCollisionEditor::TileDataCollisionEditor() {
- undo_redo = EditorNode::get_undo_redo();
-
polygon_editor = memnew(GenericTilePolygonEditor);
polygon_editor->set_multiple_polygon_mode(true);
polygon_editor->connect("polygons_changed", callable_mp(this, &TileDataCollisionEditor::_polygons_changed));
@@ -1593,12 +1603,31 @@ void TileDataCollisionEditor::draw_over_tile(CanvasItem *p_canvas_item, Transfor
}
RenderingServer::get_singleton()->canvas_item_add_set_transform(p_canvas_item->get_canvas_item(), p_transform);
+
+ Ref<Texture2D> one_way_icon = get_theme_icon(SNAME("OneWayTile"), SNAME("EditorIcons"));
for (int i = 0; i < tile_data->get_collision_polygons_count(physics_layer); i++) {
Vector<Vector2> polygon = tile_data->get_collision_polygon_points(physics_layer, i);
- if (polygon.size() >= 3) {
- p_canvas_item->draw_polygon(polygon, color);
+ if (polygon.size() < 3) {
+ continue;
+ }
+
+ p_canvas_item->draw_polygon(polygon, color);
+
+ if (tile_data->is_collision_polygon_one_way(physics_layer, i)) {
+ PackedVector2Array uvs;
+ uvs.resize(polygon.size());
+ Vector2 size_1 = Vector2(1, 1) / tile_set->get_tile_size();
+
+ for (int j = 0; j < polygon.size(); j++) {
+ uvs.write[j] = polygon[j] * size_1 + Vector2(0.5, 0.5);
+ }
+
+ Vector<Color> color2;
+ color2.push_back(Color(1, 1, 1, 0.4));
+ p_canvas_item->draw_polygon(polygon, color2, uvs, one_way_icon);
}
}
+
RenderingServer::get_singleton()->canvas_item_add_set_transform(p_canvas_item->get_canvas_item(), Transform2D());
}
@@ -2185,6 +2214,7 @@ void TileDataTerrainsEditor::forward_painting_atlas_gui_input(TileAtlasView *p_t
}
}
} else {
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
if (drag_type == DRAG_TYPE_PAINT_TERRAIN_SET_RECT) {
Rect2i rect;
rect.set_position(p_tile_atlas_view->get_atlas_tile_coords_at_pos(drag_start_pos));
@@ -2557,6 +2587,7 @@ void TileDataTerrainsEditor::forward_painting_alternatives_gui_input(TileAtlasVi
}
}
} else {
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
if (drag_type == DRAG_TYPE_PAINT_TERRAIN_SET) {
undo_redo->create_action(TTR("Painting Tiles Property"));
for (KeyValue<TileMapCell, Variant> &E : drag_modified) {
@@ -2622,8 +2653,6 @@ void TileDataTerrainsEditor::_notification(int p_what) {
}
TileDataTerrainsEditor::TileDataTerrainsEditor() {
- undo_redo = EditorNode::get_undo_redo();
-
label = memnew(Label);
label->set_text(TTR("Painting:"));
label->set_theme_type_variation("HeaderSmall");
@@ -2707,6 +2736,7 @@ Variant TileDataNavigationEditor::_get_value(TileSetAtlasSource *p_tile_set_atla
}
void TileDataNavigationEditor::_setup_undo_redo_action(TileSetAtlasSource *p_tile_set_atlas_source, HashMap<TileMapCell, Variant, TileMapCell> p_previous_values, Variant p_new_value) {
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
for (const KeyValue<TileMapCell, Variant> &E : p_previous_values) {
Vector2i coords = E.key.get_atlas_coords();
undo_redo->add_undo_property(p_tile_set_atlas_source, vformat("%d:%d/%d/navigation_layer_%d/polygon", coords.x, coords.y, E.key.alternative_tile, navigation_layer), E.value);
@@ -2729,8 +2759,6 @@ void TileDataNavigationEditor::_notification(int p_what) {
}
TileDataNavigationEditor::TileDataNavigationEditor() {
- undo_redo = EditorNode::get_undo_redo();
-
polygon_editor = memnew(GenericTilePolygonEditor);
polygon_editor->set_multiple_polygon_mode(true);
add_child(polygon_editor);
diff --git a/editor/plugins/tiles/tile_data_editors.h b/editor/plugins/tiles/tile_data_editors.h
index 0a947fce8b..e98e1d6701 100644
--- a/editor/plugins/tiles/tile_data_editors.h
+++ b/editor/plugins/tiles/tile_data_editors.h
@@ -39,6 +39,7 @@
#include "scene/gui/control.h"
#include "scene/gui/label.h"
+class MenuButton;
class EditorUndoRedoManager;
class TileDataEditor : public VBoxContainer {
@@ -95,7 +96,6 @@ private:
bool multiple_polygon_mode = false;
bool use_undo_redo = true;
- Ref<EditorUndoRedoManager> editor_undo_redo;
// UI
int hovered_polygon_index = -1;
@@ -216,8 +216,6 @@ private:
protected:
DummyObject *dummy_object = memnew(DummyObject);
- Ref<EditorUndoRedoManager> undo_redo;
-
StringName type;
String property;
Variant::Type property_type;
@@ -283,8 +281,6 @@ private:
virtual void _setup_undo_redo_action(TileSetAtlasSource *p_tile_set_atlas_source, HashMap<TileMapCell, Variant, TileMapCell> p_previous_values, Variant p_new_value) override;
protected:
- Ref<EditorUndoRedoManager> undo_redo;
-
virtual void _tile_set_changed() override;
void _notification(int p_what);
@@ -318,8 +314,6 @@ class TileDataCollisionEditor : public TileDataDefaultEditor {
virtual void _setup_undo_redo_action(TileSetAtlasSource *p_tile_set_atlas_source, HashMap<TileMapCell, Variant, TileMapCell> p_previous_values, Variant p_new_value) override;
protected:
- Ref<EditorUndoRedoManager> undo_redo;
-
virtual void _tile_set_changed() override;
void _notification(int p_what);
@@ -370,8 +364,6 @@ protected:
void _notification(int p_what);
- Ref<EditorUndoRedoManager> undo_redo;
-
public:
virtual Control *get_toolbar() override { return toolbar; };
virtual void forward_draw_over_atlas(TileAtlasView *p_tile_atlas_view, TileSetAtlasSource *p_tile_atlas_source, CanvasItem *p_canvas_item, Transform2D p_transform) override;
@@ -403,8 +395,6 @@ private:
virtual void _setup_undo_redo_action(TileSetAtlasSource *p_tile_set_atlas_source, HashMap<TileMapCell, Variant, TileMapCell> p_previous_values, Variant p_new_value) override;
protected:
- Ref<EditorUndoRedoManager> undo_redo;
-
virtual void _tile_set_changed() override;
void _notification(int p_what);
diff --git a/editor/plugins/tiles/tile_map_editor.cpp b/editor/plugins/tiles/tile_map_editor.cpp
index 93f9df4d6e..0331e3f69e 100644
--- a/editor/plugins/tiles/tile_map_editor.cpp
+++ b/editor/plugins/tiles/tile_map_editor.cpp
@@ -35,6 +35,7 @@
#include "editor/editor_node.h"
#include "editor/editor_resource_preview.h"
#include "editor/editor_scale.h"
+#include "editor/editor_settings.h"
#include "editor/editor_undo_redo_manager.h"
#include "editor/plugins/canvas_item_editor_plugin.h"
@@ -155,7 +156,7 @@ void TileMapEditorTilesPlugin::_update_tile_set_sources_list() {
// Common to all type of sources.
if (!source->get_name().is_empty()) {
- item_text = vformat(TTR("%s (id:%d)"), source->get_name(), source_id);
+ item_text = vformat(TTR("%s (ID: %d)"), source->get_name(), source_id);
}
// Atlas source.
@@ -164,7 +165,7 @@ void TileMapEditorTilesPlugin::_update_tile_set_sources_list() {
texture = atlas_source->get_texture();
if (item_text.is_empty()) {
if (texture.is_valid()) {
- item_text = vformat("%s (ID: %d)", texture->get_path().get_file(), source_id);
+ item_text = vformat(TTR("%s (ID: %d)"), texture->get_path().get_file(), source_id);
} else {
item_text = vformat(TTR("No Texture Atlas Source (ID: %d)"), source_id);
}
@@ -272,6 +273,7 @@ void TileMapEditorTilesPlugin::_patterns_item_list_gui_input(const Ref<InputEven
if (ED_IS_SHORTCUT("tiles_editor/paste", p_event) && p_event->is_pressed() && !p_event->is_echo()) {
select_last_pattern = true;
int new_pattern_index = tile_set->get_patterns_count();
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Add TileSet pattern"));
undo_redo->add_do_method(*tile_set, "add_pattern", tile_map_clipboard, new_pattern_index);
undo_redo->add_undo_method(*tile_set, "remove_pattern", new_pattern_index);
@@ -281,6 +283,7 @@ void TileMapEditorTilesPlugin::_patterns_item_list_gui_input(const Ref<InputEven
if (ED_IS_SHORTCUT("tiles_editor/delete", p_event) && p_event->is_pressed() && !p_event->is_echo()) {
Vector<int> selected = patterns_item_list->get_selected_items();
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Remove TileSet patterns"));
for (int i = 0; i < selected.size(); i++) {
int pattern_index = selected[i];
@@ -469,6 +472,7 @@ void TileMapEditorTilesPlugin::_update_theme() {
random_tile_toggle->set_icon(tiles_bottom_panel->get_theme_icon(SNAME("RandomNumberGenerator"), SNAME("EditorIcons")));
missing_atlas_texture_icon = tiles_bottom_panel->get_theme_icon(SNAME("TileSet"), SNAME("EditorIcons"));
+ _update_tile_set_sources_list();
}
bool TileMapEditorTilesPlugin::forward_canvas_gui_input(const Ref<InputEvent> &p_event) {
@@ -511,6 +515,7 @@ bool TileMapEditorTilesPlugin::forward_canvas_gui_input(const Ref<InputEvent> &p
if (ED_IS_SHORTCUT("tiles_editor/cut", p_event)) {
// Delete selected tiles.
if (!tile_map_selection.is_empty()) {
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Delete tiles"));
for (const Vector2i &E : tile_map_selection) {
undo_redo->add_do_method(tile_map, "set_cell", tile_map_layer, E, TileSet::INVALID_SOURCE, TileSetSource::INVALID_ATLAS_COORDS, TileSetSource::INVALID_TILE_ALTERNATIVE);
@@ -542,6 +547,7 @@ bool TileMapEditorTilesPlugin::forward_canvas_gui_input(const Ref<InputEvent> &p
if (ED_IS_SHORTCUT("tiles_editor/delete", p_event)) {
// Delete selected tiles.
if (!tile_map_selection.is_empty()) {
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Delete tiles"));
for (const Vector2i &E : tile_map_selection) {
undo_redo->add_do_method(tile_map, "set_cell", tile_map_layer, E, TileSet::INVALID_SOURCE, TileSetSource::INVALID_ATLAS_COORDS, TileSetSource::INVALID_TILE_ALTERNATIVE);
@@ -1159,7 +1165,7 @@ HashMap<Vector2i, TileMapCell> TileMapEditorTilesPlugin::_draw_bucket_fill(Vecto
}
// Get surrounding tiles (handles different tile shapes).
- TypedArray<Vector2i> around = tile_map->get_surrounding_tiles(coords);
+ TypedArray<Vector2i> around = tile_map->get_surrounding_cells(coords);
for (int i = 0; i < around.size(); i++) {
to_check.push_back(around[i]);
}
@@ -1233,6 +1239,7 @@ void TileMapEditorTilesPlugin::_stop_dragging() {
Transform2D xform = CanvasItemEditor::get_singleton()->get_canvas_transform() * tile_map->get_global_transform();
Vector2 mpos = xform.affine_inverse().xform(CanvasItemEditor::get_singleton()->get_viewport_control()->get_local_mouse_position());
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
switch (drag_type) {
case DRAG_TYPE_SELECT: {
undo_redo->create_action(TTR("Change selection"));
@@ -1691,7 +1698,7 @@ void TileMapEditorTilesPlugin::_tile_atlas_control_draw() {
if (frame > 0) {
color.a *= 0.3;
}
- tile_atlas_control->draw_rect(atlas->get_tile_texture_region(E.get_atlas_coords(), frame), color, false);
+ TilesEditorPlugin::draw_selection_rect(tile_atlas_control, atlas->get_tile_texture_region(E.get_atlas_coords(), frame), color);
}
}
}
@@ -1699,11 +1706,8 @@ void TileMapEditorTilesPlugin::_tile_atlas_control_draw() {
// Draw the hovered tile.
if (hovered_tile.get_atlas_coords() != TileSetSource::INVALID_ATLAS_COORDS && hovered_tile.alternative_tile == 0 && !tile_set_dragging_selection) {
for (int frame = 0; frame < atlas->get_tile_animation_frames_count(hovered_tile.get_atlas_coords()); frame++) {
- Color color = Color(1.0, 1.0, 1.0);
- if (frame > 0) {
- color.a *= 0.3;
- }
- tile_atlas_control->draw_rect(atlas->get_tile_texture_region(hovered_tile.get_atlas_coords(), frame), color, false);
+ Color color = Color(1.0, 0.8, 0.0, frame == 0 ? 0.6 : 0.3);
+ TilesEditorPlugin::draw_selection_rect(tile_atlas_control, atlas->get_tile_texture_region(hovered_tile.get_atlas_coords(), frame), color);
}
}
@@ -1724,9 +1728,8 @@ void TileMapEditorTilesPlugin::_tile_atlas_control_draw() {
}
}
}
- Color selection_rect_color = selection_color.lightened(0.2);
for (const Vector2i &E : to_draw) {
- tile_atlas_control->draw_rect(atlas->get_tile_texture_region(E), selection_rect_color, false);
+ TilesEditorPlugin::draw_selection_rect(tile_atlas_control, atlas->get_tile_texture_region(E));
}
}
}
@@ -1875,7 +1878,7 @@ void TileMapEditorTilesPlugin::_tile_alternatives_control_draw() {
if (E.source_id == source_id && E.get_atlas_coords() != TileSetSource::INVALID_ATLAS_COORDS && E.alternative_tile > 0) {
Rect2i rect = tile_atlas_view->get_alternative_tile_rect(E.get_atlas_coords(), E.alternative_tile);
if (rect != Rect2i()) {
- alternative_tiles_control->draw_rect(rect, Color(0.2, 0.2, 1.0), false);
+ TilesEditorPlugin::draw_selection_rect(alternative_tiles_control, rect);
}
}
}
@@ -1884,7 +1887,7 @@ void TileMapEditorTilesPlugin::_tile_alternatives_control_draw() {
if (hovered_tile.get_atlas_coords() != TileSetSource::INVALID_ATLAS_COORDS && hovered_tile.alternative_tile > 0) {
Rect2i rect = tile_atlas_view->get_alternative_tile_rect(hovered_tile.get_atlas_coords(), hovered_tile.alternative_tile);
if (rect != Rect2i()) {
- alternative_tiles_control->draw_rect(rect, Color(1.0, 1.0, 1.0), false);
+ TilesEditorPlugin::draw_selection_rect(alternative_tiles_control, rect, Color(1.0, 0.8, 0.0, 0.5));
}
}
}
@@ -2012,8 +2015,6 @@ void TileMapEditorTilesPlugin::_bind_methods() {
}
TileMapEditorTilesPlugin::TileMapEditorTilesPlugin() {
- undo_redo = EditorNode::get_undo_redo();
-
CanvasItemEditor::get_singleton()
->get_viewport_control()
->connect("mouse_exited", callable_mp(this, &TileMapEditorTilesPlugin::_mouse_exited_viewport));
@@ -2543,7 +2544,7 @@ RBSet<Vector2i> TileMapEditorTerrainsPlugin::_get_cells_for_bucket_fill(Vector2i
output.insert(coords);
// Get surrounding tiles (handles different tile shapes).
- TypedArray<Vector2i> around = tile_map->get_surrounding_tiles(coords);
+ TypedArray<Vector2i> around = tile_map->get_surrounding_cells(coords);
for (int i = 0; i < around.size(); i++) {
to_check.push_back(around[i]);
}
@@ -2634,6 +2635,7 @@ void TileMapEditorTerrainsPlugin::_stop_dragging() {
Transform2D xform = CanvasItemEditor::get_singleton()->get_canvas_transform() * tile_map->get_global_transform();
Vector2 mpos = xform.affine_inverse().xform(CanvasItemEditor::get_singleton()->get_viewport_control()->get_local_mouse_position());
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
switch (drag_type) {
case DRAG_TYPE_PICK: {
Vector2i coords = tile_map->local_to_map(mpos);
@@ -3304,8 +3306,6 @@ void TileMapEditorTerrainsPlugin::edit(ObjectID p_tile_map_id, int p_tile_map_la
}
TileMapEditorTerrainsPlugin::TileMapEditorTerrainsPlugin() {
- undo_redo = EditorNode::get_undo_redo();
-
main_vbox_container = memnew(VBoxContainer);
main_vbox_container->connect("tree_entered", callable_mp(this, &TileMapEditorTerrainsPlugin::_update_theme));
main_vbox_container->connect("theme_changed", callable_mp(this, &TileMapEditorTerrainsPlugin::_update_theme));
@@ -3479,6 +3479,7 @@ void TileMapEditor::_advanced_menu_button_id_pressed(int p_id) {
}
if (p_id == 0) { // Replace Tile Proxies
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Replace Tiles with Proxies"));
for (int layer_index = 0; layer_index < tile_map->get_layers_count(); layer_index++) {
TypedArray<Vector2i> used_cells = tile_map->get_used_cells(layer_index);
@@ -3952,8 +3953,6 @@ void TileMapEditor::edit(TileMap *p_tile_map) {
}
TileMapEditor::TileMapEditor() {
- undo_redo = EditorNode::get_undo_redo();
-
set_process_internal(true);
// Shortcuts.
diff --git a/editor/plugins/tiles/tile_map_editor.h b/editor/plugins/tiles/tile_map_editor.h
index 9a47d8bbc4..ad27795437 100644
--- a/editor/plugins/tiles/tile_map_editor.h
+++ b/editor/plugins/tiles/tile_map_editor.h
@@ -47,8 +47,6 @@
#include "scene/gui/tab_bar.h"
#include "scene/gui/tree.h"
-class EditorUndoRedoManager;
-
class TileMapEditorPlugin : public Object {
public:
struct TabData {
@@ -70,7 +68,6 @@ class TileMapEditorTilesPlugin : public TileMapEditorPlugin {
GDCLASS(TileMapEditorTilesPlugin, TileMapEditorPlugin);
private:
- Ref<EditorUndoRedoManager> undo_redo;
ObjectID tile_map_id;
int tile_map_layer = -1;
virtual void edit(ObjectID p_tile_map_id, int p_tile_map_layer) override;
@@ -223,7 +220,6 @@ class TileMapEditorTerrainsPlugin : public TileMapEditorPlugin {
GDCLASS(TileMapEditorTerrainsPlugin, TileMapEditorPlugin);
private:
- Ref<EditorUndoRedoManager> undo_redo;
ObjectID tile_map_id;
int tile_map_layer = -1;
virtual void edit(ObjectID p_tile_map_id, int p_tile_map_layer) override;
@@ -317,7 +313,6 @@ class TileMapEditor : public VBoxContainer {
GDCLASS(TileMapEditor, VBoxContainer);
private:
- Ref<EditorUndoRedoManager> undo_redo;
bool tileset_changed_needs_update = false;
ObjectID tile_map_id;
int tile_map_layer = -1;
diff --git a/editor/plugins/tiles/tile_proxies_manager_dialog.cpp b/editor/plugins/tiles/tile_proxies_manager_dialog.cpp
index 9e4c29fa79..b31fb1aa58 100644
--- a/editor/plugins/tiles/tile_proxies_manager_dialog.cpp
+++ b/editor/plugins/tiles/tile_proxies_manager_dialog.cpp
@@ -32,9 +32,11 @@
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
+#include "editor/editor_settings.h"
#include "editor/editor_undo_redo_manager.h"
+#include "scene/gui/separator.h"
-void TileProxiesManagerDialog::_right_clicked(int p_item, Vector2 p_local_mouse_pos, Object *p_item_list, MouseButton p_mouse_button_index) {
+void TileProxiesManagerDialog::_right_clicked(int p_item, Vector2 p_local_mouse_pos, MouseButton p_mouse_button_index, Object *p_item_list) {
if (p_mouse_button_index != MouseButton::RIGHT) {
return;
}
@@ -53,6 +55,7 @@ void TileProxiesManagerDialog::_menu_id_pressed(int p_id) {
}
void TileProxiesManagerDialog::_delete_selected_bindings() {
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Remove Tile Proxies"));
Vector<int> source_level_selected = source_level_list->get_selected_items();
@@ -74,7 +77,7 @@ void TileProxiesManagerDialog::_delete_selected_bindings() {
Vector<int> alternative_level_selected = alternative_level_list->get_selected_items();
for (int i = 0; i < alternative_level_selected.size(); i++) {
Array key = alternative_level_list->get_item_metadata(alternative_level_selected[i]);
- Array val = tile_set->get_coords_level_tile_proxy(key[0], key[1]);
+ Array val = tile_set->get_alternative_level_tile_proxy(key[0], key[1], key[2]);
undo_redo->add_do_method(*tile_set, "remove_alternative_level_tile_proxy", key[0], key[1], key[2]);
undo_redo->add_undo_method(*tile_set, "set_alternative_level_tile_proxy", key[0], key[1], key[2], val[0], val[1], val[2]);
}
@@ -152,6 +155,7 @@ void TileProxiesManagerDialog::_property_changed(const String &p_path, const Var
}
void TileProxiesManagerDialog::_add_button_pressed() {
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
if (from.source_id != TileSet::INVALID_SOURCE && to.source_id != TileSet::INVALID_SOURCE) {
Vector2i from_coords = from.get_atlas_coords();
Vector2i to_coords = to.get_atlas_coords();
@@ -192,6 +196,7 @@ void TileProxiesManagerDialog::_add_button_pressed() {
}
void TileProxiesManagerDialog::_clear_invalid_button_pressed() {
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Delete All Invalid Tile Proxies"));
undo_redo->add_do_method(*tile_set, "cleanup_invalid_tile_proxies");
@@ -219,6 +224,7 @@ void TileProxiesManagerDialog::_clear_invalid_button_pressed() {
}
void TileProxiesManagerDialog::_clear_all_button_pressed() {
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Delete All Tile Proxies"));
undo_redo->add_do_method(*tile_set, "clear_tile_proxies");
@@ -299,6 +305,7 @@ void TileProxiesManagerDialog::_unhandled_key_input(Ref<InputEvent> p_event) {
}
void TileProxiesManagerDialog::cancel_pressed() {
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
for (int i = 0; i < commited_actions_count; i++) {
undo_redo->undo();
}
@@ -318,8 +325,6 @@ void TileProxiesManagerDialog::update_tile_set(Ref<TileSet> p_tile_set) {
}
TileProxiesManagerDialog::TileProxiesManagerDialog() {
- undo_redo = EditorNode::get_singleton()->get_undo_redo();
-
// Tile proxy management window.
set_title(TTR("Tile Proxies Management"));
set_process_unhandled_key_input(true);
diff --git a/editor/plugins/tiles/tile_proxies_manager_dialog.h b/editor/plugins/tiles/tile_proxies_manager_dialog.h
index 511e442a10..09c8068336 100644
--- a/editor/plugins/tiles/tile_proxies_manager_dialog.h
+++ b/editor/plugins/tiles/tile_proxies_manager_dialog.h
@@ -36,6 +36,8 @@
#include "scene/gui/dialogs.h"
#include "scene/gui/item_list.h"
+class EditorUndoRedoManager;
+
class TileProxiesManagerDialog : public ConfirmationDialog {
GDCLASS(TileProxiesManagerDialog, ConfirmationDialog);
@@ -43,8 +45,6 @@ private:
int commited_actions_count = 0;
Ref<TileSet> tile_set;
- Ref<EditorUndoRedoManager> undo_redo;
-
TileMapCell from;
TileMapCell to;
@@ -61,7 +61,7 @@ private:
EditorPropertyInteger *alternative_to_property_editor = nullptr;
PopupMenu *popup_menu = nullptr;
- void _right_clicked(int p_item, Vector2 p_local_mouse_pos, Object *p_item_list, MouseButton p_mouse_button_index);
+ void _right_clicked(int p_item, Vector2 p_local_mouse_pos, MouseButton p_mouse_button_index, Object *p_item_list);
void _menu_id_pressed(int p_id);
void _delete_selected_bindings();
void _update_lists();
diff --git a/editor/plugins/tiles/tile_set_atlas_source_editor.cpp b/editor/plugins/tiles/tile_set_atlas_source_editor.cpp
index 8e69abd7ff..524a1fa38a 100644
--- a/editor/plugins/tiles/tile_set_atlas_source_editor.cpp
+++ b/editor/plugins/tiles/tile_set_atlas_source_editor.cpp
@@ -35,10 +35,10 @@
#include "editor/editor_inspector.h"
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
+#include "editor/editor_settings.h"
#include "editor/editor_undo_redo_manager.h"
#include "editor/progress_dialog.h"
-#include "editor/editor_node.h"
#include "scene/gui/box_container.h"
#include "scene/gui/button.h"
#include "scene/gui/control.h"
@@ -152,7 +152,7 @@ bool TileSetAtlasSourceEditor::AtlasTileProxyObject::_set(const StringName &p_na
// ID and size related properties.
if (tiles.size() == 1) {
- const Vector2i &coords = tiles.front()->get().tile;
+ const Vector2i coords = tiles.front()->get().tile;
const int &alternative = tiles.front()->get().alternative;
if (alternative == 0) {
@@ -543,11 +543,13 @@ void TileSetAtlasSourceEditor::_update_source_inspector() {
void TileSetAtlasSourceEditor::_update_fix_selected_and_hovered_tiles() {
// Fix selected.
- for (RBSet<TileSelection>::Element *E = selection.front(); E; E = E->next()) {
+ for (RBSet<TileSelection>::Element *E = selection.front(); E;) {
+ RBSet<TileSelection>::Element *N = E->next();
TileSelection selected = E->get();
if (!tile_set_atlas_source->has_tile(selected.tile) || !tile_set_atlas_source->has_alternative_tile(selected.tile, selected.alternative)) {
selection.erase(E);
}
+ E = N;
}
// Fix hovered.
@@ -1682,10 +1684,6 @@ Array TileSetAtlasSourceEditor::_get_selection_as_array() {
}
void TileSetAtlasSourceEditor::_tile_atlas_control_draw() {
- // Colors.
- Color grid_color = EDITOR_GET("editors/tiles_editor/grid_color");
- Color selection_color = Color().from_hsv(Math::fposmod(grid_color.get_h() + 0.5, 1.0), grid_color.get_s(), grid_color.get_v(), 1.0);
-
// Draw the selected tile.
if (tools_button_group->get_pressed_button() == tool_select_button) {
for (const TileSelection &E : selection) {
@@ -1693,12 +1691,9 @@ void TileSetAtlasSourceEditor::_tile_atlas_control_draw() {
if (selected.alternative == 0) {
// Draw the rect.
for (int frame = 0; frame < tile_set_atlas_source->get_tile_animation_frames_count(selected.tile); frame++) {
- Color color = selection_color;
- if (frame > 0) {
- color.a *= 0.3;
- }
+ Color color = Color(0.0, 1.0, 0.0, frame == 0 ? 1.0 : 0.3);
Rect2 region = tile_set_atlas_source->get_tile_texture_region(selected.tile, frame);
- tile_atlas_control->draw_rect(region, color, false);
+ TilesEditorPlugin::draw_selection_rect(tile_atlas_control, region, color);
}
}
}
@@ -1740,7 +1735,7 @@ void TileSetAtlasSourceEditor::_tile_atlas_control_draw() {
// Draw the tiles to be removed.
for (const Vector2i &E : drag_modified_tiles) {
for (int frame = 0; frame < tile_set_atlas_source->get_tile_animation_frames_count(E); frame++) {
- tile_atlas_control->draw_rect(tile_set_atlas_source->get_tile_texture_region(E, frame), Color(0.0, 0.0, 0.0), false);
+ TilesEditorPlugin::draw_selection_rect(tile_atlas_control, tile_set_atlas_source->get_tile_texture_region(E, frame), Color(0.0, 0.0, 0.0));
}
}
} else if (drag_type == DRAG_TYPE_RECT_SELECT || drag_type == DRAG_TYPE_REMOVE_TILES_USING_RECT) {
@@ -1752,7 +1747,7 @@ void TileSetAtlasSourceEditor::_tile_atlas_control_draw() {
Color color = Color(0.0, 0.0, 0.0);
if (drag_type == DRAG_TYPE_RECT_SELECT) {
- color = selection_color.lightened(0.2);
+ color = Color(1.0, 1.0, 0.0);
}
RBSet<Vector2i> to_paint;
@@ -1767,7 +1762,7 @@ void TileSetAtlasSourceEditor::_tile_atlas_control_draw() {
for (const Vector2i &E : to_paint) {
Vector2i coords = E;
- tile_atlas_control->draw_rect(tile_set_atlas_source->get_tile_texture_region(coords), color, false);
+ TilesEditorPlugin::draw_selection_rect(tile_atlas_control, tile_set_atlas_source->get_tile_texture_region(coords), color);
}
} else if (drag_type == DRAG_TYPE_CREATE_TILES_USING_RECT) {
// Draw tiles to be created.
@@ -1784,7 +1779,7 @@ void TileSetAtlasSourceEditor::_tile_atlas_control_draw() {
Vector2i coords = Vector2i(x, y);
if (tile_set_atlas_source->get_tile_at_coords(coords) == TileSetSource::INVALID_ATLAS_COORDS) {
Vector2i origin = margins + (coords * (tile_size + separation));
- tile_atlas_control->draw_rect(Rect2i(origin, tile_size), Color(1.0, 1.0, 1.0), false);
+ TilesEditorPlugin::draw_selection_rect(tile_atlas_control, Rect2i(origin, tile_size));
}
}
}
@@ -1801,7 +1796,7 @@ void TileSetAtlasSourceEditor::_tile_atlas_control_draw() {
Vector2i separation = tile_set_atlas_source->get_separation();
Vector2i tile_size = tile_set_atlas_source->get_texture_region_size();
Vector2i origin = margins + (area.position * (tile_size + separation));
- tile_atlas_control->draw_rect(Rect2i(origin, area.size * tile_size), Color(1.0, 1.0, 1.0), false);
+ TilesEditorPlugin::draw_selection_rect(tile_atlas_control, Rect2i(origin, area.size * tile_size));
} else {
Vector2i grid_size = tile_set_atlas_source->get_atlas_grid_size();
if (hovered_base_tile_coords.x >= 0 && hovered_base_tile_coords.y >= 0 && hovered_base_tile_coords.x < grid_size.x && hovered_base_tile_coords.y < grid_size.y) {
@@ -1809,11 +1804,8 @@ void TileSetAtlasSourceEditor::_tile_atlas_control_draw() {
if (hovered_tile != TileSetSource::INVALID_ATLAS_COORDS) {
// Draw existing hovered tile.
for (int frame = 0; frame < tile_set_atlas_source->get_tile_animation_frames_count(hovered_tile); frame++) {
- Color color = Color(1.0, 1.0, 1.0);
- if (frame > 0) {
- color.a *= 0.3;
- }
- tile_atlas_control->draw_rect(tile_set_atlas_source->get_tile_texture_region(hovered_tile, frame), color, false);
+ Color color = Color(1.0, 0.8, 0.0, frame == 0 ? 0.6 : 0.3);
+ TilesEditorPlugin::draw_selection_rect(tile_atlas_control, tile_set_atlas_source->get_tile_texture_region(hovered_tile, frame), color);
}
} else {
// Draw empty tile, only in add/remove tiles mode.
@@ -1822,7 +1814,7 @@ void TileSetAtlasSourceEditor::_tile_atlas_control_draw() {
Vector2i separation = tile_set_atlas_source->get_separation();
Vector2i tile_size = tile_set_atlas_source->get_texture_region_size();
Vector2i origin = margins + (hovered_base_tile_coords * (tile_size + separation));
- tile_atlas_control->draw_rect(Rect2i(origin, tile_size), Color(1.0, 1.0, 1.0), false);
+ TilesEditorPlugin::draw_selection_rect(tile_atlas_control, Rect2i(origin, tile_size));
}
}
}
@@ -1974,9 +1966,6 @@ void TileSetAtlasSourceEditor::_tile_alternatives_control_mouse_exited() {
}
void TileSetAtlasSourceEditor::_tile_alternatives_control_draw() {
- Color grid_color = EDITOR_GET("editors/tiles_editor/grid_color");
- Color selection_color = Color().from_hsv(Math::fposmod(grid_color.get_h() + 0.5, 1.0), grid_color.get_s(), grid_color.get_v(), 1.0);
-
// Update the hovered alternative tile.
if (tools_button_group->get_pressed_button() == tool_select_button) {
// Draw hovered tile.
@@ -1984,7 +1973,7 @@ void TileSetAtlasSourceEditor::_tile_alternatives_control_draw() {
if (coords != TileSetSource::INVALID_ATLAS_COORDS) {
Rect2i rect = tile_atlas_view->get_alternative_tile_rect(coords, hovered_alternative_tile_coords.z);
if (rect != Rect2i()) {
- alternative_tiles_control->draw_rect(rect, Color(1.0, 1.0, 1.0), false);
+ TilesEditorPlugin::draw_selection_rect(alternative_tiles_control, rect, Color(1.0, 0.8, 0.0, 0.5));
}
}
@@ -1994,7 +1983,7 @@ void TileSetAtlasSourceEditor::_tile_alternatives_control_draw() {
if (selected.alternative >= 1) {
Rect2i rect = tile_atlas_view->get_alternative_tile_rect(selected.tile, selected.alternative);
if (rect != Rect2i()) {
- alternative_tiles_control->draw_rect(rect, selection_color, false);
+ TilesEditorPlugin::draw_selection_rect(alternative_tiles_control, rect);
}
}
}
@@ -2343,6 +2332,15 @@ void TileSetAtlasSourceEditor::_notification(int p_what) {
tile_set_changed_needs_update = false;
}
} break;
+
+ case NOTIFICATION_EXIT_TREE: {
+ for (KeyValue<String, TileDataEditor *> &E : tile_data_editors) {
+ Control *toolbar = E.value->get_toolbar();
+ if (toolbar->get_parent() == tool_settings_tile_data_toolbar_container) {
+ tool_settings_tile_data_toolbar_container->remove_child(toolbar);
+ }
+ }
+ } break;
}
}
diff --git a/editor/plugins/tiles/tile_set_atlas_source_editor.h b/editor/plugins/tiles/tile_set_atlas_source_editor.h
index 8e217e359f..14e120e2a3 100644
--- a/editor/plugins/tiles/tile_set_atlas_source_editor.h
+++ b/editor/plugins/tiles/tile_set_atlas_source_editor.h
@@ -37,7 +37,10 @@
#include "scene/gui/split_container.h"
#include "scene/resources/tile_set.h"
+class Popup;
class TileSet;
+class Tree;
+class VSeparator;
class TileSetAtlasSourceEditor : public HBoxContainer {
GDCLASS(TileSetAtlasSourceEditor, HBoxContainer);
diff --git a/editor/plugins/tiles/tile_set_editor.cpp b/editor/plugins/tiles/tile_set_editor.cpp
index eaae9555dc..e8ceacf8f8 100644
--- a/editor/plugins/tiles/tile_set_editor.cpp
+++ b/editor/plugins/tiles/tile_set_editor.cpp
@@ -36,6 +36,7 @@
#include "editor/editor_file_system.h"
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
+#include "editor/editor_settings.h"
#include "editor/editor_undo_redo_manager.h"
#include "scene/gui/box_container.h"
@@ -66,6 +67,7 @@ void TileSetEditor::_drop_data_fw(const Point2 &p_point, const Variant &p_data,
// Actually create the new source.
Ref<TileSetAtlasSource> atlas_source = memnew(TileSetAtlasSource);
atlas_source->set_texture(resource);
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Add a new atlas source"));
undo_redo->add_do_method(*tile_set, "add_source", atlas_source, source_id);
undo_redo->add_do_method(*atlas_source, "set_texture_region_size", tile_set->get_tile_size());
@@ -118,7 +120,9 @@ bool TileSetEditor::_can_drop_data_fw(const Point2 &p_point, const Variant &p_da
}
void TileSetEditor::_update_sources_list(int force_selected_id) {
- ERR_FAIL_COND(!tile_set.is_valid());
+ if (tile_set.is_null()) {
+ return;
+ }
// Get the previously selected id.
int old_selected = TileSet::INVALID_SOURCE;
@@ -149,7 +153,7 @@ void TileSetEditor::_update_sources_list(int force_selected_id) {
// Common to all type of sources.
if (!source->get_name().is_empty()) {
- item_text = vformat(TTR("%s (id:%d)"), source->get_name(), source_id);
+ item_text = vformat(TTR("%s (ID: %d)"), source->get_name(), source_id);
}
// Atlas source.
@@ -158,7 +162,7 @@ void TileSetEditor::_update_sources_list(int force_selected_id) {
texture = atlas_source->get_texture();
if (item_text.is_empty()) {
if (texture.is_valid()) {
- item_text = vformat("%s (ID: %d)", texture->get_path().get_file(), source_id);
+ item_text = vformat(TTR("%s (ID: %d)"), texture->get_path().get_file(), source_id);
} else {
item_text = vformat(TTR("No Texture Atlas Source (ID: %d)"), source_id);
}
@@ -256,6 +260,7 @@ void TileSetEditor::_source_delete_pressed() {
Ref<TileSetSource> source = tile_set->get_source(to_delete);
// Remove the source.
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Remove source"));
undo_redo->add_do_method(*tile_set, "remove_source", to_delete);
undo_redo->add_undo_method(*tile_set, "add_source", source, to_delete);
@@ -274,6 +279,7 @@ void TileSetEditor::_source_add_id_pressed(int p_id_pressed) {
Ref<TileSetAtlasSource> atlas_source = memnew(TileSetAtlasSource);
// Add a new source.
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Add atlas source"));
undo_redo->add_do_method(*tile_set, "add_source", atlas_source, source_id);
undo_redo->add_do_method(*atlas_source, "set_texture_region_size", tile_set->get_tile_size());
@@ -288,6 +294,7 @@ void TileSetEditor::_source_add_id_pressed(int p_id_pressed) {
Ref<TileSetScenesCollectionSource> scene_collection_source = memnew(TileSetScenesCollectionSource);
// Add a new source.
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Add atlas source"));
undo_redo->add_do_method(*tile_set, "add_source", scene_collection_source, source_id);
undo_redo->add_undo_method(*tile_set, "remove_source", source_id);
@@ -341,6 +348,7 @@ void TileSetEditor::_notification(int p_what) {
source_sort_button->set_icon(get_theme_icon(SNAME("Sort"), SNAME("EditorIcons")));
sources_advanced_menu_button->set_icon(get_theme_icon(SNAME("GuiTabMenuHl"), SNAME("EditorIcons")));
missing_texture_texture = get_theme_icon(SNAME("TileSet"), SNAME("EditorIcons"));
+ _update_sources_list();
} break;
case NOTIFICATION_INTERNAL_PROCESS: {
@@ -361,6 +369,7 @@ void TileSetEditor::_patterns_item_list_gui_input(const Ref<InputEvent> &p_event
if (ED_IS_SHORTCUT("tiles_editor/delete", p_event) && p_event->is_pressed() && !p_event->is_echo()) {
Vector<int> selected = patterns_item_list->get_selected_items();
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Remove TileSet patterns"));
for (int i = 0; i < selected.size(); i++) {
int pattern_index = selected[i];
@@ -666,8 +675,6 @@ void TileSetEditor::edit(Ref<TileSet> p_tile_set) {
TileSetEditor::TileSetEditor() {
singleton = this;
- undo_redo = EditorNode::get_undo_redo();
-
set_process_internal(true);
// TabBar.
diff --git a/editor/plugins/tiles/tile_set_editor.h b/editor/plugins/tiles/tile_set_editor.h
index 76a471db74..95697f7ecc 100644
--- a/editor/plugins/tiles/tile_set_editor.h
+++ b/editor/plugins/tiles/tile_set_editor.h
@@ -39,8 +39,6 @@
#include "tile_set_atlas_source_editor.h"
#include "tile_set_scenes_collection_source_editor.h"
-class EditorUndoRedoManager;
-
class TileSetEditor : public VBoxContainer {
GDCLASS(TileSetEditor, VBoxContainer);
@@ -60,8 +58,6 @@ private:
TileSetAtlasSourceEditor *tile_set_atlas_source_editor = nullptr;
TileSetScenesCollectionSourceEditor *tile_set_scenes_collection_source_editor = nullptr;
- Ref<EditorUndoRedoManager> undo_redo;
-
void _drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from);
bool _can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const;
diff --git a/editor/plugins/tiles/tile_set_scenes_collection_source_editor.cpp b/editor/plugins/tiles/tile_set_scenes_collection_source_editor.cpp
index 3b711a568e..a14aad6652 100644
--- a/editor/plugins/tiles/tile_set_scenes_collection_source_editor.cpp
+++ b/editor/plugins/tiles/tile_set_scenes_collection_source_editor.cpp
@@ -38,6 +38,7 @@
#include "editor/editor_undo_redo_manager.h"
#include "scene/gui/item_list.h"
+#include "scene/gui/split_container.h"
#include "core/core_string_names.h"
diff --git a/editor/plugins/tiles/tiles_editor_plugin.cpp b/editor/plugins/tiles/tiles_editor_plugin.cpp
index 4239e2c981..ee29913334 100644
--- a/editor/plugins/tiles/tiles_editor_plugin.cpp
+++ b/editor/plugins/tiles/tiles_editor_plugin.cpp
@@ -30,10 +30,13 @@
#include "tiles_editor_plugin.h"
+#include "tile_set_editor.h"
+
#include "core/os/mutex.h"
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
+#include "editor/editor_settings.h"
#include "editor/plugins/canvas_item_editor_plugin.h"
#include "scene/2d/tile_map.h"
@@ -43,8 +46,6 @@
#include "scene/gui/separator.h"
#include "scene/resources/tile_set.h"
-#include "tile_set_editor.h"
-
TilesEditorPlugin *TilesEditorPlugin::singleton = nullptr;
void TilesEditorPlugin::_preview_frame_started() {
@@ -384,6 +385,15 @@ bool TilesEditorPlugin::handles(Object *p_object) const {
return p_object->is_class("TileMap") || p_object->is_class("TileSet");
}
+void TilesEditorPlugin::draw_selection_rect(CanvasItem *p_ci, const Rect2 &p_rect, const Color &p_color) {
+ 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_theme_icon(SNAME("TileSelection"), SNAME("EditorIcons"))->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());
+}
+
TilesEditorPlugin::TilesEditorPlugin() {
set_process_internal(true);
diff --git a/editor/plugins/tiles/tiles_editor_plugin.h b/editor/plugins/tiles/tiles_editor_plugin.h
index fe0d8179bc..825a10dac2 100644
--- a/editor/plugins/tiles/tiles_editor_plugin.h
+++ b/editor/plugins/tiles/tiles_editor_plugin.h
@@ -128,6 +128,8 @@ public:
virtual bool handles(Object *p_object) const override;
virtual void make_visible(bool p_visible) override;
+ static void draw_selection_rect(CanvasItem *p_ci, const Rect2 &p_rect, const Color &p_color = Color(1.0, 1.0, 1.0));
+
TilesEditorPlugin();
~TilesEditorPlugin();
};
diff --git a/editor/plugins/version_control_editor_plugin.cpp b/editor/plugins/version_control_editor_plugin.cpp
index 4fdfaed50e..369a59c443 100644
--- a/editor/plugins/version_control_editor_plugin.cpp
+++ b/editor/plugins/version_control_editor_plugin.cpp
@@ -38,6 +38,7 @@
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
#include "editor/filesystem_dock.h"
+#include "editor/plugins/script_editor_plugin.h"
#include "scene/gui/separator.h"
#define CHECK_PLUGIN_INITIALIZED() \
@@ -987,7 +988,7 @@ VersionControlEditorPlugin::VersionControlEditorPlugin() {
metadata_dialog->set_title(TTR("Create Version Control Metadata"));
metadata_dialog->set_min_size(Size2(200, 40));
metadata_dialog->get_ok_button()->connect(SNAME("pressed"), callable_mp(this, &VersionControlEditorPlugin::_create_vcs_metadata_files));
- version_control_actions->add_child(metadata_dialog);
+ add_child(metadata_dialog);
VBoxContainer *metadata_vb = memnew(VBoxContainer);
metadata_dialog->add_child(metadata_vb);
@@ -1016,7 +1017,7 @@ VersionControlEditorPlugin::VersionControlEditorPlugin() {
set_up_dialog->set_min_size(Size2(600, 100));
set_up_dialog->add_cancel_button("Cancel");
set_up_dialog->set_hide_on_ok(true);
- version_control_actions->add_child(set_up_dialog);
+ add_child(set_up_dialog);
Button *set_up_apply_button = set_up_dialog->get_ok_button();
set_up_apply_button->set_text(TTR("Apply"));
diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp
index adc93c0752..cf811067c9 100644
--- a/editor/plugins/visual_shader_editor_plugin.cpp
+++ b/editor/plugins/visual_shader_editor_plugin.cpp
@@ -32,31 +32,31 @@
#include "core/config/project_settings.h"
#include "core/core_string_names.h"
-#include "core/input/input.h"
#include "core/io/resource_loader.h"
#include "core/math/math_defs.h"
#include "core/os/keyboard.h"
-#include "editor/editor_log.h"
#include "editor/editor_node.h"
#include "editor/editor_properties.h"
#include "editor/editor_scale.h"
+#include "editor/editor_settings.h"
#include "editor/editor_undo_redo_manager.h"
+#include "editor/inspector_dock.h"
#include "editor/plugins/curve_editor_plugin.h"
#include "editor/plugins/shader_editor_plugin.h"
-#include "scene/animation/animation_player.h"
#include "scene/gui/button.h"
+#include "scene/gui/check_box.h"
#include "scene/gui/code_edit.h"
#include "scene/gui/graph_edit.h"
#include "scene/gui/menu_button.h"
-#include "scene/gui/panel.h"
+#include "scene/gui/option_button.h"
#include "scene/gui/popup.h"
#include "scene/gui/rich_text_label.h"
+#include "scene/gui/separator.h"
#include "scene/gui/tree.h"
#include "scene/gui/view_panner.h"
#include "scene/main/window.h"
#include "scene/resources/visual_shader_nodes.h"
#include "scene/resources/visual_shader_particle_nodes.h"
-#include "scene/resources/visual_shader_sdf_nodes.h"
#include "servers/display_server.h"
#include "servers/rendering/shader_types.h"
@@ -269,6 +269,19 @@ void VisualShaderGraphPlugin::set_expression(VisualShader::Type p_type, int p_no
links[p_node_id].expression_edit->set_text(p_expression);
}
+Ref<Script> VisualShaderGraphPlugin::get_node_script(int p_node_id) const {
+ if (!links.has(p_node_id)) {
+ return Ref<Script>();
+ }
+
+ Ref<VisualShaderNodeCustom> custom = Ref<VisualShaderNodeCustom>(links[p_node_id].visual_node);
+ if (custom.is_valid()) {
+ return custom->get_script();
+ }
+
+ return Ref<Script>();
+}
+
void VisualShaderGraphPlugin::update_node_size(int p_node_id) {
if (!links.has(p_node_id)) {
return;
@@ -1113,6 +1126,8 @@ void VisualShaderEditor::edit(VisualShader *p_visual_shader) {
}
visual_shader->set_graph_offset(graph->get_scroll_ofs() / EDSCALE);
_set_mode(visual_shader->get_mode());
+
+ _update_nodes();
} else {
if (visual_shader.is_valid()) {
Callable ce = callable_mp(this, &VisualShaderEditor::_update_preview);
@@ -1135,10 +1150,6 @@ void VisualShaderEditor::edit(VisualShader *p_visual_shader) {
}
}
-void VisualShaderEditor::update_nodes() {
- _update_nodes();
-}
-
void VisualShaderEditor::add_plugin(const Ref<VisualShaderNodePlugin> &p_plugin) {
if (plugins.has(p_plugin)) {
return;
@@ -1200,6 +1211,228 @@ void VisualShaderEditor::add_custom_type(const String &p_name, const Ref<Script>
add_options.push_back(ao);
}
+Dictionary VisualShaderEditor::get_custom_node_data(Ref<VisualShaderNodeCustom> &p_custom_node) {
+ Dictionary dict;
+ dict["script"] = p_custom_node->get_script();
+
+ String name;
+ if (p_custom_node->has_method("_get_name")) {
+ name = (String)p_custom_node->call("_get_name");
+ } else {
+ name = "Unnamed";
+ }
+ dict["name"] = name;
+
+ String description = "";
+ if (p_custom_node->has_method("_get_description")) {
+ description = (String)p_custom_node->call("_get_description");
+ }
+ dict["description"] = description;
+
+ int return_icon_type = -1;
+ if (p_custom_node->has_method("_get_return_icon_type")) {
+ return_icon_type = (int)p_custom_node->call("_get_return_icon_type");
+ }
+ dict["return_icon_type"] = return_icon_type;
+
+ String category = "";
+ if (p_custom_node->has_method("_get_category")) {
+ category = (String)p_custom_node->call("_get_category");
+ }
+ category = category.rstrip("/");
+ category = category.lstrip("/");
+ category = "Addons/" + category;
+
+ String subcategory = "";
+ if (p_custom_node->has_method("_get_subcategory")) {
+ subcategory = (String)p_custom_node->call("_get_subcategory");
+ }
+ if (!subcategory.is_empty()) {
+ category += "/" + subcategory;
+ }
+ dict["category"] = category;
+
+ bool highend = false;
+ if (p_custom_node->has_method("_is_highend")) {
+ highend = (bool)p_custom_node->call("_is_highend");
+ }
+ dict["highend"] = highend;
+
+ return dict;
+}
+
+void VisualShaderEditor::update_custom_type(const Ref<Resource> &p_resource) {
+ Ref<Script> scr = Ref<Script>(p_resource.ptr());
+ if (scr.is_null() || scr->get_instance_base_type() != String("VisualShaderNodeCustom")) {
+ return;
+ }
+
+ Ref<VisualShaderNodeCustom> ref;
+ ref.instantiate();
+ ref->set_script(scr);
+ if (!ref->is_available(visual_shader->get_mode(), visual_shader->get_shader_type())) {
+ for (int i = 0; i < add_options.size(); i++) {
+ if (add_options[i].is_custom && add_options[i].script == scr) {
+ add_options.remove_at(i);
+ _update_options_menu();
+ // TODO: Make indication for the existed custom nodes with that script on graph to be disabled.
+ break;
+ }
+ }
+ return;
+ }
+ Dictionary dict = get_custom_node_data(ref);
+
+ bool found_type = false;
+ bool need_rebuild = false;
+
+ for (int i = 0; i < add_options.size(); i++) {
+ if (add_options[i].is_custom && add_options[i].script == scr) {
+ found_type = true;
+
+ add_options.write[i].name = dict["name"];
+ add_options.write[i].return_type = dict["return_icon_type"];
+ add_options.write[i].description = dict["description"];
+ add_options.write[i].category = dict["category"];
+ add_options.write[i].highend = dict["highend"];
+
+ int max_type = 0;
+ int type_offset = 0;
+ switch (visual_shader->get_mode()) {
+ case Shader::MODE_CANVAS_ITEM:
+ case Shader::MODE_SPATIAL: {
+ max_type = 3;
+ } break;
+ case Shader::MODE_PARTICLES: {
+ max_type = 5;
+ type_offset = 3;
+ } break;
+ case Shader::MODE_SKY: {
+ max_type = 1;
+ type_offset = 8;
+ } break;
+ case Shader::MODE_FOG: {
+ max_type = 1;
+ type_offset = 9;
+ } break;
+ default: {
+ } break;
+ }
+ max_type = type_offset + max_type;
+
+ for (int t = type_offset; t < max_type; t++) {
+ VisualShader::Type type = (VisualShader::Type)t;
+ Vector<int> nodes = visual_shader->get_node_list(type);
+
+ List<VisualShader::Connection> node_connections;
+ visual_shader->get_node_connections(type, &node_connections);
+
+ List<VisualShader::Connection> custom_node_input_connections;
+ List<VisualShader::Connection> custom_node_output_connections;
+ for (const VisualShader::Connection &E : node_connections) {
+ int from = E.from_node;
+ int from_idx = E.from_port;
+ int to = E.to_node;
+ int to_idx = E.to_port;
+
+ if (graph_plugin->get_node_script(from) == scr) {
+ custom_node_output_connections.push_back({ from, from_idx, to, to_idx });
+ } else if (graph_plugin->get_node_script(to) == scr) {
+ custom_node_input_connections.push_back({ from, from_idx, to, to_idx });
+ }
+ }
+
+ for (int j = 0; j < nodes.size(); j++) {
+ int node_id = nodes[j];
+
+ Ref<VisualShaderNode> vsnode = visual_shader->get_node(type, node_id);
+ if (vsnode.is_null()) {
+ continue;
+ }
+ Ref<VisualShaderNodeCustom> custom_node = Ref<VisualShaderNodeCustom>(vsnode.ptr());
+ if (custom_node.is_null() || custom_node->get_script() != scr) {
+ continue;
+ }
+ need_rebuild = true;
+
+ // Removes invalid connections.
+ {
+ int prev_input_port_count = custom_node->get_input_port_count();
+ int prev_output_port_count = custom_node->get_output_port_count();
+
+ custom_node->update_ports();
+
+ int input_port_count = custom_node->get_input_port_count();
+ int output_port_count = custom_node->get_output_port_count();
+
+ if (output_port_count != prev_output_port_count) {
+ for (const VisualShader::Connection &E : custom_node_output_connections) {
+ int from = E.from_node;
+ int from_idx = E.from_port;
+ int to = E.to_node;
+ int to_idx = E.to_port;
+
+ if (from_idx >= output_port_count) {
+ visual_shader->disconnect_nodes(type, from, from_idx, to, to_idx);
+ graph_plugin->disconnect_nodes(type, from, from_idx, to, to_idx);
+ }
+ }
+ }
+ if (input_port_count != prev_input_port_count) {
+ for (const VisualShader::Connection &E : custom_node_input_connections) {
+ int from = E.from_node;
+ int from_idx = E.from_port;
+ int to = E.to_node;
+ int to_idx = E.to_port;
+
+ if (to_idx >= input_port_count) {
+ visual_shader->disconnect_nodes(type, from, from_idx, to, to_idx);
+ graph_plugin->disconnect_nodes(type, from, from_idx, to, to_idx);
+ }
+ }
+ }
+ }
+
+ graph_plugin->update_node(type, node_id);
+ }
+ }
+ break;
+ }
+ }
+
+ if (!found_type) {
+ add_custom_type(dict["name"], dict["script"], dict["description"], dict["return_icon_type"], dict["category"], dict["highend"]);
+ }
+
+ // To prevent updating options multiple times when multiple scripts are saved.
+ if (!_block_update_options_menu) {
+ _block_update_options_menu = true;
+
+ call_deferred(SNAME("_update_options_menu_deferred"));
+ }
+
+ // To prevent rebuilding the shader multiple times when multiple scripts are saved.
+ if (need_rebuild && !_block_rebuild_shader) {
+ _block_rebuild_shader = true;
+
+ call_deferred(SNAME("_rebuild_shader_deferred"));
+ }
+}
+
+void VisualShaderEditor::_update_options_menu_deferred() {
+ _update_options_menu();
+
+ _block_update_options_menu = false;
+}
+
+void VisualShaderEditor::_rebuild_shader_deferred() {
+ if (visual_shader.is_valid()) {
+ visual_shader->rebuild();
+ }
+
+ _block_rebuild_shader = false;
+}
+
bool VisualShaderEditor::_is_available(int p_mode) {
int current_mode = edit_type->get_selected();
@@ -1241,57 +1474,10 @@ void VisualShaderEditor::_update_nodes() {
if (!ref->is_available(visual_shader->get_mode(), visual_shader->get_shader_type())) {
continue;
}
-
- String name;
- if (ref->has_method("_get_name")) {
- name = (String)ref->call("_get_name");
- } else {
- name = "Unnamed";
- }
-
- String description = "";
- if (ref->has_method("_get_description")) {
- description = (String)ref->call("_get_description");
- }
-
- int return_icon_type = -1;
- if (ref->has_method("_get_return_icon_type")) {
- return_icon_type = (int)ref->call("_get_return_icon_type");
- }
-
- String category = "";
- if (ref->has_method("_get_category")) {
- category = (String)ref->call("_get_category");
- }
-
- String subcategory = "";
- if (ref->has_method("_get_subcategory")) {
- subcategory = (String)ref->call("_get_subcategory");
- }
-
- bool highend = false;
- if (ref->has_method("_is_highend")) {
- highend = (bool)ref->call("_is_highend");
- }
-
- Dictionary dict;
- dict["name"] = name;
- dict["script"] = scr;
- dict["description"] = description;
- dict["return_icon_type"] = return_icon_type;
-
- category = category.rstrip("/");
- category = category.lstrip("/");
- category = "Addons/" + category;
- if (!subcategory.is_empty()) {
- category += "/" + subcategory;
- }
-
- dict["category"] = category;
- dict["highend"] = highend;
+ Dictionary dict = get_custom_node_data(ref);
String key;
- key = category + "/" + name;
+ key = String(dict["category"]) + "/" + String(dict["name"]);
added[key] = dict;
}
@@ -1659,6 +1845,7 @@ void VisualShaderEditor::_update_parameters(bool p_update_refs) {
}
void VisualShaderEditor::_update_parameter_refs(HashSet<String> &p_deleted_names) {
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
for (int i = 0; i < VisualShader::TYPE_MAX; i++) {
VisualShader::Type type = VisualShader::Type(i);
@@ -1758,6 +1945,7 @@ void VisualShaderEditor::_add_input_port(int p_node, int p_port, int p_port_type
return;
}
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Add Input Port"));
undo_redo->add_do_method(node.ptr(), "add_input_port", p_port, p_port_type, p_name);
undo_redo->add_undo_method(node.ptr(), "remove_input_port", p_port);
@@ -1773,6 +1961,7 @@ void VisualShaderEditor::_add_output_port(int p_node, int p_port, int p_port_typ
return;
}
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Add Output Port"));
undo_redo->add_do_method(node.ptr(), "add_output_port", p_port, p_port_type, p_name);
undo_redo->add_undo_method(node.ptr(), "remove_output_port", p_port);
@@ -1788,6 +1977,7 @@ void VisualShaderEditor::_change_input_port_type(int p_type, int p_node, int p_p
return;
}
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Change Input Port Type"));
undo_redo->add_do_method(node.ptr(), "set_input_port_type", p_port, p_type);
undo_redo->add_undo_method(node.ptr(), "set_input_port_type", p_port, node->get_input_port_type(p_port));
@@ -1803,6 +1993,7 @@ void VisualShaderEditor::_change_output_port_type(int p_type, int p_node, int p_
return;
}
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Change Output Port Type"));
undo_redo->add_do_method(node.ptr(), "set_output_port_type", p_port, p_type);
undo_redo->add_undo_method(node.ptr(), "set_output_port_type", p_port, node->get_output_port_type(p_port));
@@ -1831,6 +2022,7 @@ void VisualShaderEditor::_change_input_port_name(const String &p_text, Object *p
return;
}
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Change Input Port Name"));
undo_redo->add_do_method(node.ptr(), "set_input_port_name", p_port_id, validated_name);
undo_redo->add_undo_method(node.ptr(), "set_input_port_name", p_port_id, node->get_input_port_name(p_port_id));
@@ -1857,6 +2049,7 @@ void VisualShaderEditor::_change_output_port_name(const String &p_text, Object *
return;
}
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Change Output Port Name"));
undo_redo->add_do_method(node.ptr(), "set_output_port_name", p_port_id, validated_name);
undo_redo->add_undo_method(node.ptr(), "set_output_port_name", p_port_id, prev_name);
@@ -1869,6 +2062,7 @@ void VisualShaderEditor::_expand_output_port(int p_node, int p_port, bool p_expa
Ref<VisualShaderNode> node = visual_shader->get_node(type, p_node);
ERR_FAIL_COND(!node.is_valid());
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
if (p_expand) {
undo_redo->create_action(TTR("Expand Output Port"));
} else {
@@ -1966,6 +2160,7 @@ void VisualShaderEditor::_remove_input_port(int p_node, int p_port) {
return;
}
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Remove Input Port"));
List<VisualShader::Connection> conns;
@@ -2015,6 +2210,7 @@ void VisualShaderEditor::_remove_output_port(int p_node, int p_port) {
return;
}
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Remove Output Port"));
List<VisualShader::Connection> conns;
@@ -2081,6 +2277,7 @@ void VisualShaderEditor::_expression_focus_out(Object *code_edit, int p_node) {
return;
}
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Set VisualShader Expression"));
undo_redo->add_do_method(node.ptr(), "set_expression", expression_box->get_text());
undo_redo->add_undo_method(node.ptr(), "set_expression", node->get_expression());
@@ -2144,6 +2341,7 @@ void VisualShaderEditor::_node_resized(const Vector2 &p_new_size, int p_type, in
return;
}
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Resize VisualShader Node"), UndoRedo::MERGE_ENDS);
undo_redo->add_do_method(this, "_set_node_size", p_type, p_node, p_new_size);
undo_redo->add_undo_method(this, "_set_node_size", p_type, p_node, node->get_size());
@@ -2160,6 +2358,7 @@ void VisualShaderEditor::_preview_select_port(int p_node, int p_port) {
if (node->get_output_port_for_preview() == p_port) {
p_port = -1; //toggle it
}
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(p_port == -1 ? TTR("Hide Port Preview") : TTR("Show Port Preview"));
undo_redo->add_do_method(node.ptr(), "set_output_port_for_preview", p_port);
undo_redo->add_undo_method(node.ptr(), "set_output_port_for_preview", prev_port);
@@ -2205,6 +2404,7 @@ void VisualShaderEditor::_comment_title_popup_hide() {
if (node->get_title() == comment_title_change_edit->get_text()) {
return; // nothing changed - ignored
}
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Set Comment Node Title"));
undo_redo->add_do_method(node.ptr(), "set_title", comment_title_change_edit->get_text());
undo_redo->add_undo_method(node.ptr(), "set_title", node->get_title());
@@ -2247,6 +2447,7 @@ void VisualShaderEditor::_comment_desc_popup_hide() {
if (node->get_description() == comment_desc_change_edit->get_text()) {
return; // nothing changed - ignored
}
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Set Comment Node Description"));
undo_redo->add_do_method(node.ptr(), "set_description", comment_desc_change_edit->get_text());
undo_redo->add_undo_method(node.ptr(), "set_description", node->get_title());
@@ -2267,6 +2468,7 @@ void VisualShaderEditor::_parameter_line_edit_changed(const String &p_text, int
return;
}
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Set Parameter Name"));
undo_redo->add_do_method(node.ptr(), "set_parameter_name", validated_name);
undo_redo->add_undo_method(node.ptr(), "set_parameter_name", node->get_parameter_name());
@@ -2302,6 +2504,7 @@ void VisualShaderEditor::_port_edited(const StringName &p_property, const Varian
Ref<VisualShaderNode> vsn = visual_shader->get_node(type, editing_node);
ERR_FAIL_COND(!vsn.is_valid());
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Set Input Default Port"));
Ref<VisualShaderNodeCustom> custom = Object::cast_to<VisualShaderNodeCustom>(vsn.ptr());
@@ -2725,6 +2928,7 @@ void VisualShaderEditor::_add_node(int p_idx, const Vector<Variant> &p_ops, Stri
int id_to_use = visual_shader->get_valid_node_id(type);
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
if (p_resource_path.is_empty()) {
undo_redo->create_action(TTR("Add Node to Visual Shader"));
} else {
@@ -2894,6 +3098,7 @@ void VisualShaderEditor::_add_node(int p_idx, const Vector<Variant> &p_ops, Stri
}
void VisualShaderEditor::_add_varying(const String &p_name, VisualShader::VaryingMode p_mode, VisualShader::VaryingType p_type) {
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(vformat(TTR("Add Varying to Visual Shader: %s"), p_name));
undo_redo->add_do_method(visual_shader.ptr(), "add_varying", p_name, p_mode, p_type);
@@ -2928,6 +3133,7 @@ void VisualShaderEditor::_add_varying(const String &p_name, VisualShader::Varyin
}
void VisualShaderEditor::_remove_varying(const String &p_name) {
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(vformat(TTR("Remove Varying from Visual Shader: %s"), p_name));
VisualShader::VaryingMode var_mode = visual_shader->get_varying_mode(p_name);
@@ -3015,6 +3221,7 @@ void VisualShaderEditor::_node_dragged(const Vector2 &p_from, const Vector2 &p_t
void VisualShaderEditor::_nodes_dragged() {
drag_dirty = false;
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Node(s) Moved"));
for (const DragOp &E : drag_buffer) {
@@ -3038,6 +3245,7 @@ void VisualShaderEditor::_connection_request(const String &p_from, int p_from_in
return;
}
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Nodes Connected"));
List<VisualShader::Connection> conns;
@@ -3069,6 +3277,7 @@ void VisualShaderEditor::_disconnection_request(const String &p_from, int p_from
int from = p_from.to_int();
int to = p_to.to_int();
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Nodes Disconnected"));
undo_redo->add_do_method(visual_shader.ptr(), "disconnect_nodes", type, from, p_from_index, to, p_to_index);
undo_redo->add_undo_method(visual_shader.ptr(), "connect_nodes", type, from, p_from_index, to, p_to_index);
@@ -3108,6 +3317,7 @@ void VisualShaderEditor::_delete_nodes(int p_type, const List<int> &p_nodes) {
List<VisualShader::Connection> conns;
visual_shader->get_node_connections(type, &conns);
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
for (const int &F : p_nodes) {
for (const VisualShader::Connection &E : conns) {
if (E.from_node == F || E.to_node == F) {
@@ -3180,6 +3390,7 @@ void VisualShaderEditor::_delete_nodes(int p_type, const List<int> &p_nodes) {
}
void VisualShaderEditor::_replace_node(VisualShader::Type p_type_id, int p_node_id, const StringName &p_from, const StringName &p_to) {
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->add_do_method(visual_shader.ptr(), "replace_node", p_type_id, p_node_id, p_to);
undo_redo->add_undo_method(visual_shader.ptr(), "replace_node", p_type_id, p_node_id, p_from);
}
@@ -3214,6 +3425,7 @@ void VisualShaderEditor::_update_parameter(VisualShader::Type p_type_id, int p_n
void VisualShaderEditor::_convert_constants_to_parameters(bool p_vice_versa) {
VisualShader::Type type_id = get_current_shader_type();
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
if (!p_vice_versa) {
undo_redo->create_action(TTR("Convert Constant Node(s) To Parameter(s)"));
} else {
@@ -3412,6 +3624,7 @@ void VisualShaderEditor::_delete_node_request(int p_type, int p_node) {
List<int> to_erase;
to_erase.push_back(p_node);
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Delete VisualShader Node"));
_delete_nodes(p_type, to_erase);
undo_redo->commit_action();
@@ -3440,6 +3653,7 @@ void VisualShaderEditor::_delete_nodes_request(const TypedArray<StringName> &p_n
return;
}
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Delete VisualShader Node(s)"));
_delete_nodes(get_current_shader_type(), to_erase);
undo_redo->commit_action();
@@ -3852,6 +4066,7 @@ void VisualShaderEditor::_dup_copy_nodes(int p_type, List<CopyItem> &r_items, Li
}
void VisualShaderEditor::_dup_paste_nodes(int p_type, List<CopyItem> &r_items, const List<VisualShader::Connection> &p_connections, const Vector2 &p_offset, bool p_duplicate) {
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
if (p_duplicate) {
undo_redo->create_action(TTR("Duplicate VisualShader Node(s)"));
} else {
@@ -3970,6 +4185,7 @@ void VisualShaderEditor::_copy_nodes(bool p_cut) {
_dup_copy_nodes(get_current_shader_type(), copy_items_buffer, copy_connections_buffer);
if (p_cut) {
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Cut VisualShader Node(s)"));
List<int> ids;
@@ -4240,6 +4456,7 @@ void VisualShaderEditor::_float_constant_selected(int p_which) {
return; // same
}
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(vformat(TTR("Set Constant: %s"), float_constant_defs[p_which].name));
undo_redo->add_do_method(node.ptr(), "set_constant", float_constant_defs[p_which].value);
undo_redo->add_undo_method(node.ptr(), "set_constant", node->get_constant());
@@ -4500,6 +4717,7 @@ void VisualShaderEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da
saved_node_pos_dirty = true;
_add_node(idx, add_options[idx].ops);
} else if (d.has("files")) {
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Add Node(s) to Visual Shader"));
if (d["files"].get_type() == Variant::PACKED_STRING_ARRAY) {
@@ -4660,6 +4878,8 @@ void VisualShaderEditor::_bind_methods() {
ClassDB::bind_method("_update_constant", &VisualShaderEditor::_update_constant);
ClassDB::bind_method("_update_parameter", &VisualShaderEditor::_update_parameter);
ClassDB::bind_method("_expand_output_port", &VisualShaderEditor::_expand_output_port);
+ ClassDB::bind_method("_update_options_menu_deferred", &VisualShaderEditor::_update_options_menu_deferred);
+ ClassDB::bind_method("_rebuild_shader_deferred", &VisualShaderEditor::_rebuild_shader_deferred);
ClassDB::bind_method(D_METHOD("_get_drag_data_fw"), &VisualShaderEditor::get_drag_data_fw);
ClassDB::bind_method(D_METHOD("_can_drop_data_fw"), &VisualShaderEditor::can_drop_data_fw);
@@ -4670,6 +4890,7 @@ void VisualShaderEditor::_bind_methods() {
VisualShaderEditor::VisualShaderEditor() {
ShaderLanguage::get_keyword_list(&keyword_list);
+ EditorNode::get_singleton()->connect("resource_saved", callable_mp(this, &VisualShaderEditor::update_custom_type));
graph = memnew(GraphEdit);
graph->get_zoom_hbox()->set_h_size_flags(SIZE_EXPAND_FILL);
@@ -5175,6 +5396,7 @@ VisualShaderEditor::VisualShaderEditor() {
add_options.push_back(AddOption("NodePositionWorld", "Input/Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "node_position_world", "NODE_POSITION_WORLD"), { "node_position_world" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL));
add_options.push_back(AddOption("CameraPositionWorld", "Input/Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "camera_position_world", "CAMERA_POSITION_WORLD"), { "camera_position_world" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL));
add_options.push_back(AddOption("CameraDirectionWorld", "Input/Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "camera_direction_world", "CAMERA_DIRECTION_WORLD"), { "camera_direction_world" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("CameraVisibleLayers", "Input/Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "camera_visible_layers", "CAMERA_VISIBLE_LAYERS"), { "camera_visible_layers" }, VisualShaderNode::PORT_TYPE_SCALAR_INT, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL));
add_options.push_back(AddOption("NodePositionView", "Input/Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "node_position_view", "NODE_POSITION_VIEW"), { "node_position_view" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL));
add_options.push_back(AddOption("Binormal", "Input/Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "binormal", "BINORMAL"), { "binormal" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
@@ -5194,6 +5416,7 @@ VisualShaderEditor::VisualShaderEditor() {
add_options.push_back(AddOption("NodePositionWorld", "Input/Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "node_position_world", "NODE_POSITION_WORLD"), { "node_position_world" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
add_options.push_back(AddOption("CameraPositionWorld", "Input/Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "camera_position_world", "CAMERA_POSITION_WORLD"), { "camera_position_world" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
add_options.push_back(AddOption("CameraDirectionWorld", "Input/Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "camera_direction_world", "CAMERA_DIRECTION_WORLD"), { "camera_direction_world" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("CameraVisibleLayers", "Input/Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "camera_visible_layers", "CAMERA_VISIBLE_LAYERS"), { "camera_visible_layers" }, VisualShaderNode::PORT_TYPE_SCALAR_INT, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
add_options.push_back(AddOption("NodePositionView", "Input/Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "node_position_view", "NODE_POSITION_VIEW"), { "node_position_view" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
add_options.push_back(AddOption("Albedo", "Input/Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "albedo", "ALBEDO"), { "albedo" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL));
@@ -5675,8 +5898,6 @@ VisualShaderEditor::VisualShaderEditor() {
_update_options_menu();
- undo_redo = EditorNode::get_undo_redo();
-
Ref<VisualShaderNodePluginDefault> default_plugin;
default_plugin.instantiate();
default_plugin->set_editor(this);
diff --git a/editor/plugins/visual_shader_editor_plugin.h b/editor/plugins/visual_shader_editor_plugin.h
index e673051eb3..d559237569 100644
--- a/editor/plugins/visual_shader_editor_plugin.h
+++ b/editor/plugins/visual_shader_editor_plugin.h
@@ -34,14 +34,19 @@
#include "editor/editor_plugin.h"
#include "editor/editor_properties.h"
#include "editor/plugins/editor_resource_conversion_plugin.h"
+#include "scene/resources/syntax_highlighter.h"
#include "scene/resources/visual_shader.h"
+class CodeEdit;
class CurveEditor;
class GraphEdit;
class GraphNode;
+class MenuButton;
+class PopupPanel;
+class RichTextLabel;
+class Tree;
class VisualShaderEditor;
-class EditorUndoRedoManager;
class VisualShaderNodePlugin : public RefCounted {
GDCLASS(VisualShaderNodePlugin, RefCounted);
@@ -128,6 +133,7 @@ public:
void update_curve_xyz(int p_node_id);
void set_expression(VisualShader::Type p_type, int p_node_id, const String &p_expression);
int get_constant_index(float p_constant) const;
+ Ref<Script> get_node_script(int p_node_id) const;
void update_node_size(int p_node_id);
void update_theme();
VisualShader::Type get_shader_type() const;
@@ -185,7 +191,9 @@ class VisualShaderEditor : public VBoxContainer {
PanelContainer *error_panel = nullptr;
Label *error_label = nullptr;
- Ref<EditorUndoRedoManager> undo_redo;
+ bool _block_update_options_menu = false;
+ bool _block_rebuild_shader = false;
+
Point2 saved_node_pos;
bool saved_node_pos_dirty = false;
@@ -493,6 +501,9 @@ class VisualShaderEditor : public VBoxContainer {
void _update_parameter_refs(HashSet<String> &p_names);
void _update_varyings();
+ void _update_options_menu_deferred();
+ void _rebuild_shader_deferred();
+
void _visibility_changed();
protected:
@@ -500,7 +511,6 @@ protected:
static void _bind_methods();
public:
- void update_nodes();
void add_plugin(const Ref<VisualShaderNodePlugin> &p_plugin);
void remove_plugin(const Ref<VisualShaderNodePlugin> &p_plugin);
@@ -509,6 +519,9 @@ public:
void clear_custom_types();
void add_custom_type(const String &p_name, const Ref<Script> &p_script, const String &p_description, int p_return_icon_type, const String &p_category, bool p_highend);
+ Dictionary get_custom_node_data(Ref<VisualShaderNodeCustom> &p_custom_node);
+ void update_custom_type(const Ref<Resource> &p_resource);
+
virtual Size2 get_minimum_size() const override;
void edit(VisualShader *p_visual_shader);
VisualShaderEditor();