summaryrefslogtreecommitdiff
path: root/editor/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'editor/plugins')
-rw-r--r--editor/plugins/abstract_polygon_2d_editor.cpp16
-rw-r--r--editor/plugins/abstract_polygon_2d_editor.h8
-rw-r--r--editor/plugins/animation_blend_space_1d_editor.cpp67
-rw-r--r--editor/plugins/animation_blend_space_1d_editor.h1
-rw-r--r--editor/plugins/animation_blend_space_2d_editor.cpp87
-rw-r--r--editor/plugins/animation_blend_space_2d_editor.h1
-rw-r--r--editor/plugins/animation_blend_tree_editor_plugin.cpp133
-rw-r--r--editor/plugins/animation_blend_tree_editor_plugin.h5
-rw-r--r--editor/plugins/animation_player_editor_plugin.cpp179
-rw-r--r--editor/plugins/animation_player_editor_plugin.h14
-rw-r--r--editor/plugins/animation_state_machine_editor.cpp287
-rw-r--r--editor/plugins/animation_state_machine_editor.h3
-rw-r--r--editor/plugins/animation_tree_editor_plugin.cpp35
-rw-r--r--editor/plugins/animation_tree_editor_plugin.h6
-rw-r--r--editor/plugins/asset_library_editor_plugin.cpp28
-rw-r--r--editor/plugins/asset_library_editor_plugin.h3
-rw-r--r--editor/plugins/audio_stream_editor_plugin.cpp53
-rw-r--r--editor/plugins/audio_stream_editor_plugin.h4
-rw-r--r--editor/plugins/audio_stream_randomizer_editor_plugin.cpp121
-rw-r--r--editor/plugins/audio_stream_randomizer_editor_plugin.h54
-rw-r--r--editor/plugins/camera_3d_editor_plugin.cpp6
-rw-r--r--editor/plugins/camera_3d_editor_plugin.h4
-rw-r--r--editor/plugins/canvas_item_editor_plugin.cpp860
-rw-r--r--editor/plugins/canvas_item_editor_plugin.h171
-rw-r--r--editor/plugins/collision_polygon_2d_editor_plugin.cpp8
-rw-r--r--editor/plugins/collision_polygon_2d_editor_plugin.h4
-rw-r--r--editor/plugins/collision_shape_2d_editor_plugin.cpp22
-rw-r--r--editor/plugins/collision_shape_2d_editor_plugin.h8
-rw-r--r--editor/plugins/control_editor_plugin.cpp1034
-rw-r--r--editor/plugins/control_editor_plugin.h252
-rw-r--r--editor/plugins/cpu_particles_2d_editor_plugin.cpp17
-rw-r--r--editor/plugins/cpu_particles_2d_editor_plugin.h9
-rw-r--r--editor/plugins/cpu_particles_3d_editor_plugin.cpp14
-rw-r--r--editor/plugins/cpu_particles_3d_editor_plugin.h3
-rw-r--r--editor/plugins/curve_editor_plugin.cpp9
-rw-r--r--editor/plugins/curve_editor_plugin.h3
-rw-r--r--editor/plugins/debugger_editor_plugin.cpp9
-rw-r--r--editor/plugins/debugger_editor_plugin.h3
-rw-r--r--editor/plugins/editor_preview_plugins.cpp9
-rw-r--r--editor/plugins/editor_preview_plugins.h3
-rw-r--r--editor/plugins/font_editor_plugin.cpp20
-rw-r--r--editor/plugins/font_editor_plugin.h3
-rw-r--r--editor/plugins/gpu_particles_2d_editor_plugin.cpp22
-rw-r--r--editor/plugins/gpu_particles_2d_editor_plugin.h8
-rw-r--r--editor/plugins/gpu_particles_3d_editor_plugin.cpp15
-rw-r--r--editor/plugins/gpu_particles_3d_editor_plugin.h6
-rw-r--r--editor/plugins/gpu_particles_collision_sdf_editor_plugin.cpp68
-rw-r--r--editor/plugins/gpu_particles_collision_sdf_editor_plugin.h7
-rw-r--r--editor/plugins/gradient_editor_plugin.cpp19
-rw-r--r--editor/plugins/gradient_editor_plugin.h3
-rw-r--r--editor/plugins/input_event_editor_plugin.cpp2
-rw-r--r--editor/plugins/input_event_editor_plugin.h4
-rw-r--r--editor/plugins/light_occluder_2d_editor_plugin.cpp8
-rw-r--r--editor/plugins/light_occluder_2d_editor_plugin.h4
-rw-r--r--editor/plugins/lightmap_gi_editor_plugin.cpp10
-rw-r--r--editor/plugins/lightmap_gi_editor_plugin.h7
-rw-r--r--editor/plugins/line_2d_editor_plugin.cpp8
-rw-r--r--editor/plugins/line_2d_editor_plugin.h4
-rw-r--r--editor/plugins/material_editor_plugin.cpp43
-rw-r--r--editor/plugins/material_editor_plugin.h8
-rw-r--r--editor/plugins/mesh_editor_plugin.cpp28
-rw-r--r--editor/plugins/mesh_editor_plugin.h3
-rw-r--r--editor/plugins/mesh_instance_3d_editor_plugin.cpp6
-rw-r--r--editor/plugins/mesh_instance_3d_editor_plugin.h4
-rw-r--r--editor/plugins/mesh_library_editor_plugin.cpp17
-rw-r--r--editor/plugins/mesh_library_editor_plugin.h12
-rw-r--r--editor/plugins/multimesh_editor_plugin.cpp7
-rw-r--r--editor/plugins/multimesh_editor_plugin.h7
-rw-r--r--editor/plugins/navigation_polygon_editor_plugin.cpp8
-rw-r--r--editor/plugins/navigation_polygon_editor_plugin.h4
-rw-r--r--editor/plugins/node_3d_editor_gizmos.cpp245
-rw-r--r--editor/plugins/node_3d_editor_gizmos.h5
-rw-r--r--editor/plugins/node_3d_editor_plugin.cpp2048
-rw-r--r--editor/plugins/node_3d_editor_plugin.h36
-rw-r--r--editor/plugins/occluder_instance_3d_editor_plugin.cpp16
-rw-r--r--editor/plugins/occluder_instance_3d_editor_plugin.h6
-rw-r--r--editor/plugins/ot_features_plugin.cpp30
-rw-r--r--editor/plugins/ot_features_plugin.h3
-rw-r--r--editor/plugins/packed_scene_translation_parser_plugin.cpp9
-rw-r--r--editor/plugins/packed_scene_translation_parser_plugin.h4
-rw-r--r--editor/plugins/path_2d_editor_plugin.cpp11
-rw-r--r--editor/plugins/path_2d_editor_plugin.h8
-rw-r--r--editor/plugins/path_3d_editor_plugin.cpp14
-rw-r--r--editor/plugins/path_3d_editor_plugin.h5
-rw-r--r--editor/plugins/physical_bone_3d_editor_plugin.cpp9
-rw-r--r--editor/plugins/physical_bone_3d_editor_plugin.h11
-rw-r--r--editor/plugins/polygon_2d_editor_plugin.cpp23
-rw-r--r--editor/plugins/polygon_2d_editor_plugin.h9
-rw-r--r--editor/plugins/polygon_3d_editor_plugin.cpp (renamed from editor/plugins/collision_polygon_3d_editor_plugin.cpp)122
-rw-r--r--editor/plugins/polygon_3d_editor_plugin.h (renamed from editor/plugins/collision_polygon_3d_editor_plugin.h)34
-rw-r--r--editor/plugins/replication_editor_plugin.cpp58
-rw-r--r--editor/plugins/replication_editor_plugin.h7
-rw-r--r--editor/plugins/resource_preloader_editor_plugin.cpp24
-rw-r--r--editor/plugins/resource_preloader_editor_plugin.h7
-rw-r--r--editor/plugins/root_motion_editor_plugin.cpp9
-rw-r--r--editor/plugins/script_editor_plugin.cpp314
-rw-r--r--editor/plugins/script_editor_plugin.h8
-rw-r--r--editor/plugins/script_text_editor.cpp31
-rw-r--r--editor/plugins/shader_editor_plugin.cpp27
-rw-r--r--editor/plugins/shader_editor_plugin.h5
-rw-r--r--editor/plugins/shader_file_editor_plugin.cpp23
-rw-r--r--editor/plugins/shader_file_editor_plugin.h7
-rw-r--r--editor/plugins/skeleton_2d_editor_plugin.cpp6
-rw-r--r--editor/plugins/skeleton_2d_editor_plugin.h4
-rw-r--r--editor/plugins/skeleton_3d_editor_plugin.cpp33
-rw-r--r--editor/plugins/skeleton_3d_editor_plugin.h8
-rw-r--r--editor/plugins/skeleton_ik_3d_editor_plugin.cpp6
-rw-r--r--editor/plugins/skeleton_ik_3d_editor_plugin.h4
-rw-r--r--editor/plugins/sprite_2d_editor_plugin.cpp32
-rw-r--r--editor/plugins/sprite_2d_editor_plugin.h5
-rw-r--r--editor/plugins/sprite_frames_editor_plugin.cpp14
-rw-r--r--editor/plugins/sprite_frames_editor_plugin.h11
-rw-r--r--editor/plugins/style_box_editor_plugin.cpp2
-rw-r--r--editor/plugins/style_box_editor_plugin.h4
-rw-r--r--editor/plugins/sub_viewport_preview_editor_plugin.cpp2
-rw-r--r--editor/plugins/sub_viewport_preview_editor_plugin.h3
-rw-r--r--editor/plugins/text_control_editor_plugin.cpp460
-rw-r--r--editor/plugins/text_control_editor_plugin.h12
-rw-r--r--editor/plugins/texture_3d_editor_plugin.cpp25
-rw-r--r--editor/plugins/texture_3d_editor_plugin.h4
-rw-r--r--editor/plugins/texture_editor_plugin.cpp8
-rw-r--r--editor/plugins/texture_editor_plugin.h3
-rw-r--r--editor/plugins/texture_layered_editor_plugin.cpp25
-rw-r--r--editor/plugins/texture_layered_editor_plugin.h4
-rw-r--r--editor/plugins/texture_region_editor_plugin.cpp22
-rw-r--r--editor/plugins/texture_region_editor_plugin.h7
-rw-r--r--editor/plugins/theme_editor_plugin.cpp103
-rw-r--r--editor/plugins/theme_editor_plugin.h21
-rw-r--r--editor/plugins/theme_editor_preview.cpp9
-rw-r--r--editor/plugins/theme_editor_preview.h16
-rw-r--r--editor/plugins/tiles/atlas_merging_dialog.cpp4
-rw-r--r--editor/plugins/tiles/atlas_merging_dialog.h6
-rw-r--r--editor/plugins/tiles/tile_atlas_view.cpp11
-rw-r--r--editor/plugins/tiles/tile_atlas_view.h2
-rw-r--r--editor/plugins/tiles/tile_data_editors.cpp45
-rw-r--r--editor/plugins/tiles/tile_data_editors.h14
-rw-r--r--editor/plugins/tiles/tile_map_editor.cpp54
-rw-r--r--editor/plugins/tiles/tile_map_editor.h16
-rw-r--r--editor/plugins/tiles/tile_proxies_manager_dialog.cpp3
-rw-r--r--editor/plugins/tiles/tile_proxies_manager_dialog.h4
-rw-r--r--editor/plugins/tiles/tile_set_atlas_source_editor.cpp18
-rw-r--r--editor/plugins/tiles/tile_set_atlas_source_editor.h3
-rw-r--r--editor/plugins/tiles/tile_set_editor.cpp15
-rw-r--r--editor/plugins/tiles/tile_set_editor.h3
-rw-r--r--editor/plugins/tiles/tile_set_scenes_collection_source_editor.cpp20
-rw-r--r--editor/plugins/tiles/tile_set_scenes_collection_source_editor.h8
-rw-r--r--editor/plugins/tiles/tiles_editor_plugin.cpp22
-rw-r--r--editor/plugins/tiles/tiles_editor_plugin.h4
-rw-r--r--editor/plugins/version_control_editor_plugin.cpp2
-rw-r--r--editor/plugins/version_control_editor_plugin.h3
-rw-r--r--editor/plugins/visual_shader_editor_plugin.cpp1175
-rw-r--r--editor/plugins/visual_shader_editor_plugin.h42
-rw-r--r--editor/plugins/voxel_gi_editor_plugin.cpp66
-rw-r--r--editor/plugins/voxel_gi_editor_plugin.h7
154 files changed, 5976 insertions, 3510 deletions
diff --git a/editor/plugins/abstract_polygon_2d_editor.cpp b/editor/plugins/abstract_polygon_2d_editor.cpp
index c6bde4c98a..5a2696fff1 100644
--- a/editor/plugins/abstract_polygon_2d_editor.cpp
+++ b/editor/plugins/abstract_polygon_2d_editor.cpp
@@ -33,6 +33,7 @@
#include "canvas_item_editor_plugin.h"
#include "core/math/geometry_2d.h"
#include "core/os/keyboard.h"
+#include "editor/editor_node.h"
#include "editor/editor_scale.h"
bool AbstractPolygon2DEditor::Vertex::operator==(const AbstractPolygon2DEditor::Vertex &p_vertex) const {
@@ -153,6 +154,7 @@ void AbstractPolygon2DEditor::_notification(int p_what) {
button_edit->set_icon(get_theme_icon(SNAME("CurveEdit"), SNAME("EditorIcons")));
button_delete->set_icon(get_theme_icon(SNAME("CurveDelete"), SNAME("EditorIcons")));
} break;
+
case NOTIFICATION_READY: {
disable_polygon_editing(false, String());
@@ -245,6 +247,10 @@ bool AbstractPolygon2DEditor::forward_gui_input(const Ref<InputEvent> &p_event)
return false;
}
+ if (!_get_node()->is_visible_in_tree()) {
+ return false;
+ }
+
Ref<InputEventMouseButton> mb = p_event;
if (!_has_resource()) {
@@ -478,6 +484,10 @@ void AbstractPolygon2DEditor::forward_canvas_draw_over_viewport(Control *p_overl
return;
}
+ if (!_get_node()->is_visible_in_tree()) {
+ return;
+ }
+
Transform2D xform = canvas_item_editor->get_canvas_transform() * _get_node()->get_global_transform();
// All polygon points are sharp, so use the sharp handle icon
const Ref<Texture2D> handle = get_theme_icon(SNAME("EditorPathSharpHandle"), SNAME("EditorIcons"));
@@ -693,9 +703,8 @@ AbstractPolygon2DEditor::PosVertex AbstractPolygon2DEditor::closest_edge_point(c
return closest;
}
-AbstractPolygon2DEditor::AbstractPolygon2DEditor(EditorNode *p_editor, bool p_wip_destructive) {
+AbstractPolygon2DEditor::AbstractPolygon2DEditor(bool p_wip_destructive) {
canvas_item_editor = nullptr;
- editor = p_editor;
undo_redo = EditorNode::get_undo_redo();
wip_active = false;
@@ -749,9 +758,8 @@ void AbstractPolygon2DEditorPlugin::make_visible(bool p_visible) {
}
}
-AbstractPolygon2DEditorPlugin::AbstractPolygon2DEditorPlugin(EditorNode *p_node, AbstractPolygon2DEditor *p_polygon_editor, String p_class) :
+AbstractPolygon2DEditorPlugin::AbstractPolygon2DEditorPlugin(AbstractPolygon2DEditor *p_polygon_editor, String p_class) :
polygon_editor(p_polygon_editor),
- editor(p_node),
klass(p_class) {
CanvasItemEditor::get_singleton()->add_control_to_menu_panel(polygon_editor);
polygon_editor->hide();
diff --git a/editor/plugins/abstract_polygon_2d_editor.h b/editor/plugins/abstract_polygon_2d_editor.h
index 8db5bf58dd..c0e7c1be2e 100644
--- a/editor/plugins/abstract_polygon_2d_editor.h
+++ b/editor/plugins/abstract_polygon_2d_editor.h
@@ -31,9 +31,9 @@
#ifndef ABSTRACT_POLYGON_2D_EDITOR_H
#define ABSTRACT_POLYGON_2D_EDITOR_H
-#include "editor/editor_node.h"
#include "editor/editor_plugin.h"
#include "scene/2d/polygon_2d.h"
+#include "scene/gui/box_container.h"
class CanvasItemEditor;
@@ -86,7 +86,6 @@ class AbstractPolygon2DEditor : public HBoxContainer {
bool _polygon_editing_enabled;
CanvasItemEditor *canvas_item_editor;
- EditorNode *editor;
Panel *panel;
ConfirmationDialog *create_resource;
@@ -144,14 +143,13 @@ public:
void forward_canvas_draw_over_viewport(Control *p_overlay);
void edit(Node *p_polygon);
- AbstractPolygon2DEditor(EditorNode *p_editor, bool p_wip_destructive = true);
+ AbstractPolygon2DEditor(bool p_wip_destructive = true);
};
class AbstractPolygon2DEditorPlugin : public EditorPlugin {
GDCLASS(AbstractPolygon2DEditorPlugin, EditorPlugin);
AbstractPolygon2DEditor *polygon_editor;
- EditorNode *editor;
String klass;
public:
@@ -164,7 +162,7 @@ public:
virtual bool handles(Object *p_object) const override;
virtual void make_visible(bool p_visible) override;
- AbstractPolygon2DEditorPlugin(EditorNode *p_node, AbstractPolygon2DEditor *p_polygon_editor, String p_class);
+ AbstractPolygon2DEditorPlugin(AbstractPolygon2DEditor *p_polygon_editor, String p_class);
~AbstractPolygon2DEditorPlugin();
};
diff --git a/editor/plugins/animation_blend_space_1d_editor.cpp b/editor/plugins/animation_blend_space_1d_editor.cpp
index 3dcb769faf..94882b3464 100644
--- a/editor/plugins/animation_blend_space_1d_editor.cpp
+++ b/editor/plugins/animation_blend_space_1d_editor.cpp
@@ -31,6 +31,8 @@
#include "animation_blend_space_1d_editor.h"
#include "core/os/keyboard.h"
+#include "editor/editor_file_dialog.h"
+#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "scene/animation/animation_blend_tree.h"
@@ -86,7 +88,7 @@ void AnimationNodeBlendSpace1DEditor::_blend_space_gui_input(const Ref<InputEven
}
int idx = menu->get_item_count();
- menu->add_item(vformat("Add %s", name), idx);
+ menu->add_item(vformat(TTR("Add %s"), name), idx);
menu->set_item_metadata(idx, E);
}
@@ -529,39 +531,42 @@ void AnimationNodeBlendSpace1DEditor::_open_editor() {
}
void AnimationNodeBlendSpace1DEditor::_notification(int p_what) {
- if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) {
- error_panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("bg"), SNAME("Tree")));
- error_label->add_theme_color_override("font_color", get_theme_color(SNAME("error_color"), SNAME("Editor")));
- panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("bg"), SNAME("Tree")));
- tool_blend->set_icon(get_theme_icon(SNAME("EditPivot"), SNAME("EditorIcons")));
- tool_select->set_icon(get_theme_icon(SNAME("ToolSelect"), SNAME("EditorIcons")));
- tool_create->set_icon(get_theme_icon(SNAME("EditKey"), SNAME("EditorIcons")));
- tool_erase->set_icon(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")));
- snap->set_icon(get_theme_icon(SNAME("SnapGrid"), SNAME("EditorIcons")));
- open_editor->set_icon(get_theme_icon(SNAME("Edit"), SNAME("EditorIcons")));
- }
-
- if (p_what == NOTIFICATION_PROCESS) {
- String error;
-
- if (!AnimationTreeEditor::get_singleton()->get_tree()->is_active()) {
- error = TTR("AnimationTree is inactive.\nActivate to enable playback, check node warnings if activation fails.");
- } else if (AnimationTreeEditor::get_singleton()->get_tree()->is_state_invalid()) {
- error = AnimationTreeEditor::get_singleton()->get_tree()->get_invalid_state_reason();
- }
+ switch (p_what) {
+ case NOTIFICATION_ENTER_TREE:
+ case NOTIFICATION_THEME_CHANGED: {
+ error_panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("bg"), SNAME("Tree")));
+ error_label->add_theme_color_override("font_color", get_theme_color(SNAME("error_color"), SNAME("Editor")));
+ panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("bg"), SNAME("Tree")));
+ tool_blend->set_icon(get_theme_icon(SNAME("EditPivot"), SNAME("EditorIcons")));
+ tool_select->set_icon(get_theme_icon(SNAME("ToolSelect"), SNAME("EditorIcons")));
+ tool_create->set_icon(get_theme_icon(SNAME("EditKey"), SNAME("EditorIcons")));
+ tool_erase->set_icon(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")));
+ snap->set_icon(get_theme_icon(SNAME("SnapGrid"), SNAME("EditorIcons")));
+ open_editor->set_icon(get_theme_icon(SNAME("Edit"), SNAME("EditorIcons")));
+ } break;
+
+ case NOTIFICATION_PROCESS: {
+ String error;
+
+ if (!AnimationTreeEditor::get_singleton()->get_tree()->is_active()) {
+ error = TTR("AnimationTree is inactive.\nActivate to enable playback, check node warnings if activation fails.");
+ } else if (AnimationTreeEditor::get_singleton()->get_tree()->is_state_invalid()) {
+ error = AnimationTreeEditor::get_singleton()->get_tree()->get_invalid_state_reason();
+ }
- if (error != error_label->get_text()) {
- error_label->set_text(error);
- if (!error.is_empty()) {
- error_panel->show();
- } else {
- error_panel->hide();
+ if (error != error_label->get_text()) {
+ error_label->set_text(error);
+ if (!error.is_empty()) {
+ error_panel->show();
+ } else {
+ error_panel->hide();
+ }
}
- }
- }
+ } break;
- if (p_what == NOTIFICATION_VISIBILITY_CHANGED) {
- set_process(is_visible_in_tree());
+ case NOTIFICATION_VISIBILITY_CHANGED: {
+ set_process(is_visible_in_tree());
+ } break;
}
}
diff --git a/editor/plugins/animation_blend_space_1d_editor.h b/editor/plugins/animation_blend_space_1d_editor.h
index 7906395c8f..54cded6048 100644
--- a/editor/plugins/animation_blend_space_1d_editor.h
+++ b/editor/plugins/animation_blend_space_1d_editor.h
@@ -31,7 +31,6 @@
#ifndef ANIMATION_BLEND_SPACE_1D_EDITOR_H
#define ANIMATION_BLEND_SPACE_1D_EDITOR_H
-#include "editor/editor_node.h"
#include "editor/editor_plugin.h"
#include "editor/plugins/animation_tree_editor_plugin.h"
#include "editor/property_editor.h"
diff --git a/editor/plugins/animation_blend_space_2d_editor.cpp b/editor/plugins/animation_blend_space_2d_editor.cpp
index f9df8db419..4b7df75aec 100644
--- a/editor/plugins/animation_blend_space_2d_editor.cpp
+++ b/editor/plugins/animation_blend_space_2d_editor.cpp
@@ -35,6 +35,8 @@
#include "core/io/resource_loader.h"
#include "core/math/geometry_2d.h"
#include "core/os/keyboard.h"
+#include "editor/editor_file_dialog.h"
+#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "scene/animation/animation_blend_tree.h"
#include "scene/animation/animation_player.h"
@@ -109,7 +111,7 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_gui_input(const Ref<InputEven
continue; // nope
}
int idx = menu->get_item_count();
- menu->add_item(vformat("Add %s", name), idx);
+ menu->add_item(vformat(TTR("Add %s"), name), idx);
menu->set_item_metadata(idx, E);
}
@@ -729,49 +731,52 @@ void AnimationNodeBlendSpace2DEditor::_edit_point_pos(double) {
}
void AnimationNodeBlendSpace2DEditor::_notification(int p_what) {
- if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) {
- error_panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("bg"), SNAME("Tree")));
- error_label->add_theme_color_override("font_color", get_theme_color(SNAME("error_color"), SNAME("Editor")));
- panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("bg"), SNAME("Tree")));
- tool_blend->set_icon(get_theme_icon(SNAME("EditPivot"), SNAME("EditorIcons")));
- tool_select->set_icon(get_theme_icon(SNAME("ToolSelect"), SNAME("EditorIcons")));
- tool_create->set_icon(get_theme_icon(SNAME("EditKey"), SNAME("EditorIcons")));
- tool_triangle->set_icon(get_theme_icon(SNAME("ToolTriangle"), SNAME("EditorIcons")));
- tool_erase->set_icon(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")));
- snap->set_icon(get_theme_icon(SNAME("SnapGrid"), SNAME("EditorIcons")));
- open_editor->set_icon(get_theme_icon(SNAME("Edit"), SNAME("EditorIcons")));
- auto_triangles->set_icon(get_theme_icon(SNAME("AutoTriangle"), SNAME("EditorIcons")));
- interpolation->clear();
- interpolation->add_icon_item(get_theme_icon(SNAME("TrackContinuous"), SNAME("EditorIcons")), "", 0);
- interpolation->add_icon_item(get_theme_icon(SNAME("TrackDiscrete"), SNAME("EditorIcons")), "", 1);
- interpolation->add_icon_item(get_theme_icon(SNAME("TrackCapture"), SNAME("EditorIcons")), "", 2);
- }
-
- if (p_what == NOTIFICATION_PROCESS) {
- String error;
-
- if (!AnimationTreeEditor::get_singleton()->get_tree()) {
- error = TTR("BlendSpace2D does not belong to an AnimationTree node.");
- } else if (!AnimationTreeEditor::get_singleton()->get_tree()->is_active()) {
- error = TTR("AnimationTree is inactive.\nActivate to enable playback, check node warnings if activation fails.");
- } else if (AnimationTreeEditor::get_singleton()->get_tree()->is_state_invalid()) {
- error = AnimationTreeEditor::get_singleton()->get_tree()->get_invalid_state_reason();
- } else if (blend_space->get_triangle_count() == 0) {
- error = TTR("No triangles exist, so no blending can take place.");
- }
+ switch (p_what) {
+ case NOTIFICATION_ENTER_TREE:
+ case NOTIFICATION_THEME_CHANGED: {
+ error_panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("bg"), SNAME("Tree")));
+ error_label->add_theme_color_override("font_color", get_theme_color(SNAME("error_color"), SNAME("Editor")));
+ panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("bg"), SNAME("Tree")));
+ tool_blend->set_icon(get_theme_icon(SNAME("EditPivot"), SNAME("EditorIcons")));
+ tool_select->set_icon(get_theme_icon(SNAME("ToolSelect"), SNAME("EditorIcons")));
+ tool_create->set_icon(get_theme_icon(SNAME("EditKey"), SNAME("EditorIcons")));
+ tool_triangle->set_icon(get_theme_icon(SNAME("ToolTriangle"), SNAME("EditorIcons")));
+ tool_erase->set_icon(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")));
+ snap->set_icon(get_theme_icon(SNAME("SnapGrid"), SNAME("EditorIcons")));
+ open_editor->set_icon(get_theme_icon(SNAME("Edit"), SNAME("EditorIcons")));
+ auto_triangles->set_icon(get_theme_icon(SNAME("AutoTriangle"), SNAME("EditorIcons")));
+ interpolation->clear();
+ interpolation->add_icon_item(get_theme_icon(SNAME("TrackContinuous"), SNAME("EditorIcons")), "", 0);
+ interpolation->add_icon_item(get_theme_icon(SNAME("TrackDiscrete"), SNAME("EditorIcons")), "", 1);
+ interpolation->add_icon_item(get_theme_icon(SNAME("TrackCapture"), SNAME("EditorIcons")), "", 2);
+ } break;
+
+ case NOTIFICATION_PROCESS: {
+ String error;
+
+ if (!AnimationTreeEditor::get_singleton()->get_tree()) {
+ error = TTR("BlendSpace2D does not belong to an AnimationTree node.");
+ } else if (!AnimationTreeEditor::get_singleton()->get_tree()->is_active()) {
+ error = TTR("AnimationTree is inactive.\nActivate to enable playback, check node warnings if activation fails.");
+ } else if (AnimationTreeEditor::get_singleton()->get_tree()->is_state_invalid()) {
+ error = AnimationTreeEditor::get_singleton()->get_tree()->get_invalid_state_reason();
+ } else if (blend_space->get_triangle_count() == 0) {
+ error = TTR("No triangles exist, so no blending can take place.");
+ }
- if (error != error_label->get_text()) {
- error_label->set_text(error);
- if (!error.is_empty()) {
- error_panel->show();
- } else {
- error_panel->hide();
+ if (error != error_label->get_text()) {
+ error_label->set_text(error);
+ if (!error.is_empty()) {
+ error_panel->show();
+ } else {
+ error_panel->hide();
+ }
}
- }
- }
+ } break;
- if (p_what == NOTIFICATION_VISIBILITY_CHANGED) {
- set_process(is_visible_in_tree());
+ case NOTIFICATION_VISIBILITY_CHANGED: {
+ set_process(is_visible_in_tree());
+ } break;
}
}
diff --git a/editor/plugins/animation_blend_space_2d_editor.h b/editor/plugins/animation_blend_space_2d_editor.h
index b46efff304..933d2bd96d 100644
--- a/editor/plugins/animation_blend_space_2d_editor.h
+++ b/editor/plugins/animation_blend_space_2d_editor.h
@@ -31,7 +31,6 @@
#ifndef ANIMATION_BLEND_SPACE_2D_EDITOR_H
#define ANIMATION_BLEND_SPACE_2D_EDITOR_H
-#include "editor/editor_node.h"
#include "editor/editor_plugin.h"
#include "editor/plugins/animation_tree_editor_plugin.h"
#include "editor/property_editor.h"
diff --git a/editor/plugins/animation_blend_tree_editor_plugin.cpp b/editor/plugins/animation_blend_tree_editor_plugin.cpp
index b000ff8eee..0b3164aada 100644
--- a/editor/plugins/animation_blend_tree_editor_plugin.cpp
+++ b/editor/plugins/animation_blend_tree_editor_plugin.cpp
@@ -34,7 +34,9 @@
#include "core/input/input.h"
#include "core/io/resource_loader.h"
#include "core/os/keyboard.h"
+#include "editor/editor_file_dialog.h"
#include "editor/editor_inspector.h"
+#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "scene/animation/animation_player.h"
#include "scene/gui/menu_button.h"
@@ -300,7 +302,7 @@ void AnimationNodeBlendTreeEditor::_add_node(int p_idx) {
base_name = add_options[p_idx].name;
} else {
ERR_FAIL_COND(add_options[p_idx].script.is_null());
- String base_type = add_options[p_idx].script->get_instance_base_type();
+ StringName base_type = add_options[p_idx].script->get_instance_base_type();
AnimationNode *an = Object::cast_to<AnimationNode>(ClassDB::instantiate(base_type));
ERR_FAIL_COND(!an);
anode = Ref<AnimationNode>(an);
@@ -732,80 +734,95 @@ void AnimationNodeBlendTreeEditor::_removed_from_graph() {
}
}
+void AnimationNodeBlendTreeEditor::_update_editor_settings() {
+ graph->get_panner()->setup((ViewPanner::ControlScheme)EDITOR_GET("editors/panning/sub_editors_panning_scheme").operator int(), ED_GET_SHORTCUT("canvas_item_editor/pan_view"), bool(EditorSettings::get_singleton()->get("editors/panning/simple_panning")));
+ graph->set_warped_panning(bool(EditorSettings::get_singleton()->get("editors/panning/warped_mouse_panning")));
+}
+
+void AnimationNodeBlendTreeEditor::_update_theme() {
+ error_panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("bg"), SNAME("Tree")));
+ error_label->add_theme_color_override("font_color", get_theme_color(SNAME("error_color"), SNAME("Editor")));
+}
+
void AnimationNodeBlendTreeEditor::_notification(int p_what) {
- if (p_what == NOTIFICATION_ENTER_TREE || p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) {
- graph->get_panner()->setup((ViewPanner::ControlScheme)EDITOR_GET("editors/panning/sub_editors_panning_scheme").operator int(), ED_GET_SHORTCUT("canvas_item_editor/pan_view"), bool(EditorSettings::get_singleton()->get("editors/panning/simple_panning")));
- graph->set_warped_panning(bool(EditorSettings::get_singleton()->get("editors/panning/warped_mouse_panning")));
- }
+ switch (p_what) {
+ case NOTIFICATION_ENTER_TREE: {
+ _update_editor_settings();
+ _update_theme();
+ } break;
- if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) {
- error_panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("bg"), SNAME("Tree")));
- error_label->add_theme_color_override("font_color", get_theme_color(SNAME("error_color"), SNAME("Editor")));
+ case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
+ _update_editor_settings();
+ } break;
- if (p_what == NOTIFICATION_THEME_CHANGED && is_visible_in_tree()) {
- _update_graph();
- }
- }
+ case NOTIFICATION_THEME_CHANGED: {
+ _update_theme();
- if (p_what == NOTIFICATION_PROCESS) {
- String error;
+ if (is_visible_in_tree()) {
+ _update_graph();
+ }
+ } break;
- if (!AnimationTreeEditor::get_singleton()->get_tree()->is_active()) {
- error = TTR("AnimationTree is inactive.\nActivate to enable playback, check node warnings if activation fails.");
- } else if (AnimationTreeEditor::get_singleton()->get_tree()->is_state_invalid()) {
- error = AnimationTreeEditor::get_singleton()->get_tree()->get_invalid_state_reason();
- }
+ case NOTIFICATION_PROCESS: {
+ String error;
- if (error != error_label->get_text()) {
- error_label->set_text(error);
- if (!error.is_empty()) {
- error_panel->show();
- } else {
- error_panel->hide();
+ if (!AnimationTreeEditor::get_singleton()->get_tree()->is_active()) {
+ error = TTR("AnimationTree is inactive.\nActivate to enable playback, check node warnings if activation fails.");
+ } else if (AnimationTreeEditor::get_singleton()->get_tree()->is_state_invalid()) {
+ error = AnimationTreeEditor::get_singleton()->get_tree()->get_invalid_state_reason();
}
- }
- List<AnimationNodeBlendTree::NodeConnection> conns;
- blend_tree->get_node_connections(&conns);
- for (const AnimationNodeBlendTree::NodeConnection &E : conns) {
- float activity = 0;
- StringName path = AnimationTreeEditor::get_singleton()->get_base_path() + E.input_node;
- if (AnimationTreeEditor::get_singleton()->get_tree() && !AnimationTreeEditor::get_singleton()->get_tree()->is_state_invalid()) {
- activity = AnimationTreeEditor::get_singleton()->get_tree()->get_connection_activity(path, E.input_index);
+ if (error != error_label->get_text()) {
+ error_label->set_text(error);
+ if (!error.is_empty()) {
+ error_panel->show();
+ } else {
+ error_panel->hide();
+ }
}
- graph->set_connection_activity(E.output_node, 0, E.input_node, E.input_index, activity);
- }
- AnimationTree *graph_player = AnimationTreeEditor::get_singleton()->get_tree();
- AnimationPlayer *player = nullptr;
- if (graph_player->has_node(graph_player->get_animation_player())) {
- player = Object::cast_to<AnimationPlayer>(graph_player->get_node(graph_player->get_animation_player()));
- }
+ List<AnimationNodeBlendTree::NodeConnection> conns;
+ blend_tree->get_node_connections(&conns);
+ for (const AnimationNodeBlendTree::NodeConnection &E : conns) {
+ float activity = 0;
+ StringName path = AnimationTreeEditor::get_singleton()->get_base_path() + E.input_node;
+ if (AnimationTreeEditor::get_singleton()->get_tree() && !AnimationTreeEditor::get_singleton()->get_tree()->is_state_invalid()) {
+ activity = AnimationTreeEditor::get_singleton()->get_tree()->get_connection_activity(path, E.input_index);
+ }
+ graph->set_connection_activity(E.output_node, 0, E.input_node, E.input_index, activity);
+ }
- if (player) {
- for (const KeyValue<StringName, ProgressBar *> &E : animations) {
- Ref<AnimationNodeAnimation> an = blend_tree->get_node(E.key);
- if (an.is_valid()) {
- if (player->has_animation(an->get_animation())) {
- Ref<Animation> anim = player->get_animation(an->get_animation());
- if (anim.is_valid()) {
- E.value->set_max(anim->get_length());
- //StringName path = AnimationTreeEditor::get_singleton()->get_base_path() + E.input_node;
- StringName time_path = AnimationTreeEditor::get_singleton()->get_base_path() + String(E.key) + "/time";
- E.value->set_value(AnimationTreeEditor::get_singleton()->get_tree()->get(time_path));
+ AnimationTree *graph_player = AnimationTreeEditor::get_singleton()->get_tree();
+ AnimationPlayer *player = nullptr;
+ if (graph_player->has_node(graph_player->get_animation_player())) {
+ player = Object::cast_to<AnimationPlayer>(graph_player->get_node(graph_player->get_animation_player()));
+ }
+
+ if (player) {
+ for (const KeyValue<StringName, ProgressBar *> &E : animations) {
+ Ref<AnimationNodeAnimation> an = blend_tree->get_node(E.key);
+ if (an.is_valid()) {
+ if (player->has_animation(an->get_animation())) {
+ Ref<Animation> anim = player->get_animation(an->get_animation());
+ if (anim.is_valid()) {
+ E.value->set_max(anim->get_length());
+ //StringName path = AnimationTreeEditor::get_singleton()->get_base_path() + E.input_node;
+ StringName time_path = AnimationTreeEditor::get_singleton()->get_base_path() + String(E.key) + "/time";
+ E.value->set_value(AnimationTreeEditor::get_singleton()->get_tree()->get(time_path));
+ }
}
}
}
}
- }
- for (int i = 0; i < visible_properties.size(); i++) {
- visible_properties[i]->update_property();
- }
- }
+ for (int i = 0; i < visible_properties.size(); i++) {
+ visible_properties[i]->update_property();
+ }
+ } break;
- if (p_what == NOTIFICATION_VISIBILITY_CHANGED) {
- set_process(is_visible_in_tree());
+ case NOTIFICATION_VISIBILITY_CHANGED: {
+ set_process(is_visible_in_tree());
+ } break;
}
}
diff --git a/editor/plugins/animation_blend_tree_editor_plugin.h b/editor/plugins/animation_blend_tree_editor_plugin.h
index 1e55cc8598..c111f9245e 100644
--- a/editor/plugins/animation_blend_tree_editor_plugin.h
+++ b/editor/plugins/animation_blend_tree_editor_plugin.h
@@ -31,7 +31,6 @@
#ifndef ANIMATION_BLEND_TREE_EDITOR_PLUGIN_H
#define ANIMATION_BLEND_TREE_EDITOR_PLUGIN_H
-#include "editor/editor_node.h"
#include "editor/editor_plugin.h"
#include "editor/plugins/animation_tree_editor_plugin.h"
#include "editor/property_editor.h"
@@ -42,6 +41,7 @@
#include "scene/gui/tree.h"
class ProgressBar;
+class EditorFileDialog;
class AnimationNodeBlendTreeEditor : public AnimationTreeNodeEditorPlugin {
GDCLASS(AnimationNodeBlendTreeEditor, AnimationTreeNodeEditorPlugin);
@@ -119,6 +119,9 @@ class AnimationNodeBlendTreeEditor : public AnimationTreeNodeEditorPlugin {
void _property_changed(const StringName &p_property, const Variant &p_value, const String &p_field, bool p_changing);
void _removed_from_graph();
+ void _update_editor_settings();
+ void _update_theme();
+
EditorFileDialog *open_file;
Ref<AnimationNode> file_loaded;
void _file_opened(const String &p_file);
diff --git a/editor/plugins/animation_player_editor_plugin.cpp b/editor/plugins/animation_player_editor_plugin.cpp
index 320c47e820..fba6d8e57f 100644
--- a/editor/plugins/animation_player_editor_plugin.cpp
+++ b/editor/plugins/animation_player_editor_plugin.cpp
@@ -35,11 +35,13 @@
#include "core/io/resource_loader.h"
#include "core/io/resource_saver.h"
#include "core/os/keyboard.h"
-#include "editor/animation_track_editor.h"
+#include "editor/editor_file_dialog.h"
+#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.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/main/window.h"
#include "scene/resources/animation.h"
#include "scene/scene_string_names.h"
@@ -92,6 +94,7 @@ void AnimationPlayerEditor::_notification(int p_what) {
last_active = player->is_playing();
updating = false;
} break;
+
case NOTIFICATION_ENTER_TREE: {
tool_anim->get_popup()->connect("id_pressed", callable_mp(this, &AnimationPlayerEditor::_animation_tool_menu));
@@ -101,11 +104,13 @@ void AnimationPlayerEditor::_notification(int p_what) {
get_tree()->connect("node_removed", callable_mp(this, &AnimationPlayerEditor::_node_removed));
- add_theme_style_override("panel", editor->get_gui_base()->get_theme_stylebox(SNAME("panel"), SNAME("Panel")));
+ add_theme_style_override("panel", EditorNode::get_singleton()->get_gui_base()->get_theme_stylebox(SNAME("panel"), SNAME("Panel")));
} break;
+
case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
- add_theme_style_override("panel", editor->get_gui_base()->get_theme_stylebox(SNAME("panel"), SNAME("Panel")));
+ add_theme_style_override("panel", EditorNode::get_singleton()->get_gui_base()->get_theme_stylebox(SNAME("panel"), SNAME("Panel")));
} break;
+
case NOTIFICATION_TRANSLATION_CHANGED:
case NOTIFICATION_LAYOUT_DIRECTION_CHANGED:
case NOTIFICATION_THEME_CHANGED: {
@@ -151,6 +156,8 @@ void AnimationPlayerEditor::_notification(int p_what) {
ITEM_ICON(TOOL_EDIT_TRANSITIONS, "Blend");
ITEM_ICON(TOOL_EDIT_RESOURCE, "Edit");
ITEM_ICON(TOOL_REMOVE_ANIM, "Remove");
+
+ _update_animation_list_icons();
} break;
}
}
@@ -305,7 +312,7 @@ void AnimationPlayerEditor::_animation_selected(int p_which) {
}
void AnimationPlayerEditor::_animation_new() {
- renaming = false;
+ name_dialog_op = TOOL_NEW_ANIM;
name_title->set_text(TTR("New Animation Name:"));
int count = 1;
@@ -338,7 +345,7 @@ void AnimationPlayerEditor::_animation_rename() {
name_title->set_text(TTR("Change Animation Name:"));
name->set_text(selected_name);
- renaming = true;
+ name_dialog_op = TOOL_RENAME_ANIM;
name_dialog->popup_centered(Size2(300, 90));
name->select_all();
name->grab_focus();
@@ -373,7 +380,7 @@ void AnimationPlayerEditor::_animation_save_in_path(const Ref<Resource> &p_resou
}
((Resource *)p_resource.ptr())->set_path(path);
- editor->emit_signal(SNAME("resource_saved"), p_resource);
+ EditorNode::get_singleton()->emit_signal(SNAME("resource_saved"), p_resource);
}
void AnimationPlayerEditor::_animation_save(const Ref<Resource> &p_resource) {
@@ -491,7 +498,7 @@ void AnimationPlayerEditor::_animation_name_edited() {
return;
}
- if (renaming && animation->get_item_count() > 0 && animation->get_item_text(animation->get_selected()) == new_name) {
+ if (name_dialog_op == TOOL_RENAME_ANIM && animation->get_item_count() > 0 && animation->get_item_text(animation->get_selected()) == new_name) {
name_dialog->hide();
return;
}
@@ -502,37 +509,58 @@ void AnimationPlayerEditor::_animation_name_edited() {
return;
}
- if (renaming) {
- String current = animation->get_item_text(animation->get_selected());
- Ref<Animation> anim = player->get_animation(current);
+ switch (name_dialog_op) {
+ case TOOL_RENAME_ANIM: {
+ String current = animation->get_item_text(animation->get_selected());
+ Ref<Animation> anim = player->get_animation(current);
+
+ undo_redo->create_action(TTR("Rename Animation"));
+ undo_redo->add_do_method(player, "rename_animation", current, new_name);
+ undo_redo->add_do_method(anim.ptr(), "set_name", new_name);
+ undo_redo->add_undo_method(player, "rename_animation", new_name, current);
+ undo_redo->add_undo_method(anim.ptr(), "set_name", current);
+ undo_redo->add_do_method(this, "_animation_player_changed", player);
+ undo_redo->add_undo_method(this, "_animation_player_changed", player);
+ undo_redo->commit_action();
+
+ _select_anim_by_name(new_name);
+ } break;
- undo_redo->create_action(TTR("Rename Animation"));
- undo_redo->add_do_method(player, "rename_animation", current, new_name);
- undo_redo->add_do_method(anim.ptr(), "set_name", new_name);
- undo_redo->add_undo_method(player, "rename_animation", new_name, current);
- undo_redo->add_undo_method(anim.ptr(), "set_name", current);
- undo_redo->add_do_method(this, "_animation_player_changed", player);
- undo_redo->add_undo_method(this, "_animation_player_changed", player);
- undo_redo->commit_action();
+ case TOOL_NEW_ANIM: {
+ Ref<Animation> new_anim = Ref<Animation>(memnew(Animation));
+ new_anim->set_name(new_name);
+
+ undo_redo->create_action(TTR("Add Animation"));
+ undo_redo->add_do_method(player, "add_animation", new_name, new_anim);
+ undo_redo->add_undo_method(player, "remove_animation", new_name);
+ undo_redo->add_do_method(this, "_animation_player_changed", player);
+ undo_redo->add_undo_method(this, "_animation_player_changed", player);
+ if (animation->get_item_count() == 0) {
+ undo_redo->add_do_method(this, "_start_onion_skinning");
+ undo_redo->add_undo_method(this, "_stop_onion_skinning");
+ }
+ undo_redo->commit_action();
- _select_anim_by_name(new_name);
+ _select_anim_by_name(new_name);
+ } break;
- } else {
- Ref<Animation> new_anim = Ref<Animation>(memnew(Animation));
- new_anim->set_name(new_name);
+ case TOOL_DUPLICATE_ANIM: {
+ String current = animation->get_item_text(animation->get_selected());
+ Ref<Animation> anim = player->get_animation(current);
- undo_redo->create_action(TTR("Add Animation"));
- undo_redo->add_do_method(player, "add_animation", new_name, new_anim);
- undo_redo->add_undo_method(player, "remove_animation", new_name);
- undo_redo->add_do_method(this, "_animation_player_changed", player);
- undo_redo->add_undo_method(this, "_animation_player_changed", player);
- if (animation->get_item_count() == 0) {
- undo_redo->add_do_method(this, "_start_onion_skinning");
- undo_redo->add_undo_method(this, "_stop_onion_skinning");
- }
- undo_redo->commit_action();
+ Ref<Animation> new_anim = _animation_clone(anim);
+ new_anim->set_name(new_name);
- _select_anim_by_name(new_name);
+ undo_redo->create_action(TTR("Duplicate Animation"));
+ undo_redo->add_do_method(player, "add_animation", new_name, new_anim);
+ undo_redo->add_undo_method(player, "remove_animation", new_name);
+ undo_redo->add_do_method(player, "animation_set_next", new_name, player->animation_get_next(current));
+ undo_redo->add_do_method(this, "_animation_player_changed", player);
+ undo_redo->add_undo_method(this, "_animation_player_changed", player);
+ undo_redo->commit_action();
+
+ _select_anim_by_name(new_name);
+ } break;
}
name_dialog->hide();
@@ -674,7 +702,7 @@ void AnimationPlayerEditor::set_state(const Dictionary &p_state) {
if (Object::cast_to<AnimationPlayer>(n) && EditorNode::get_singleton()->get_editor_selection()->is_selected(n)) {
player = Object::cast_to<AnimationPlayer>(n);
_update_player();
- editor->make_bottom_panel_item_visible(this);
+ EditorNode::get_singleton()->make_bottom_panel_item_visible(this);
set_process(true);
ensure_visibility();
@@ -697,7 +725,7 @@ void AnimationPlayerEditor::_animation_resource_edit() {
if (animation->get_item_count()) {
String current = animation->get_item_text(animation->get_selected());
Ref<Animation> anim = player->get_animation(current);
- editor->edit_resource(anim);
+ EditorNode::get_singleton()->edit_resource(anim);
}
}
@@ -833,22 +861,13 @@ void AnimationPlayerEditor::_update_player() {
int active_idx = -1;
for (const StringName &E : animlist) {
- Ref<Texture2D> icon;
- if (E == player->get_autoplay()) {
- if (E == SceneStringNames::get_singleton()->RESET) {
- icon = autoplay_reset_icon;
- } else {
- icon = autoplay_icon;
- }
- } else if (E == SceneStringNames::get_singleton()->RESET) {
- icon = reset_icon;
- }
- animation->add_icon_item(icon, E);
+ animation->add_item(E);
if (player->get_assigned_animation() == E) {
active_idx = animation->get_item_count() - 1;
}
}
+ _update_animation_list_icons();
updating = false;
if (active_idx != -1) {
@@ -877,6 +896,30 @@ void AnimationPlayerEditor::_update_player() {
_update_animation();
}
+void AnimationPlayerEditor::_update_animation_list_icons() {
+ List<StringName> animlist;
+ if (player) {
+ player->get_animation_list(&animlist);
+ }
+
+ for (int i = 0; i < animation->get_item_count(); i++) {
+ String name = animation->get_item_text(i);
+
+ Ref<Texture2D> icon;
+ if (name == player->get_autoplay()) {
+ if (name == SceneStringNames::get_singleton()->RESET) {
+ icon = autoplay_reset_icon;
+ } else {
+ icon = autoplay_icon;
+ }
+ } else if (name == SceneStringNames::get_singleton()->RESET) {
+ icon = reset_icon;
+ }
+
+ animation->set_item_icon(i, icon);
+ }
+}
+
void AnimationPlayerEditor::edit(AnimationPlayer *p_player) {
if (player && pin->is_pressed()) {
return; // Ignore, pinned.
@@ -965,28 +1008,17 @@ void AnimationPlayerEditor::_animation_duplicate() {
return;
}
- Ref<Animation> new_anim = _animation_clone(anim);
String new_name = current;
while (player->has_animation(new_name)) {
new_name = new_name + " (copy)";
}
- new_anim->set_name(new_name);
- undo_redo->create_action(TTR("Duplicate Animation"));
- undo_redo->add_do_method(player, "add_animation", new_name, new_anim);
- undo_redo->add_undo_method(player, "remove_animation", new_name);
- undo_redo->add_do_method(player, "animation_set_next", new_name, player->animation_get_next(current));
- undo_redo->add_do_method(this, "_animation_player_changed", player);
- undo_redo->add_undo_method(this, "_animation_player_changed", player);
- undo_redo->commit_action();
-
- for (int i = 0; i < animation->get_item_count(); i++) {
- if (animation->get_item_text(i) == new_name) {
- animation->select(i);
- _animation_selected(i);
- return;
- }
- }
+ name_title->set_text(TTR("New Animation Name:"));
+ name->set_text(new_name);
+ name_dialog_op = TOOL_DUPLICATE_ANIM;
+ name_dialog->popup_centered(Size2(300, 90));
+ name->select_all();
+ name->grab_focus();
}
Ref<Animation> AnimationPlayerEditor::_animation_clone(Ref<Animation> p_anim) {
@@ -1136,9 +1168,7 @@ void AnimationPlayerEditor::_animation_tool_menu(int p_option) {
} break;
case TOOL_DUPLICATE_ANIM: {
_animation_duplicate();
-
- [[fallthrough]]; // Allow immediate rename after animation is duplicated
- }
+ } break;
case TOOL_RENAME_ANIM: {
_animation_rename();
} break;
@@ -1188,7 +1218,7 @@ void AnimationPlayerEditor::_animation_tool_menu(int p_option) {
String current2 = animation->get_item_text(animation->get_selected());
Ref<Animation> anim2 = player->get_animation(current2);
- editor->edit_resource(anim2);
+ EditorNode::get_singleton()->edit_resource(anim2);
} break;
}
}
@@ -1532,8 +1562,7 @@ AnimationPlayer *AnimationPlayerEditor::get_player() const {
return player;
}
-AnimationPlayerEditor::AnimationPlayerEditor(EditorNode *p_editor, AnimationPlayerEditorPlugin *p_plugin) {
- editor = p_editor;
+AnimationPlayerEditor::AnimationPlayerEditor(AnimationPlayerEditorPlugin *p_plugin) {
plugin = p_plugin;
singleton = this;
@@ -1607,7 +1636,7 @@ AnimationPlayerEditor::AnimationPlayerEditor(EditorNode *p_editor, AnimationPlay
tool_anim->get_popup()->add_shortcut(ED_SHORTCUT("animation_player_editor/paste_animation", TTR("Paste")), TOOL_PASTE_ANIM);
tool_anim->get_popup()->add_shortcut(ED_SHORTCUT("animation_player_editor/paste_animation_as_reference", TTR("Paste As Reference")), TOOL_PASTE_ANIM_REF);
tool_anim->get_popup()->add_separator();
- tool_anim->get_popup()->add_shortcut(ED_SHORTCUT("animation_player_editor/duplicate_animation", TTR("Duplicate")), TOOL_DUPLICATE_ANIM);
+ tool_anim->get_popup()->add_shortcut(ED_SHORTCUT("animation_player_editor/duplicate_animation", TTR("Duplicate...")), TOOL_DUPLICATE_ANIM);
tool_anim->get_popup()->add_separator();
tool_anim->get_popup()->add_shortcut(ED_SHORTCUT("animation_player_editor/rename_animation", TTR("Rename...")), TOOL_RENAME_ANIM);
tool_anim->get_popup()->add_shortcut(ED_SHORTCUT("animation_player_editor/edit_transitions", TTR("Edit Transitions...")), TOOL_EDIT_TRANSITIONS);
@@ -1723,7 +1752,6 @@ AnimationPlayerEditor::AnimationPlayerEditor(EditorNode *p_editor, AnimationPlay
frame->connect("value_changed", callable_mp(this, &AnimationPlayerEditor::_seek_value_changed), make_binds(true, false));
scale->connect("text_submitted", callable_mp(this, &AnimationPlayerEditor::_scale_changed));
- renaming = false;
last_active = false;
timeline_position = 0;
@@ -1840,17 +1868,16 @@ bool AnimationPlayerEditorPlugin::handles(Object *p_object) const {
void AnimationPlayerEditorPlugin::make_visible(bool p_visible) {
if (p_visible) {
- editor->make_bottom_panel_item_visible(anim_editor);
+ EditorNode::get_singleton()->make_bottom_panel_item_visible(anim_editor);
anim_editor->set_process(true);
anim_editor->ensure_visibility();
}
}
-AnimationPlayerEditorPlugin::AnimationPlayerEditorPlugin(EditorNode *p_node) {
- editor = p_node;
- anim_editor = memnew(AnimationPlayerEditor(editor, this));
+AnimationPlayerEditorPlugin::AnimationPlayerEditorPlugin() {
+ anim_editor = memnew(AnimationPlayerEditor(this));
anim_editor->set_undo_redo(EditorNode::get_undo_redo());
- editor->add_bottom_panel_item(TTR("Animation"), anim_editor);
+ EditorNode::get_singleton()->add_bottom_panel_item(TTR("Animation"), anim_editor);
}
AnimationPlayerEditorPlugin::~AnimationPlayerEditorPlugin() {
diff --git a/editor/plugins/animation_player_editor_plugin.h b/editor/plugins/animation_player_editor_plugin.h
index 06dca11aff..5bb32e25e6 100644
--- a/editor/plugins/animation_player_editor_plugin.h
+++ b/editor/plugins/animation_player_editor_plugin.h
@@ -31,21 +31,21 @@
#ifndef ANIMATION_PLAYER_EDITOR_PLUGIN_H
#define ANIMATION_PLAYER_EDITOR_PLUGIN_H
-#include "editor/editor_node.h"
+#include "editor/animation_track_editor.h"
#include "editor/editor_plugin.h"
#include "scene/animation/animation_player.h"
#include "scene/gui/dialogs.h"
#include "scene/gui/slider.h"
#include "scene/gui/spin_box.h"
#include "scene/gui/texture_button.h"
+#include "scene/gui/tree.h"
-class AnimationTrackEditor;
+class EditorFileDialog;
class AnimationPlayerEditorPlugin;
class AnimationPlayerEditor : public VBoxContainer {
GDCLASS(AnimationPlayerEditor, VBoxContainer);
- EditorNode *editor;
AnimationPlayerEditorPlugin *plugin;
AnimationPlayer *player;
@@ -123,7 +123,7 @@ class AnimationPlayerEditor : public VBoxContainer {
ConfirmationDialog *name_dialog;
ConfirmationDialog *error_dialog;
- bool renaming;
+ int name_dialog_op = TOOL_NEW_ANIM;
bool updating;
bool updating_blends;
@@ -196,6 +196,7 @@ class AnimationPlayerEditor : public VBoxContainer {
void _list_changed();
void _update_animation();
void _update_player();
+ void _update_animation_list_icons();
void _blend_edited();
void _animation_player_changed(Object *p_pl);
@@ -243,14 +244,13 @@ public:
void edit(AnimationPlayer *p_player);
void forward_force_draw_over_viewport(Control *p_overlay);
- AnimationPlayerEditor(EditorNode *p_editor, AnimationPlayerEditorPlugin *p_plugin);
+ AnimationPlayerEditor(AnimationPlayerEditorPlugin *p_plugin);
};
class AnimationPlayerEditorPlugin : public EditorPlugin {
GDCLASS(AnimationPlayerEditorPlugin, EditorPlugin);
AnimationPlayerEditor *anim_editor;
- EditorNode *editor;
protected:
void _notification(int p_what);
@@ -272,7 +272,7 @@ public:
virtual void forward_canvas_force_draw_over_viewport(Control *p_overlay) override { anim_editor->forward_force_draw_over_viewport(p_overlay); }
virtual void forward_spatial_force_draw_over_viewport(Control *p_overlay) override { anim_editor->forward_force_draw_over_viewport(p_overlay); }
- AnimationPlayerEditorPlugin(EditorNode *p_node);
+ AnimationPlayerEditorPlugin();
~AnimationPlayerEditorPlugin();
};
diff --git a/editor/plugins/animation_state_machine_editor.cpp b/editor/plugins/animation_state_machine_editor.cpp
index f750c92fb3..2f94176e2a 100644
--- a/editor/plugins/animation_state_machine_editor.cpp
+++ b/editor/plugins/animation_state_machine_editor.cpp
@@ -35,6 +35,8 @@
#include "core/io/resource_loader.h"
#include "core/math/geometry_2d.h"
#include "core/os/keyboard.h"
+#include "editor/editor_file_dialog.h"
+#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "scene/animation/animation_blend_tree.h"
#include "scene/animation/animation_player.h"
@@ -106,7 +108,7 @@ void AnimationNodeStateMachineEditor::_state_machine_gui_input(const Ref<InputEv
continue; // nope
}
int idx = menu->get_item_count();
- menu->add_item(vformat("Add %s", name), idx);
+ menu->add_item(vformat(TTR("Add %s"), name), idx);
menu->set_item_metadata(idx, E);
}
Ref<AnimationNode> clipb = EditorSettings::get_singleton()->get_resource_clipboard();
@@ -882,169 +884,174 @@ void AnimationNodeStateMachineEditor::_update_graph() {
}
void AnimationNodeStateMachineEditor::_notification(int p_what) {
- if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED || p_what == NOTIFICATION_LAYOUT_DIRECTION_CHANGED || p_what == NOTIFICATION_TRANSLATION_CHANGED) {
- error_panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("bg"), SNAME("Tree")));
- error_label->add_theme_color_override("font_color", get_theme_color(SNAME("error_color"), SNAME("Editor")));
- panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("bg"), SNAME("Tree")));
-
- tool_select->set_icon(get_theme_icon(SNAME("ToolSelect"), SNAME("EditorIcons")));
- tool_create->set_icon(get_theme_icon(SNAME("ToolAddNode"), SNAME("EditorIcons")));
- tool_connect->set_icon(get_theme_icon(SNAME("ToolConnect"), SNAME("EditorIcons")));
-
- transition_mode->clear();
- transition_mode->add_icon_item(get_theme_icon(SNAME("TransitionImmediate"), SNAME("EditorIcons")), TTR("Immediate"));
- transition_mode->add_icon_item(get_theme_icon(SNAME("TransitionSync"), SNAME("EditorIcons")), TTR("Sync"));
- transition_mode->add_icon_item(get_theme_icon(SNAME("TransitionEnd"), SNAME("EditorIcons")), TTR("At End"));
-
- tool_erase->set_icon(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")));
- tool_autoplay->set_icon(get_theme_icon(SNAME("AutoPlay"), SNAME("EditorIcons")));
- tool_end->set_icon(get_theme_icon(SNAME("AutoEnd"), SNAME("EditorIcons")));
-
- play_mode->clear();
- play_mode->add_icon_item(get_theme_icon(SNAME("PlayTravel"), SNAME("EditorIcons")), TTR("Travel"));
- play_mode->add_icon_item(get_theme_icon(SNAME("Play"), SNAME("EditorIcons")), TTR("Immediate"));
- }
-
- if (p_what == NOTIFICATION_PROCESS) {
- String error;
-
- Ref<AnimationNodeStateMachinePlayback> playback = AnimationTreeEditor::get_singleton()->get_tree()->get(AnimationTreeEditor::get_singleton()->get_base_path() + "playback");
-
- if (error_time > 0) {
- error = error_text;
- error_time -= get_process_delta_time();
- } else if (!AnimationTreeEditor::get_singleton()->get_tree()->is_active()) {
- error = TTR("AnimationTree is inactive.\nActivate to enable playback, check node warnings if activation fails.");
- } else if (AnimationTreeEditor::get_singleton()->get_tree()->is_state_invalid()) {
- error = AnimationTreeEditor::get_singleton()->get_tree()->get_invalid_state_reason();
- /*} else if (state_machine->get_parent().is_valid() && state_machine->get_parent()->is_class("AnimationNodeStateMachine")) {
- if (state_machine->get_start_node() == StringName() || state_machine->get_end_node() == StringName()) {
- error = TTR("Start and end nodes are needed for a sub-transition.");
- }*/
- } else if (playback.is_null()) {
- error = vformat(TTR("No playback resource set at path: %s."), AnimationTreeEditor::get_singleton()->get_base_path() + "playback");
- }
-
- if (error != error_label->get_text()) {
- error_label->set_text(error);
- if (!error.is_empty()) {
- error_panel->show();
- } else {
- error_panel->hide();
+ switch (p_what) {
+ case NOTIFICATION_ENTER_TREE:
+ case NOTIFICATION_THEME_CHANGED:
+ case NOTIFICATION_LAYOUT_DIRECTION_CHANGED:
+ case NOTIFICATION_TRANSLATION_CHANGED: {
+ error_panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("bg"), SNAME("Tree")));
+ error_label->add_theme_color_override("font_color", get_theme_color(SNAME("error_color"), SNAME("Editor")));
+ panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("bg"), SNAME("Tree")));
+
+ tool_select->set_icon(get_theme_icon(SNAME("ToolSelect"), SNAME("EditorIcons")));
+ tool_create->set_icon(get_theme_icon(SNAME("ToolAddNode"), SNAME("EditorIcons")));
+ tool_connect->set_icon(get_theme_icon(SNAME("ToolConnect"), SNAME("EditorIcons")));
+
+ transition_mode->clear();
+ transition_mode->add_icon_item(get_theme_icon(SNAME("TransitionImmediate"), SNAME("EditorIcons")), TTR("Immediate"));
+ transition_mode->add_icon_item(get_theme_icon(SNAME("TransitionSync"), SNAME("EditorIcons")), TTR("Sync"));
+ transition_mode->add_icon_item(get_theme_icon(SNAME("TransitionEnd"), SNAME("EditorIcons")), TTR("At End"));
+
+ tool_erase->set_icon(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")));
+ tool_autoplay->set_icon(get_theme_icon(SNAME("AutoPlay"), SNAME("EditorIcons")));
+ tool_end->set_icon(get_theme_icon(SNAME("AutoEnd"), SNAME("EditorIcons")));
+
+ play_mode->clear();
+ play_mode->add_icon_item(get_theme_icon(SNAME("PlayTravel"), SNAME("EditorIcons")), TTR("Travel"));
+ play_mode->add_icon_item(get_theme_icon(SNAME("Play"), SNAME("EditorIcons")), TTR("Immediate"));
+ } break;
+
+ case NOTIFICATION_PROCESS: {
+ String error;
+
+ Ref<AnimationNodeStateMachinePlayback> playback = AnimationTreeEditor::get_singleton()->get_tree()->get(AnimationTreeEditor::get_singleton()->get_base_path() + "playback");
+
+ if (error_time > 0) {
+ error = error_text;
+ error_time -= get_process_delta_time();
+ } else if (!AnimationTreeEditor::get_singleton()->get_tree()->is_active()) {
+ error = TTR("AnimationTree is inactive.\nActivate to enable playback, check node warnings if activation fails.");
+ } else if (AnimationTreeEditor::get_singleton()->get_tree()->is_state_invalid()) {
+ error = AnimationTreeEditor::get_singleton()->get_tree()->get_invalid_state_reason();
+ /*} else if (state_machine->get_parent().is_valid() && state_machine->get_parent()->is_class("AnimationNodeStateMachine")) {
+ if (state_machine->get_start_node() == StringName() || state_machine->get_end_node() == StringName()) {
+ error = TTR("Start and end nodes are needed for a sub-transition.");
+ }*/
+ } else if (playback.is_null()) {
+ error = vformat(TTR("No playback resource set at path: %s."), AnimationTreeEditor::get_singleton()->get_base_path() + "playback");
}
- }
- for (int i = 0; i < transition_lines.size(); i++) {
- int tidx = -1;
- for (int j = 0; j < state_machine->get_transition_count(); j++) {
- if (transition_lines[i].from_node == state_machine->get_transition_from(j) && transition_lines[i].to_node == state_machine->get_transition_to(j)) {
- tidx = j;
- break;
+ if (error != error_label->get_text()) {
+ error_label->set_text(error);
+ if (!error.is_empty()) {
+ error_panel->show();
+ } else {
+ error_panel->hide();
}
}
- if (tidx == -1) { //missing transition, should redraw
- state_machine_draw->update();
- break;
- }
+ for (int i = 0; i < transition_lines.size(); i++) {
+ int tidx = -1;
+ for (int j = 0; j < state_machine->get_transition_count(); j++) {
+ if (transition_lines[i].from_node == state_machine->get_transition_from(j) && transition_lines[i].to_node == state_machine->get_transition_to(j)) {
+ tidx = j;
+ break;
+ }
+ }
- if (transition_lines[i].disabled != state_machine->get_transition(tidx)->is_disabled()) {
- state_machine_draw->update();
- break;
- }
+ if (tidx == -1) { //missing transition, should redraw
+ state_machine_draw->update();
+ break;
+ }
- if (transition_lines[i].auto_advance != state_machine->get_transition(tidx)->has_auto_advance()) {
- state_machine_draw->update();
- break;
- }
+ if (transition_lines[i].disabled != state_machine->get_transition(tidx)->is_disabled()) {
+ state_machine_draw->update();
+ break;
+ }
- if (transition_lines[i].advance_condition_name != state_machine->get_transition(tidx)->get_advance_condition_name()) {
- state_machine_draw->update();
- break;
- }
+ if (transition_lines[i].auto_advance != state_machine->get_transition(tidx)->has_auto_advance()) {
+ state_machine_draw->update();
+ break;
+ }
- if (transition_lines[i].mode != state_machine->get_transition(tidx)->get_switch_mode()) {
- state_machine_draw->update();
- break;
- }
+ if (transition_lines[i].advance_condition_name != state_machine->get_transition(tidx)->get_advance_condition_name()) {
+ state_machine_draw->update();
+ break;
+ }
- bool acstate = transition_lines[i].advance_condition_name != StringName() && bool(AnimationTreeEditor::get_singleton()->get_tree()->get(AnimationTreeEditor::get_singleton()->get_base_path() + String(transition_lines[i].advance_condition_name)));
+ if (transition_lines[i].mode != state_machine->get_transition(tidx)->get_switch_mode()) {
+ state_machine_draw->update();
+ break;
+ }
- if (transition_lines[i].advance_condition_state != acstate) {
- state_machine_draw->update();
- break;
+ bool acstate = transition_lines[i].advance_condition_name != StringName() && bool(AnimationTreeEditor::get_singleton()->get_tree()->get(AnimationTreeEditor::get_singleton()->get_base_path() + String(transition_lines[i].advance_condition_name)));
+
+ if (transition_lines[i].advance_condition_state != acstate) {
+ state_machine_draw->update();
+ break;
+ }
}
- }
- bool same_travel_path = true;
- Vector<StringName> tp;
- bool is_playing = false;
- StringName current_node;
- StringName blend_from_node;
- play_pos = 0;
- current_length = 0;
-
- if (playback.is_valid()) {
- tp = playback->get_travel_path();
- is_playing = playback->is_playing();
- current_node = playback->get_current_node();
- blend_from_node = playback->get_blend_from_node();
- play_pos = playback->get_current_play_pos();
- current_length = playback->get_current_length();
- }
+ bool same_travel_path = true;
+ Vector<StringName> tp;
+ bool is_playing = false;
+ StringName current_node;
+ StringName blend_from_node;
+ play_pos = 0;
+ current_length = 0;
+
+ if (playback.is_valid()) {
+ tp = playback->get_travel_path();
+ is_playing = playback->is_playing();
+ current_node = playback->get_current_node();
+ blend_from_node = playback->get_blend_from_node();
+ play_pos = playback->get_current_play_pos();
+ current_length = playback->get_current_length();
+ }
- {
- if (last_travel_path.size() != tp.size()) {
- same_travel_path = false;
- } else {
- for (int i = 0; i < last_travel_path.size(); i++) {
- if (last_travel_path[i] != tp[i]) {
- same_travel_path = false;
- break;
+ {
+ if (last_travel_path.size() != tp.size()) {
+ same_travel_path = false;
+ } else {
+ for (int i = 0; i < last_travel_path.size(); i++) {
+ if (last_travel_path[i] != tp[i]) {
+ same_travel_path = false;
+ break;
+ }
}
}
}
- }
- //update if travel state changed
- if (!same_travel_path || last_active != is_playing || last_current_node != current_node || last_blend_from_node != blend_from_node) {
- state_machine_draw->update();
- last_travel_path = tp;
- last_current_node = current_node;
- last_active = is_playing;
- last_blend_from_node = blend_from_node;
- state_machine_play_pos->update();
- }
+ //update if travel state changed
+ if (!same_travel_path || last_active != is_playing || last_current_node != current_node || last_blend_from_node != blend_from_node) {
+ state_machine_draw->update();
+ last_travel_path = tp;
+ last_current_node = current_node;
+ last_active = is_playing;
+ last_blend_from_node = blend_from_node;
+ state_machine_play_pos->update();
+ }
- {
- if (current_node != StringName() && state_machine->has_node(current_node)) {
- String next = current_node;
- Ref<AnimationNodeStateMachine> anodesm = state_machine->get_node(next);
- Ref<AnimationNodeStateMachinePlayback> current_node_playback;
-
- while (anodesm.is_valid()) {
- current_node_playback = AnimationTreeEditor::get_singleton()->get_tree()->get(AnimationTreeEditor::get_singleton()->get_base_path() + next + "/playback");
- next += "/" + current_node_playback->get_current_node();
- anodesm = anodesm->get_node(current_node_playback->get_current_node());
- }
+ {
+ if (current_node != StringName() && state_machine->has_node(current_node)) {
+ String next = current_node;
+ Ref<AnimationNodeStateMachine> anodesm = state_machine->get_node(next);
+ Ref<AnimationNodeStateMachinePlayback> current_node_playback;
- // when current_node is a state machine, use playback of current_node to set play_pos
- if (current_node_playback.is_valid()) {
- play_pos = current_node_playback->get_current_play_pos();
- current_length = current_node_playback->get_current_length();
+ while (anodesm.is_valid()) {
+ current_node_playback = AnimationTreeEditor::get_singleton()->get_tree()->get(AnimationTreeEditor::get_singleton()->get_base_path() + next + "/playback");
+ next += "/" + current_node_playback->get_current_node();
+ anodesm = anodesm->get_node(current_node_playback->get_current_node());
+ }
+
+ // when current_node is a state machine, use playback of current_node to set play_pos
+ if (current_node_playback.is_valid()) {
+ play_pos = current_node_playback->get_current_play_pos();
+ current_length = current_node_playback->get_current_length();
+ }
}
}
- }
- if (last_play_pos != play_pos) {
- last_play_pos = play_pos;
- state_machine_play_pos->update();
- }
- }
+ if (last_play_pos != play_pos) {
+ last_play_pos = play_pos;
+ state_machine_play_pos->update();
+ }
+ } break;
- if (p_what == NOTIFICATION_VISIBILITY_CHANGED) {
- over_node = StringName();
- set_process(is_visible_in_tree());
+ case NOTIFICATION_VISIBILITY_CHANGED: {
+ over_node = StringName();
+ set_process(is_visible_in_tree());
+ } break;
}
}
diff --git a/editor/plugins/animation_state_machine_editor.h b/editor/plugins/animation_state_machine_editor.h
index 8970e3e062..208bd27f8e 100644
--- a/editor/plugins/animation_state_machine_editor.h
+++ b/editor/plugins/animation_state_machine_editor.h
@@ -31,7 +31,6 @@
#ifndef ANIMATION_STATE_MACHINE_EDITOR_H
#define ANIMATION_STATE_MACHINE_EDITOR_H
-#include "editor/editor_node.h"
#include "editor/editor_plugin.h"
#include "editor/plugins/animation_tree_editor_plugin.h"
#include "editor/property_editor.h"
@@ -41,6 +40,8 @@
#include "scene/gui/popup.h"
#include "scene/gui/tree.h"
+class EditorFileDialog;
+
class AnimationNodeStateMachineEditor : public AnimationTreeNodeEditorPlugin {
GDCLASS(AnimationNodeStateMachineEditor, AnimationTreeNodeEditorPlugin);
diff --git a/editor/plugins/animation_tree_editor_plugin.cpp b/editor/plugins/animation_tree_editor_plugin.cpp
index adfea236d3..7ea6906d72 100644
--- a/editor/plugins/animation_tree_editor_plugin.cpp
+++ b/editor/plugins/animation_tree_editor_plugin.cpp
@@ -39,6 +39,8 @@
#include "core/io/resource_loader.h"
#include "core/math/delaunay_2d.h"
#include "core/os/keyboard.h"
+#include "editor/editor_file_dialog.h"
+#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "scene/animation/animation_blend_tree.h"
#include "scene/animation/animation_player.h"
@@ -143,19 +145,21 @@ void AnimationTreeEditor::enter_editor(const String &p_path) {
}
void AnimationTreeEditor::_notification(int p_what) {
- if (p_what == NOTIFICATION_PROCESS) {
- ObjectID root;
- if (tree && tree->get_tree_root().is_valid()) {
- root = tree->get_tree_root()->get_instance_id();
- }
+ switch (p_what) {
+ case NOTIFICATION_PROCESS: {
+ ObjectID root;
+ if (tree && tree->get_tree_root().is_valid()) {
+ root = tree->get_tree_root()->get_instance_id();
+ }
- if (root != current_root) {
- edit_path(Vector<String>());
- }
+ if (root != current_root) {
+ edit_path(Vector<String>());
+ }
- if (button_path.size() != edited_path.size()) {
- edit_path(edited_path);
- }
+ if (button_path.size() != edited_path.size()) {
+ edit_path(edited_path);
+ }
+ } break;
}
}
@@ -257,23 +261,22 @@ void AnimationTreeEditorPlugin::make_visible(bool p_visible) {
//editor->hide_animation_player_editors();
//editor->animation_panel_make_visible(true);
button->show();
- editor->make_bottom_panel_item_visible(anim_tree_editor);
+ EditorNode::get_singleton()->make_bottom_panel_item_visible(anim_tree_editor);
anim_tree_editor->set_process(true);
} else {
if (anim_tree_editor->is_visible_in_tree()) {
- editor->hide_bottom_panel();
+ EditorNode::get_singleton()->hide_bottom_panel();
}
button->hide();
anim_tree_editor->set_process(false);
}
}
-AnimationTreeEditorPlugin::AnimationTreeEditorPlugin(EditorNode *p_node) {
- editor = p_node;
+AnimationTreeEditorPlugin::AnimationTreeEditorPlugin() {
anim_tree_editor = memnew(AnimationTreeEditor);
anim_tree_editor->set_custom_minimum_size(Size2(0, 300) * EDSCALE);
- button = editor->add_bottom_panel_item(TTR("AnimationTree"), anim_tree_editor);
+ button = EditorNode::get_singleton()->add_bottom_panel_item(TTR("AnimationTree"), anim_tree_editor);
button->hide();
}
diff --git a/editor/plugins/animation_tree_editor_plugin.h b/editor/plugins/animation_tree_editor_plugin.h
index 14c5658478..5442584a40 100644
--- a/editor/plugins/animation_tree_editor_plugin.h
+++ b/editor/plugins/animation_tree_editor_plugin.h
@@ -31,7 +31,6 @@
#ifndef ANIMATION_TREE_EDITOR_PLUGIN_H
#define ANIMATION_TREE_EDITOR_PLUGIN_H
-#include "editor/editor_node.h"
#include "editor/editor_plugin.h"
#include "editor/property_editor.h"
#include "scene/animation/animation_tree.h"
@@ -40,6 +39,8 @@
#include "scene/gui/popup.h"
#include "scene/gui/tree.h"
+class EditorFileDialog;
+
class AnimationTreeNodeEditorPlugin : public VBoxContainer {
GDCLASS(AnimationTreeNodeEditorPlugin, VBoxContainer);
@@ -96,7 +97,6 @@ class AnimationTreeEditorPlugin : public EditorPlugin {
GDCLASS(AnimationTreeEditorPlugin, EditorPlugin);
AnimationTreeEditor *anim_tree_editor;
- EditorNode *editor;
Button *button;
public:
@@ -106,7 +106,7 @@ public:
virtual bool handles(Object *p_object) const override;
virtual void make_visible(bool p_visible) override;
- AnimationTreeEditorPlugin(EditorNode *p_node);
+ AnimationTreeEditorPlugin();
~AnimationTreeEditorPlugin();
};
diff --git a/editor/plugins/asset_library_editor_plugin.cpp b/editor/plugins/asset_library_editor_plugin.cpp
index 7199f69f0b..50f253b167 100644
--- a/editor/plugins/asset_library_editor_plugin.cpp
+++ b/editor/plugins/asset_library_editor_plugin.cpp
@@ -34,7 +34,9 @@
#include "core/io/json.h"
#include "core/os/keyboard.h"
#include "core/version.h"
+#include "editor/editor_file_dialog.h"
#include "editor/editor_node.h"
+#include "editor/editor_paths.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
#include "editor/project_settings_editor.h"
@@ -42,8 +44,8 @@
static inline void setup_http_request(HTTPRequest *request) {
request->set_use_threads(EDITOR_DEF("asset_library/use_threads", true));
- const String proxy_host = EDITOR_DEF("network/http_proxy/host", "");
- const int proxy_port = EDITOR_DEF("network/http_proxy/port", -1);
+ const String proxy_host = EDITOR_GET("network/http_proxy/host");
+ const int proxy_port = EDITOR_GET("network/http_proxy/port");
request->set_http_proxy(proxy_host, proxy_port);
request->set_https_proxy(proxy_host, proxy_port);
}
@@ -66,11 +68,13 @@ void EditorAssetLibraryItem::set_image(int p_type, int p_index, const Ref<Textur
}
void EditorAssetLibraryItem::_notification(int p_what) {
- if (p_what == NOTIFICATION_ENTER_TREE) {
- icon->set_normal_texture(get_theme_icon(SNAME("ProjectIconLoading"), SNAME("EditorIcons")));
- category->add_theme_color_override("font_color", Color(0.5, 0.5, 0.5));
- author->add_theme_color_override("font_color", Color(0.5, 0.5, 0.5));
- price->add_theme_color_override("font_color", Color(0.5, 0.5, 0.5));
+ switch (p_what) {
+ case NOTIFICATION_ENTER_TREE: {
+ icon->set_normal_texture(get_theme_icon(SNAME("ProjectIconLoading"), SNAME("EditorIcons")));
+ category->add_theme_color_override("font_color", Color(0.5, 0.5, 0.5));
+ author->add_theme_color_override("font_color", Color(0.5, 0.5, 0.5));
+ price->add_theme_color_override("font_color", Color(0.5, 0.5, 0.5));
+ } break;
}
}
@@ -404,6 +408,7 @@ void EditorAssetLibraryItemDownload::_notification(int p_what) {
status->add_theme_color_override("font_color", get_theme_color(SNAME("status_color"), SNAME("AssetLib")));
dismiss_button->set_normal_texture(get_theme_icon(SNAME("dismiss"), SNAME("AssetLib")));
} break;
+
case NOTIFICATION_PROCESS: {
// Make the progress bar visible again when retrying the download.
progress->set_modulate(Color(1, 1, 1, 1));
@@ -574,6 +579,7 @@ void EditorAssetLibrary::_notification(int p_what) {
case NOTIFICATION_READY: {
error_label->raise();
} break;
+
case NOTIFICATION_ENTER_TREE:
case NOTIFICATION_THEME_CHANGED: {
error_tr->set_texture(get_theme_icon(SNAME("Error"), SNAME("EditorIcons")));
@@ -582,6 +588,7 @@ void EditorAssetLibrary::_notification(int p_what) {
downloads_scroll->add_theme_style_override("bg", get_theme_stylebox(SNAME("bg"), SNAME("Tree")));
error_label->add_theme_color_override("color", get_theme_color(SNAME("error_color"), SNAME("Editor")));
} break;
+
case NOTIFICATION_VISIBILITY_CHANGED: {
if (is_visible()) {
// Focus the search box automatically when switching to the Templates tab (in the Project Manager)
@@ -594,6 +601,7 @@ void EditorAssetLibrary::_notification(int p_what) {
}
}
} break;
+
case NOTIFICATION_PROCESS: {
HTTPClient::Status s = request->get_http_client_status();
const bool loading = s != HTTPClient::STATUS_DISCONNECTED;
@@ -610,6 +618,7 @@ void EditorAssetLibrary::_notification(int p_what) {
}
} break;
+
case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
_update_repository_options();
setup_http_request(request);
@@ -1561,11 +1570,10 @@ void AssetLibraryEditorPlugin::make_visible(bool p_visible) {
}
}
-AssetLibraryEditorPlugin::AssetLibraryEditorPlugin(EditorNode *p_node) {
- editor = p_node;
+AssetLibraryEditorPlugin::AssetLibraryEditorPlugin() {
addon_library = memnew(EditorAssetLibrary);
addon_library->set_v_size_flags(Control::SIZE_EXPAND_FILL);
- editor->get_main_control()->add_child(addon_library);
+ EditorNode::get_singleton()->get_main_control()->add_child(addon_library);
addon_library->set_anchors_and_offsets_preset(Control::PRESET_WIDE);
addon_library->hide();
}
diff --git a/editor/plugins/asset_library_editor_plugin.h b/editor/plugins/asset_library_editor_plugin.h
index 29d26411f3..493ffc4033 100644
--- a/editor/plugins/asset_library_editor_plugin.h
+++ b/editor/plugins/asset_library_editor_plugin.h
@@ -316,7 +316,6 @@ class AssetLibraryEditorPlugin : public EditorPlugin {
GDCLASS(AssetLibraryEditorPlugin, EditorPlugin);
EditorAssetLibrary *addon_library;
- EditorNode *editor;
public:
virtual String get_name() const override { return "AssetLib"; }
@@ -328,7 +327,7 @@ public:
//virtual Dictionary get_state() const;
//virtual void set_state(const Dictionary& p_state);
- AssetLibraryEditorPlugin(EditorNode *p_node);
+ AssetLibraryEditorPlugin();
~AssetLibraryEditorPlugin();
};
diff --git a/editor/plugins/audio_stream_editor_plugin.cpp b/editor/plugins/audio_stream_editor_plugin.cpp
index 086d5474ba..a60e49ca9d 100644
--- a/editor/plugins/audio_stream_editor_plugin.cpp
+++ b/editor/plugins/audio_stream_editor_plugin.cpp
@@ -34,33 +34,37 @@
#include "core/io/resource_loader.h"
#include "core/os/keyboard.h"
#include "editor/audio_stream_preview.h"
+#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
void AudioStreamEditor::_notification(int p_what) {
- if (p_what == NOTIFICATION_READY) {
- AudioStreamPreviewGenerator::get_singleton()->connect("preview_updated", callable_mp(this, &AudioStreamEditor::_preview_changed));
- }
-
- if (p_what == NOTIFICATION_THEME_CHANGED || p_what == NOTIFICATION_ENTER_TREE) {
- _play_button->set_icon(get_theme_icon(SNAME("MainPlay"), SNAME("EditorIcons")));
- _stop_button->set_icon(get_theme_icon(SNAME("Stop"), SNAME("EditorIcons")));
- _preview->set_color(get_theme_color(SNAME("dark_color_2"), SNAME("Editor")));
- set_color(get_theme_color(SNAME("dark_color_1"), SNAME("Editor")));
-
- _indicator->update();
- _preview->update();
- }
-
- if (p_what == NOTIFICATION_PROCESS) {
- _current = _player->get_playback_position();
- _indicator->update();
- }
-
- if (p_what == NOTIFICATION_VISIBILITY_CHANGED) {
- if (!is_visible_in_tree()) {
- _stop();
- }
+ switch (p_what) {
+ case NOTIFICATION_READY: {
+ AudioStreamPreviewGenerator::get_singleton()->connect("preview_updated", callable_mp(this, &AudioStreamEditor::_preview_changed));
+ } break;
+
+ case NOTIFICATION_THEME_CHANGED:
+ case NOTIFICATION_ENTER_TREE: {
+ _play_button->set_icon(get_theme_icon(SNAME("MainPlay"), SNAME("EditorIcons")));
+ _stop_button->set_icon(get_theme_icon(SNAME("Stop"), SNAME("EditorIcons")));
+ _preview->set_color(get_theme_color(SNAME("dark_color_2"), SNAME("Editor")));
+ set_color(get_theme_color(SNAME("dark_color_1"), SNAME("Editor")));
+
+ _indicator->update();
+ _preview->update();
+ } break;
+
+ case NOTIFICATION_PROCESS: {
+ _current = _player->get_playback_position();
+ _indicator->update();
+ } break;
+
+ case NOTIFICATION_VISIBILITY_CHANGED: {
+ if (!is_visible_in_tree()) {
+ _stop();
+ }
+ } break;
}
}
@@ -271,8 +275,7 @@ void AudioStreamEditorPlugin::make_visible(bool p_visible) {
audio_editor->set_visible(p_visible);
}
-AudioStreamEditorPlugin::AudioStreamEditorPlugin(EditorNode *p_node) {
- editor = p_node;
+AudioStreamEditorPlugin::AudioStreamEditorPlugin() {
audio_editor = memnew(AudioStreamEditor);
add_control_to_container(CONTAINER_PROPERTY_EDITOR_BOTTOM, audio_editor);
audio_editor->hide();
diff --git a/editor/plugins/audio_stream_editor_plugin.h b/editor/plugins/audio_stream_editor_plugin.h
index db0e204616..2478210430 100644
--- a/editor/plugins/audio_stream_editor_plugin.h
+++ b/editor/plugins/audio_stream_editor_plugin.h
@@ -31,7 +31,6 @@
#ifndef AUDIO_STREAM_EDITOR_PLUGIN_H
#define AUDIO_STREAM_EDITOR_PLUGIN_H
-#include "editor/editor_node.h"
#include "editor/editor_plugin.h"
#include "scene/audio/audio_stream_player.h"
#include "scene/gui/color_rect.h"
@@ -77,7 +76,6 @@ class AudioStreamEditorPlugin : public EditorPlugin {
GDCLASS(AudioStreamEditorPlugin, EditorPlugin);
AudioStreamEditor *audio_editor;
- EditorNode *editor;
public:
virtual String get_name() const override { return "Audio"; }
@@ -86,7 +84,7 @@ public:
virtual bool handles(Object *p_object) const override;
virtual void make_visible(bool p_visible) override;
- AudioStreamEditorPlugin(EditorNode *p_node);
+ AudioStreamEditorPlugin();
~AudioStreamEditorPlugin();
};
diff --git a/editor/plugins/audio_stream_randomizer_editor_plugin.cpp b/editor/plugins/audio_stream_randomizer_editor_plugin.cpp
new file mode 100644
index 0000000000..9e551ae0ed
--- /dev/null
+++ b/editor/plugins/audio_stream_randomizer_editor_plugin.cpp
@@ -0,0 +1,121 @@
+/*************************************************************************/
+/* audio_stream_randomizer_editor_plugin.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "audio_stream_randomizer_editor_plugin.h"
+
+#include "editor/editor_node.h"
+
+void AudioStreamRandomizerEditorPlugin::edit(Object *p_object) {
+}
+
+bool AudioStreamRandomizerEditorPlugin::handles(Object *p_object) const {
+ return false;
+}
+
+void AudioStreamRandomizerEditorPlugin::make_visible(bool p_visible) {
+}
+
+void AudioStreamRandomizerEditorPlugin::_move_stream_array_element(Object *p_undo_redo, Object *p_edited, String p_array_prefix, int p_from_index, int p_to_pos) {
+ UndoRedo *undo_redo = Object::cast_to<UndoRedo>(p_undo_redo);
+ ERR_FAIL_COND(!undo_redo);
+
+ AudioStreamRandomizer *randomizer = Object::cast_to<AudioStreamRandomizer>(p_edited);
+ if (!randomizer) {
+ return;
+ }
+
+ // Compute the array indices to save.
+ int begin = 0;
+ int end;
+ if (p_array_prefix == "stream_") {
+ end = randomizer->get_streams_count();
+ } else {
+ ERR_FAIL_MSG("Invalid array prefix for AudioStreamRandomizer.");
+ }
+ if (p_from_index < 0) {
+ // Adding new.
+ if (p_to_pos >= 0) {
+ begin = p_to_pos;
+ } else {
+ end = 0; // Nothing to save when adding at the end.
+ }
+ } else if (p_to_pos < 0) {
+ // Removing.
+ begin = p_from_index;
+ } else {
+ // Moving.
+ begin = MIN(p_from_index, p_to_pos);
+ end = MIN(MAX(p_from_index, p_to_pos) + 1, end);
+ }
+
+#define ADD_UNDO(obj, property) undo_redo->add_undo_property(obj, property, obj->get(property));
+ // Save layers' properties.
+ if (p_from_index < 0) {
+ undo_redo->add_undo_method(randomizer, "remove_stream", p_to_pos < 0 ? randomizer->get_streams_count() : p_to_pos);
+ } else if (p_to_pos < 0) {
+ undo_redo->add_undo_method(randomizer, "add_stream", p_from_index);
+ }
+
+ List<PropertyInfo> properties;
+ randomizer->get_property_list(&properties);
+ for (PropertyInfo pi : properties) {
+ if (pi.name.begins_with(p_array_prefix)) {
+ String str = pi.name.trim_prefix(p_array_prefix);
+ int to_char_index = 0;
+ while (to_char_index < str.length()) {
+ if (str[to_char_index] < '0' || str[to_char_index] > '9') {
+ break;
+ }
+ to_char_index++;
+ }
+ if (to_char_index > 0) {
+ int array_index = str.left(to_char_index).to_int();
+ if (array_index >= begin && array_index < end) {
+ ADD_UNDO(randomizer, pi.name);
+ }
+ }
+ }
+ }
+#undef ADD_UNDO
+
+ if (p_from_index < 0) {
+ undo_redo->add_do_method(randomizer, "add_stream", p_to_pos);
+ } else if (p_to_pos < 0) {
+ undo_redo->add_do_method(randomizer, "remove_stream", p_from_index);
+ } else {
+ undo_redo->add_do_method(randomizer, "move_stream", p_from_index, p_to_pos);
+ }
+}
+
+AudioStreamRandomizerEditorPlugin::AudioStreamRandomizerEditorPlugin() {
+ EditorNode::get_singleton()->get_editor_data().add_move_array_element_function(SNAME("AudioStreamRandomizer"), callable_mp(this, &AudioStreamRandomizerEditorPlugin::_move_stream_array_element));
+}
+
+AudioStreamRandomizerEditorPlugin::~AudioStreamRandomizerEditorPlugin() {}
diff --git a/editor/plugins/audio_stream_randomizer_editor_plugin.h b/editor/plugins/audio_stream_randomizer_editor_plugin.h
new file mode 100644
index 0000000000..7e509dc670
--- /dev/null
+++ b/editor/plugins/audio_stream_randomizer_editor_plugin.h
@@ -0,0 +1,54 @@
+/*************************************************************************/
+/* audio_stream_randomizer_editor_plugin.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef AUDIO_STREAM_RANDOMIZER_EDITOR_PLUGIN_H
+#define AUDIO_STREAM_RANDOMIZER_EDITOR_PLUGIN_H
+
+#include "editor/editor_plugin.h"
+#include "servers/audio/audio_stream.h"
+
+class AudioStreamRandomizerEditorPlugin : public EditorPlugin {
+ GDCLASS(AudioStreamRandomizerEditorPlugin, EditorPlugin);
+
+private:
+ void _move_stream_array_element(Object *p_undo_redo, Object *p_edited, String p_array_prefix, int p_from_index, int p_to_pos);
+
+public:
+ virtual String get_name() const override { return "AudioStreamRandomizer"; }
+ bool has_main_screen() const override { return false; }
+ virtual void edit(Object *p_object) override;
+ virtual bool handles(Object *p_object) const override;
+ virtual void make_visible(bool p_visible) override;
+
+ AudioStreamRandomizerEditorPlugin();
+ ~AudioStreamRandomizerEditorPlugin();
+};
+
+#endif // AUDIO_STREAM_RANDOMIZER_EDITOR_PLUGIN_H
diff --git a/editor/plugins/camera_3d_editor_plugin.cpp b/editor/plugins/camera_3d_editor_plugin.cpp
index 7c920fa15e..141837244a 100644
--- a/editor/plugins/camera_3d_editor_plugin.cpp
+++ b/editor/plugins/camera_3d_editor_plugin.cpp
@@ -30,6 +30,7 @@
#include "camera_3d_editor_plugin.h"
+#include "editor/editor_node.h"
#include "node_3d_editor_plugin.h"
void Camera3DEditor::_node_removed(Node *p_node) {
@@ -95,10 +96,9 @@ void Camera3DEditorPlugin::make_visible(bool p_visible) {
}
}
-Camera3DEditorPlugin::Camera3DEditorPlugin(EditorNode *p_node) {
- editor = p_node;
+Camera3DEditorPlugin::Camera3DEditorPlugin() {
/* camera_editor = memnew( CameraEditor );
- editor->get_main_control()->add_child(camera_editor);
+ EditorNode::get_singleton()->get_main_control()->add_child(camera_editor);
camera_editor->set_anchor(SIDE_LEFT,Control::ANCHOR_END);
camera_editor->set_anchor(SIDE_RIGHT,Control::ANCHOR_END);
diff --git a/editor/plugins/camera_3d_editor_plugin.h b/editor/plugins/camera_3d_editor_plugin.h
index e175a931b0..c1f71d3b1b 100644
--- a/editor/plugins/camera_3d_editor_plugin.h
+++ b/editor/plugins/camera_3d_editor_plugin.h
@@ -31,7 +31,6 @@
#ifndef CAMERA_EDITOR_PLUGIN_H
#define CAMERA_EDITOR_PLUGIN_H
-#include "editor/editor_node.h"
#include "editor/editor_plugin.h"
#include "scene/3d/camera_3d.h"
@@ -57,7 +56,6 @@ class Camera3DEditorPlugin : public EditorPlugin {
GDCLASS(Camera3DEditorPlugin, EditorPlugin);
//CameraEditor *camera_editor;
- EditorNode *editor;
public:
virtual String get_name() const override { return "Camera3D"; }
@@ -66,7 +64,7 @@ public:
virtual bool handles(Object *p_object) const override;
virtual void make_visible(bool p_visible) override;
- Camera3DEditorPlugin(EditorNode *p_node);
+ Camera3DEditorPlugin();
~Camera3DEditorPlugin();
};
diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp
index d496804bf2..75f97efdbc 100644
--- a/editor/plugins/canvas_item_editor_plugin.cpp
+++ b/editor/plugins/canvas_item_editor_plugin.cpp
@@ -39,8 +39,10 @@
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_toaster.h"
#include "editor/plugins/animation_player_editor_plugin.h"
#include "editor/plugins/script_editor_plugin.h"
+#include "editor/scene_tree_dock.h"
#include "scene/2d/cpu_particles_2d.h"
#include "scene/2d/gpu_particles_2d.h"
#include "scene/2d/light_2d.h"
@@ -623,7 +625,7 @@ void CanvasItemEditor::_find_canvas_items_at_pos(const Point2 &p_pos, Node *p_no
}
void CanvasItemEditor::_get_canvas_items_at_pos(const Point2 &p_pos, Vector<_SelectResult> &r_items, bool p_allow_locked) {
- Node *scene = editor->get_edited_scene();
+ Node *scene = EditorNode::get_singleton()->get_edited_scene();
_find_canvas_items_at_pos(p_pos, scene, r_items);
@@ -676,7 +678,7 @@ void CanvasItemEditor::_find_canvas_items_in_rect(const Rect2 &p_rect, Node *p_n
}
CanvasItem *canvas_item = Object::cast_to<CanvasItem>(p_node);
- Node *scene = editor->get_edited_scene();
+ Node *scene = EditorNode::get_singleton()->get_edited_scene();
bool editable = p_node == scene || p_node->get_owner() == scene || p_node == scene->get_deepest_editable_node(p_node);
bool lock_children = p_node->has_meta("_edit_group_") && p_node->get_meta("_edit_group_");
@@ -725,7 +727,7 @@ bool CanvasItemEditor::_select_click_on_item(CanvasItem *item, Point2 p_click_po
still_selected = false;
if (editor_selection->get_selected_node_list().size() == 1) {
- editor->push_item(editor_selection->get_selected_node_list()[0]);
+ EditorNode::get_singleton()->push_item(editor_selection->get_selected_node_list()[0]);
}
} else {
// Add the item to the selection
@@ -739,7 +741,7 @@ bool CanvasItemEditor::_select_click_on_item(CanvasItem *item, Point2 p_click_po
// Reselect
if (Engine::get_singleton()->is_editor_hint()) {
selected_from_canvas = true;
- editor->call("edit_node", item);
+ EditorNode::get_singleton()->edit_node(item);
}
}
}
@@ -747,11 +749,11 @@ bool CanvasItemEditor::_select_click_on_item(CanvasItem *item, Point2 p_click_po
return still_selected;
}
-List<CanvasItem *> CanvasItemEditor::_get_edited_canvas_items(bool retreive_locked, bool remove_canvas_item_if_parent_in_selection) {
+List<CanvasItem *> CanvasItemEditor::_get_edited_canvas_items(bool retrieve_locked, bool remove_canvas_item_if_parent_in_selection) {
List<CanvasItem *> selection;
for (const KeyValue<Node *, Object *> &E : editor_selection->get_selection()) {
CanvasItem *canvas_item = Object::cast_to<CanvasItem>(E.key);
- if (canvas_item && canvas_item->is_visible_in_tree() && canvas_item->get_viewport() == EditorNode::get_singleton()->get_scene_root() && (retreive_locked || !_is_node_locked(canvas_item))) {
+ if (canvas_item && canvas_item->is_visible_in_tree() && canvas_item->get_viewport() == EditorNode::get_singleton()->get_scene_root() && (retrieve_locked || !_is_node_locked(canvas_item))) {
CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item);
if (se) {
selection.push_back(canvas_item);
@@ -1161,25 +1163,25 @@ bool CanvasItemEditor::_gui_input_zoom_or_pan(const Ref<InputEvent> &p_event, bo
if (k.is_valid()) {
if (k->is_pressed()) {
if (ED_GET_SHORTCUT("canvas_item_editor/zoom_3.125_percent")->matches_event(p_event)) {
- _update_zoom((1.0 / 32.0) * MAX(1, EDSCALE));
+ _shortcut_zoom_set(1.0 / 32.0);
} else if (ED_GET_SHORTCUT("canvas_item_editor/zoom_6.25_percent")->matches_event(p_event)) {
- _update_zoom((1.0 / 16.0) * MAX(1, EDSCALE));
+ _shortcut_zoom_set(1.0 / 16.0);
} else if (ED_GET_SHORTCUT("canvas_item_editor/zoom_12.5_percent")->matches_event(p_event)) {
- _update_zoom((1.0 / 8.0) * MAX(1, EDSCALE));
+ _shortcut_zoom_set(1.0 / 8.0);
} else if (ED_GET_SHORTCUT("canvas_item_editor/zoom_25_percent")->matches_event(p_event)) {
- _update_zoom((1.0 / 4.0) * MAX(1, EDSCALE));
+ _shortcut_zoom_set(1.0 / 4.0);
} else if (ED_GET_SHORTCUT("canvas_item_editor/zoom_50_percent")->matches_event(p_event)) {
- _update_zoom((1.0 / 2.0) * MAX(1, EDSCALE));
+ _shortcut_zoom_set(1.0 / 2.0);
} else if (ED_GET_SHORTCUT("canvas_item_editor/zoom_100_percent")->matches_event(p_event)) {
- _update_zoom(1.0 * MAX(1, EDSCALE));
+ _shortcut_zoom_set(1.0);
} else if (ED_GET_SHORTCUT("canvas_item_editor/zoom_200_percent")->matches_event(p_event)) {
- _update_zoom(2.0 * MAX(1, EDSCALE));
+ _shortcut_zoom_set(2.0);
} else if (ED_GET_SHORTCUT("canvas_item_editor/zoom_400_percent")->matches_event(p_event)) {
- _update_zoom(4.0 * MAX(1, EDSCALE));
+ _shortcut_zoom_set(4.0);
} else if (ED_GET_SHORTCUT("canvas_item_editor/zoom_800_percent")->matches_event(p_event)) {
- _update_zoom(8.0 * MAX(1, EDSCALE));
+ _shortcut_zoom_set(8.0);
} else if (ED_GET_SHORTCUT("canvas_item_editor/zoom_1600_percent")->matches_event(p_event)) {
- _update_zoom(16.0 * MAX(1, EDSCALE));
+ _shortcut_zoom_set(16.0);
}
}
}
@@ -1409,8 +1411,8 @@ bool CanvasItemEditor::_gui_input_open_scene_on_double_click(const Ref<InputEven
List<CanvasItem *> selection = _get_edited_canvas_items();
if (selection.size() == 1) {
CanvasItem *canvas_item = selection[0];
- if (!canvas_item->get_scene_file_path().is_empty() && canvas_item != editor->get_edited_scene()) {
- editor->open_request(canvas_item->get_scene_file_path());
+ if (!canvas_item->get_scene_file_path().is_empty() && canvas_item != EditorNode::get_singleton()->get_edited_scene()) {
+ EditorNode::get_singleton()->open_request(canvas_item->get_scene_file_path());
return true;
}
}
@@ -1831,7 +1833,7 @@ bool CanvasItemEditor::_gui_input_scale(const Ref<InputEvent> &p_event) {
Point2 drag_to_local = simple_xform.xform(drag_to);
Point2 offset = drag_to_local - drag_from_local;
- Size2 scale = canvas_item->call("get_scale");
+ Size2 scale = canvas_item->_edit_get_scale();
Size2 original_scale = scale;
real_t ratio = scale.y / scale.x;
if (drag_type == DRAG_SCALE_BOTH) {
@@ -1869,7 +1871,7 @@ bool CanvasItemEditor::_gui_input_scale(const Ref<InputEvent> &p_event) {
}
}
- canvas_item->call("set_scale", scale);
+ canvas_item->_edit_set_scale(scale);
return true;
}
@@ -2190,7 +2192,7 @@ bool CanvasItemEditor::_gui_input_select(const Ref<InputEvent> &p_event) {
if (_is_node_locked(item)) {
locked = 1;
} else {
- Node *scene = editor->get_edited_scene();
+ Node *scene = EditorNode::get_singleton()->get_edited_scene();
Node *node = item;
while (node && node != scene->get_parent()) {
@@ -2250,7 +2252,7 @@ bool CanvasItemEditor::_gui_input_select(const Ref<InputEvent> &p_event) {
// Single item selection
Point2 click = transform.affine_inverse().xform(b->get_position());
- Node *scene = editor->get_edited_scene();
+ Node *scene = EditorNode::get_singleton()->get_edited_scene();
if (!scene) {
return true;
}
@@ -2324,7 +2326,7 @@ bool CanvasItemEditor::_gui_input_select(const Ref<InputEvent> &p_event) {
if (drag_type == DRAG_BOX_SELECTION) {
if (b.is_valid() && !b->is_pressed() && b->get_button_index() == MouseButton::LEFT) {
// Confirms box selection
- Node *scene = editor->get_edited_scene();
+ Node *scene = EditorNode::get_singleton()->get_edited_scene();
if (scene) {
List<CanvasItem *> selitems;
@@ -2339,7 +2341,7 @@ bool CanvasItemEditor::_gui_input_select(const Ref<InputEvent> &p_event) {
_find_canvas_items_in_rect(Rect2(bsfrom, bsto - bsfrom), scene, &selitems);
if (selitems.size() == 1 && editor_selection->get_selected_node_list().is_empty()) {
- editor->push_item(selitems[0]);
+ EditorNode::get_singleton()->push_item(selitems[0]);
}
for (CanvasItem *E : selitems) {
editor_selection->add_node(E);
@@ -2469,7 +2471,7 @@ void CanvasItemEditor::_gui_input_viewport(const Ref<InputEvent> &p_event) {
if (EditorSettings::get_singleton()->get("editors/panning/simple_panning") || !pan_pressed || release_lmb) {
if ((accepted = _gui_input_rulers_and_guides(p_event))) {
// print_line("Rulers and guides");
- } else if ((accepted = editor->get_editor_plugins_over()->forward_gui_input(p_event))) {
+ } else if ((accepted = EditorNode::get_singleton()->get_editor_plugins_over()->forward_gui_input(p_event))) {
// print_line("Plugin");
} else if ((accepted = _gui_input_open_scene_on_double_click(p_event))) {
// print_line("Open scene on double click");
@@ -3503,12 +3505,12 @@ void CanvasItemEditor::_draw_axis() {
void CanvasItemEditor::_draw_invisible_nodes_positions(Node *p_node, const Transform2D &p_parent_xform, const Transform2D &p_canvas_xform) {
ERR_FAIL_COND(!p_node);
- Node *scene = editor->get_edited_scene();
+ Node *scene = EditorNode::get_singleton()->get_edited_scene();
if (p_node != scene && p_node->get_owner() != scene && !scene->is_editable_instance(p_node->get_owner())) {
return;
}
CanvasItem *canvas_item = Object::cast_to<CanvasItem>(p_node);
- if (canvas_item && !canvas_item->is_visible()) {
+ if (canvas_item && !canvas_item->is_visible_in_tree()) {
return;
}
@@ -3573,12 +3575,12 @@ void CanvasItemEditor::_draw_hover() {
void CanvasItemEditor::_draw_locks_and_groups(Node *p_node, const Transform2D &p_parent_xform, const Transform2D &p_canvas_xform) {
ERR_FAIL_COND(!p_node);
- Node *scene = editor->get_edited_scene();
+ Node *scene = EditorNode::get_singleton()->get_edited_scene();
if (p_node != scene && p_node->get_owner() != scene && !scene->is_editable_instance(p_node->get_owner())) {
return;
}
CanvasItem *canvas_item = Object::cast_to<CanvasItem>(p_node);
- if (canvas_item && !canvas_item->is_visible()) {
+ if (canvas_item && !canvas_item->is_visible_in_tree()) {
return;
}
@@ -3620,7 +3622,7 @@ void CanvasItemEditor::_draw_viewport() {
transform = Transform2D();
transform.scale_basis(Size2(zoom, zoom));
transform.elements[2] = -view_offset * zoom;
- editor->get_scene_root()->set_global_canvas_transform(transform);
+ EditorNode::get_singleton()->get_scene_root()->set_global_canvas_transform(transform);
// hide/show buttons depending on the selection
bool all_locked = true;
@@ -3654,20 +3656,20 @@ void CanvasItemEditor::_draw_viewport() {
_draw_grid();
_draw_ruler_tool();
_draw_axis();
- if (editor->get_edited_scene()) {
- _draw_locks_and_groups(editor->get_edited_scene());
- _draw_invisible_nodes_positions(editor->get_edited_scene());
+ if (EditorNode::get_singleton()->get_edited_scene()) {
+ _draw_locks_and_groups(EditorNode::get_singleton()->get_edited_scene());
+ _draw_invisible_nodes_positions(EditorNode::get_singleton()->get_edited_scene());
}
_draw_selection();
RID ci = viewport->get_canvas_item();
RenderingServer::get_singleton()->canvas_item_add_set_transform(ci, Transform2D());
- EditorPluginList *over_plugin_list = editor->get_editor_plugins_over();
+ EditorPluginList *over_plugin_list = EditorNode::get_singleton()->get_editor_plugins_over();
if (!over_plugin_list->is_empty()) {
over_plugin_list->forward_canvas_draw_over_viewport(viewport);
}
- EditorPluginList *force_over_plugin_list = editor->get_editor_plugins_force_over();
+ EditorPluginList *force_over_plugin_list = EditorNode::get_singleton()->get_editor_plugins_force_over();
if (!force_over_plugin_list->is_empty()) {
force_over_plugin_list->forward_canvas_force_draw_over_viewport(viewport);
}
@@ -3692,255 +3694,158 @@ void CanvasItemEditor::set_current_tool(Tool p_tool) {
_button_tool_select(p_tool);
}
-void CanvasItemEditor::_notification(int p_what) {
- if (p_what == NOTIFICATION_PHYSICS_PROCESS) {
- EditorNode::get_singleton()->get_scene_root()->set_snap_controls_to_pixels(GLOBAL_GET("gui/common/snap_controls_to_pixels"));
+void CanvasItemEditor::_update_editor_settings() {
+ select_button->set_icon(get_theme_icon(SNAME("ToolSelect"), SNAME("EditorIcons")));
+ list_select_button->set_icon(get_theme_icon(SNAME("ListSelect"), SNAME("EditorIcons")));
+ move_button->set_icon(get_theme_icon(SNAME("ToolMove"), SNAME("EditorIcons")));
+ scale_button->set_icon(get_theme_icon(SNAME("ToolScale"), SNAME("EditorIcons")));
+ rotate_button->set_icon(get_theme_icon(SNAME("ToolRotate"), SNAME("EditorIcons")));
+ smart_snap_button->set_icon(get_theme_icon(SNAME("Snap"), SNAME("EditorIcons")));
+ grid_snap_button->set_icon(get_theme_icon(SNAME("SnapGrid"), SNAME("EditorIcons")));
+ snap_config_menu->set_icon(get_theme_icon(SNAME("GuiTabMenuHl"), SNAME("EditorIcons")));
+ skeleton_menu->set_icon(get_theme_icon(SNAME("Bone"), SNAME("EditorIcons")));
+ override_camera_button->set_icon(get_theme_icon(SNAME("Camera2D"), SNAME("EditorIcons")));
+ pan_button->set_icon(get_theme_icon(SNAME("ToolPan"), SNAME("EditorIcons")));
+ ruler_button->set_icon(get_theme_icon(SNAME("Ruler"), SNAME("EditorIcons")));
+ pivot_button->set_icon(get_theme_icon(SNAME("EditPivot"), SNAME("EditorIcons")));
+ select_handle = get_theme_icon(SNAME("EditorHandle"), SNAME("EditorIcons"));
+ anchor_handle = get_theme_icon(SNAME("EditorControlAnchor"), SNAME("EditorIcons"));
+ lock_button->set_icon(get_theme_icon(SNAME("Lock"), SNAME("EditorIcons")));
+ unlock_button->set_icon(get_theme_icon(SNAME("Unlock"), SNAME("EditorIcons")));
+ group_button->set_icon(get_theme_icon(SNAME("Group"), SNAME("EditorIcons")));
+ ungroup_button->set_icon(get_theme_icon(SNAME("Ungroup"), SNAME("EditorIcons")));
+ key_loc_button->set_icon(get_theme_icon(SNAME("KeyPosition"), SNAME("EditorIcons")));
+ key_rot_button->set_icon(get_theme_icon(SNAME("KeyRotation"), SNAME("EditorIcons")));
+ key_scale_button->set_icon(get_theme_icon(SNAME("KeyScale"), SNAME("EditorIcons")));
+ key_insert_button->set_icon(get_theme_icon(SNAME("Key"), SNAME("EditorIcons")));
+ key_auto_insert_button->set_icon(get_theme_icon(SNAME("AutoKey"), SNAME("EditorIcons")));
+ // Use a different color for the active autokey icon to make them easier
+ // to distinguish from the other key icons at the top. On a light theme,
+ // the icon will be dark, so we need to lighten it before blending it
+ // with the red color.
+ const Color key_auto_color = EditorSettings::get_singleton()->is_dark_theme() ? Color(1, 1, 1) : Color(4.25, 4.25, 4.25);
+ key_auto_insert_button->add_theme_color_override("icon_pressed_color", key_auto_color.lerp(Color(1, 0, 0), 0.55));
+ animation_menu->set_icon(get_theme_icon(SNAME("GuiTabMenuHl"), SNAME("EditorIcons")));
- bool has_container_parents = false;
- int nb_control = 0;
- int nb_having_pivot = 0;
+ _update_context_menu_stylebox();
- // Update the viewport if the canvas_item changes
- List<CanvasItem *> selection = _get_edited_canvas_items(true);
- for (CanvasItem *canvas_item : selection) {
- CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item);
+ panner->setup((ViewPanner::ControlScheme)EDITOR_GET("editors/panning/2d_editor_panning_scheme").operator int(), ED_GET_SHORTCUT("canvas_item_editor/pan_view"), bool(EditorSettings::get_singleton()->get("editors/panning/simple_panning")));
+ pan_speed = int(EditorSettings::get_singleton()->get("editors/panning/2d_editor_pan_speed"));
+ warped_panning = bool(EditorSettings::get_singleton()->get("editors/panning/warped_mouse_panning"));
+}
- Rect2 rect;
- if (canvas_item->_edit_use_rect()) {
- rect = canvas_item->_edit_get_rect();
- } else {
- rect = Rect2();
- }
- Transform2D xform = canvas_item->get_transform();
+void CanvasItemEditor::_notification(int p_what) {
+ switch (p_what) {
+ case NOTIFICATION_PHYSICS_PROCESS: {
+ EditorNode::get_singleton()->get_scene_root()->set_snap_controls_to_pixels(GLOBAL_GET("gui/common/snap_controls_to_pixels"));
- if (rect != se->prev_rect || xform != se->prev_xform) {
- viewport->update();
- se->prev_rect = rect;
- se->prev_xform = xform;
- }
+ int nb_having_pivot = 0;
- Control *control = Object::cast_to<Control>(canvas_item);
- if (control) {
- real_t anchors[4];
- Vector2 pivot;
-
- pivot = control->get_pivot_offset();
- anchors[SIDE_LEFT] = control->get_anchor(SIDE_LEFT);
- anchors[SIDE_RIGHT] = control->get_anchor(SIDE_RIGHT);
- anchors[SIDE_TOP] = control->get_anchor(SIDE_TOP);
- anchors[SIDE_BOTTOM] = control->get_anchor(SIDE_BOTTOM);
-
- if (pivot != se->prev_pivot || anchors[SIDE_LEFT] != se->prev_anchors[SIDE_LEFT] || anchors[SIDE_RIGHT] != se->prev_anchors[SIDE_RIGHT] || anchors[SIDE_TOP] != se->prev_anchors[SIDE_TOP] || anchors[SIDE_BOTTOM] != se->prev_anchors[SIDE_BOTTOM]) {
- se->prev_pivot = pivot;
- se->prev_anchors[SIDE_LEFT] = anchors[SIDE_LEFT];
- se->prev_anchors[SIDE_RIGHT] = anchors[SIDE_RIGHT];
- se->prev_anchors[SIDE_TOP] = anchors[SIDE_TOP];
- se->prev_anchors[SIDE_BOTTOM] = anchors[SIDE_BOTTOM];
+ // Update the viewport if the canvas_item changes
+ List<CanvasItem *> selection = _get_edited_canvas_items(true);
+ for (CanvasItem *canvas_item : selection) {
+ CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item);
+
+ Rect2 rect;
+ if (canvas_item->_edit_use_rect()) {
+ rect = canvas_item->_edit_get_rect();
+ } else {
+ rect = Rect2();
+ }
+ Transform2D xform = canvas_item->get_transform();
+
+ if (rect != se->prev_rect || xform != se->prev_xform) {
viewport->update();
+ se->prev_rect = rect;
+ se->prev_xform = xform;
}
- nb_control++;
- if (Object::cast_to<Container>(control->get_parent())) {
- has_container_parents = true;
+ Control *control = Object::cast_to<Control>(canvas_item);
+ if (control) {
+ real_t anchors[4];
+ Vector2 pivot;
+
+ pivot = control->get_pivot_offset();
+ anchors[SIDE_LEFT] = control->get_anchor(SIDE_LEFT);
+ anchors[SIDE_RIGHT] = control->get_anchor(SIDE_RIGHT);
+ anchors[SIDE_TOP] = control->get_anchor(SIDE_TOP);
+ anchors[SIDE_BOTTOM] = control->get_anchor(SIDE_BOTTOM);
+
+ if (pivot != se->prev_pivot || anchors[SIDE_LEFT] != se->prev_anchors[SIDE_LEFT] || anchors[SIDE_RIGHT] != se->prev_anchors[SIDE_RIGHT] || anchors[SIDE_TOP] != se->prev_anchors[SIDE_TOP] || anchors[SIDE_BOTTOM] != se->prev_anchors[SIDE_BOTTOM]) {
+ se->prev_pivot = pivot;
+ se->prev_anchors[SIDE_LEFT] = anchors[SIDE_LEFT];
+ se->prev_anchors[SIDE_RIGHT] = anchors[SIDE_RIGHT];
+ se->prev_anchors[SIDE_TOP] = anchors[SIDE_TOP];
+ se->prev_anchors[SIDE_BOTTOM] = anchors[SIDE_BOTTOM];
+ viewport->update();
+ }
}
- }
- if (canvas_item->_edit_use_pivot()) {
- nb_having_pivot++;
+ if (canvas_item->_edit_use_pivot()) {
+ nb_having_pivot++;
+ }
}
- }
- // Activate / Deactivate the pivot tool
- pivot_button->set_disabled(nb_having_pivot == 0);
+ // Activate / Deactivate the pivot tool
+ pivot_button->set_disabled(nb_having_pivot == 0);
- // Show / Hide the layout and anchors mode buttons
- if (nb_control > 0 && nb_control == selection.size()) {
- presets_menu->set_visible(true);
- anchor_mode_button->set_visible(true);
+ // Update the viewport if bones changes
+ for (KeyValue<BoneKey, BoneList> &E : bone_list) {
+ Object *b = ObjectDB::get_instance(E.key.from);
+ if (!b) {
+ viewport->update();
+ break;
+ }
- // Disable if the selected node is child of a container
- if (has_container_parents) {
- presets_menu->set_disabled(true);
- presets_menu->set_tooltip(TTR("Children of containers have their anchors and margins values overridden by their parent."));
- anchor_mode_button->set_disabled(true);
- anchor_mode_button->set_tooltip(TTR("Children of containers have their anchors and margins values overridden by their parent."));
- } else {
- presets_menu->set_disabled(false);
- presets_menu->set_tooltip(TTR("Presets for the anchors and margins values of a Control node."));
- anchor_mode_button->set_disabled(false);
- anchor_mode_button->set_tooltip(TTR("When active, moving Control nodes changes their anchors instead of their margins."));
- }
- } else {
- presets_menu->set_visible(false);
- anchor_mode_button->set_visible(false);
- }
+ Node2D *b2 = Object::cast_to<Node2D>(b);
+ if (!b2 || !b2->is_inside_tree()) {
+ continue;
+ }
- // Update the viewport if bones changes
- for (KeyValue<BoneKey, BoneList> &E : bone_list) {
- Object *b = ObjectDB::get_instance(E.key.from);
- if (!b) {
- viewport->update();
- break;
+ Transform2D global_xform = b2->get_global_transform();
+
+ if (global_xform != E.value.xform) {
+ E.value.xform = global_xform;
+ viewport->update();
+ }
+
+ Bone2D *bone = Object::cast_to<Bone2D>(b);
+ if (bone && bone->get_length() != E.value.length) {
+ E.value.length = bone->get_length();
+ viewport->update();
+ }
}
+ } break;
- Node2D *b2 = Object::cast_to<Node2D>(b);
- if (!b2 || !b2->is_inside_tree()) {
- continue;
+ case NOTIFICATION_ENTER_TREE: {
+ select_sb->set_texture(get_theme_icon(SNAME("EditorRect2D"), SNAME("EditorIcons")));
+ for (int i = 0; i < 4; i++) {
+ select_sb->set_margin_size(Side(i), 4);
+ select_sb->set_default_margin(Side(i), 4);
}
- Transform2D global_xform = b2->get_global_transform();
+ AnimationPlayerEditor::get_singleton()->get_track_editor()->connect("visibility_changed", callable_mp(this, &CanvasItemEditor::_keying_changed));
+ _keying_changed();
+ _update_editor_settings();
+ } break;
- if (global_xform != E.value.xform) {
- E.value.xform = global_xform;
- viewport->update();
- }
+ case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
+ select_sb->set_texture(get_theme_icon(SNAME("EditorRect2D"), SNAME("EditorIcons")));
+ _update_editor_settings();
+ } break;
- Bone2D *bone = Object::cast_to<Bone2D>(b);
- if (bone && bone->get_length() != E.value.length) {
- E.value.length = bone->get_length();
- viewport->update();
- }
- }
- }
+ case NOTIFICATION_VISIBILITY_CHANGED: {
+ if (!is_visible() && override_camera_button->is_pressed()) {
+ EditorDebuggerNode *debugger = EditorDebuggerNode::get_singleton();
- if (p_what == NOTIFICATION_ENTER_TREE) {
- select_sb->set_texture(get_theme_icon(SNAME("EditorRect2D"), SNAME("EditorIcons")));
- for (int i = 0; i < 4; i++) {
- select_sb->set_margin_size(Side(i), 4);
- select_sb->set_default_margin(Side(i), 4);
- }
-
- AnimationPlayerEditor::get_singleton()->get_track_editor()->connect("visibility_changed", callable_mp(this, &CanvasItemEditor::_keying_changed));
- _keying_changed();
-
- } else if (p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) {
- select_sb->set_texture(get_theme_icon(SNAME("EditorRect2D"), SNAME("EditorIcons")));
- }
-
- if (p_what == NOTIFICATION_ENTER_TREE || p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) {
- select_button->set_icon(get_theme_icon(SNAME("ToolSelect"), SNAME("EditorIcons")));
- list_select_button->set_icon(get_theme_icon(SNAME("ListSelect"), SNAME("EditorIcons")));
- move_button->set_icon(get_theme_icon(SNAME("ToolMove"), SNAME("EditorIcons")));
- scale_button->set_icon(get_theme_icon(SNAME("ToolScale"), SNAME("EditorIcons")));
- rotate_button->set_icon(get_theme_icon(SNAME("ToolRotate"), SNAME("EditorIcons")));
- smart_snap_button->set_icon(get_theme_icon(SNAME("Snap"), SNAME("EditorIcons")));
- grid_snap_button->set_icon(get_theme_icon(SNAME("SnapGrid"), SNAME("EditorIcons")));
- snap_config_menu->set_icon(get_theme_icon(SNAME("GuiTabMenuHl"), SNAME("EditorIcons")));
- skeleton_menu->set_icon(get_theme_icon(SNAME("Bone"), SNAME("EditorIcons")));
- override_camera_button->set_icon(get_theme_icon(SNAME("Camera2D"), SNAME("EditorIcons")));
- pan_button->set_icon(get_theme_icon(SNAME("ToolPan"), SNAME("EditorIcons")));
- ruler_button->set_icon(get_theme_icon(SNAME("Ruler"), SNAME("EditorIcons")));
- pivot_button->set_icon(get_theme_icon(SNAME("EditPivot"), SNAME("EditorIcons")));
- select_handle = get_theme_icon(SNAME("EditorHandle"), SNAME("EditorIcons"));
- anchor_handle = get_theme_icon(SNAME("EditorControlAnchor"), SNAME("EditorIcons"));
- lock_button->set_icon(get_theme_icon(SNAME("Lock"), SNAME("EditorIcons")));
- unlock_button->set_icon(get_theme_icon(SNAME("Unlock"), SNAME("EditorIcons")));
- group_button->set_icon(get_theme_icon(SNAME("Group"), SNAME("EditorIcons")));
- ungroup_button->set_icon(get_theme_icon(SNAME("Ungroup"), SNAME("EditorIcons")));
- key_loc_button->set_icon(get_theme_icon(SNAME("KeyPosition"), SNAME("EditorIcons")));
- key_rot_button->set_icon(get_theme_icon(SNAME("KeyRotation"), SNAME("EditorIcons")));
- key_scale_button->set_icon(get_theme_icon(SNAME("KeyScale"), SNAME("EditorIcons")));
- key_insert_button->set_icon(get_theme_icon(SNAME("Key"), SNAME("EditorIcons")));
- key_auto_insert_button->set_icon(get_theme_icon(SNAME("AutoKey"), SNAME("EditorIcons")));
- // Use a different color for the active autokey icon to make them easier
- // to distinguish from the other key icons at the top. On a light theme,
- // the icon will be dark, so we need to lighten it before blending it
- // with the red color.
- const Color key_auto_color = EditorSettings::get_singleton()->is_dark_theme() ? Color(1, 1, 1) : Color(4.25, 4.25, 4.25);
- key_auto_insert_button->add_theme_color_override("icon_pressed_color", key_auto_color.lerp(Color(1, 0, 0), 0.55));
- animation_menu->set_icon(get_theme_icon(SNAME("GuiTabMenuHl"), SNAME("EditorIcons")));
-
- _update_context_menu_stylebox();
-
- presets_menu->set_icon(get_theme_icon(SNAME("ControlLayout"), SNAME("EditorIcons")));
-
- PopupMenu *p = presets_menu->get_popup();
-
- p->clear();
- p->add_icon_item(get_theme_icon(SNAME("ControlAlignTopLeft"), SNAME("EditorIcons")), TTR("Top Left"), ANCHORS_AND_OFFSETS_PRESET_TOP_LEFT);
- p->add_icon_item(get_theme_icon(SNAME("ControlAlignTopRight"), SNAME("EditorIcons")), TTR("Top Right"), ANCHORS_AND_OFFSETS_PRESET_TOP_RIGHT);
- p->add_icon_item(get_theme_icon(SNAME("ControlAlignBottomRight"), SNAME("EditorIcons")), TTR("Bottom Right"), ANCHORS_AND_OFFSETS_PRESET_BOTTOM_RIGHT);
- p->add_icon_item(get_theme_icon(SNAME("ControlAlignBottomLeft"), SNAME("EditorIcons")), TTR("Bottom Left"), ANCHORS_AND_OFFSETS_PRESET_BOTTOM_LEFT);
- p->add_separator();
- p->add_icon_item(get_theme_icon(SNAME("ControlAlignLeftCenter"), SNAME("EditorIcons")), TTR("Center Left"), ANCHORS_AND_OFFSETS_PRESET_CENTER_LEFT);
- p->add_icon_item(get_theme_icon(SNAME("ControlAlignTopCenter"), SNAME("EditorIcons")), TTR("Center Top"), ANCHORS_AND_OFFSETS_PRESET_CENTER_TOP);
- p->add_icon_item(get_theme_icon(SNAME("ControlAlignRightCenter"), SNAME("EditorIcons")), TTR("Center Right"), ANCHORS_AND_OFFSETS_PRESET_CENTER_RIGHT);
- p->add_icon_item(get_theme_icon(SNAME("ControlAlignBottomCenter"), SNAME("EditorIcons")), TTR("Center Bottom"), ANCHORS_AND_OFFSETS_PRESET_CENTER_BOTTOM);
- p->add_icon_item(get_theme_icon(SNAME("ControlAlignCenter"), SNAME("EditorIcons")), TTR("Center"), ANCHORS_AND_OFFSETS_PRESET_CENTER);
- p->add_separator();
- p->add_icon_item(get_theme_icon(SNAME("ControlAlignLeftWide"), SNAME("EditorIcons")), TTR("Left Wide"), ANCHORS_AND_OFFSETS_PRESET_LEFT_WIDE);
- p->add_icon_item(get_theme_icon(SNAME("ControlAlignTopWide"), SNAME("EditorIcons")), TTR("Top Wide"), ANCHORS_AND_OFFSETS_PRESET_TOP_WIDE);
- p->add_icon_item(get_theme_icon(SNAME("ControlAlignRightWide"), SNAME("EditorIcons")), TTR("Right Wide"), ANCHORS_AND_OFFSETS_PRESET_RIGHT_WIDE);
- p->add_icon_item(get_theme_icon(SNAME("ControlAlignBottomWide"), SNAME("EditorIcons")), TTR("Bottom Wide"), ANCHORS_AND_OFFSETS_PRESET_BOTTOM_WIDE);
- p->add_icon_item(get_theme_icon(SNAME("ControlVcenterWide"), SNAME("EditorIcons")), TTR("VCenter Wide"), ANCHORS_AND_OFFSETS_PRESET_VCENTER_WIDE);
- p->add_icon_item(get_theme_icon(SNAME("ControlHcenterWide"), SNAME("EditorIcons")), TTR("HCenter Wide"), ANCHORS_AND_OFFSETS_PRESET_HCENTER_WIDE);
- p->add_separator();
- p->add_icon_item(get_theme_icon(SNAME("ControlAlignWide"), SNAME("EditorIcons")), TTR("Full Rect"), ANCHORS_AND_OFFSETS_PRESET_WIDE);
- p->add_icon_item(get_theme_icon(SNAME("Anchor"), SNAME("EditorIcons")), TTR("Keep Ratio"), ANCHORS_AND_OFFSETS_PRESET_KEEP_RATIO);
- p->add_separator();
- p->add_submenu_item(TTR("Anchors only"), "Anchors");
- p->set_item_icon(21, get_theme_icon(SNAME("Anchor"), SNAME("EditorIcons")));
-
- anchors_popup->clear();
- anchors_popup->add_icon_item(get_theme_icon(SNAME("ControlAlignTopLeft"), SNAME("EditorIcons")), TTR("Top Left"), ANCHORS_PRESET_TOP_LEFT);
- anchors_popup->add_icon_item(get_theme_icon(SNAME("ControlAlignTopRight"), SNAME("EditorIcons")), TTR("Top Right"), ANCHORS_PRESET_TOP_RIGHT);
- anchors_popup->add_icon_item(get_theme_icon(SNAME("ControlAlignBottomRight"), SNAME("EditorIcons")), TTR("Bottom Right"), ANCHORS_PRESET_BOTTOM_RIGHT);
- anchors_popup->add_icon_item(get_theme_icon(SNAME("ControlAlignBottomLeft"), SNAME("EditorIcons")), TTR("Bottom Left"), ANCHORS_PRESET_BOTTOM_LEFT);
- anchors_popup->add_separator();
- anchors_popup->add_icon_item(get_theme_icon(SNAME("ControlAlignLeftCenter"), SNAME("EditorIcons")), TTR("Center Left"), ANCHORS_PRESET_CENTER_LEFT);
- anchors_popup->add_icon_item(get_theme_icon(SNAME("ControlAlignTopCenter"), SNAME("EditorIcons")), TTR("Center Top"), ANCHORS_PRESET_CENTER_TOP);
- anchors_popup->add_icon_item(get_theme_icon(SNAME("ControlAlignRightCenter"), SNAME("EditorIcons")), TTR("Center Right"), ANCHORS_PRESET_CENTER_RIGHT);
- anchors_popup->add_icon_item(get_theme_icon(SNAME("ControlAlignBottomCenter"), SNAME("EditorIcons")), TTR("Center Bottom"), ANCHORS_PRESET_CENTER_BOTTOM);
- anchors_popup->add_icon_item(get_theme_icon(SNAME("ControlAlignCenter"), SNAME("EditorIcons")), TTR("Center"), ANCHORS_PRESET_CENTER);
- anchors_popup->add_separator();
- anchors_popup->add_icon_item(get_theme_icon(SNAME("ControlAlignLeftWide"), SNAME("EditorIcons")), TTR("Left Wide"), ANCHORS_PRESET_LEFT_WIDE);
- anchors_popup->add_icon_item(get_theme_icon(SNAME("ControlAlignTopWide"), SNAME("EditorIcons")), TTR("Top Wide"), ANCHORS_PRESET_TOP_WIDE);
- anchors_popup->add_icon_item(get_theme_icon(SNAME("ControlAlignRightWide"), SNAME("EditorIcons")), TTR("Right Wide"), ANCHORS_PRESET_RIGHT_WIDE);
- anchors_popup->add_icon_item(get_theme_icon(SNAME("ControlAlignBottomWide"), SNAME("EditorIcons")), TTR("Bottom Wide"), ANCHORS_PRESET_BOTTOM_WIDE);
- anchors_popup->add_icon_item(get_theme_icon(SNAME("ControlVcenterWide"), SNAME("EditorIcons")), TTR("VCenter Wide"), ANCHORS_PRESET_VCENTER_WIDE);
- anchors_popup->add_icon_item(get_theme_icon(SNAME("ControlHcenterWide"), SNAME("EditorIcons")), TTR("HCenter Wide"), ANCHORS_PRESET_HCENTER_WIDE);
- anchors_popup->add_separator();
- anchors_popup->add_icon_item(get_theme_icon(SNAME("ControlAlignWide"), SNAME("EditorIcons")), TTR("Full Rect"), ANCHORS_PRESET_WIDE);
-
- anchor_mode_button->set_icon(get_theme_icon(SNAME("Anchor"), SNAME("EditorIcons")));
-
- panner->setup((ViewPanner::ControlScheme)EDITOR_GET("editors/panning/2d_editor_panning_scheme").operator int(), ED_GET_SHORTCUT("canvas_item_editor/pan_view"), bool(EditorSettings::get_singleton()->get("editors/panning/simple_panning")));
- pan_speed = int(EditorSettings::get_singleton()->get("editors/panning/2d_editor_pan_speed"));
- warped_panning = bool(EditorSettings::get_singleton()->get("editors/panning/warped_mouse_panning"));
- }
-
- if (p_what == NOTIFICATION_VISIBILITY_CHANGED) {
- if (!is_visible() && override_camera_button->is_pressed()) {
- EditorDebuggerNode *debugger = EditorDebuggerNode::get_singleton();
-
- debugger->set_camera_override(EditorDebuggerNode::OVERRIDE_NONE);
- override_camera_button->set_pressed(false);
- }
+ debugger->set_camera_override(EditorDebuggerNode::OVERRIDE_NONE);
+ override_camera_button->set_pressed(false);
+ }
+ } break;
}
}
void CanvasItemEditor::_selection_changed() {
- // Update the anchors_mode
- int nbValidControls = 0;
- int nbAnchorsMode = 0;
- List<Node *> selection = editor_selection->get_selected_node_list();
- for (Node *E : selection) {
- Control *control = Object::cast_to<Control>(E);
- if (!control) {
- continue;
- }
- if (Object::cast_to<Container>(control->get_parent())) {
- continue;
- }
-
- nbValidControls++;
- if (control->has_meta("_edit_use_anchors_") && control->get_meta("_edit_use_anchors_")) {
- nbAnchorsMode++;
- }
- }
- anchors_mode = (nbValidControls == nbAnchorsMode);
- anchor_mode_button->set_pressed(anchors_mode);
-
if (!selected_from_canvas) {
drag_type = DRAG_NONE;
}
@@ -3987,8 +3892,8 @@ void CanvasItemEditor::_update_scrollbars() {
// Calculate scrollable area.
Rect2 canvas_item_rect = Rect2(Point2(), screen_rect);
- if (editor->is_inside_tree() && editor->get_edited_scene()) {
- Rect2 content_rect = _get_encompassing_rect(editor->get_edited_scene());
+ if (EditorNode::get_singleton()->is_inside_tree() && EditorNode::get_singleton()->get_edited_scene()) {
+ Rect2 content_rect = _get_encompassing_rect(EditorNode::get_singleton()->get_edited_scene());
canvas_item_rect.expand_to(content_rect.position);
canvas_item_rect.expand_to(content_rect.position + content_rect.size);
}
@@ -4072,90 +3977,6 @@ void CanvasItemEditor::_update_scroll(real_t) {
viewport->update();
}
-void CanvasItemEditor::_set_anchors_and_offsets_preset(Control::LayoutPreset p_preset) {
- List<Node *> selection = editor_selection->get_selected_node_list();
-
- undo_redo->create_action(TTR("Change Anchors and Offsets"));
-
- for (Node *E : selection) {
- Control *control = Object::cast_to<Control>(E);
- if (control) {
- undo_redo->add_do_method(control, "set_anchors_preset", p_preset);
- switch (p_preset) {
- case PRESET_TOP_LEFT:
- case PRESET_TOP_RIGHT:
- case PRESET_BOTTOM_LEFT:
- case PRESET_BOTTOM_RIGHT:
- case PRESET_CENTER_LEFT:
- case PRESET_CENTER_TOP:
- case PRESET_CENTER_RIGHT:
- case PRESET_CENTER_BOTTOM:
- case PRESET_CENTER:
- undo_redo->add_do_method(control, "set_offsets_preset", p_preset, Control::PRESET_MODE_KEEP_SIZE);
- break;
- case PRESET_LEFT_WIDE:
- case PRESET_TOP_WIDE:
- case PRESET_RIGHT_WIDE:
- case PRESET_BOTTOM_WIDE:
- case PRESET_VCENTER_WIDE:
- case PRESET_HCENTER_WIDE:
- case PRESET_WIDE:
- undo_redo->add_do_method(control, "set_offsets_preset", p_preset, Control::PRESET_MODE_MINSIZE);
- break;
- }
- undo_redo->add_undo_method(control, "_edit_set_state", control->_edit_get_state());
- }
- }
-
- undo_redo->commit_action();
-
- anchors_mode = false;
- anchor_mode_button->set_pressed(anchors_mode);
-}
-
-void CanvasItemEditor::_set_anchors_and_offsets_to_keep_ratio() {
- List<Node *> selection = editor_selection->get_selected_node_list();
-
- undo_redo->create_action(TTR("Change Anchors and Offsets"));
-
- for (Node *E : selection) {
- Control *control = Object::cast_to<Control>(E);
- if (control) {
- Point2 top_left_anchor = _position_to_anchor(control, Point2());
- Point2 bottom_right_anchor = _position_to_anchor(control, control->get_size());
- undo_redo->add_do_method(control, "set_anchor", SIDE_LEFT, top_left_anchor.x, false, true);
- undo_redo->add_do_method(control, "set_anchor", SIDE_RIGHT, bottom_right_anchor.x, false, true);
- undo_redo->add_do_method(control, "set_anchor", SIDE_TOP, top_left_anchor.y, false, true);
- undo_redo->add_do_method(control, "set_anchor", SIDE_BOTTOM, bottom_right_anchor.y, false, true);
- undo_redo->add_do_method(control, "set_meta", "_edit_use_anchors_", true);
-
- bool use_anchors = control->has_meta("_edit_use_anchors_") && control->get_meta("_edit_use_anchors_");
- undo_redo->add_undo_method(control, "_edit_set_state", control->_edit_get_state());
- undo_redo->add_undo_method(control, "set_meta", "_edit_use_anchors_", use_anchors);
-
- anchors_mode = true;
- anchor_mode_button->set_pressed(anchors_mode);
- }
- }
-
- undo_redo->commit_action();
-}
-
-void CanvasItemEditor::_set_anchors_preset(Control::LayoutPreset p_preset) {
- List<Node *> selection = editor_selection->get_selected_node_list();
-
- undo_redo->create_action(TTR("Change Anchors"));
- for (Node *E : selection) {
- Control *control = Object::cast_to<Control>(E);
- if (control) {
- undo_redo->add_do_method(control, "set_anchors_preset", p_preset);
- undo_redo->add_undo_method(control, "_edit_set_state", control->_edit_get_state());
- }
- }
-
- undo_redo->commit_action();
-}
-
void CanvasItemEditor::_zoom_on_position(real_t p_zoom, Point2 p_position) {
p_zoom = CLAMP(p_zoom, MIN_ZOOM, MAX_ZOOM);
@@ -4189,6 +4010,10 @@ void CanvasItemEditor::_update_zoom(real_t p_zoom) {
_zoom_on_position(p_zoom, viewport_scrollable->get_size() / 2.0);
}
+void CanvasItemEditor::_shortcut_zoom_set(real_t p_zoom) {
+ _zoom_on_position(p_zoom * MAX(1, EDSCALE), viewport->get_local_mouse_position());
+}
+
void CanvasItemEditor::_button_toggle_smart_snap(bool p_status) {
smart_snap_active = p_status;
viewport->update();
@@ -4298,21 +4123,6 @@ void CanvasItemEditor::_insert_animation_keys(bool p_location, bool p_rotation,
}
}
-void CanvasItemEditor::_button_toggle_anchor_mode(bool p_status) {
- List<CanvasItem *> selection = _get_edited_canvas_items(false, false);
- for (CanvasItem *E : selection) {
- Control *control = Object::cast_to<Control>(E);
- if (!control || Object::cast_to<Container>(control->get_parent())) {
- continue;
- }
-
- control->set_meta("_edit_use_anchors_", p_status);
- }
-
- anchors_mode = p_status;
- viewport->update();
-}
-
void CanvasItemEditor::_update_override_camera_button(bool p_game_running) {
if (p_game_running) {
override_camera_button->set_disabled(false);
@@ -4534,106 +4344,6 @@ void CanvasItemEditor::_popup_callback(int p_op) {
undo_redo->add_undo_method(viewport, "update", Variant());
undo_redo->commit_action();
} break;
- case ANCHORS_AND_OFFSETS_PRESET_TOP_LEFT: {
- _set_anchors_and_offsets_preset(PRESET_TOP_LEFT);
- } break;
- case ANCHORS_AND_OFFSETS_PRESET_TOP_RIGHT: {
- _set_anchors_and_offsets_preset(PRESET_TOP_RIGHT);
- } break;
- case ANCHORS_AND_OFFSETS_PRESET_BOTTOM_LEFT: {
- _set_anchors_and_offsets_preset(PRESET_BOTTOM_LEFT);
- } break;
- case ANCHORS_AND_OFFSETS_PRESET_BOTTOM_RIGHT: {
- _set_anchors_and_offsets_preset(PRESET_BOTTOM_RIGHT);
- } break;
- case ANCHORS_AND_OFFSETS_PRESET_CENTER_LEFT: {
- _set_anchors_and_offsets_preset(PRESET_CENTER_LEFT);
- } break;
- case ANCHORS_AND_OFFSETS_PRESET_CENTER_RIGHT: {
- _set_anchors_and_offsets_preset(PRESET_CENTER_RIGHT);
- } break;
- case ANCHORS_AND_OFFSETS_PRESET_CENTER_TOP: {
- _set_anchors_and_offsets_preset(PRESET_CENTER_TOP);
- } break;
- case ANCHORS_AND_OFFSETS_PRESET_CENTER_BOTTOM: {
- _set_anchors_and_offsets_preset(PRESET_CENTER_BOTTOM);
- } break;
- case ANCHORS_AND_OFFSETS_PRESET_CENTER: {
- _set_anchors_and_offsets_preset(PRESET_CENTER);
- } break;
- case ANCHORS_AND_OFFSETS_PRESET_TOP_WIDE: {
- _set_anchors_and_offsets_preset(PRESET_TOP_WIDE);
- } break;
- case ANCHORS_AND_OFFSETS_PRESET_LEFT_WIDE: {
- _set_anchors_and_offsets_preset(PRESET_LEFT_WIDE);
- } break;
- case ANCHORS_AND_OFFSETS_PRESET_RIGHT_WIDE: {
- _set_anchors_and_offsets_preset(PRESET_RIGHT_WIDE);
- } break;
- case ANCHORS_AND_OFFSETS_PRESET_BOTTOM_WIDE: {
- _set_anchors_and_offsets_preset(PRESET_BOTTOM_WIDE);
- } break;
- case ANCHORS_AND_OFFSETS_PRESET_VCENTER_WIDE: {
- _set_anchors_and_offsets_preset(PRESET_VCENTER_WIDE);
- } break;
- case ANCHORS_AND_OFFSETS_PRESET_HCENTER_WIDE: {
- _set_anchors_and_offsets_preset(PRESET_HCENTER_WIDE);
- } break;
- case ANCHORS_AND_OFFSETS_PRESET_WIDE: {
- _set_anchors_and_offsets_preset(Control::PRESET_WIDE);
- } break;
- case ANCHORS_AND_OFFSETS_PRESET_KEEP_RATIO: {
- _set_anchors_and_offsets_to_keep_ratio();
- } break;
-
- case ANCHORS_PRESET_TOP_LEFT: {
- _set_anchors_preset(PRESET_TOP_LEFT);
- } break;
- case ANCHORS_PRESET_TOP_RIGHT: {
- _set_anchors_preset(PRESET_TOP_RIGHT);
- } break;
- case ANCHORS_PRESET_BOTTOM_LEFT: {
- _set_anchors_preset(PRESET_BOTTOM_LEFT);
- } break;
- case ANCHORS_PRESET_BOTTOM_RIGHT: {
- _set_anchors_preset(PRESET_BOTTOM_RIGHT);
- } break;
- case ANCHORS_PRESET_CENTER_LEFT: {
- _set_anchors_preset(PRESET_CENTER_LEFT);
- } break;
- case ANCHORS_PRESET_CENTER_RIGHT: {
- _set_anchors_preset(PRESET_CENTER_RIGHT);
- } break;
- case ANCHORS_PRESET_CENTER_TOP: {
- _set_anchors_preset(PRESET_CENTER_TOP);
- } break;
- case ANCHORS_PRESET_CENTER_BOTTOM: {
- _set_anchors_preset(PRESET_CENTER_BOTTOM);
- } break;
- case ANCHORS_PRESET_CENTER: {
- _set_anchors_preset(PRESET_CENTER);
- } break;
- case ANCHORS_PRESET_TOP_WIDE: {
- _set_anchors_preset(PRESET_TOP_WIDE);
- } break;
- case ANCHORS_PRESET_LEFT_WIDE: {
- _set_anchors_preset(PRESET_LEFT_WIDE);
- } break;
- case ANCHORS_PRESET_RIGHT_WIDE: {
- _set_anchors_preset(PRESET_RIGHT_WIDE);
- } break;
- case ANCHORS_PRESET_BOTTOM_WIDE: {
- _set_anchors_preset(PRESET_BOTTOM_WIDE);
- } break;
- case ANCHORS_PRESET_VCENTER_WIDE: {
- _set_anchors_preset(PRESET_VCENTER_WIDE);
- } break;
- case ANCHORS_PRESET_HCENTER_WIDE: {
- _set_anchors_preset(PRESET_HCENTER_WIDE);
- } break;
- case ANCHORS_PRESET_WIDE: {
- _set_anchors_preset(Control::PRESET_WIDE);
- } break;
case ANIM_INSERT_KEY:
case ANIM_INSERT_KEY_EXISTING: {
@@ -4854,7 +4564,7 @@ void CanvasItemEditor::_focus_selection(int p_op) {
if (p_op == VIEW_CENTER_TO_SELECTION) {
center = rect.get_center();
- Vector2 offset = viewport->get_size() / 2 - editor->get_scene_root()->get_global_canvas_transform().xform(center);
+ Vector2 offset = viewport->get_size() / 2 - EditorNode::get_singleton()->get_scene_root()->get_global_canvas_transform().xform(center);
view_offset -= (offset / zoom).round();
update_viewport();
@@ -5127,67 +4837,24 @@ void CanvasItemEditor::focus_selection() {
_focus_selection(VIEW_CENTER_TO_SELECTION);
}
-CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
- key_pos = true;
- key_rot = true;
- key_scale = false;
-
- show_grid = false;
- show_origin = true;
- show_viewport = true;
- show_helpers = false;
- show_rulers = true;
- show_guides = true;
- show_transformation_gizmos = true;
- show_edit_locks = true;
+CanvasItemEditor::CanvasItemEditor() {
zoom = 1.0 / MAX(1, EDSCALE);
view_offset = Point2(-150 - RULER_WIDTH, -95 - RULER_WIDTH);
previous_update_view_offset = view_offset; // Moves the view a little bit to the left so that (0,0) is visible. The values a relative to a 16/10 screen
+
grid_offset = Point2();
grid_step = Point2(8, 8); // A power-of-two value works better as a default
primary_grid_steps = 8; // A power-of-two value works better as a default
grid_step_multiplier = 0;
+
snap_rotation_offset = 0;
snap_rotation_step = Math::deg2rad(15.0);
snap_scale_step = 0.1f;
- smart_snap_active = false;
- grid_snap_active = false;
- snap_node_parent = true;
- snap_node_anchors = true;
- snap_node_sides = true;
- snap_node_center = true;
- snap_other_nodes = true;
- snap_guides = true;
- snap_rotation = false;
- snap_scale = false;
- snap_relative = false;
- // Enable pixel snapping even if pixel snap rendering is disabled in the Project Settings.
- // This results in crisper visuals by preventing 2D nodes from being placed at subpixel coordinates.
- snap_pixel = true;
snap_target[0] = SNAP_TARGET_NONE;
snap_target[1] = SNAP_TARGET_NONE;
- selected_from_canvas = false;
- anchors_mode = false;
-
- drag_type = DRAG_NONE;
- drag_from = Vector2();
- drag_to = Vector2();
- dragged_guide_pos = Point2();
- dragged_guide_index = -1;
- is_hovering_h_guide = false;
- is_hovering_v_guide = false;
- pan_pressed = false;
-
- ruler_tool_active = false;
- ruler_tool_origin = Point2();
-
- bone_last_frame = 0;
-
- tool = TOOL_SELECT;
- undo_redo = p_editor->get_undo_redo();
- editor = p_editor;
- editor_selection = p_editor->get_editor_selection();
+ 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((CanvasItem *)this, &CanvasItem::update));
editor_selection->connect("selection_changed", callable_mp(this, &CanvasItemEditor::_selection_changed));
@@ -5195,8 +4862,8 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
SceneTreeDock::get_singleton()->connect("node_created", callable_mp(this, &CanvasItemEditor::_node_created));
SceneTreeDock::get_singleton()->connect("add_node_used", callable_mp(this, &CanvasItemEditor::_reset_create_position));
- editor->call_deferred(SNAME("connect"), "play_pressed", Callable(this, "_update_override_camera_button"), make_binds(true));
- editor->call_deferred(SNAME("connect"), "stop_pressed", Callable(this, "_update_override_camera_button"), make_binds(false));
+ EditorNode::get_singleton()->call_deferred(SNAME("connect"), "play_pressed", Callable(this, "_update_override_camera_button"), make_binds(true));
+ EditorNode::get_singleton()->call_deferred(SNAME("connect"), "stop_pressed", Callable(this, "_update_override_camera_button"), make_binds(false));
hb = memnew(HBoxContainer);
add_child(hb);
@@ -5226,7 +4893,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
viewport_scrollable->add_child(scene_tree);
scene_tree->set_stretch(true);
scene_tree->set_anchors_and_offsets_preset(Control::PRESET_WIDE);
- scene_tree->add_child(p_editor->get_scene_root());
+ scene_tree->add_child(EditorNode::get_singleton()->get_scene_root());
controls_vb = memnew(VBoxContainer);
controls_vb->set_begin(Point2(5, 5));
@@ -5239,7 +4906,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
panner.instantiate();
panner->set_callbacks(callable_mp(this, &CanvasItemEditor::_scroll_callback), callable_mp(this, &CanvasItemEditor::_pan_callback), callable_mp(this, &CanvasItemEditor::_zoom_callback));
- viewport = memnew(CanvasItemEditorViewport(p_editor, this));
+ viewport = memnew(CanvasItemEditorViewport(this));
viewport_scrollable->add_child(viewport);
viewport->set_mouse_filter(MOUSE_FILTER_PASS);
viewport->set_anchors_and_offsets_preset(Control::PRESET_WIDE);
@@ -5261,8 +4928,6 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
viewport->add_child(controls_vb);
- updating_scroll = false;
-
// Add some margin to the left for better aesthetics.
// This prevents the first button's hover/pressed effect from "touching" the panel's border,
// which looks ugly.
@@ -5492,28 +5157,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
hb->add_child(context_menu_container);
_update_context_menu_stylebox();
- presets_menu = memnew(MenuButton);
- presets_menu->set_shortcut_context(this);
- presets_menu->set_text(TTR("Layout"));
- hbc_context_menu->add_child(presets_menu);
- presets_menu->hide();
- presets_menu->set_switch_on_hover(true);
-
- p = presets_menu->get_popup();
- p->connect("id_pressed", callable_mp(this, &CanvasItemEditor::_popup_callback));
-
- anchors_popup = memnew(PopupMenu);
- p->add_child(anchors_popup);
- anchors_popup->set_name("Anchors");
- anchors_popup->connect("id_pressed", callable_mp(this, &CanvasItemEditor::_popup_callback));
-
- anchor_mode_button = memnew(Button);
- anchor_mode_button->set_flat(true);
- hbc_context_menu->add_child(anchor_mode_button);
- anchor_mode_button->set_toggle_mode(true);
- anchor_mode_button->hide();
- anchor_mode_button->connect("toggled", callable_mp(this, &CanvasItemEditor::_button_toggle_anchor_mode));
-
+ // Animation controls.
animation_hb = memnew(HBoxContainer);
hbc_context_menu->add_child(animation_hb);
animation_hb->add_child(memnew(VSeparator));
@@ -5599,6 +5243,8 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
divide_grid_step_shortcut = ED_SHORTCUT("canvas_item_editor/divide_grid_step", TTR("Divide grid step by 2"), Key::KP_DIVIDE);
skeleton_menu->get_popup()->set_item_checked(skeleton_menu->get_popup()->get_item_index(SKELETON_SHOW_BONES), true);
+
+ // Store the singleton instance.
singleton = this;
// To ensure that scripts can parse the list of shortcuts correctly, we have to define
@@ -5637,12 +5283,12 @@ void CanvasItemEditorPlugin::make_visible(bool p_visible) {
if (p_visible) {
canvas_item_editor->show();
canvas_item_editor->set_physics_process(true);
- RenderingServer::get_singleton()->viewport_set_disable_2d(editor->get_scene_root()->get_viewport_rid(), false);
+ RenderingServer::get_singleton()->viewport_set_disable_2d(EditorNode::get_singleton()->get_scene_root()->get_viewport_rid(), false);
} else {
canvas_item_editor->hide();
canvas_item_editor->set_physics_process(false);
- RenderingServer::get_singleton()->viewport_set_disable_2d(editor->get_scene_root()->get_viewport_rid(), true);
+ RenderingServer::get_singleton()->viewport_set_disable_2d(EditorNode::get_singleton()->get_scene_root()->get_viewport_rid(), true);
}
}
@@ -5654,11 +5300,10 @@ void CanvasItemEditorPlugin::set_state(const Dictionary &p_state) {
canvas_item_editor->set_state(p_state);
}
-CanvasItemEditorPlugin::CanvasItemEditorPlugin(EditorNode *p_node) {
- editor = p_node;
- canvas_item_editor = memnew(CanvasItemEditor(editor));
+CanvasItemEditorPlugin::CanvasItemEditorPlugin() {
+ canvas_item_editor = memnew(CanvasItemEditor);
canvas_item_editor->set_v_size_flags(Control::SIZE_EXPAND_FILL);
- editor->get_main_control()->add_child(canvas_item_editor);
+ EditorNode::get_singleton()->get_main_control()->add_child(canvas_item_editor);
canvas_item_editor->set_anchors_and_offsets_preset(Control::PRESET_WIDE);
canvas_item_editor->hide();
}
@@ -5726,7 +5371,7 @@ void CanvasItemEditorViewport::_create_preview(const Vector<String> &files) cons
}
if (add_preview) {
- editor->get_scene_root()->add_child(preview_node);
+ EditorNode::get_singleton()->get_scene_root()->add_child(preview_node);
}
}
@@ -5737,7 +5382,7 @@ void CanvasItemEditorViewport::_remove_preview() {
node->queue_delete();
preview_node->remove_child(node);
}
- editor->get_scene_root()->remove_child(preview_node);
+ EditorNode::get_singleton()->get_scene_root()->remove_child(preview_node);
label->hide();
label_desc->hide();
@@ -5780,39 +5425,34 @@ void CanvasItemEditorViewport::_create_nodes(Node *parent, Node *child, String &
if (parent) {
editor_data->get_undo_redo().add_do_method(parent, "add_child", child, true);
- editor_data->get_undo_redo().add_do_method(child, "set_owner", editor->get_edited_scene());
+ editor_data->get_undo_redo().add_do_method(child, "set_owner", EditorNode::get_singleton()->get_edited_scene());
editor_data->get_undo_redo().add_do_reference(child);
editor_data->get_undo_redo().add_undo_method(parent, "remove_child", child);
} else { // If no parent is selected, set as root node of the scene.
- editor_data->get_undo_redo().add_do_method(editor, "set_edited_scene", child);
- editor_data->get_undo_redo().add_do_method(child, "set_owner", editor->get_edited_scene());
+ editor_data->get_undo_redo().add_do_method(EditorNode::get_singleton(), "set_edited_scene", child);
+ editor_data->get_undo_redo().add_do_method(child, "set_owner", EditorNode::get_singleton()->get_edited_scene());
editor_data->get_undo_redo().add_do_reference(child);
- editor_data->get_undo_redo().add_undo_method(editor, "set_edited_scene", (Object *)nullptr);
+ editor_data->get_undo_redo().add_undo_method(EditorNode::get_singleton(), "set_edited_scene", (Object *)nullptr);
}
if (parent) {
String new_name = parent->validate_child_name(child);
EditorDebuggerNode *ed = EditorDebuggerNode::get_singleton();
- editor_data->get_undo_redo().add_do_method(ed, "live_debug_create_node", editor->get_edited_scene()->get_path_to(parent), child->get_class(), new_name);
- editor_data->get_undo_redo().add_undo_method(ed, "live_debug_remove_node", NodePath(String(editor->get_edited_scene()->get_path_to(parent)) + "/" + new_name));
+ editor_data->get_undo_redo().add_do_method(ed, "live_debug_create_node", EditorNode::get_singleton()->get_edited_scene()->get_path_to(parent), child->get_class(), new_name);
+ editor_data->get_undo_redo().add_undo_method(ed, "live_debug_remove_node", NodePath(String(EditorNode::get_singleton()->get_edited_scene()->get_path_to(parent)) + "/" + new_name));
}
- String node_class = child->get_class();
- if (node_class == "Polygon2D") {
- editor_data->get_undo_redo().add_do_property(child, "texture/texture", texture);
- } else if (node_class == "TouchScreenButton") {
- editor_data->get_undo_redo().add_do_property(child, "normal", texture);
- } else if (node_class == "TextureButton") {
- editor_data->get_undo_redo().add_do_property(child, "texture_button", texture);
+ if (Object::cast_to<TouchScreenButton>(child) || Object::cast_to<TextureButton>(child)) {
+ editor_data->get_undo_redo().add_do_property(child, "texture_normal", texture);
} else {
editor_data->get_undo_redo().add_do_property(child, "texture", texture);
}
// make visible for certain node type
- if (ClassDB::is_parent_class(node_class, "Control")) {
+ if (Object::cast_to<Control>(child)) {
Size2 texture_size = texture->get_size();
editor_data->get_undo_redo().add_do_property(child, "rect_size", texture_size);
- } else if (node_class == "Polygon2D") {
+ } else if (Object::cast_to<Polygon2D>(child)) {
Size2 texture_size = texture->get_size();
Vector<Vector2> list = {
Vector2(0, 0),
@@ -5843,8 +5483,10 @@ bool CanvasItemEditorViewport::_create_instance(Node *parent, String &path, cons
return false;
}
- if (!editor->get_edited_scene()->get_scene_file_path().is_empty()) { // cyclical instancing
- if (_cyclical_dependency_exists(editor->get_edited_scene()->get_scene_file_path(), instantiated_scene)) {
+ Node *edited_scene = EditorNode::get_singleton()->get_edited_scene();
+
+ if (!edited_scene->get_scene_file_path().is_empty()) { // cyclical instancing
+ if (_cyclical_dependency_exists(edited_scene->get_scene_file_path(), instantiated_scene)) {
memdelete(instantiated_scene);
return false;
}
@@ -5853,25 +5495,27 @@ bool CanvasItemEditorViewport::_create_instance(Node *parent, String &path, cons
instantiated_scene->set_scene_file_path(ProjectSettings::get_singleton()->localize_path(path));
editor_data->get_undo_redo().add_do_method(parent, "add_child", instantiated_scene, true);
- editor_data->get_undo_redo().add_do_method(instantiated_scene, "set_owner", editor->get_edited_scene());
+ editor_data->get_undo_redo().add_do_method(instantiated_scene, "set_owner", edited_scene);
editor_data->get_undo_redo().add_do_reference(instantiated_scene);
editor_data->get_undo_redo().add_undo_method(parent, "remove_child", instantiated_scene);
String new_name = parent->validate_child_name(instantiated_scene);
EditorDebuggerNode *ed = EditorDebuggerNode::get_singleton();
- editor_data->get_undo_redo().add_do_method(ed, "live_debug_instance_node", editor->get_edited_scene()->get_path_to(parent), path, new_name);
- editor_data->get_undo_redo().add_undo_method(ed, "live_debug_remove_node", NodePath(String(editor->get_edited_scene()->get_path_to(parent)) + "/" + new_name));
+ editor_data->get_undo_redo().add_do_method(ed, "live_debug_instance_node", edited_scene->get_path_to(parent), path, new_name);
+ editor_data->get_undo_redo().add_undo_method(ed, "live_debug_remove_node", NodePath(String(edited_scene->get_path_to(parent)) + "/" + new_name));
- CanvasItem *parent_ci = Object::cast_to<CanvasItem>(parent);
- if (parent_ci) {
+ CanvasItem *instance_ci = Object::cast_to<CanvasItem>(instantiated_scene);
+ if (instance_ci) {
Vector2 target_pos = canvas_item_editor->get_canvas_transform().affine_inverse().xform(p_point);
target_pos = canvas_item_editor->snap_point(target_pos);
- target_pos = parent_ci->get_global_transform_with_canvas().affine_inverse().xform(target_pos);
- // Preserve instance position of the original scene.
- CanvasItem *instance_ci = Object::cast_to<CanvasItem>(instantiated_scene);
- if (instance_ci) {
- target_pos += instance_ci->_edit_get_position();
+
+ CanvasItem *parent_ci = Object::cast_to<CanvasItem>(parent);
+ if (parent_ci) {
+ target_pos = parent_ci->get_global_transform_with_canvas().affine_inverse().xform(target_pos);
}
+ // Preserve instance position of the original scene.
+ target_pos += instance_ci->_edit_get_position();
+
editor_data->get_undo_redo().add_do_method(instantiated_scene, "set_position", target_pos);
}
@@ -5940,29 +5584,30 @@ bool CanvasItemEditorViewport::can_drop_data(const Point2 &p_point, const Varian
if (String(d["type"]) == "files") {
Vector<String> files = d["files"];
bool can_instantiate = false;
- for (int i = 0; i < files.size(); i++) { // check if dragged files contain resource or scene can be created at least once
- RES res = ResourceLoader::load(files[i]);
- if (res.is_null()) {
- continue;
- }
- String type = res->get_class();
- if (type == "PackedScene") {
- Ref<PackedScene> sdata = Ref<PackedScene>(Object::cast_to<PackedScene>(*res));
- Node *instantiated_scene = sdata->instantiate(PackedScene::GEN_EDIT_STATE_INSTANCE);
- if (!instantiated_scene) {
+
+ List<String> scene_extensions;
+ ResourceLoader::get_recognized_extensions_for_type("PackedScene", &scene_extensions);
+ List<String> texture_extensions;
+ ResourceLoader::get_recognized_extensions_for_type("Texture2D", &texture_extensions);
+
+ for (int i = 0; i < files.size(); i++) {
+ // Check if dragged files with texture or scene extension can be created at least once.
+ if (texture_extensions.find(files[i].get_extension()) || scene_extensions.find(files[i].get_extension())) {
+ RES res = ResourceLoader::load(files[i]);
+ if (res.is_null()) {
continue;
}
- memdelete(instantiated_scene);
- } else if (ClassDB::is_parent_class(type, "Texture2D")) {
- Ref<Texture2D> texture = Ref<Texture2D>(Object::cast_to<Texture2D>(*res));
- if (!texture.is_valid()) {
- continue;
+ Ref<PackedScene> scn = res;
+ if (scn.is_valid()) {
+ Node *instantiated_scene = scn->instantiate(PackedScene::GEN_EDIT_STATE_INSTANCE);
+ if (!instantiated_scene) {
+ continue;
+ }
+ memdelete(instantiated_scene);
}
- } else {
- continue;
+ can_instantiate = true;
+ break;
}
- can_instantiate = true;
- break;
}
if (can_instantiate) {
if (!preview_node->get_parent()) { // create preview only once
@@ -6016,8 +5661,8 @@ void CanvasItemEditorViewport::drop_data(const Point2 &p_point, const Variant &p
return;
}
- List<Node *> selected_nodes = editor->get_editor_selection()->get_selected_node_list();
- Node *root_node = editor->get_edited_scene();
+ List<Node *> selected_nodes = EditorNode::get_singleton()->get_editor_selection()->get_selected_node_list();
+ Node *root_node = EditorNode::get_singleton()->get_edited_scene();
if (selected_nodes.size() > 0) {
Node *selected_node = selected_nodes[0];
target_node = root_node;
@@ -6068,25 +5713,39 @@ Node *CanvasItemEditorViewport::_make_texture_node_type(String texture_node_type
return node;
}
+void CanvasItemEditorViewport::_update_theme() {
+ List<BaseButton *> btn_list;
+ button_group->get_buttons(&btn_list);
+
+ for (int i = 0; i < btn_list.size(); i++) {
+ CheckBox *check = Object::cast_to<CheckBox>(btn_list[i]);
+ check->set_icon(get_theme_icon(check->get_text(), SNAME("EditorIcons")));
+ }
+
+ label->add_theme_color_override("font_color", get_theme_color(SNAME("warning_color"), SNAME("Editor")));
+}
+
void CanvasItemEditorViewport::_notification(int p_what) {
switch (p_what) {
+ case NOTIFICATION_THEME_CHANGED: {
+ _update_theme();
+ } break;
+
case NOTIFICATION_ENTER_TREE: {
+ _update_theme();
connect("mouse_exited", callable_mp(this, &CanvasItemEditorViewport::_on_mouse_exit));
- label->add_theme_color_override("font_color", get_theme_color(SNAME("warning_color"), SNAME("Editor")));
} break;
+
case NOTIFICATION_EXIT_TREE: {
disconnect("mouse_exited", callable_mp(this, &CanvasItemEditorViewport::_on_mouse_exit));
} break;
-
- default:
- break;
}
}
void CanvasItemEditorViewport::_bind_methods() {
}
-CanvasItemEditorViewport::CanvasItemEditorViewport(EditorNode *p_node, CanvasItemEditor *p_canvas_item_editor) {
+CanvasItemEditorViewport::CanvasItemEditorViewport(CanvasItemEditor *p_canvas_item_editor) {
default_texture_node_type = "Sprite2D";
// Node2D
texture_node_types.push_back("Sprite2D");
@@ -6101,16 +5760,15 @@ CanvasItemEditorViewport::CanvasItemEditorViewport(EditorNode *p_node, CanvasIte
texture_node_types.push_back("NinePatchRect");
target_node = nullptr;
- editor = p_node;
editor_data = SceneTreeDock::get_singleton()->get_editor_data();
canvas_item_editor = p_canvas_item_editor;
preview_node = memnew(Control);
accept = memnew(AcceptDialog);
- editor->get_gui_base()->add_child(accept);
+ EditorNode::get_singleton()->get_gui_base()->add_child(accept);
selector = memnew(AcceptDialog);
- editor->get_gui_base()->add_child(selector);
+ EditorNode::get_singleton()->get_gui_base()->add_child(selector);
selector->set_title(TTR("Change Default Type"));
selector->connect("confirmed", callable_mp(this, &CanvasItemEditorViewport::_on_change_type_confirmed));
selector->connect("cancelled", callable_mp(this, &CanvasItemEditorViewport::_on_change_type_closed));
@@ -6123,7 +5781,7 @@ CanvasItemEditorViewport::CanvasItemEditorViewport(EditorNode *p_node, CanvasIte
btn_group = memnew(VBoxContainer);
vbc->add_child(btn_group);
- btn_group->set_h_size_flags(0);
+ btn_group->set_h_size_flags(SIZE_EXPAND_FILL);
button_group.instantiate();
for (int i = 0; i < texture_node_types.size(); i++) {
diff --git a/editor/plugins/canvas_item_editor_plugin.h b/editor/plugins/canvas_item_editor_plugin.h
index 9fa44bfb25..e7c265ee02 100644
--- a/editor/plugins/canvas_item_editor_plugin.h
+++ b/editor/plugins/canvas_item_editor_plugin.h
@@ -28,10 +28,9 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef CONTROL_EDITOR_PLUGIN_H
-#define CONTROL_EDITOR_PLUGIN_H
+#ifndef CANVAS_ITEM_EDITOR_PLUGIN_H
+#define CANVAS_ITEM_EDITOR_PLUGIN_H
-#include "editor/editor_node.h"
#include "editor/editor_plugin.h"
#include "editor/editor_zoom_widget.h"
#include "scene/gui/box_container.h"
@@ -39,8 +38,11 @@
#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 EditorData;
class CanvasItemEditorViewport;
class ViewPanner;
@@ -89,8 +91,6 @@ public:
};
private:
- EditorNode *editor;
-
enum SnapTarget {
SNAP_TARGET_NONE = 0,
SNAP_TARGET_PARENT,
@@ -128,55 +128,6 @@ private:
UNLOCK_SELECTED,
GROUP_SELECTED,
UNGROUP_SELECTED,
- ANCHORS_AND_OFFSETS_PRESET_TOP_LEFT,
- ANCHORS_AND_OFFSETS_PRESET_TOP_RIGHT,
- ANCHORS_AND_OFFSETS_PRESET_BOTTOM_LEFT,
- ANCHORS_AND_OFFSETS_PRESET_BOTTOM_RIGHT,
- ANCHORS_AND_OFFSETS_PRESET_CENTER_LEFT,
- ANCHORS_AND_OFFSETS_PRESET_CENTER_RIGHT,
- ANCHORS_AND_OFFSETS_PRESET_CENTER_TOP,
- ANCHORS_AND_OFFSETS_PRESET_CENTER_BOTTOM,
- ANCHORS_AND_OFFSETS_PRESET_CENTER,
- ANCHORS_AND_OFFSETS_PRESET_TOP_WIDE,
- ANCHORS_AND_OFFSETS_PRESET_LEFT_WIDE,
- ANCHORS_AND_OFFSETS_PRESET_RIGHT_WIDE,
- ANCHORS_AND_OFFSETS_PRESET_BOTTOM_WIDE,
- ANCHORS_AND_OFFSETS_PRESET_VCENTER_WIDE,
- ANCHORS_AND_OFFSETS_PRESET_HCENTER_WIDE,
- ANCHORS_AND_OFFSETS_PRESET_WIDE,
- ANCHORS_AND_OFFSETS_PRESET_KEEP_RATIO,
- ANCHORS_PRESET_TOP_LEFT,
- ANCHORS_PRESET_TOP_RIGHT,
- ANCHORS_PRESET_BOTTOM_LEFT,
- ANCHORS_PRESET_BOTTOM_RIGHT,
- ANCHORS_PRESET_CENTER_LEFT,
- ANCHORS_PRESET_CENTER_RIGHT,
- ANCHORS_PRESET_CENTER_TOP,
- ANCHORS_PRESET_CENTER_BOTTOM,
- ANCHORS_PRESET_CENTER,
- ANCHORS_PRESET_TOP_WIDE,
- ANCHORS_PRESET_LEFT_WIDE,
- ANCHORS_PRESET_RIGHT_WIDE,
- ANCHORS_PRESET_BOTTOM_WIDE,
- ANCHORS_PRESET_VCENTER_WIDE,
- ANCHORS_PRESET_HCENTER_WIDE,
- ANCHORS_PRESET_WIDE,
- OFFSETS_PRESET_TOP_LEFT,
- OFFSETS_PRESET_TOP_RIGHT,
- OFFSETS_PRESET_BOTTOM_LEFT,
- OFFSETS_PRESET_BOTTOM_RIGHT,
- OFFSETS_PRESET_CENTER_LEFT,
- OFFSETS_PRESET_CENTER_RIGHT,
- OFFSETS_PRESET_CENTER_TOP,
- OFFSETS_PRESET_CENTER_BOTTOM,
- OFFSETS_PRESET_CENTER,
- OFFSETS_PRESET_TOP_WIDE,
- OFFSETS_PRESET_LEFT_WIDE,
- OFFSETS_PRESET_RIGHT_WIDE,
- OFFSETS_PRESET_BOTTOM_WIDE,
- OFFSETS_PRESET_VCENTER_WIDE,
- OFFSETS_PRESET_HCENTER_WIDE,
- OFFSETS_PRESET_WIDE,
ANIM_INSERT_KEY,
ANIM_INSERT_KEY_EXISTING,
ANIM_INSERT_POS,
@@ -226,7 +177,7 @@ private:
bool selection_menu_additive_selection;
- Tool tool;
+ Tool tool = TOOL_SELECT;
Control *viewport;
Control *viewport_scrollable;
@@ -239,21 +190,20 @@ private:
HBoxContainer *hbc_context_menu;
Transform2D transform;
- bool show_grid;
- bool show_rulers;
- bool show_guides;
- bool show_origin;
- bool show_viewport;
- bool show_helpers;
- bool show_edit_locks;
- bool show_transformation_gizmos;
+ bool show_grid = false;
+ bool show_rulers = true;
+ bool show_guides = true;
+ bool show_origin = true;
+ bool show_viewport = true;
+ bool show_helpers = false;
+ bool show_edit_locks = true;
+ bool show_transformation_gizmos = true;
real_t zoom;
Point2 view_offset;
Point2 previous_update_view_offset;
- bool selected_from_canvas;
- bool anchors_mode;
+ bool selected_from_canvas = false;
Point2 grid_offset;
Point2 grid_step;
@@ -263,26 +213,30 @@ private:
real_t snap_rotation_step;
real_t snap_rotation_offset;
real_t snap_scale_step;
- bool smart_snap_active;
- bool grid_snap_active;
-
- bool snap_node_parent;
- bool snap_node_anchors;
- bool snap_node_sides;
- bool snap_node_center;
- bool snap_other_nodes;
- bool snap_guides;
- bool snap_rotation;
- bool snap_scale;
- bool snap_relative;
- bool snap_pixel;
- bool key_pos;
- bool key_rot;
- bool key_scale;
- bool pan_pressed;
-
- bool ruler_tool_active;
- Point2 ruler_tool_origin;
+ bool smart_snap_active = false;
+ bool grid_snap_active = false;
+
+ bool snap_node_parent = true;
+ bool snap_node_anchors = true;
+ bool snap_node_sides = true;
+ bool snap_node_center = true;
+ bool snap_other_nodes = true;
+ bool snap_guides = true;
+ bool snap_rotation = false;
+ bool snap_scale = false;
+ bool snap_relative = false;
+ // Enable pixel snapping even if pixel snap rendering is disabled in the Project Settings.
+ // This results in crisper visuals by preventing 2D nodes from being placed at subpixel coordinates.
+ bool snap_pixel = true;
+
+ bool key_pos = true;
+ bool key_rot = true;
+ bool key_scale = false;
+
+ bool pan_pressed = false;
+
+ bool ruler_tool_active = false;
+ Point2 ruler_tool_origin = Point2();
Point2 node_create_position;
MenuOption last_option;
@@ -310,7 +264,7 @@ private:
uint64_t last_pass = 0;
};
- uint64_t bone_last_frame;
+ uint64_t bone_last_frame = 0;
struct BoneKey {
ObjectID from;
@@ -363,12 +317,6 @@ private:
HBoxContainer *animation_hb;
MenuButton *animation_menu;
- MenuButton *presets_menu;
- PopupMenu *anchors_and_margins_popup;
- PopupMenu *anchors_popup;
-
- Button *anchor_mode_button;
-
Button *key_loc_button;
Button *key_rot_button;
Button *key_scale_button;
@@ -382,15 +330,15 @@ private:
Control *left_ruler;
Point2 drag_start_origin;
- DragType drag_type;
- Point2 drag_from;
- Point2 drag_to;
+ DragType drag_type = DRAG_NONE;
+ Point2 drag_from = Vector2();
+ Point2 drag_to = Vector2();
Point2 drag_rotation_center;
List<CanvasItem *> drag_selection;
- int dragged_guide_index;
- Point2 dragged_guide_pos;
- bool is_hovering_h_guide;
- bool is_hovering_v_guide;
+ int dragged_guide_index = -1;
+ Point2 dragged_guide_pos = Point2();
+ bool is_hovering_h_guide = false;
+ bool is_hovering_v_guide = false;
bool updating_value_dialog;
@@ -432,7 +380,7 @@ private:
Vector2 _position_to_anchor(const Control *p_control, Vector2 position);
void _popup_callback(int p_op);
- bool updating_scroll;
+ bool updating_scroll = false;
void _update_scroll(real_t);
void _update_scrollbars();
void _snap_changed();
@@ -441,10 +389,11 @@ private:
void _add_node_pressed(int p_result);
void _node_created(Node *p_node);
void _reset_create_position();
+ void _update_editor_settings();
UndoRedo *undo_redo;
- List<CanvasItem *> _get_edited_canvas_items(bool retreive_locked = false, bool remove_canvas_item_if_parent_in_selection = true);
+ List<CanvasItem *> _get_edited_canvas_items(bool retrieve_locked = false, bool remove_canvas_item_if_parent_in_selection = true);
Rect2 _get_encompassing_rect_from_list(List<CanvasItem *> p_list);
void _expand_encompassing_rect_using_children(Rect2 &r_rect, const Node *p_node, bool &r_first, const Transform2D &p_parent_xform = Transform2D(), const Transform2D &p_canvas_xform = Transform2D(), bool include_locked_nodes = true);
Rect2 _get_encompassing_rect(const Node *p_node);
@@ -518,15 +467,10 @@ private:
const SnapTarget p_snap_target, List<const CanvasItem *> p_exceptions,
const Node *p_current);
- void _set_anchors_preset(Control::LayoutPreset p_preset);
- void _set_anchors_and_offsets_preset(Control::LayoutPreset p_preset);
- void _set_anchors_and_offsets_to_keep_ratio();
-
- void _button_toggle_anchor_mode(bool p_status);
-
VBoxContainer *controls_vb;
EditorZoomWidget *zoom_widget;
void _update_zoom(real_t p_zoom);
+ void _shortcut_zoom_set(real_t p_zoom);
void _zoom_on_position(real_t p_zoom, Point2 p_position = Point2());
void _button_toggle_smart_snap(bool p_status);
void _button_toggle_grid_snap(bool p_status);
@@ -602,18 +546,15 @@ public:
void focus_selection();
- bool is_anchors_mode_enabled() { return anchors_mode; };
-
EditorSelection *editor_selection;
- CanvasItemEditor(EditorNode *p_editor);
+ CanvasItemEditor();
};
class CanvasItemEditorPlugin : public EditorPlugin {
GDCLASS(CanvasItemEditorPlugin, EditorPlugin);
CanvasItemEditor *canvas_item_editor;
- EditorNode *editor;
public:
virtual String get_name() const override { return "2D"; }
@@ -626,7 +567,7 @@ public:
CanvasItemEditor *get_canvas_item_editor() { return canvas_item_editor; }
- CanvasItemEditorPlugin(EditorNode *p_node);
+ CanvasItemEditorPlugin();
~CanvasItemEditorPlugin();
};
@@ -642,7 +583,6 @@ class CanvasItemEditorViewport : public Control {
Node *target_node;
Point2 drop_pos;
- EditorNode *editor;
EditorData *editor_data;
CanvasItemEditor *canvas_item_editor;
Control *preview_node;
@@ -669,6 +609,7 @@ class CanvasItemEditorViewport : public Control {
bool _create_instance(Node *parent, String &path, const Point2 &p_point);
void _perform_drop_data();
void _show_resource_type_selector();
+ void _update_theme();
static void _bind_methods();
@@ -679,8 +620,8 @@ public:
virtual bool can_drop_data(const Point2 &p_point, const Variant &p_data) const override;
virtual void drop_data(const Point2 &p_point, const Variant &p_data) override;
- CanvasItemEditorViewport(EditorNode *p_node, CanvasItemEditor *p_canvas_item_editor);
+ CanvasItemEditorViewport(CanvasItemEditor *p_canvas_item_editor);
~CanvasItemEditorViewport();
};
-#endif
+#endif //CANVAS_ITEM_EDITOR_PLUGIN_H
diff --git a/editor/plugins/collision_polygon_2d_editor_plugin.cpp b/editor/plugins/collision_polygon_2d_editor_plugin.cpp
index 22d3768a97..5d769e7987 100644
--- a/editor/plugins/collision_polygon_2d_editor_plugin.cpp
+++ b/editor/plugins/collision_polygon_2d_editor_plugin.cpp
@@ -38,11 +38,11 @@ void CollisionPolygon2DEditor::_set_node(Node *p_polygon) {
node = Object::cast_to<CollisionPolygon2D>(p_polygon);
}
-CollisionPolygon2DEditor::CollisionPolygon2DEditor(EditorNode *p_editor) :
- AbstractPolygon2DEditor(p_editor) {
+CollisionPolygon2DEditor::CollisionPolygon2DEditor() :
+ AbstractPolygon2DEditor() {
node = nullptr;
}
-CollisionPolygon2DEditorPlugin::CollisionPolygon2DEditorPlugin(EditorNode *p_node) :
- AbstractPolygon2DEditorPlugin(p_node, memnew(CollisionPolygon2DEditor(p_node)), "CollisionPolygon2D") {
+CollisionPolygon2DEditorPlugin::CollisionPolygon2DEditorPlugin() :
+ AbstractPolygon2DEditorPlugin(memnew(CollisionPolygon2DEditor), "CollisionPolygon2D") {
}
diff --git a/editor/plugins/collision_polygon_2d_editor_plugin.h b/editor/plugins/collision_polygon_2d_editor_plugin.h
index cf2e452937..bdd4228b3b 100644
--- a/editor/plugins/collision_polygon_2d_editor_plugin.h
+++ b/editor/plugins/collision_polygon_2d_editor_plugin.h
@@ -44,14 +44,14 @@ protected:
virtual void _set_node(Node *p_polygon) override;
public:
- CollisionPolygon2DEditor(EditorNode *p_editor);
+ CollisionPolygon2DEditor();
};
class CollisionPolygon2DEditorPlugin : public AbstractPolygon2DEditorPlugin {
GDCLASS(CollisionPolygon2DEditorPlugin, AbstractPolygon2DEditorPlugin);
public:
- CollisionPolygon2DEditorPlugin(EditorNode *p_node);
+ CollisionPolygon2DEditorPlugin();
};
#endif // COLLISION_POLYGON_2D_EDITOR_PLUGIN_H
diff --git a/editor/plugins/collision_shape_2d_editor_plugin.cpp b/editor/plugins/collision_shape_2d_editor_plugin.cpp
index 8a5df6ac50..af20064a8d 100644
--- a/editor/plugins/collision_shape_2d_editor_plugin.cpp
+++ b/editor/plugins/collision_shape_2d_editor_plugin.cpp
@@ -32,6 +32,7 @@
#include "canvas_item_editor_plugin.h"
#include "core/os/keyboard.h"
+#include "editor/editor_node.h"
#include "scene/resources/capsule_shape_2d.h"
#include "scene/resources/circle_shape_2d.h"
#include "scene/resources/concave_polygon_shape_2d.h"
@@ -323,6 +324,10 @@ bool CollisionShape2DEditor::forward_canvas_gui_input(const Ref<InputEvent> &p_e
return false;
}
+ if (!node->is_visible_in_tree()) {
+ return false;
+ }
+
if (shape_type == -1) {
return false;
}
@@ -445,6 +450,10 @@ void CollisionShape2DEditor::forward_canvas_draw_over_viewport(Control *p_overla
return;
}
+ if (!node->is_visible_in_tree()) {
+ return;
+ }
+
_get_current_shape_type();
if (shape_type == -1) {
@@ -574,12 +583,11 @@ void CollisionShape2DEditor::_bind_methods() {
ClassDB::bind_method("_get_current_shape_type", &CollisionShape2DEditor::_get_current_shape_type);
}
-CollisionShape2DEditor::CollisionShape2DEditor(EditorNode *p_editor) {
+CollisionShape2DEditor::CollisionShape2DEditor() {
node = nullptr;
canvas_item_editor = nullptr;
- editor = p_editor;
- undo_redo = p_editor->get_undo_redo();
+ undo_redo = EditorNode::get_singleton()->get_undo_redo();
edit_handle = -1;
pressed = false;
@@ -601,11 +609,9 @@ void CollisionShape2DEditorPlugin::make_visible(bool visible) {
}
}
-CollisionShape2DEditorPlugin::CollisionShape2DEditorPlugin(EditorNode *p_editor) {
- editor = p_editor;
-
- collision_shape_2d_editor = memnew(CollisionShape2DEditor(p_editor));
- p_editor->get_gui_base()->add_child(collision_shape_2d_editor);
+CollisionShape2DEditorPlugin::CollisionShape2DEditorPlugin() {
+ collision_shape_2d_editor = memnew(CollisionShape2DEditor);
+ EditorNode::get_singleton()->get_gui_base()->add_child(collision_shape_2d_editor);
}
CollisionShape2DEditorPlugin::~CollisionShape2DEditorPlugin() {
diff --git a/editor/plugins/collision_shape_2d_editor_plugin.h b/editor/plugins/collision_shape_2d_editor_plugin.h
index 1c01b7019f..033ea3db93 100644
--- a/editor/plugins/collision_shape_2d_editor_plugin.h
+++ b/editor/plugins/collision_shape_2d_editor_plugin.h
@@ -31,9 +31,7 @@
#ifndef COLLISION_SHAPE_2D_EDITOR_PLUGIN_H
#define COLLISION_SHAPE_2D_EDITOR_PLUGIN_H
-#include "editor/editor_node.h"
#include "editor/editor_plugin.h"
-
#include "scene/2d/collision_shape_2d.h"
class CanvasItemEditor;
@@ -63,7 +61,6 @@ class CollisionShape2DEditor : public Control {
Point2(1, -1),
};
- EditorNode *editor;
UndoRedo *undo_redo;
CanvasItemEditor *canvas_item_editor;
CollisionShape2D *node;
@@ -93,14 +90,13 @@ public:
void forward_canvas_draw_over_viewport(Control *p_overlay);
void edit(Node *p_node);
- CollisionShape2DEditor(EditorNode *p_editor);
+ CollisionShape2DEditor();
};
class CollisionShape2DEditorPlugin : public EditorPlugin {
GDCLASS(CollisionShape2DEditorPlugin, EditorPlugin);
CollisionShape2DEditor *collision_shape_2d_editor;
- EditorNode *editor;
public:
virtual bool forward_canvas_gui_input(const Ref<InputEvent> &p_event) override { return collision_shape_2d_editor->forward_canvas_gui_input(p_event); }
@@ -112,7 +108,7 @@ public:
virtual bool handles(Object *p_obj) const override;
virtual void make_visible(bool visible) override;
- CollisionShape2DEditorPlugin(EditorNode *p_editor);
+ CollisionShape2DEditorPlugin();
~CollisionShape2DEditorPlugin();
};
diff --git a/editor/plugins/control_editor_plugin.cpp b/editor/plugins/control_editor_plugin.cpp
new file mode 100644
index 0000000000..7b85fea1e9
--- /dev/null
+++ b/editor/plugins/control_editor_plugin.cpp
@@ -0,0 +1,1034 @@
+/*************************************************************************/
+/* control_editor_plugin.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "control_editor_plugin.h"
+
+#include "editor/editor_node.h"
+#include "editor/plugins/canvas_item_editor_plugin.h"
+
+void ControlPositioningWarning::_update_warning() {
+ if (!control_node) {
+ title_icon->set_texture(nullptr);
+ title_label->set_text("");
+ hint_label->set_text("");
+ return;
+ }
+
+ Node *parent_node = control_node->get_parent_control();
+ if (!parent_node) {
+ title_icon->set_texture(get_theme_icon(SNAME("SubViewport"), SNAME("EditorIcons")));
+ title_label->set_text(TTR("This node doesn't have a control parent."));
+ hint_label->set_text(TTR("Use the appropriate layout properties depending on where you are going to put it."));
+ } else if (Object::cast_to<Container>(parent_node)) {
+ title_icon->set_texture(get_theme_icon(SNAME("Container"), SNAME("EditorIcons")));
+ title_label->set_text(TTR("This node is a child of a container."));
+ hint_label->set_text(TTR("Use container properties for positioning."));
+ } else {
+ title_icon->set_texture(get_theme_icon(SNAME("ControlLayout"), SNAME("EditorIcons")));
+ title_label->set_text(TTR("This node is a child of a regular control."));
+ hint_label->set_text(TTR("Use anchors and the rectangle for positioning."));
+ }
+
+ bg_panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("bg_group_note"), SNAME("EditorProperty")));
+}
+
+void ControlPositioningWarning::_update_toggler() {
+ Ref<Texture2D> arrow;
+ if (hint_label->is_visible()) {
+ arrow = get_theme_icon(SNAME("arrow"), SNAME("Tree"));
+ set_tooltip(TTR("Collapse positioning hint."));
+ } else {
+ if (is_layout_rtl()) {
+ arrow = get_theme_icon(SNAME("arrow_collapsed"), SNAME("Tree"));
+ } else {
+ arrow = get_theme_icon(SNAME("arrow_collapsed_mirrored"), SNAME("Tree"));
+ }
+ set_tooltip(TTR("Expand positioning hint."));
+ }
+
+ hint_icon->set_texture(arrow);
+}
+
+void ControlPositioningWarning::set_control(Control *p_node) {
+ control_node = p_node;
+ _update_warning();
+}
+
+void ControlPositioningWarning::gui_input(const Ref<InputEvent> &p_event) {
+ Ref<InputEventMouseButton> mb = p_event;
+ if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == MouseButton::LEFT) {
+ bool state = !hint_label->is_visible();
+
+ hint_filler_left->set_visible(state);
+ hint_label->set_visible(state);
+ hint_filler_right->set_visible(state);
+
+ _update_toggler();
+ }
+}
+
+void ControlPositioningWarning::_notification(int p_notification) {
+ switch (p_notification) {
+ case NOTIFICATION_ENTER_TREE:
+ case NOTIFICATION_THEME_CHANGED:
+ _update_warning();
+ _update_toggler();
+ break;
+ }
+}
+
+ControlPositioningWarning::ControlPositioningWarning() {
+ set_mouse_filter(MOUSE_FILTER_STOP);
+
+ bg_panel = memnew(PanelContainer);
+ bg_panel->set_mouse_filter(MOUSE_FILTER_IGNORE);
+ add_child(bg_panel);
+
+ grid = memnew(GridContainer);
+ grid->set_columns(3);
+ bg_panel->add_child(grid);
+
+ title_icon = memnew(TextureRect);
+ title_icon->set_stretch_mode(TextureRect::StretchMode::STRETCH_KEEP_CENTERED);
+ grid->add_child(title_icon);
+
+ title_label = memnew(Label);
+ title_label->set_autowrap_mode(Label::AutowrapMode::AUTOWRAP_WORD);
+ title_label->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ title_label->set_vertical_alignment(VerticalAlignment::VERTICAL_ALIGNMENT_CENTER);
+ grid->add_child(title_label);
+
+ hint_icon = memnew(TextureRect);
+ hint_icon->set_stretch_mode(TextureRect::StretchMode::STRETCH_KEEP_CENTERED);
+ grid->add_child(hint_icon);
+
+ // Filler.
+ hint_filler_left = memnew(Control);
+ hint_filler_left->hide();
+ grid->add_child(hint_filler_left);
+
+ hint_label = memnew(Label);
+ hint_label->set_autowrap_mode(Label::AutowrapMode::AUTOWRAP_WORD);
+ hint_label->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ hint_label->set_vertical_alignment(VerticalAlignment::VERTICAL_ALIGNMENT_CENTER);
+ hint_label->hide();
+ grid->add_child(hint_label);
+
+ // Filler.
+ hint_filler_right = memnew(Control);
+ hint_filler_right->hide();
+ grid->add_child(hint_filler_right);
+}
+
+void EditorPropertyAnchorsPreset::_set_read_only(bool p_read_only) {
+ options->set_disabled(p_read_only);
+};
+
+void EditorPropertyAnchorsPreset::_option_selected(int p_which) {
+ int64_t val = options->get_item_metadata(p_which);
+ emit_changed(get_edited_property(), val);
+}
+
+void EditorPropertyAnchorsPreset::update_property() {
+ int64_t which = get_edited_object()->get(get_edited_property());
+
+ for (int i = 0; i < options->get_item_count(); i++) {
+ Variant val = options->get_item_metadata(i);
+ if (val != Variant() && which == (int64_t)val) {
+ options->select(i);
+ return;
+ }
+ }
+}
+
+void EditorPropertyAnchorsPreset::setup(const Vector<String> &p_options) {
+ options->clear();
+
+ Vector<String> split_after;
+ split_after.append("Custom");
+ split_after.append("PresetWide");
+ split_after.append("PresetBottomLeft");
+ split_after.append("PresetCenter");
+
+ for (int i = 0, j = 0; i < p_options.size(); i++, j++) {
+ Vector<String> text_split = p_options[i].split(":");
+ int64_t current_val = text_split[1].to_int();
+
+ String humanized_name = text_split[0];
+ if (humanized_name.begins_with("Preset")) {
+ if (humanized_name == "PresetWide") {
+ humanized_name = "Full Rect";
+ } else {
+ humanized_name = humanized_name.trim_prefix("Preset");
+ humanized_name = humanized_name.capitalize();
+ }
+
+ String icon_name = text_split[0].trim_prefix("Preset");
+ icon_name = "ControlAlign" + icon_name;
+ options->add_icon_item(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(icon_name, "EditorIcons"), humanized_name);
+ } else {
+ options->add_item(humanized_name);
+ }
+
+ options->set_item_metadata(j, current_val);
+ if (split_after.has(text_split[0])) {
+ options->add_separator();
+ j++;
+ }
+ }
+}
+
+EditorPropertyAnchorsPreset::EditorPropertyAnchorsPreset() {
+ options = memnew(OptionButton);
+ options->set_clip_text(true);
+ options->set_flat(true);
+ add_child(options);
+ add_focusable(options);
+ options->connect("item_selected", callable_mp(this, &EditorPropertyAnchorsPreset::_option_selected));
+}
+
+void EditorPropertySizeFlags::_set_read_only(bool p_read_only) {
+ for (CheckBox *check : flag_checks) {
+ check->set_disabled(p_read_only);
+ }
+ flag_presets->set_disabled(p_read_only);
+};
+
+void EditorPropertySizeFlags::_preset_selected(int p_which) {
+ int preset = flag_presets->get_item_id(p_which);
+ if (preset == SIZE_FLAGS_PRESET_CUSTOM) {
+ flag_options->set_visible(true);
+ return;
+ }
+ flag_options->set_visible(false);
+
+ uint32_t value = 0;
+ switch (preset) {
+ case SIZE_FLAGS_PRESET_FILL:
+ value = Control::SIZE_FILL;
+ break;
+ case SIZE_FLAGS_PRESET_SHRINK_BEGIN:
+ value = Control::SIZE_SHRINK_BEGIN;
+ break;
+ case SIZE_FLAGS_PRESET_SHRINK_CENTER:
+ value = Control::SIZE_SHRINK_CENTER;
+ break;
+ case SIZE_FLAGS_PRESET_SHRINK_END:
+ value = Control::SIZE_SHRINK_END;
+ break;
+ }
+
+ bool is_expand = flag_expand->is_visible() && flag_expand->is_pressed();
+ if (is_expand) {
+ value |= Control::SIZE_EXPAND;
+ }
+
+ emit_changed(get_edited_property(), value);
+}
+
+void EditorPropertySizeFlags::_expand_toggled() {
+ uint32_t value = get_edited_object()->get(get_edited_property());
+
+ if (flag_expand->is_visible() && flag_expand->is_pressed()) {
+ value |= Control::SIZE_EXPAND;
+ } else {
+ value ^= Control::SIZE_EXPAND;
+ }
+
+ // Keep the custom preset selected as we toggle individual flags.
+ keep_selected_preset = true;
+ emit_changed(get_edited_property(), value);
+}
+
+void EditorPropertySizeFlags::_flag_toggled() {
+ uint32_t value = 0;
+ for (int i = 0; i < flag_checks.size(); i++) {
+ if (flag_checks[i]->is_pressed()) {
+ int flag_value = flag_checks[i]->get_meta("_value");
+ value |= flag_value;
+ }
+ }
+
+ bool is_expand = flag_expand->is_visible() && flag_expand->is_pressed();
+ if (is_expand) {
+ value |= Control::SIZE_EXPAND;
+ }
+
+ // Keep the custom preset selected as we toggle individual flags.
+ keep_selected_preset = true;
+ emit_changed(get_edited_property(), value);
+}
+
+void EditorPropertySizeFlags::update_property() {
+ uint32_t value = get_edited_object()->get(get_edited_property());
+
+ for (int i = 0; i < flag_checks.size(); i++) {
+ int flag_value = flag_checks[i]->get_meta("_value");
+ if (value & flag_value) {
+ flag_checks[i]->set_pressed(true);
+ } else {
+ flag_checks[i]->set_pressed(false);
+ }
+ }
+
+ bool is_expand = value & Control::SIZE_EXPAND;
+ flag_expand->set_pressed(is_expand);
+
+ if (keep_selected_preset) {
+ keep_selected_preset = false;
+ return;
+ }
+
+ FlagPreset preset = SIZE_FLAGS_PRESET_CUSTOM;
+ if (value == Control::SIZE_FILL || value == (Control::SIZE_FILL | Control::SIZE_EXPAND)) {
+ preset = SIZE_FLAGS_PRESET_FILL;
+ } else if (value == Control::SIZE_SHRINK_BEGIN || value == (Control::SIZE_SHRINK_BEGIN | Control::SIZE_EXPAND)) {
+ preset = SIZE_FLAGS_PRESET_SHRINK_BEGIN;
+ } else if (value == Control::SIZE_SHRINK_CENTER || value == (Control::SIZE_SHRINK_CENTER | Control::SIZE_EXPAND)) {
+ preset = SIZE_FLAGS_PRESET_SHRINK_CENTER;
+ } else if (value == Control::SIZE_SHRINK_END || value == (Control::SIZE_SHRINK_END | Control::SIZE_EXPAND)) {
+ preset = SIZE_FLAGS_PRESET_SHRINK_END;
+ }
+
+ int preset_idx = flag_presets->get_item_index(preset);
+ if (preset_idx >= 0) {
+ flag_presets->select(preset_idx);
+ }
+ flag_options->set_visible(preset == SIZE_FLAGS_PRESET_CUSTOM);
+}
+
+void EditorPropertySizeFlags::setup(const Vector<String> &p_options, bool p_vertical) {
+ vertical = p_vertical;
+
+ if (p_options.size() == 0) {
+ flag_presets->clear();
+ flag_presets->add_item(TTR("Container Default"));
+ flag_presets->set_disabled(true);
+ flag_expand->set_visible(false);
+ return;
+ }
+
+ Map<int, String> flags;
+ for (int i = 0, j = 0; i < p_options.size(); i++, j++) {
+ Vector<String> text_split = p_options[i].split(":");
+ int64_t current_val = text_split[1].to_int();
+ flags[current_val] = text_split[0];
+
+ if (current_val == SIZE_EXPAND) {
+ continue;
+ }
+
+ CheckBox *cb = memnew(CheckBox);
+ cb->set_text(text_split[0]);
+ cb->set_clip_text(true);
+ cb->set_meta("_value", current_val);
+ cb->connect("pressed", callable_mp(this, &EditorPropertySizeFlags::_flag_toggled));
+ add_focusable(cb);
+
+ flag_options->add_child(cb);
+ flag_checks.append(cb);
+ }
+
+ Control *gui_base = EditorNode::get_singleton()->get_gui_base();
+ String wide_preset_icon = SNAME("ControlAlignHCenterWide");
+ String begin_preset_icon = SNAME("ControlAlignCenterLeft");
+ String end_preset_icon = SNAME("ControlAlignCenterRight");
+ if (vertical) {
+ wide_preset_icon = SNAME("ControlAlignVCenterWide");
+ begin_preset_icon = SNAME("ControlAlignCenterTop");
+ end_preset_icon = SNAME("ControlAlignCenterBottom");
+ }
+
+ flag_presets->clear();
+ if (flags.has(SIZE_FILL)) {
+ flag_presets->add_icon_item(gui_base->get_theme_icon(wide_preset_icon, SNAME("EditorIcons")), TTR("Fill"), SIZE_FLAGS_PRESET_FILL);
+ }
+ // Shrink Begin is the same as no flags at all, as such it cannot be disabled.
+ flag_presets->add_icon_item(gui_base->get_theme_icon(begin_preset_icon, SNAME("EditorIcons")), TTR("Shrink Begin"), SIZE_FLAGS_PRESET_SHRINK_BEGIN);
+ if (flags.has(SIZE_SHRINK_CENTER)) {
+ flag_presets->add_icon_item(gui_base->get_theme_icon(SNAME("ControlAlignCenter"), SNAME("EditorIcons")), TTR("Shrink Center"), SIZE_FLAGS_PRESET_SHRINK_CENTER);
+ }
+ if (flags.has(SIZE_SHRINK_END)) {
+ flag_presets->add_icon_item(gui_base->get_theme_icon(end_preset_icon, SNAME("EditorIcons")), TTR("Shrink End"), SIZE_FLAGS_PRESET_SHRINK_END);
+ }
+ flag_presets->add_separator();
+ flag_presets->add_item(TTR("Custom"), SIZE_FLAGS_PRESET_CUSTOM);
+
+ flag_expand->set_visible(flags.has(SIZE_EXPAND));
+}
+
+EditorPropertySizeFlags::EditorPropertySizeFlags() {
+ VBoxContainer *vb = memnew(VBoxContainer);
+ add_child(vb);
+
+ flag_presets = memnew(OptionButton);
+ flag_presets->set_clip_text(true);
+ flag_presets->set_flat(true);
+ vb->add_child(flag_presets);
+ add_focusable(flag_presets);
+ set_label_reference(flag_presets);
+ flag_presets->connect("item_selected", callable_mp(this, &EditorPropertySizeFlags::_preset_selected));
+
+ flag_options = memnew(VBoxContainer);
+ flag_options->hide();
+ vb->add_child(flag_options);
+
+ flag_expand = memnew(CheckBox);
+ flag_expand->set_text(TTR("Expand"));
+ vb->add_child(flag_expand);
+ add_focusable(flag_expand);
+ flag_expand->connect("pressed", callable_mp(this, &EditorPropertySizeFlags::_expand_toggled));
+}
+
+bool EditorInspectorPluginControl::can_handle(Object *p_object) {
+ return Object::cast_to<Control>(p_object) != nullptr;
+}
+
+void EditorInspectorPluginControl::parse_group(Object *p_object, const String &p_group) {
+ Control *control = Object::cast_to<Control>(p_object);
+ if (!control || p_group != "Layout") {
+ return;
+ }
+
+ ControlPositioningWarning *pos_warning = memnew(ControlPositioningWarning);
+ pos_warning->set_control(control);
+ add_custom_control(pos_warning);
+}
+
+bool EditorInspectorPluginControl::parse_property(Object *p_object, const Variant::Type p_type, const String &p_path, const PropertyHint p_hint, const String &p_hint_text, const uint32_t p_usage, const bool p_wide) {
+ Control *control = Object::cast_to<Control>(p_object);
+ if (!control) {
+ return false;
+ }
+
+ if (p_path == "anchors_preset") {
+ EditorPropertyAnchorsPreset *prop_editor = memnew(EditorPropertyAnchorsPreset);
+ Vector<String> options = p_hint_text.split(",");
+ prop_editor->setup(options);
+ add_property_editor(p_path, prop_editor);
+
+ return true;
+ }
+
+ if (p_path == "size_flags_horizontal" || p_path == "size_flags_vertical") {
+ EditorPropertySizeFlags *prop_editor = memnew(EditorPropertySizeFlags);
+ Vector<String> options;
+ if (!p_hint_text.is_empty()) {
+ options = p_hint_text.split(",");
+ }
+ prop_editor->setup(options, p_path == "size_flags_vertical");
+ add_property_editor(p_path, prop_editor);
+
+ return true;
+ }
+
+ return false;
+}
+
+void ControlEditorToolbar::_set_anchors_and_offsets_preset(Control::LayoutPreset p_preset) {
+ List<Node *> selection = editor_selection->get_selected_node_list();
+
+ undo_redo->create_action(TTR("Change Anchors and Offsets"));
+
+ for (Node *E : selection) {
+ Control *control = Object::cast_to<Control>(E);
+ if (control) {
+ undo_redo->add_do_method(control, "set_anchors_preset", p_preset);
+ switch (p_preset) {
+ case PRESET_TOP_LEFT:
+ case PRESET_TOP_RIGHT:
+ case PRESET_BOTTOM_LEFT:
+ case PRESET_BOTTOM_RIGHT:
+ case PRESET_CENTER_LEFT:
+ case PRESET_CENTER_TOP:
+ case PRESET_CENTER_RIGHT:
+ case PRESET_CENTER_BOTTOM:
+ case PRESET_CENTER:
+ undo_redo->add_do_method(control, "set_offsets_preset", p_preset, Control::PRESET_MODE_KEEP_SIZE);
+ break;
+ case PRESET_LEFT_WIDE:
+ case PRESET_TOP_WIDE:
+ case PRESET_RIGHT_WIDE:
+ case PRESET_BOTTOM_WIDE:
+ case PRESET_VCENTER_WIDE:
+ case PRESET_HCENTER_WIDE:
+ case PRESET_WIDE:
+ undo_redo->add_do_method(control, "set_offsets_preset", p_preset, Control::PRESET_MODE_MINSIZE);
+ break;
+ }
+ undo_redo->add_undo_method(control, "_edit_set_state", control->_edit_get_state());
+ }
+ }
+
+ undo_redo->commit_action();
+
+ anchors_mode = false;
+ anchor_mode_button->set_pressed(anchors_mode);
+}
+
+void ControlEditorToolbar::_set_anchors_and_offsets_to_keep_ratio() {
+ List<Node *> selection = editor_selection->get_selected_node_list();
+
+ undo_redo->create_action(TTR("Change Anchors and Offsets"));
+
+ for (Node *E : selection) {
+ Control *control = Object::cast_to<Control>(E);
+ if (control) {
+ Point2 top_left_anchor = _position_to_anchor(control, Point2());
+ Point2 bottom_right_anchor = _position_to_anchor(control, control->get_size());
+ undo_redo->add_do_method(control, "set_anchor", SIDE_LEFT, top_left_anchor.x, false, true);
+ undo_redo->add_do_method(control, "set_anchor", SIDE_RIGHT, bottom_right_anchor.x, false, true);
+ undo_redo->add_do_method(control, "set_anchor", SIDE_TOP, top_left_anchor.y, false, true);
+ undo_redo->add_do_method(control, "set_anchor", SIDE_BOTTOM, bottom_right_anchor.y, false, true);
+ undo_redo->add_do_method(control, "set_meta", "_edit_use_anchors_", true);
+
+ const bool use_anchors = control->has_meta("_edit_use_anchors_") && control->get_meta("_edit_use_anchors_");
+ undo_redo->add_undo_method(control, "_edit_set_state", control->_edit_get_state());
+ if (use_anchors) {
+ undo_redo->add_undo_method(control, "set_meta", "_edit_use_anchors_", true);
+ } else {
+ undo_redo->add_undo_method(control, "remove_meta", "_edit_use_anchors_");
+ }
+
+ anchors_mode = true;
+ anchor_mode_button->set_pressed(anchors_mode);
+ }
+ }
+
+ undo_redo->commit_action();
+}
+
+void ControlEditorToolbar::_set_anchors_preset(Control::LayoutPreset p_preset) {
+ List<Node *> selection = editor_selection->get_selected_node_list();
+
+ undo_redo->create_action(TTR("Change Anchors"));
+ for (Node *E : selection) {
+ Control *control = Object::cast_to<Control>(E);
+ if (control) {
+ undo_redo->add_do_method(control, "set_anchors_preset", p_preset);
+ undo_redo->add_undo_method(control, "_edit_set_state", control->_edit_get_state());
+ }
+ }
+
+ undo_redo->commit_action();
+}
+
+void ControlEditorToolbar::_set_container_h_preset(Control::SizeFlags p_preset) {
+ List<Node *> selection = editor_selection->get_selected_node_list();
+
+ undo_redo->create_action(TTR("Change Horizontal Size Flags"));
+ for (Node *E : selection) {
+ Control *control = Object::cast_to<Control>(E);
+ if (control) {
+ undo_redo->add_do_method(control, "set_h_size_flags", p_preset);
+ undo_redo->add_undo_method(control, "_edit_set_state", control->_edit_get_state());
+ }
+ }
+
+ undo_redo->commit_action();
+}
+
+void ControlEditorToolbar::_set_container_v_preset(Control::SizeFlags p_preset) {
+ List<Node *> selection = editor_selection->get_selected_node_list();
+
+ undo_redo->create_action(TTR("Change Horizontal Size Flags"));
+ for (Node *E : selection) {
+ Control *control = Object::cast_to<Control>(E);
+ if (control) {
+ undo_redo->add_do_method(control, "set_v_size_flags", p_preset);
+ undo_redo->add_undo_method(control, "_edit_set_state", control->_edit_get_state());
+ }
+ }
+
+ undo_redo->commit_action();
+}
+
+Vector2 ControlEditorToolbar::_anchor_to_position(const Control *p_control, Vector2 anchor) {
+ ERR_FAIL_COND_V(!p_control, Vector2());
+
+ Transform2D parent_transform = p_control->get_transform().affine_inverse();
+ Rect2 parent_rect = p_control->get_parent_anchorable_rect();
+
+ if (p_control->is_layout_rtl()) {
+ return parent_transform.xform(parent_rect.position + Vector2(parent_rect.size.x - parent_rect.size.x * anchor.x, parent_rect.size.y * anchor.y));
+ } else {
+ return parent_transform.xform(parent_rect.position + Vector2(parent_rect.size.x * anchor.x, parent_rect.size.y * anchor.y));
+ }
+}
+
+Vector2 ControlEditorToolbar::_position_to_anchor(const Control *p_control, Vector2 position) {
+ ERR_FAIL_COND_V(!p_control, Vector2());
+
+ Rect2 parent_rect = p_control->get_parent_anchorable_rect();
+
+ Vector2 output = Vector2();
+ if (p_control->is_layout_rtl()) {
+ output.x = (parent_rect.size.x == 0) ? 0.0 : (parent_rect.size.x - p_control->get_transform().xform(position).x - parent_rect.position.x) / parent_rect.size.x;
+ } else {
+ output.x = (parent_rect.size.x == 0) ? 0.0 : (p_control->get_transform().xform(position).x - parent_rect.position.x) / parent_rect.size.x;
+ }
+ output.y = (parent_rect.size.y == 0) ? 0.0 : (p_control->get_transform().xform(position).y - parent_rect.position.y) / parent_rect.size.y;
+ return output;
+}
+
+void ControlEditorToolbar::_button_toggle_anchor_mode(bool p_status) {
+ List<Control *> selection = _get_edited_controls(false, false);
+ for (Control *E : selection) {
+ if (Object::cast_to<Container>(E->get_parent())) {
+ continue;
+ }
+
+ if (p_status) {
+ E->set_meta("_edit_use_anchors_", true);
+ } else {
+ E->remove_meta("_edit_use_anchors_");
+ }
+ }
+
+ anchors_mode = p_status;
+ CanvasItemEditor::get_singleton()->update_viewport();
+}
+
+bool ControlEditorToolbar::_is_node_locked(const Node *p_node) {
+ return p_node->has_meta("_edit_lock_") && p_node->get_meta("_edit_lock_");
+}
+
+List<Control *> ControlEditorToolbar::_get_edited_controls(bool retrieve_locked, bool remove_controls_if_parent_in_selection) {
+ List<Control *> selection;
+ for (const KeyValue<Node *, Object *> &E : editor_selection->get_selection()) {
+ Control *control = Object::cast_to<Control>(E.key);
+ if (control && control->is_visible_in_tree() && control->get_viewport() == EditorNode::get_singleton()->get_scene_root() && (retrieve_locked || !_is_node_locked(control))) {
+ selection.push_back(control);
+ }
+ }
+
+ if (remove_controls_if_parent_in_selection) {
+ List<Control *> filtered_selection;
+ for (Control *E : selection) {
+ if (!selection.find(E->get_parent())) {
+ filtered_selection.push_back(E);
+ }
+ }
+ return filtered_selection;
+ }
+
+ return selection;
+}
+
+void ControlEditorToolbar::_popup_callback(int p_op) {
+ switch (p_op) {
+ case ANCHORS_AND_OFFSETS_PRESET_TOP_LEFT: {
+ _set_anchors_and_offsets_preset(PRESET_TOP_LEFT);
+ } break;
+ case ANCHORS_AND_OFFSETS_PRESET_TOP_RIGHT: {
+ _set_anchors_and_offsets_preset(PRESET_TOP_RIGHT);
+ } break;
+ case ANCHORS_AND_OFFSETS_PRESET_BOTTOM_LEFT: {
+ _set_anchors_and_offsets_preset(PRESET_BOTTOM_LEFT);
+ } break;
+ case ANCHORS_AND_OFFSETS_PRESET_BOTTOM_RIGHT: {
+ _set_anchors_and_offsets_preset(PRESET_BOTTOM_RIGHT);
+ } break;
+ case ANCHORS_AND_OFFSETS_PRESET_CENTER_LEFT: {
+ _set_anchors_and_offsets_preset(PRESET_CENTER_LEFT);
+ } break;
+ case ANCHORS_AND_OFFSETS_PRESET_CENTER_RIGHT: {
+ _set_anchors_and_offsets_preset(PRESET_CENTER_RIGHT);
+ } break;
+ case ANCHORS_AND_OFFSETS_PRESET_CENTER_TOP: {
+ _set_anchors_and_offsets_preset(PRESET_CENTER_TOP);
+ } break;
+ case ANCHORS_AND_OFFSETS_PRESET_CENTER_BOTTOM: {
+ _set_anchors_and_offsets_preset(PRESET_CENTER_BOTTOM);
+ } break;
+ case ANCHORS_AND_OFFSETS_PRESET_CENTER: {
+ _set_anchors_and_offsets_preset(PRESET_CENTER);
+ } break;
+ case ANCHORS_AND_OFFSETS_PRESET_TOP_WIDE: {
+ _set_anchors_and_offsets_preset(PRESET_TOP_WIDE);
+ } break;
+ case ANCHORS_AND_OFFSETS_PRESET_LEFT_WIDE: {
+ _set_anchors_and_offsets_preset(PRESET_LEFT_WIDE);
+ } break;
+ case ANCHORS_AND_OFFSETS_PRESET_RIGHT_WIDE: {
+ _set_anchors_and_offsets_preset(PRESET_RIGHT_WIDE);
+ } break;
+ case ANCHORS_AND_OFFSETS_PRESET_BOTTOM_WIDE: {
+ _set_anchors_and_offsets_preset(PRESET_BOTTOM_WIDE);
+ } break;
+ case ANCHORS_AND_OFFSETS_PRESET_VCENTER_WIDE: {
+ _set_anchors_and_offsets_preset(PRESET_VCENTER_WIDE);
+ } break;
+ case ANCHORS_AND_OFFSETS_PRESET_HCENTER_WIDE: {
+ _set_anchors_and_offsets_preset(PRESET_HCENTER_WIDE);
+ } break;
+ case ANCHORS_AND_OFFSETS_PRESET_WIDE: {
+ _set_anchors_and_offsets_preset(Control::PRESET_WIDE);
+ } break;
+ case ANCHORS_AND_OFFSETS_PRESET_KEEP_RATIO: {
+ _set_anchors_and_offsets_to_keep_ratio();
+ } break;
+
+ case ANCHORS_PRESET_TOP_LEFT: {
+ _set_anchors_preset(PRESET_TOP_LEFT);
+ } break;
+ case ANCHORS_PRESET_TOP_RIGHT: {
+ _set_anchors_preset(PRESET_TOP_RIGHT);
+ } break;
+ case ANCHORS_PRESET_BOTTOM_LEFT: {
+ _set_anchors_preset(PRESET_BOTTOM_LEFT);
+ } break;
+ case ANCHORS_PRESET_BOTTOM_RIGHT: {
+ _set_anchors_preset(PRESET_BOTTOM_RIGHT);
+ } break;
+ case ANCHORS_PRESET_CENTER_LEFT: {
+ _set_anchors_preset(PRESET_CENTER_LEFT);
+ } break;
+ case ANCHORS_PRESET_CENTER_RIGHT: {
+ _set_anchors_preset(PRESET_CENTER_RIGHT);
+ } break;
+ case ANCHORS_PRESET_CENTER_TOP: {
+ _set_anchors_preset(PRESET_CENTER_TOP);
+ } break;
+ case ANCHORS_PRESET_CENTER_BOTTOM: {
+ _set_anchors_preset(PRESET_CENTER_BOTTOM);
+ } break;
+ case ANCHORS_PRESET_CENTER: {
+ _set_anchors_preset(PRESET_CENTER);
+ } break;
+ case ANCHORS_PRESET_TOP_WIDE: {
+ _set_anchors_preset(PRESET_TOP_WIDE);
+ } break;
+ case ANCHORS_PRESET_LEFT_WIDE: {
+ _set_anchors_preset(PRESET_LEFT_WIDE);
+ } break;
+ case ANCHORS_PRESET_RIGHT_WIDE: {
+ _set_anchors_preset(PRESET_RIGHT_WIDE);
+ } break;
+ case ANCHORS_PRESET_BOTTOM_WIDE: {
+ _set_anchors_preset(PRESET_BOTTOM_WIDE);
+ } break;
+ case ANCHORS_PRESET_VCENTER_WIDE: {
+ _set_anchors_preset(PRESET_VCENTER_WIDE);
+ } break;
+ case ANCHORS_PRESET_HCENTER_WIDE: {
+ _set_anchors_preset(PRESET_HCENTER_WIDE);
+ } break;
+ case ANCHORS_PRESET_WIDE: {
+ _set_anchors_preset(Control::PRESET_WIDE);
+ } break;
+
+ case CONTAINERS_H_PRESET_FILL: {
+ _set_container_h_preset(Control::SIZE_FILL);
+ } break;
+ case CONTAINERS_H_PRESET_FILL_EXPAND: {
+ _set_container_h_preset(Control::SIZE_EXPAND_FILL);
+ } break;
+ case CONTAINERS_H_PRESET_SHRINK_BEGIN: {
+ _set_container_h_preset(Control::SIZE_SHRINK_BEGIN);
+ } break;
+ case CONTAINERS_H_PRESET_SHRINK_CENTER: {
+ _set_container_h_preset(Control::SIZE_SHRINK_CENTER);
+ } break;
+ case CONTAINERS_H_PRESET_SHRINK_END: {
+ _set_container_h_preset(Control::SIZE_SHRINK_END);
+ } break;
+
+ case CONTAINERS_V_PRESET_FILL: {
+ _set_container_v_preset(Control::SIZE_FILL);
+ } break;
+ case CONTAINERS_V_PRESET_FILL_EXPAND: {
+ _set_container_v_preset(Control::SIZE_EXPAND_FILL);
+ } break;
+ case CONTAINERS_V_PRESET_SHRINK_BEGIN: {
+ _set_container_v_preset(Control::SIZE_SHRINK_BEGIN);
+ } break;
+ case CONTAINERS_V_PRESET_SHRINK_CENTER: {
+ _set_container_v_preset(Control::SIZE_SHRINK_CENTER);
+ } break;
+ case CONTAINERS_V_PRESET_SHRINK_END: {
+ _set_container_v_preset(Control::SIZE_SHRINK_END);
+ } break;
+ }
+}
+
+void ControlEditorToolbar::_selection_changed() {
+ // Update the anchors_mode.
+ int nb_controls = 0;
+ int nb_valid_controls = 0;
+ int nb_anchors_mode = 0;
+
+ List<Node *> selection = editor_selection->get_selected_node_list();
+ for (Node *E : selection) {
+ Control *control = Object::cast_to<Control>(E);
+ if (!control) {
+ continue;
+ }
+
+ nb_controls++;
+ if (Object::cast_to<Container>(control->get_parent())) {
+ continue;
+ }
+
+ nb_valid_controls++;
+ if (control->has_meta("_edit_use_anchors_") && control->get_meta("_edit_use_anchors_")) {
+ nb_anchors_mode++;
+ }
+ }
+
+ anchors_mode = (nb_valid_controls == nb_anchors_mode);
+ anchor_mode_button->set_pressed(anchors_mode);
+
+ if (nb_controls > 0) {
+ set_physics_process(true);
+ } else {
+ set_physics_process(false);
+ set_visible(false);
+ }
+}
+
+void ControlEditorToolbar::_notification(int p_what) {
+ switch (p_what) {
+ case NOTIFICATION_ENTER_TREE:
+ case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
+ anchor_layouts_icon->set_texture(get_theme_icon(SNAME("ControlLayout"), SNAME("EditorIcons")));
+
+ PopupMenu *p = anchor_presets_menu->get_popup();
+ p->clear();
+ p->add_icon_item(get_theme_icon(SNAME("ControlAlignTopLeft"), SNAME("EditorIcons")), TTR("Top Left"), ANCHORS_AND_OFFSETS_PRESET_TOP_LEFT);
+ p->add_icon_item(get_theme_icon(SNAME("ControlAlignTopRight"), SNAME("EditorIcons")), TTR("Top Right"), ANCHORS_AND_OFFSETS_PRESET_TOP_RIGHT);
+ p->add_icon_item(get_theme_icon(SNAME("ControlAlignBottomRight"), SNAME("EditorIcons")), TTR("Bottom Right"), ANCHORS_AND_OFFSETS_PRESET_BOTTOM_RIGHT);
+ p->add_icon_item(get_theme_icon(SNAME("ControlAlignBottomLeft"), SNAME("EditorIcons")), TTR("Bottom Left"), ANCHORS_AND_OFFSETS_PRESET_BOTTOM_LEFT);
+ p->add_separator();
+ p->add_icon_item(get_theme_icon(SNAME("ControlAlignCenterLeft"), SNAME("EditorIcons")), TTR("Center Left"), ANCHORS_AND_OFFSETS_PRESET_CENTER_LEFT);
+ p->add_icon_item(get_theme_icon(SNAME("ControlAlignCenterTop"), SNAME("EditorIcons")), TTR("Center Top"), ANCHORS_AND_OFFSETS_PRESET_CENTER_TOP);
+ p->add_icon_item(get_theme_icon(SNAME("ControlAlignCenterRight"), SNAME("EditorIcons")), TTR("Center Right"), ANCHORS_AND_OFFSETS_PRESET_CENTER_RIGHT);
+ p->add_icon_item(get_theme_icon(SNAME("ControlAlignCenterBottom"), SNAME("EditorIcons")), TTR("Center Bottom"), ANCHORS_AND_OFFSETS_PRESET_CENTER_BOTTOM);
+ p->add_icon_item(get_theme_icon(SNAME("ControlAlignCenter"), SNAME("EditorIcons")), TTR("Center"), ANCHORS_AND_OFFSETS_PRESET_CENTER);
+ p->add_separator();
+ p->add_icon_item(get_theme_icon(SNAME("ControlAlignLeftWide"), SNAME("EditorIcons")), TTR("Left Wide"), ANCHORS_AND_OFFSETS_PRESET_LEFT_WIDE);
+ p->add_icon_item(get_theme_icon(SNAME("ControlAlignTopWide"), SNAME("EditorIcons")), TTR("Top Wide"), ANCHORS_AND_OFFSETS_PRESET_TOP_WIDE);
+ p->add_icon_item(get_theme_icon(SNAME("ControlAlignRightWide"), SNAME("EditorIcons")), TTR("Right Wide"), ANCHORS_AND_OFFSETS_PRESET_RIGHT_WIDE);
+ p->add_icon_item(get_theme_icon(SNAME("ControlAlignBottomWide"), SNAME("EditorIcons")), TTR("Bottom Wide"), ANCHORS_AND_OFFSETS_PRESET_BOTTOM_WIDE);
+ p->add_icon_item(get_theme_icon(SNAME("ControlAlignVCenterWide"), SNAME("EditorIcons")), TTR("VCenter Wide"), ANCHORS_AND_OFFSETS_PRESET_VCENTER_WIDE);
+ p->add_icon_item(get_theme_icon(SNAME("ControlAlignHCenterWide"), SNAME("EditorIcons")), TTR("HCenter Wide"), ANCHORS_AND_OFFSETS_PRESET_HCENTER_WIDE);
+ p->add_separator();
+ p->add_icon_item(get_theme_icon(SNAME("ControlAlignWide"), SNAME("EditorIcons")), TTR("Full Rect"), ANCHORS_AND_OFFSETS_PRESET_WIDE);
+ p->add_icon_item(get_theme_icon(SNAME("Anchor"), SNAME("EditorIcons")), TTR("Keep Current Ratio"), ANCHORS_AND_OFFSETS_PRESET_KEEP_RATIO);
+ p->set_item_tooltip(19, TTR("Adjust anchors and offsets to match the current rect size."));
+
+ p->add_separator();
+ p->add_submenu_item(TTR("Anchors only"), "Anchors");
+ p->set_item_icon(21, get_theme_icon(SNAME("Anchor"), SNAME("EditorIcons")));
+
+ anchors_popup->clear();
+ anchors_popup->add_icon_item(get_theme_icon(SNAME("ControlAlignTopLeft"), SNAME("EditorIcons")), TTR("Top Left"), ANCHORS_PRESET_TOP_LEFT);
+ anchors_popup->add_icon_item(get_theme_icon(SNAME("ControlAlignTopRight"), SNAME("EditorIcons")), TTR("Top Right"), ANCHORS_PRESET_TOP_RIGHT);
+ anchors_popup->add_icon_item(get_theme_icon(SNAME("ControlAlignBottomRight"), SNAME("EditorIcons")), TTR("Bottom Right"), ANCHORS_PRESET_BOTTOM_RIGHT);
+ anchors_popup->add_icon_item(get_theme_icon(SNAME("ControlAlignBottomLeft"), SNAME("EditorIcons")), TTR("Bottom Left"), ANCHORS_PRESET_BOTTOM_LEFT);
+ anchors_popup->add_separator();
+ anchors_popup->add_icon_item(get_theme_icon(SNAME("ControlAlignCenterLeft"), SNAME("EditorIcons")), TTR("Center Left"), ANCHORS_PRESET_CENTER_LEFT);
+ anchors_popup->add_icon_item(get_theme_icon(SNAME("ControlAlignCenterTop"), SNAME("EditorIcons")), TTR("Center Top"), ANCHORS_PRESET_CENTER_TOP);
+ anchors_popup->add_icon_item(get_theme_icon(SNAME("ControlAlignCenterRight"), SNAME("EditorIcons")), TTR("Center Right"), ANCHORS_PRESET_CENTER_RIGHT);
+ anchors_popup->add_icon_item(get_theme_icon(SNAME("ControlAlignCenterBottom"), SNAME("EditorIcons")), TTR("Center Bottom"), ANCHORS_PRESET_CENTER_BOTTOM);
+ anchors_popup->add_icon_item(get_theme_icon(SNAME("ControlAlignCenter"), SNAME("EditorIcons")), TTR("Center"), ANCHORS_PRESET_CENTER);
+ anchors_popup->add_separator();
+ anchors_popup->add_icon_item(get_theme_icon(SNAME("ControlAlignLeftWide"), SNAME("EditorIcons")), TTR("Left Wide"), ANCHORS_PRESET_LEFT_WIDE);
+ anchors_popup->add_icon_item(get_theme_icon(SNAME("ControlAlignTopWide"), SNAME("EditorIcons")), TTR("Top Wide"), ANCHORS_PRESET_TOP_WIDE);
+ anchors_popup->add_icon_item(get_theme_icon(SNAME("ControlAlignRightWide"), SNAME("EditorIcons")), TTR("Right Wide"), ANCHORS_PRESET_RIGHT_WIDE);
+ anchors_popup->add_icon_item(get_theme_icon(SNAME("ControlAlignBottomWide"), SNAME("EditorIcons")), TTR("Bottom Wide"), ANCHORS_PRESET_BOTTOM_WIDE);
+ anchors_popup->add_icon_item(get_theme_icon(SNAME("ControlAlignVCenterWide"), SNAME("EditorIcons")), TTR("VCenter Wide"), ANCHORS_PRESET_VCENTER_WIDE);
+ anchors_popup->add_icon_item(get_theme_icon(SNAME("ControlAlignHCenterWide"), SNAME("EditorIcons")), TTR("HCenter Wide"), ANCHORS_PRESET_HCENTER_WIDE);
+ anchors_popup->add_separator();
+ anchors_popup->add_icon_item(get_theme_icon(SNAME("ControlAlignWide"), SNAME("EditorIcons")), TTR("Full Rect"), ANCHORS_PRESET_WIDE);
+
+ anchor_mode_button->set_icon(get_theme_icon(SNAME("Anchor"), SNAME("EditorIcons")));
+
+ container_layouts_icon->set_texture(get_theme_icon(SNAME("Container"), SNAME("EditorIcons")));
+
+ p = container_h_presets_menu->get_popup();
+ p->clear();
+ p->add_icon_item(get_theme_icon(SNAME("ControlAlignHCenterWide"), SNAME("EditorIcons")), TTR("Fill"), CONTAINERS_H_PRESET_FILL);
+ p->add_icon_item(get_theme_icon(SNAME("ControlAlignHCenterWide"), SNAME("EditorIcons")), TTR("Fill & Expand"), CONTAINERS_H_PRESET_FILL_EXPAND);
+ p->add_icon_item(get_theme_icon(SNAME("ControlAlignCenterLeft"), SNAME("EditorIcons")), TTR("Shrink Begin"), CONTAINERS_H_PRESET_SHRINK_BEGIN);
+ p->add_icon_item(get_theme_icon(SNAME("ControlAlignCenter"), SNAME("EditorIcons")), TTR("Shrink Center"), CONTAINERS_H_PRESET_SHRINK_CENTER);
+ p->add_icon_item(get_theme_icon(SNAME("ControlAlignCenterRight"), SNAME("EditorIcons")), TTR("Shrink End"), CONTAINERS_H_PRESET_SHRINK_END);
+
+ p = container_v_presets_menu->get_popup();
+ p->clear();
+ p->add_icon_item(get_theme_icon(SNAME("ControlAlignVCenterWide"), SNAME("EditorIcons")), TTR("Fill"), CONTAINERS_V_PRESET_FILL);
+ p->add_icon_item(get_theme_icon(SNAME("ControlAlignVCenterWide"), SNAME("EditorIcons")), TTR("Fill & Expand"), CONTAINERS_V_PRESET_FILL_EXPAND);
+ p->add_icon_item(get_theme_icon(SNAME("ControlAlignCenterTop"), SNAME("EditorIcons")), TTR("Shrink Begin"), CONTAINERS_V_PRESET_SHRINK_BEGIN);
+ p->add_icon_item(get_theme_icon(SNAME("ControlAlignCenter"), SNAME("EditorIcons")), TTR("Shrink Center"), CONTAINERS_V_PRESET_SHRINK_CENTER);
+ p->add_icon_item(get_theme_icon(SNAME("ControlAlignCenterBottom"), SNAME("EditorIcons")), TTR("Shrink End"), CONTAINERS_V_PRESET_SHRINK_END);
+ } break;
+
+ case NOTIFICATION_PHYSICS_PROCESS: {
+ bool has_control_parents = false;
+ bool has_container_parents = false;
+
+ // Update the viewport if the canvas_item changes
+ List<Control *> selection = _get_edited_controls(true);
+ for (Control *control : selection) {
+ if (Object::cast_to<Control>(control->get_parent())) {
+ has_control_parents = true;
+ }
+ if (Object::cast_to<Container>(control->get_parent())) {
+ has_container_parents = true;
+ }
+ }
+
+ // Show / Hide the control layout buttons.
+ if (selection.size() > 0) {
+ set_visible(true);
+
+ // Toggle anchor and container layout buttons depending on parents of the selected nodes.
+ // - If there are no control parents, enable everything.
+ // - If there are container parents, then enable only container buttons.
+ // - If there are NO container parents, then enable only anchor buttons.
+ bool enable_anchors = false;
+ bool enable_containers = false;
+ if (!has_control_parents) {
+ enable_anchors = true;
+ enable_containers = true;
+ } else if (has_container_parents) {
+ enable_containers = true;
+ } else {
+ enable_anchors = true;
+ }
+
+ if (enable_anchors) {
+ anchor_presets_menu->set_disabled(false);
+ anchor_presets_menu->set_tooltip(TTR("Presets for the anchor and offset values of a Control node."));
+ anchor_mode_button->set_disabled(false);
+ anchor_mode_button->set_tooltip(TTR("When active, moving Control nodes changes their anchors instead of their offsets."));
+ } else {
+ anchor_presets_menu->set_disabled(true);
+ anchor_presets_menu->set_tooltip(TTR("Children of containers have their anchors and offsets values controlled by their parent."));
+ anchor_mode_button->set_disabled(true);
+ anchor_mode_button->set_tooltip(TTR("Children of containers have their anchors and offsets values controlled by their parent."));
+ }
+
+ if (enable_containers) {
+ container_h_presets_menu->set_disabled(false);
+ container_h_presets_menu->set_tooltip(TTR("Horizontal sizing setting for children of a Container node."));
+ container_v_presets_menu->set_disabled(false);
+ container_v_presets_menu->set_tooltip(TTR("Vertical sizing setting for children of a Container node."));
+ } else {
+ container_h_presets_menu->set_disabled(true);
+ container_h_presets_menu->set_tooltip(TTR("Children of regular controls are controlled by their anchors and offsets."));
+ container_v_presets_menu->set_disabled(true);
+ container_v_presets_menu->set_tooltip(TTR("Children of regular controls are controlled by their anchors and offsets."));
+ }
+ } else {
+ set_visible(false);
+ }
+ } break;
+ }
+}
+
+ControlEditorToolbar::ControlEditorToolbar() {
+ anchor_layouts_icon = memnew(TextureRect);
+ anchor_layouts_icon->set_stretch_mode(TextureRect::StretchMode::STRETCH_KEEP_CENTERED);
+ add_child(anchor_layouts_icon);
+
+ Label *l = memnew(Label);
+ l->set_text(TTR("Anchors"));
+ l->set_vertical_alignment(VerticalAlignment::VERTICAL_ALIGNMENT_CENTER);
+ add_child(l);
+
+ anchor_presets_menu = memnew(MenuButton);
+ anchor_presets_menu->set_shortcut_context(this);
+ anchor_presets_menu->set_text(TTR("Preset"));
+ add_child(anchor_presets_menu);
+ anchor_presets_menu->set_switch_on_hover(true);
+
+ PopupMenu *p = anchor_presets_menu->get_popup();
+ p->connect("id_pressed", callable_mp(this, &ControlEditorToolbar::_popup_callback));
+
+ anchors_popup = memnew(PopupMenu);
+ p->add_child(anchors_popup);
+ anchors_popup->set_name("Anchors");
+ anchors_popup->connect("id_pressed", callable_mp(this, &ControlEditorToolbar::_popup_callback));
+
+ anchor_mode_button = memnew(Button);
+ anchor_mode_button->set_flat(true);
+ anchor_mode_button->set_toggle_mode(true);
+ add_child(anchor_mode_button);
+ anchor_mode_button->connect("toggled", callable_mp(this, &ControlEditorToolbar::_button_toggle_anchor_mode));
+
+ add_child(memnew(VSeparator));
+
+ container_layouts_icon = memnew(TextureRect);
+ container_layouts_icon->set_stretch_mode(TextureRect::StretchMode::STRETCH_KEEP_CENTERED);
+ add_child(container_layouts_icon);
+
+ l = memnew(Label);
+ l->set_text(TTR("Containers"));
+ l->set_vertical_alignment(VerticalAlignment::VERTICAL_ALIGNMENT_CENTER);
+ add_child(l);
+
+ container_h_presets_menu = memnew(MenuButton);
+ container_h_presets_menu->set_shortcut_context(this);
+ container_h_presets_menu->set_text(TTR("Horizontal"));
+ add_child(container_h_presets_menu);
+ container_h_presets_menu->set_switch_on_hover(true);
+
+ p = container_h_presets_menu->get_popup();
+ p->connect("id_pressed", callable_mp(this, &ControlEditorToolbar::_popup_callback));
+
+ container_v_presets_menu = memnew(MenuButton);
+ container_v_presets_menu->set_shortcut_context(this);
+ container_v_presets_menu->set_text(TTR("Vertical"));
+ add_child(container_v_presets_menu);
+ container_v_presets_menu->set_switch_on_hover(true);
+
+ p = container_v_presets_menu->get_popup();
+ p->connect("id_pressed", callable_mp(this, &ControlEditorToolbar::_popup_callback));
+
+ 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));
+
+ singleton = this;
+}
+
+ControlEditorToolbar *ControlEditorToolbar::singleton = nullptr;
+
+ControlEditorPlugin::ControlEditorPlugin() {
+ toolbar = memnew(ControlEditorToolbar);
+ toolbar->hide();
+ add_control_to_container(CONTAINER_CANVAS_EDITOR_MENU, toolbar);
+
+ Ref<EditorInspectorPluginControl> plugin;
+ plugin.instantiate();
+ add_inspector_plugin(plugin);
+}
diff --git a/editor/plugins/control_editor_plugin.h b/editor/plugins/control_editor_plugin.h
new file mode 100644
index 0000000000..bbbada2b3f
--- /dev/null
+++ b/editor/plugins/control_editor_plugin.h
@@ -0,0 +1,252 @@
+/*************************************************************************/
+/* control_editor_plugin.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef CONTROL_EDITOR_PLUGIN_H
+#define CONTROL_EDITOR_PLUGIN_H
+
+#include "editor/editor_plugin.h"
+#include "scene/gui/box_container.h"
+#include "scene/gui/check_box.h"
+#include "scene/gui/control.h"
+#include "scene/gui/label.h"
+#include "scene/gui/margin_container.h"
+#include "scene/gui/option_button.h"
+#include "scene/gui/panel_container.h"
+#include "scene/gui/texture_rect.h"
+
+class ControlPositioningWarning : public MarginContainer {
+ GDCLASS(ControlPositioningWarning, MarginContainer);
+
+ Control *control_node = nullptr;
+
+ PanelContainer *bg_panel = nullptr;
+ GridContainer *grid = nullptr;
+ TextureRect *title_icon = nullptr;
+ TextureRect *hint_icon = nullptr;
+ Label *title_label = nullptr;
+ Label *hint_label = nullptr;
+ Control *hint_filler_left = nullptr;
+ Control *hint_filler_right = nullptr;
+
+ void _update_warning();
+ void _update_toggler();
+ virtual void gui_input(const Ref<InputEvent> &p_event) override;
+
+protected:
+ void _notification(int p_notification);
+
+public:
+ void set_control(Control *p_node);
+
+ ControlPositioningWarning();
+};
+
+class EditorPropertyAnchorsPreset : public EditorProperty {
+ GDCLASS(EditorPropertyAnchorsPreset, EditorProperty);
+ OptionButton *options;
+
+ void _option_selected(int p_which);
+
+protected:
+ virtual void _set_read_only(bool p_read_only) override;
+
+public:
+ void setup(const Vector<String> &p_options);
+ virtual void update_property() override;
+ EditorPropertyAnchorsPreset();
+};
+
+class EditorPropertySizeFlags : public EditorProperty {
+ GDCLASS(EditorPropertySizeFlags, EditorProperty);
+
+ enum FlagPreset {
+ SIZE_FLAGS_PRESET_FILL,
+ SIZE_FLAGS_PRESET_SHRINK_BEGIN,
+ SIZE_FLAGS_PRESET_SHRINK_CENTER,
+ SIZE_FLAGS_PRESET_SHRINK_END,
+ SIZE_FLAGS_PRESET_CUSTOM,
+ };
+
+ OptionButton *flag_presets;
+ CheckBox *flag_expand;
+ VBoxContainer *flag_options;
+ Vector<CheckBox *> flag_checks;
+
+ bool vertical = false;
+
+ bool keep_selected_preset = false;
+
+ void _preset_selected(int p_which);
+ void _expand_toggled();
+ void _flag_toggled();
+
+protected:
+ virtual void _set_read_only(bool p_read_only) override;
+
+public:
+ void setup(const Vector<String> &p_options, bool p_vertical);
+ virtual void update_property() override;
+ EditorPropertySizeFlags();
+};
+
+class EditorInspectorPluginControl : public EditorInspectorPlugin {
+ GDCLASS(EditorInspectorPluginControl, EditorInspectorPlugin);
+
+public:
+ virtual bool can_handle(Object *p_object) override;
+ virtual void parse_group(Object *p_object, const String &p_group) override;
+ virtual bool parse_property(Object *p_object, const Variant::Type p_type, const String &p_path, const PropertyHint p_hint, const String &p_hint_text, const uint32_t p_usage, const bool p_wide = false) override;
+};
+
+class ControlEditorToolbar : public HBoxContainer {
+ GDCLASS(ControlEditorToolbar, HBoxContainer);
+
+ UndoRedo *undo_redo;
+ EditorSelection *editor_selection;
+
+ enum MenuOption {
+ ANCHORS_AND_OFFSETS_PRESET_TOP_LEFT,
+ ANCHORS_AND_OFFSETS_PRESET_TOP_RIGHT,
+ ANCHORS_AND_OFFSETS_PRESET_BOTTOM_LEFT,
+ ANCHORS_AND_OFFSETS_PRESET_BOTTOM_RIGHT,
+ ANCHORS_AND_OFFSETS_PRESET_CENTER_LEFT,
+ ANCHORS_AND_OFFSETS_PRESET_CENTER_RIGHT,
+ ANCHORS_AND_OFFSETS_PRESET_CENTER_TOP,
+ ANCHORS_AND_OFFSETS_PRESET_CENTER_BOTTOM,
+ ANCHORS_AND_OFFSETS_PRESET_CENTER,
+ ANCHORS_AND_OFFSETS_PRESET_TOP_WIDE,
+ ANCHORS_AND_OFFSETS_PRESET_LEFT_WIDE,
+ ANCHORS_AND_OFFSETS_PRESET_RIGHT_WIDE,
+ ANCHORS_AND_OFFSETS_PRESET_BOTTOM_WIDE,
+ ANCHORS_AND_OFFSETS_PRESET_VCENTER_WIDE,
+ ANCHORS_AND_OFFSETS_PRESET_HCENTER_WIDE,
+ ANCHORS_AND_OFFSETS_PRESET_WIDE,
+
+ ANCHORS_AND_OFFSETS_PRESET_KEEP_RATIO,
+
+ ANCHORS_PRESET_TOP_LEFT,
+ ANCHORS_PRESET_TOP_RIGHT,
+ ANCHORS_PRESET_BOTTOM_LEFT,
+ ANCHORS_PRESET_BOTTOM_RIGHT,
+ ANCHORS_PRESET_CENTER_LEFT,
+ ANCHORS_PRESET_CENTER_RIGHT,
+ ANCHORS_PRESET_CENTER_TOP,
+ ANCHORS_PRESET_CENTER_BOTTOM,
+ ANCHORS_PRESET_CENTER,
+ ANCHORS_PRESET_TOP_WIDE,
+ ANCHORS_PRESET_LEFT_WIDE,
+ ANCHORS_PRESET_RIGHT_WIDE,
+ ANCHORS_PRESET_BOTTOM_WIDE,
+ ANCHORS_PRESET_VCENTER_WIDE,
+ ANCHORS_PRESET_HCENTER_WIDE,
+ ANCHORS_PRESET_WIDE,
+
+ // Offsets Presets are not currently in use.
+ OFFSETS_PRESET_TOP_LEFT,
+ OFFSETS_PRESET_TOP_RIGHT,
+ OFFSETS_PRESET_BOTTOM_LEFT,
+ OFFSETS_PRESET_BOTTOM_RIGHT,
+ OFFSETS_PRESET_CENTER_LEFT,
+ OFFSETS_PRESET_CENTER_RIGHT,
+ OFFSETS_PRESET_CENTER_TOP,
+ OFFSETS_PRESET_CENTER_BOTTOM,
+ OFFSETS_PRESET_CENTER,
+ OFFSETS_PRESET_TOP_WIDE,
+ OFFSETS_PRESET_LEFT_WIDE,
+ OFFSETS_PRESET_RIGHT_WIDE,
+ OFFSETS_PRESET_BOTTOM_WIDE,
+ OFFSETS_PRESET_VCENTER_WIDE,
+ OFFSETS_PRESET_HCENTER_WIDE,
+ OFFSETS_PRESET_WIDE,
+
+ CONTAINERS_H_PRESET_FILL,
+ CONTAINERS_H_PRESET_FILL_EXPAND,
+ CONTAINERS_H_PRESET_SHRINK_BEGIN,
+ CONTAINERS_H_PRESET_SHRINK_CENTER,
+ CONTAINERS_H_PRESET_SHRINK_END,
+ CONTAINERS_V_PRESET_FILL,
+ CONTAINERS_V_PRESET_FILL_EXPAND,
+ CONTAINERS_V_PRESET_SHRINK_BEGIN,
+ CONTAINERS_V_PRESET_SHRINK_CENTER,
+ CONTAINERS_V_PRESET_SHRINK_END,
+ };
+
+ TextureRect *anchor_layouts_icon;
+ MenuButton *anchor_presets_menu;
+ PopupMenu *anchors_popup;
+ TextureRect *container_layouts_icon;
+ MenuButton *container_h_presets_menu;
+ MenuButton *container_v_presets_menu;
+
+ Button *anchor_mode_button;
+
+ bool anchors_mode = false;
+
+ void _set_anchors_preset(Control::LayoutPreset p_preset);
+ void _set_anchors_and_offsets_preset(Control::LayoutPreset p_preset);
+ void _set_anchors_and_offsets_to_keep_ratio();
+ void _set_container_h_preset(Control::SizeFlags p_preset);
+ void _set_container_v_preset(Control::SizeFlags p_preset);
+
+ Vector2 _anchor_to_position(const Control *p_control, Vector2 anchor);
+ Vector2 _position_to_anchor(const Control *p_control, Vector2 position);
+
+ void _button_toggle_anchor_mode(bool p_status);
+
+ bool _is_node_locked(const Node *p_node);
+ List<Control *> _get_edited_controls(bool retrieve_locked = false, bool remove_controls_if_parent_in_selection = true);
+ void _popup_callback(int p_op);
+ void _selection_changed();
+
+protected:
+ void _notification(int p_notification);
+
+ static ControlEditorToolbar *singleton;
+
+public:
+ bool is_anchors_mode_enabled() { return anchors_mode; };
+
+ static ControlEditorToolbar *get_singleton() { return singleton; }
+
+ ControlEditorToolbar();
+};
+
+class ControlEditorPlugin : public EditorPlugin {
+ GDCLASS(ControlEditorPlugin, EditorPlugin);
+
+ ControlEditorToolbar *toolbar;
+
+public:
+ virtual String get_name() const override { return "Control"; }
+
+ ControlEditorPlugin();
+};
+
+#endif //CONTROL_EDITOR_PLUGIN_H
diff --git a/editor/plugins/cpu_particles_2d_editor_plugin.cpp b/editor/plugins/cpu_particles_2d_editor_plugin.cpp
index e0364dc952..79025041d3 100644
--- a/editor/plugins/cpu_particles_2d_editor_plugin.cpp
+++ b/editor/plugins/cpu_particles_2d_editor_plugin.cpp
@@ -32,6 +32,8 @@
#include "canvas_item_editor_plugin.h"
#include "core/io/image_loader.h"
+#include "editor/editor_file_dialog.h"
+#include "editor/editor_node.h"
#include "scene/2d/cpu_particles_2d.h"
#include "scene/gui/separator.h"
#include "scene/resources/particles_material.h"
@@ -222,20 +224,21 @@ void CPUParticles2DEditorPlugin::_generate_emission_mask() {
}
void CPUParticles2DEditorPlugin::_notification(int p_what) {
- if (p_what == NOTIFICATION_ENTER_TREE) {
- menu->get_popup()->connect("id_pressed", callable_mp(this, &CPUParticles2DEditorPlugin::_menu_callback));
- menu->set_icon(epoints->get_theme_icon(SNAME("CPUParticles2D"), SNAME("EditorIcons")));
- file->connect("file_selected", callable_mp(this, &CPUParticles2DEditorPlugin::_file_selected));
+ switch (p_what) {
+ case NOTIFICATION_ENTER_TREE: {
+ menu->get_popup()->connect("id_pressed", callable_mp(this, &CPUParticles2DEditorPlugin::_menu_callback));
+ menu->set_icon(epoints->get_theme_icon(SNAME("CPUParticles2D"), SNAME("EditorIcons")));
+ file->connect("file_selected", callable_mp(this, &CPUParticles2DEditorPlugin::_file_selected));
+ } break;
}
}
void CPUParticles2DEditorPlugin::_bind_methods() {
}
-CPUParticles2DEditorPlugin::CPUParticles2DEditorPlugin(EditorNode *p_node) {
+CPUParticles2DEditorPlugin::CPUParticles2DEditorPlugin() {
particles = nullptr;
- editor = p_node;
- undo_redo = editor->get_undo_redo();
+ 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 e54e1651bd..b10ed73e38 100644
--- a/editor/plugins/cpu_particles_2d_editor_plugin.h
+++ b/editor/plugins/cpu_particles_2d_editor_plugin.h
@@ -31,12 +31,14 @@
#ifndef CPU_PARTICLES_2D_EDITOR_PLUGIN_H
#define CPU_PARTICLES_2D_EDITOR_PLUGIN_H
-#include "editor/editor_node.h"
#include "editor/editor_plugin.h"
#include "scene/2d/collision_polygon_2d.h"
#include "scene/2d/cpu_particles_2d.h"
#include "scene/gui/box_container.h"
-#include "scene/gui/file_dialog.h"
+
+class EditorPlugin;
+class SpinBox;
+class EditorFileDialog;
class CPUParticles2DEditorPlugin : public EditorPlugin {
GDCLASS(CPUParticles2DEditorPlugin, EditorPlugin);
@@ -56,7 +58,6 @@ class CPUParticles2DEditorPlugin : public EditorPlugin {
CPUParticles2D *particles;
EditorFileDialog *file;
- EditorNode *editor;
HBoxContainer *toolbar;
MenuButton *menu;
@@ -85,7 +86,7 @@ public:
virtual bool handles(Object *p_object) const override;
virtual void make_visible(bool p_visible) override;
- CPUParticles2DEditorPlugin(EditorNode *p_node);
+ CPUParticles2DEditorPlugin();
~CPUParticles2DEditorPlugin();
};
diff --git a/editor/plugins/cpu_particles_3d_editor_plugin.cpp b/editor/plugins/cpu_particles_3d_editor_plugin.cpp
index bb10c04e8f..775c2dbb2a 100644
--- a/editor/plugins/cpu_particles_3d_editor_plugin.cpp
+++ b/editor/plugins/cpu_particles_3d_editor_plugin.cpp
@@ -30,7 +30,10 @@
#include "cpu_particles_3d_editor_plugin.h"
+#include "editor/editor_node.h"
#include "editor/plugins/node_3d_editor_plugin.h"
+#include "editor/scene_tree_editor.h"
+#include "scene/gui/menu_button.h"
void CPUParticles3DEditor::_node_removed(Node *p_node) {
if (p_node == node) {
@@ -40,8 +43,10 @@ void CPUParticles3DEditor::_node_removed(Node *p_node) {
}
void CPUParticles3DEditor::_notification(int p_notification) {
- if (p_notification == NOTIFICATION_ENTER_TREE) {
- options->set_icon(get_theme_icon(SNAME("CPUParticles3D"), SNAME("EditorIcons")));
+ switch (p_notification) {
+ case NOTIFICATION_ENTER_TREE: {
+ options->set_icon(get_theme_icon(SNAME("CPUParticles3D"), SNAME("EditorIcons")));
+ } break;
}
}
@@ -119,10 +124,9 @@ void CPUParticles3DEditorPlugin::make_visible(bool p_visible) {
}
}
-CPUParticles3DEditorPlugin::CPUParticles3DEditorPlugin(EditorNode *p_node) {
- editor = p_node;
+CPUParticles3DEditorPlugin::CPUParticles3DEditorPlugin() {
particles_editor = memnew(CPUParticles3DEditor);
- editor->get_main_control()->add_child(particles_editor);
+ EditorNode::get_singleton()->get_main_control()->add_child(particles_editor);
particles_editor->hide();
}
diff --git a/editor/plugins/cpu_particles_3d_editor_plugin.h b/editor/plugins/cpu_particles_3d_editor_plugin.h
index 67cc156680..0501936574 100644
--- a/editor/plugins/cpu_particles_3d_editor_plugin.h
+++ b/editor/plugins/cpu_particles_3d_editor_plugin.h
@@ -66,7 +66,6 @@ class CPUParticles3DEditorPlugin : public EditorPlugin {
GDCLASS(CPUParticles3DEditorPlugin, EditorPlugin);
CPUParticles3DEditor *particles_editor;
- EditorNode *editor;
public:
virtual String get_name() const override { return "CPUParticles3D"; }
@@ -75,7 +74,7 @@ public:
virtual bool handles(Object *p_object) const override;
virtual void make_visible(bool p_visible) override;
- CPUParticles3DEditorPlugin(EditorNode *p_node);
+ CPUParticles3DEditorPlugin();
~CPUParticles3DEditorPlugin();
};
diff --git a/editor/plugins/curve_editor_plugin.cpp b/editor/plugins/curve_editor_plugin.cpp
index a9a276fc18..6d1a86765a 100644
--- a/editor/plugins/curve_editor_plugin.cpp
+++ b/editor/plugins/curve_editor_plugin.cpp
@@ -34,6 +34,7 @@
#include "core/core_string_names.h"
#include "core/input/input.h"
#include "core/os/keyboard.h"
+#include "editor/editor_node.h"
#include "editor/editor_scale.h"
CurveEditor::CurveEditor() {
@@ -96,8 +97,10 @@ Size2 CurveEditor::get_minimum_size() const {
}
void CurveEditor::_notification(int p_what) {
- if (p_what == NOTIFICATION_DRAW) {
- _draw();
+ switch (p_what) {
+ case NOTIFICATION_DRAW: {
+ _draw();
+ } break;
}
}
@@ -773,7 +776,7 @@ void EditorInspectorPluginCurve::parse_begin(Object *p_object) {
add_custom_control(editor);
}
-CurveEditorPlugin::CurveEditorPlugin(EditorNode *p_node) {
+CurveEditorPlugin::CurveEditorPlugin() {
Ref<EditorInspectorPluginCurve> curve_plugin;
curve_plugin.instantiate();
EditorInspector::add_inspector_plugin(curve_plugin);
diff --git a/editor/plugins/curve_editor_plugin.h b/editor/plugins/curve_editor_plugin.h
index c7e8dea75a..4aba2fffd0 100644
--- a/editor/plugins/curve_editor_plugin.h
+++ b/editor/plugins/curve_editor_plugin.h
@@ -31,7 +31,6 @@
#ifndef CURVE_EDITOR_PLUGIN_H
#define CURVE_EDITOR_PLUGIN_H
-#include "editor/editor_node.h"
#include "editor/editor_plugin.h"
#include "editor/editor_resource_preview.h"
#include "scene/resources/curve.h"
@@ -129,7 +128,7 @@ class CurveEditorPlugin : public EditorPlugin {
GDCLASS(CurveEditorPlugin, EditorPlugin);
public:
- CurveEditorPlugin(EditorNode *p_node);
+ CurveEditorPlugin();
virtual String get_name() const override { return "Curve"; }
};
diff --git a/editor/plugins/debugger_editor_plugin.cpp b/editor/plugins/debugger_editor_plugin.cpp
index 6e43130a92..501becac57 100644
--- a/editor/plugins/debugger_editor_plugin.cpp
+++ b/editor/plugins/debugger_editor_plugin.cpp
@@ -36,9 +36,10 @@
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/fileserver/editor_file_server.h"
+#include "editor/plugins/script_editor_plugin.h"
#include "scene/gui/menu_button.h"
-DebuggerEditorPlugin::DebuggerEditorPlugin(EditorNode *p_editor, MenuButton *p_debug_menu) {
+DebuggerEditorPlugin::DebuggerEditorPlugin(MenuButton *p_debug_menu) {
EditorDebuggerServer::initialize();
ED_SHORTCUT("debugger/step_into", TTR("Step Into"), Key::F11);
@@ -176,8 +177,10 @@ void DebuggerEditorPlugin::_menu_option(int p_option) {
}
void DebuggerEditorPlugin::_notification(int p_what) {
- if (p_what == NOTIFICATION_READY) {
- _update_debug_options();
+ switch (p_what) {
+ case NOTIFICATION_READY: {
+ _update_debug_options();
+ } break;
}
}
diff --git a/editor/plugins/debugger_editor_plugin.h b/editor/plugins/debugger_editor_plugin.h
index 6fc83cd438..c024526285 100644
--- a/editor/plugins/debugger_editor_plugin.h
+++ b/editor/plugins/debugger_editor_plugin.h
@@ -33,7 +33,6 @@
#include "editor/editor_plugin.h"
-class EditorNode;
class EditorFileServer;
class MenuButton;
class PopupMenu;
@@ -64,7 +63,7 @@ public:
virtual String get_name() const override { return "Debugger"; }
bool has_main_screen() const override { return false; }
- DebuggerEditorPlugin(EditorNode *p_node, MenuButton *p_menu);
+ DebuggerEditorPlugin(MenuButton *p_menu);
~DebuggerEditorPlugin();
};
diff --git a/editor/plugins/editor_preview_plugins.cpp b/editor/plugins/editor_preview_plugins.cpp
index 7e0019faac..b8556220d2 100644
--- a/editor/plugins/editor_preview_plugins.cpp
+++ b/editor/plugins/editor_preview_plugins.cpp
@@ -30,10 +30,11 @@
#include "editor_preview_plugins.h"
+#include "core/config/project_settings.h"
#include "core/io/file_access_memory.h"
#include "core/io/resource_loader.h"
#include "core/os/os.h"
-#include "editor/editor_node.h"
+#include "editor/editor_paths.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
#include "scene/resources/bit_map.h"
@@ -188,7 +189,7 @@ bool EditorImagePreviewPlugin::generate_small_preview_automatically() const {
}
////////////////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////
+
bool EditorBitmapPreviewPlugin::handles(const String &p_type) const {
return ClassDB::is_parent_class(p_type, "BitMap");
}
@@ -308,7 +309,7 @@ void EditorMaterialPreviewPlugin::_preview_done() {
}
bool EditorMaterialPreviewPlugin::handles(const String &p_type) const {
- return ClassDB::is_parent_class(p_type, "Material"); //any material
+ return ClassDB::is_parent_class(p_type, "Material"); // Any material.
}
bool EditorMaterialPreviewPlugin::generate_small_preview_automatically() const {
@@ -699,7 +700,7 @@ void EditorMeshPreviewPlugin::_preview_done() {
}
bool EditorMeshPreviewPlugin::handles(const String &p_type) const {
- return ClassDB::is_parent_class(p_type, "Mesh"); //any Mesh
+ return ClassDB::is_parent_class(p_type, "Mesh"); // Any mesh.
}
Ref<Texture2D> EditorMeshPreviewPlugin::generate(const RES &p_from, const Size2 &p_size) const {
diff --git a/editor/plugins/editor_preview_plugins.h b/editor/plugins/editor_preview_plugins.h
index dd64918d41..803f03f17e 100644
--- a/editor/plugins/editor_preview_plugins.h
+++ b/editor/plugins/editor_preview_plugins.h
@@ -31,9 +31,8 @@
#ifndef EDITORPREVIEWPLUGINS_H
#define EDITORPREVIEWPLUGINS_H
-#include "editor/editor_resource_preview.h"
-
#include "core/templates/safe_refcount.h"
+#include "editor/editor_resource_preview.h"
void post_process_preview(Ref<Image> p_image);
diff --git a/editor/plugins/font_editor_plugin.cpp b/editor/plugins/font_editor_plugin.cpp
index 73a6781774..b9de621bcb 100644
--- a/editor/plugins/font_editor_plugin.cpp
+++ b/editor/plugins/font_editor_plugin.cpp
@@ -33,14 +33,16 @@
#include "editor/editor_scale.h"
void FontDataPreview::_notification(int p_what) {
- if (p_what == NOTIFICATION_DRAW) {
- Color text_color = get_theme_color(SNAME("font_color"), SNAME("Label"));
- Color line_color = text_color;
- line_color.a *= 0.6;
- Vector2 pos = (get_size() - line->get_size()) / 2;
- line->draw(get_canvas_item(), pos, text_color);
- draw_line(Vector2(0, pos.y + line->get_line_ascent()), Vector2(pos.x - 5, pos.y + line->get_line_ascent()), line_color);
- draw_line(Vector2(pos.x + line->get_size().x + 5, pos.y + line->get_line_ascent()), Vector2(get_size().x, pos.y + line->get_line_ascent()), line_color);
+ switch (p_what) {
+ case NOTIFICATION_DRAW: {
+ Color text_color = get_theme_color(SNAME("font_color"), SNAME("Label"));
+ Color line_color = text_color;
+ line_color.a *= 0.6;
+ Vector2 pos = (get_size() - line->get_size()) / 2;
+ line->draw(get_canvas_item(), pos, text_color);
+ draw_line(Vector2(0, pos.y + line->get_line_ascent()), Vector2(pos.x - 5, pos.y + line->get_line_ascent()), line_color);
+ draw_line(Vector2(pos.x + line->get_size().x + 5, pos.y + line->get_line_ascent()), Vector2(get_size().x, pos.y + line->get_line_ascent()), line_color);
+ } break;
}
}
@@ -97,7 +99,7 @@ bool EditorInspectorPluginFont::parse_property(Object *p_object, const Variant::
/*************************************************************************/
-FontEditorPlugin::FontEditorPlugin(EditorNode *p_node) {
+FontEditorPlugin::FontEditorPlugin() {
Ref<EditorInspectorPluginFont> fd_plugin;
fd_plugin.instantiate();
EditorInspector::add_inspector_plugin(fd_plugin);
diff --git a/editor/plugins/font_editor_plugin.h b/editor/plugins/font_editor_plugin.h
index 736137121a..3f0700d880 100644
--- a/editor/plugins/font_editor_plugin.h
+++ b/editor/plugins/font_editor_plugin.h
@@ -31,7 +31,6 @@
#ifndef FONT_EDITOR_PLUGIN_H
#define FONT_EDITOR_PLUGIN_H
-#include "editor/editor_node.h"
#include "editor/editor_plugin.h"
#include "scene/resources/font.h"
#include "scene/resources/text_line.h"
@@ -70,7 +69,7 @@ class FontEditorPlugin : public EditorPlugin {
GDCLASS(FontEditorPlugin, EditorPlugin);
public:
- FontEditorPlugin(EditorNode *p_node);
+ FontEditorPlugin();
virtual String get_name() const override { return "Font"; }
};
diff --git a/editor/plugins/gpu_particles_2d_editor_plugin.cpp b/editor/plugins/gpu_particles_2d_editor_plugin.cpp
index 06be9d678f..b15aec87d9 100644
--- a/editor/plugins/gpu_particles_2d_editor_plugin.cpp
+++ b/editor/plugins/gpu_particles_2d_editor_plugin.cpp
@@ -32,6 +32,9 @@
#include "canvas_item_editor_plugin.h"
#include "core/io/image_loader.h"
+#include "editor/editor_file_dialog.h"
+#include "editor/editor_node.h"
+#include "editor/scene_tree_dock.h"
#include "scene/2d/cpu_particles_2d.h"
#include "scene/gui/separator.h"
#include "scene/resources/particles_material.h"
@@ -58,7 +61,7 @@ void GPUParticles2DEditorPlugin::_file_selected(const String &p_file) {
}
void GPUParticles2DEditorPlugin::_selection_changed() {
- List<Node *> selected_nodes = editor->get_editor_selection()->get_selected_node_list();
+ List<Node *> selected_nodes = EditorNode::get_singleton()->get_editor_selection()->get_selected_node_list();
if (selected_particles.is_empty() && selected_nodes.is_empty()) {
return;
@@ -351,21 +354,22 @@ void GPUParticles2DEditorPlugin::_generate_emission_mask() {
}
void GPUParticles2DEditorPlugin::_notification(int p_what) {
- if (p_what == NOTIFICATION_ENTER_TREE) {
- menu->get_popup()->connect("id_pressed", callable_mp(this, &GPUParticles2DEditorPlugin::_menu_callback));
- menu->set_icon(menu->get_theme_icon(SNAME("GPUParticles2D"), SNAME("EditorIcons")));
- file->connect("file_selected", callable_mp(this, &GPUParticles2DEditorPlugin::_file_selected));
- EditorNode::get_singleton()->get_editor_selection()->connect("selection_changed", callable_mp(this, &GPUParticles2DEditorPlugin::_selection_changed));
+ switch (p_what) {
+ case NOTIFICATION_ENTER_TREE: {
+ menu->get_popup()->connect("id_pressed", callable_mp(this, &GPUParticles2DEditorPlugin::_menu_callback));
+ menu->set_icon(menu->get_theme_icon(SNAME("GPUParticles2D"), SNAME("EditorIcons")));
+ file->connect("file_selected", callable_mp(this, &GPUParticles2DEditorPlugin::_file_selected));
+ EditorNode::get_singleton()->get_editor_selection()->connect("selection_changed", callable_mp(this, &GPUParticles2DEditorPlugin::_selection_changed));
+ } break;
}
}
void GPUParticles2DEditorPlugin::_bind_methods() {
}
-GPUParticles2DEditorPlugin::GPUParticles2DEditorPlugin(EditorNode *p_node) {
+GPUParticles2DEditorPlugin::GPUParticles2DEditorPlugin() {
particles = nullptr;
- editor = p_node;
- undo_redo = editor->get_undo_redo();
+ 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 55e455e252..f94ce632e9 100644
--- a/editor/plugins/gpu_particles_2d_editor_plugin.h
+++ b/editor/plugins/gpu_particles_2d_editor_plugin.h
@@ -31,12 +31,13 @@
#ifndef PARTICLES_2D_EDITOR_PLUGIN_H
#define PARTICLES_2D_EDITOR_PLUGIN_H
-#include "editor/editor_node.h"
#include "editor/editor_plugin.h"
#include "scene/2d/collision_polygon_2d.h"
#include "scene/2d/gpu_particles_2d.h"
#include "scene/gui/box_container.h"
-#include "scene/gui/file_dialog.h"
+#include "scene/gui/spin_box.h"
+
+class EditorFileDialog;
class GPUParticles2DEditorPlugin : public EditorPlugin {
GDCLASS(GPUParticles2DEditorPlugin, EditorPlugin);
@@ -59,7 +60,6 @@ class GPUParticles2DEditorPlugin : public EditorPlugin {
List<GPUParticles2D *> selected_particles;
EditorFileDialog *file;
- EditorNode *editor;
HBoxContainer *toolbar;
MenuButton *menu;
@@ -93,7 +93,7 @@ public:
virtual bool handles(Object *p_object) const override;
virtual void make_visible(bool p_visible) override;
- GPUParticles2DEditorPlugin(EditorNode *p_node);
+ GPUParticles2DEditorPlugin();
~GPUParticles2DEditorPlugin();
};
diff --git a/editor/plugins/gpu_particles_3d_editor_plugin.cpp b/editor/plugins/gpu_particles_3d_editor_plugin.cpp
index 087b0a26b7..293d1c3913 100644
--- a/editor/plugins/gpu_particles_3d_editor_plugin.cpp
+++ b/editor/plugins/gpu_particles_3d_editor_plugin.cpp
@@ -31,7 +31,9 @@
#include "gpu_particles_3d_editor_plugin.h"
#include "core/io/resource_loader.h"
+#include "editor/editor_node.h"
#include "editor/plugins/node_3d_editor_plugin.h"
+#include "editor/scene_tree_dock.h"
#include "scene/3d/cpu_particles_3d.h"
#include "scene/resources/particles_material.h"
@@ -229,9 +231,11 @@ void GPUParticles3DEditor::_node_removed(Node *p_node) {
}
void GPUParticles3DEditor::_notification(int p_notification) {
- if (p_notification == NOTIFICATION_ENTER_TREE) {
- options->set_icon(options->get_popup()->get_theme_icon(SNAME("GPUParticles3D"), SNAME("EditorIcons")));
- get_tree()->connect("node_removed", callable_mp(this, &GPUParticles3DEditor::_node_removed));
+ switch (p_notification) {
+ case NOTIFICATION_ENTER_TREE: {
+ options->set_icon(options->get_popup()->get_theme_icon(SNAME("GPUParticles3D"), SNAME("EditorIcons")));
+ get_tree()->connect("node_removed", callable_mp(this, &GPUParticles3DEditor::_node_removed));
+ } break;
}
}
@@ -455,10 +459,9 @@ void GPUParticles3DEditorPlugin::make_visible(bool p_visible) {
}
}
-GPUParticles3DEditorPlugin::GPUParticles3DEditorPlugin(EditorNode *p_node) {
- editor = p_node;
+GPUParticles3DEditorPlugin::GPUParticles3DEditorPlugin() {
particles_editor = memnew(GPUParticles3DEditor);
- editor->get_main_control()->add_child(particles_editor);
+ EditorNode::get_singleton()->get_main_control()->add_child(particles_editor);
particles_editor->hide();
}
diff --git a/editor/plugins/gpu_particles_3d_editor_plugin.h b/editor/plugins/gpu_particles_3d_editor_plugin.h
index f7e4244ba4..39aa596ece 100644
--- a/editor/plugins/gpu_particles_3d_editor_plugin.h
+++ b/editor/plugins/gpu_particles_3d_editor_plugin.h
@@ -31,11 +31,12 @@
#ifndef PARTICLES_EDITOR_PLUGIN_H
#define PARTICLES_EDITOR_PLUGIN_H
-#include "editor/editor_node.h"
#include "editor/editor_plugin.h"
#include "scene/3d/gpu_particles_3d.h"
#include "scene/gui/spin_box.h"
+class SceneTreeDialog;
+
class GPUParticles3DEditorBase : public Control {
GDCLASS(GPUParticles3DEditorBase, Control);
@@ -101,7 +102,6 @@ class GPUParticles3DEditorPlugin : public EditorPlugin {
GDCLASS(GPUParticles3DEditorPlugin, EditorPlugin);
GPUParticles3DEditor *particles_editor;
- EditorNode *editor;
public:
virtual String get_name() const override { return "GPUParticles3D"; }
@@ -110,7 +110,7 @@ public:
virtual bool handles(Object *p_object) const override;
virtual void make_visible(bool p_visible) override;
- GPUParticles3DEditorPlugin(EditorNode *p_node);
+ GPUParticles3DEditorPlugin();
~GPUParticles3DEditorPlugin();
};
diff --git a/editor/plugins/gpu_particles_collision_sdf_editor_plugin.cpp b/editor/plugins/gpu_particles_collision_sdf_editor_plugin.cpp
index 1b4c944876..643a470425 100644
--- a/editor/plugins/gpu_particles_collision_sdf_editor_plugin.cpp
+++ b/editor/plugins/gpu_particles_collision_sdf_editor_plugin.cpp
@@ -30,6 +30,9 @@
#include "gpu_particles_collision_sdf_editor_plugin.h"
+#include "editor/editor_file_dialog.h"
+#include "editor/editor_node.h"
+
void GPUParticlesCollisionSDF3DEditorPlugin::_bake() {
if (col_sdf) {
if (col_sdf->get_texture().is_null() || !col_sdf->get_texture()->get_path().is_resource_file()) {
@@ -63,41 +66,43 @@ bool GPUParticlesCollisionSDF3DEditorPlugin::handles(Object *p_object) const {
}
void GPUParticlesCollisionSDF3DEditorPlugin::_notification(int p_what) {
- if (p_what == NOTIFICATION_PROCESS) {
- if (!col_sdf) {
- return;
- }
+ switch (p_what) {
+ case NOTIFICATION_PROCESS: {
+ if (!col_sdf) {
+ return;
+ }
- // Set information tooltip on the Bake button. This information is useful
- // to optimize performance (video RAM size) and reduce collision tunneling (individual cell size).
+ // Set information tooltip on the Bake button. This information is useful
+ // to optimize performance (video RAM size) and reduce collision tunneling (individual cell size).
- const Vector3i size = col_sdf->get_estimated_cell_size();
+ const Vector3i size = col_sdf->get_estimated_cell_size();
- const Vector3 extents = col_sdf->get_extents();
+ const Vector3 extents = col_sdf->get_extents();
- int data_size = 2;
- const double size_mb = size.x * size.y * size.z * data_size / (1024.0 * 1024.0);
- // Add a qualitative measurement to help the user assess whether a GPUParticlesCollisionSDF3D node is using a lot of VRAM.
- String size_quality;
- if (size_mb < 8.0) {
- size_quality = TTR("Low");
- } else if (size_mb < 32.0) {
- size_quality = TTR("Moderate");
- } else {
- size_quality = TTR("High");
- }
+ int data_size = 2;
+ const double size_mb = size.x * size.y * size.z * data_size / (1024.0 * 1024.0);
+ // Add a qualitative measurement to help the user assess whether a GPUParticlesCollisionSDF3D node is using a lot of VRAM.
+ String size_quality;
+ if (size_mb < 8.0) {
+ size_quality = TTR("Low");
+ } else if (size_mb < 32.0) {
+ size_quality = TTR("Moderate");
+ } else {
+ size_quality = TTR("High");
+ }
- String text;
- text += vformat(TTR("Subdivisions: %s"), vformat(String::utf8("%d × %d × %d"), size.x, size.y, size.z)) + "\n";
- text += vformat(TTR("Cell size: %s"), vformat(String::utf8("%.3f × %.3f × %.3f"), extents.x / size.x, extents.y / size.y, extents.z / size.z)) + "\n";
- text += vformat(TTR("Video RAM size: %s MB (%s)"), String::num(size_mb, 2), size_quality);
+ String text;
+ text += vformat(TTR("Subdivisions: %s"), vformat(String::utf8("%d × %d × %d"), size.x, size.y, size.z)) + "\n";
+ text += vformat(TTR("Cell size: %s"), vformat(String::utf8("%.3f × %.3f × %.3f"), extents.x / size.x, extents.y / size.y, extents.z / size.z)) + "\n";
+ text += vformat(TTR("Video RAM size: %s MB (%s)"), String::num(size_mb, 2), size_quality);
- // Only update the tooltip when needed to avoid constant redrawing.
- if (bake->get_tooltip(Point2()) == text) {
- return;
- }
+ // Only update the tooltip when needed to avoid constant redrawing.
+ if (bake->get_tooltip(Point2()) == text) {
+ return;
+ }
- bake->set_tooltip(text);
+ bake->set_tooltip(text);
+ } break;
}
}
@@ -147,7 +152,7 @@ void GPUParticlesCollisionSDF3DEditorPlugin::_sdf_save_path_and_bake(const Strin
}
config->set_value("remap", "importer", "3d_texture");
- config->set_value("remap", "type", "StreamTexture3D");
+ config->set_value("remap", "type", "CompressedTexture3D");
if (!config->has_section_key("params", "compress/mode")) {
config->set_value("params", "compress/mode", 3); //user may want another compression, so leave it be
}
@@ -171,14 +176,13 @@ void GPUParticlesCollisionSDF3DEditorPlugin::_sdf_save_path_and_bake(const Strin
void GPUParticlesCollisionSDF3DEditorPlugin::_bind_methods() {
}
-GPUParticlesCollisionSDF3DEditorPlugin::GPUParticlesCollisionSDF3DEditorPlugin(EditorNode *p_node) {
- editor = p_node;
+GPUParticlesCollisionSDF3DEditorPlugin::GPUParticlesCollisionSDF3DEditorPlugin() {
bake_hb = memnew(HBoxContainer);
bake_hb->set_h_size_flags(Control::SIZE_EXPAND_FILL);
bake_hb->hide();
bake = memnew(Button);
bake->set_flat(true);
- bake->set_icon(editor->get_gui_base()->get_theme_icon(SNAME("Bake"), SNAME("EditorIcons")));
+ bake->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Bake"), SNAME("EditorIcons")));
bake->set_text(TTR("Bake SDF"));
bake->connect("pressed", callable_mp(this, &GPUParticlesCollisionSDF3DEditorPlugin::_bake));
bake_hb->add_child(bake);
diff --git a/editor/plugins/gpu_particles_collision_sdf_editor_plugin.h b/editor/plugins/gpu_particles_collision_sdf_editor_plugin.h
index d74986f22b..f6e4fd3dec 100644
--- a/editor/plugins/gpu_particles_collision_sdf_editor_plugin.h
+++ b/editor/plugins/gpu_particles_collision_sdf_editor_plugin.h
@@ -31,11 +31,13 @@
#ifndef GPU_PARTICLES_COLLISION_SDF_EDITOR_PLUGIN_H
#define GPU_PARTICLES_COLLISION_SDF_EDITOR_PLUGIN_H
-#include "editor/editor_node.h"
#include "editor/editor_plugin.h"
#include "scene/3d/gpu_particles_collision_3d.h"
#include "scene/resources/material.h"
+struct EditorProgress;
+class EditorFileDialog;
+
class GPUParticlesCollisionSDF3DEditorPlugin : public EditorPlugin {
GDCLASS(GPUParticlesCollisionSDF3DEditorPlugin, EditorPlugin);
@@ -43,7 +45,6 @@ class GPUParticlesCollisionSDF3DEditorPlugin : public EditorPlugin {
HBoxContainer *bake_hb;
Button *bake;
- EditorNode *editor;
EditorFileDialog *probe_file;
@@ -66,7 +67,7 @@ public:
virtual bool handles(Object *p_object) const override;
virtual void make_visible(bool p_visible) override;
- GPUParticlesCollisionSDF3DEditorPlugin(EditorNode *p_node);
+ GPUParticlesCollisionSDF3DEditorPlugin();
~GPUParticlesCollisionSDF3DEditorPlugin();
};
diff --git a/editor/plugins/gradient_editor_plugin.cpp b/editor/plugins/gradient_editor_plugin.cpp
index 5e300d3de9..e9d7808684 100644
--- a/editor/plugins/gradient_editor_plugin.cpp
+++ b/editor/plugins/gradient_editor_plugin.cpp
@@ -31,6 +31,7 @@
#include "gradient_editor_plugin.h"
#include "canvas_item_editor_plugin.h"
+#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "node_3d_editor_plugin.h"
@@ -90,13 +91,15 @@ GradientEditor::GradientEditor() {
///////////////////////
void GradientReverseButton::_notification(int p_what) {
- if (p_what == NOTIFICATION_DRAW) {
- Ref<Texture2D> icon = get_theme_icon(SNAME("ReverseGradient"), SNAME("EditorIcons"));
- if (is_pressed()) {
- draw_texture_rect(icon, Rect2(margin, margin, icon->get_width(), icon->get_height()), false, get_theme_color(SNAME("icon_pressed_color"), SNAME("Button")));
- } else {
- draw_texture_rect(icon, Rect2(margin, margin, icon->get_width(), icon->get_height()));
- }
+ switch (p_what) {
+ case NOTIFICATION_DRAW: {
+ Ref<Texture2D> icon = get_theme_icon(SNAME("ReverseGradient"), SNAME("EditorIcons"));
+ if (is_pressed()) {
+ draw_texture_rect(icon, Rect2(margin, margin, icon->get_width(), icon->get_height()), false, get_theme_color(SNAME("icon_pressed_color"), SNAME("Button")));
+ } else {
+ draw_texture_rect(icon, Rect2(margin, margin, icon->get_width(), icon->get_height()));
+ }
+ } break;
}
}
@@ -136,7 +139,7 @@ void EditorInspectorPluginGradient::_reverse_button_pressed() {
editor->reverse_gradient();
}
-GradientEditorPlugin::GradientEditorPlugin(EditorNode *p_node) {
+GradientEditorPlugin::GradientEditorPlugin() {
Ref<EditorInspectorPluginGradient> plugin;
plugin.instantiate();
add_inspector_plugin(plugin);
diff --git a/editor/plugins/gradient_editor_plugin.h b/editor/plugins/gradient_editor_plugin.h
index 8239711667..9857ea018d 100644
--- a/editor/plugins/gradient_editor_plugin.h
+++ b/editor/plugins/gradient_editor_plugin.h
@@ -31,7 +31,6 @@
#ifndef GRADIENT_EDITOR_PLUGIN_H
#define GRADIENT_EDITOR_PLUGIN_H
-#include "editor/editor_node.h"
#include "editor/editor_plugin.h"
#include "scene/gui/gradient_edit.h"
@@ -83,7 +82,7 @@ class GradientEditorPlugin : public EditorPlugin {
public:
virtual String get_name() const override { return "Gradient"; }
- GradientEditorPlugin(EditorNode *p_node);
+ GradientEditorPlugin();
};
#endif // GRADIENT_EDITOR_PLUGIN_H
diff --git a/editor/plugins/input_event_editor_plugin.cpp b/editor/plugins/input_event_editor_plugin.cpp
index b0ee88479a..b4a7081ebc 100644
--- a/editor/plugins/input_event_editor_plugin.cpp
+++ b/editor/plugins/input_event_editor_plugin.cpp
@@ -115,7 +115,7 @@ void EditorInspectorPluginInputEvent::parse_begin(Object *p_object) {
add_custom_control(picker_controls);
}
-InputEventEditorPlugin::InputEventEditorPlugin(EditorNode *p_node) {
+InputEventEditorPlugin::InputEventEditorPlugin() {
Ref<EditorInspectorPluginInputEvent> plugin;
plugin.instantiate();
add_inspector_plugin(plugin);
diff --git a/editor/plugins/input_event_editor_plugin.h b/editor/plugins/input_event_editor_plugin.h
index ed26890229..ab948462ab 100644
--- a/editor/plugins/input_event_editor_plugin.h
+++ b/editor/plugins/input_event_editor_plugin.h
@@ -33,7 +33,7 @@
#include "editor/action_map_editor.h"
#include "editor/editor_inspector.h"
-#include "editor/editor_node.h"
+#include "editor/editor_plugin.h"
class InputEventConfigContainer : public HBoxContainer {
GDCLASS(InputEventConfigContainer, HBoxContainer);
@@ -73,7 +73,7 @@ class InputEventEditorPlugin : public EditorPlugin {
public:
virtual String get_name() const override { return "InputEvent"; }
- InputEventEditorPlugin(EditorNode *p_node);
+ InputEventEditorPlugin();
};
#endif // INPUT_EVENT_EDITOR_PLUGIN_H
diff --git a/editor/plugins/light_occluder_2d_editor_plugin.cpp b/editor/plugins/light_occluder_2d_editor_plugin.cpp
index 94ab89e2f6..6a5ead58d0 100644
--- a/editor/plugins/light_occluder_2d_editor_plugin.cpp
+++ b/editor/plugins/light_occluder_2d_editor_plugin.cpp
@@ -102,11 +102,11 @@ void LightOccluder2DEditor::_create_resource() {
_menu_option(MODE_CREATE);
}
-LightOccluder2DEditor::LightOccluder2DEditor(EditorNode *p_editor) :
- AbstractPolygon2DEditor(p_editor) {
+LightOccluder2DEditor::LightOccluder2DEditor() :
+ AbstractPolygon2DEditor() {
node = nullptr;
}
-LightOccluder2DEditorPlugin::LightOccluder2DEditorPlugin(EditorNode *p_node) :
- AbstractPolygon2DEditorPlugin(p_node, memnew(LightOccluder2DEditor(p_node)), "LightOccluder2D") {
+LightOccluder2DEditorPlugin::LightOccluder2DEditorPlugin() :
+ AbstractPolygon2DEditorPlugin(memnew(LightOccluder2DEditor), "LightOccluder2D") {
}
diff --git a/editor/plugins/light_occluder_2d_editor_plugin.h b/editor/plugins/light_occluder_2d_editor_plugin.h
index 1a0cd3514b..557e8bf292 100644
--- a/editor/plugins/light_occluder_2d_editor_plugin.h
+++ b/editor/plugins/light_occluder_2d_editor_plugin.h
@@ -56,14 +56,14 @@ protected:
virtual void _create_resource() override;
public:
- LightOccluder2DEditor(EditorNode *p_editor);
+ LightOccluder2DEditor();
};
class LightOccluder2DEditorPlugin : public AbstractPolygon2DEditorPlugin {
GDCLASS(LightOccluder2DEditorPlugin, AbstractPolygon2DEditorPlugin);
public:
- LightOccluder2DEditorPlugin(EditorNode *p_node);
+ LightOccluder2DEditorPlugin();
};
#endif // LIGHT_OCCLUDER_2D_EDITOR_PLUGIN_H
diff --git a/editor/plugins/lightmap_gi_editor_plugin.cpp b/editor/plugins/lightmap_gi_editor_plugin.cpp
index 2126ca1bc9..aef97f059a 100644
--- a/editor/plugins/lightmap_gi_editor_plugin.cpp
+++ b/editor/plugins/lightmap_gi_editor_plugin.cpp
@@ -30,6 +30,9 @@
#include "lightmap_gi_editor_plugin.h"
+#include "editor/editor_file_dialog.h"
+#include "editor/editor_node.h"
+
void LightmapGIEditorPlugin::_bake_select_file(const String &p_file) {
if (lightmap) {
LightmapGI::BakeError err;
@@ -123,11 +126,10 @@ void LightmapGIEditorPlugin::_bind_methods() {
ClassDB::bind_method("_bake", &LightmapGIEditorPlugin::_bake);
}
-LightmapGIEditorPlugin::LightmapGIEditorPlugin(EditorNode *p_node) {
- editor = p_node;
+LightmapGIEditorPlugin::LightmapGIEditorPlugin() {
bake = memnew(Button);
bake->set_flat(true);
- bake->set_icon(editor->get_gui_base()->get_theme_icon(SNAME("Bake"), SNAME("EditorIcons")));
+ bake->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Bake"), SNAME("EditorIcons")));
bake->set_text(TTR("Bake Lightmaps"));
bake->hide();
bake->connect("pressed", Callable(this, "_bake"));
@@ -136,7 +138,7 @@ LightmapGIEditorPlugin::LightmapGIEditorPlugin(EditorNode *p_node) {
file_dialog = memnew(EditorFileDialog);
file_dialog->set_file_mode(EditorFileDialog::FILE_MODE_SAVE_FILE);
- file_dialog->add_filter("*.lmbake ; LightMap Bake");
+ file_dialog->add_filter("*.lmbake ; " + TTR("LightMap Bake"));
file_dialog->set_title(TTR("Select lightmap bake file:"));
file_dialog->connect("file_selected", callable_mp(this, &LightmapGIEditorPlugin::_bake_select_file));
bake->add_child(file_dialog);
diff --git a/editor/plugins/lightmap_gi_editor_plugin.h b/editor/plugins/lightmap_gi_editor_plugin.h
index 5eec972228..e658230181 100644
--- a/editor/plugins/lightmap_gi_editor_plugin.h
+++ b/editor/plugins/lightmap_gi_editor_plugin.h
@@ -31,18 +31,19 @@
#ifndef BAKED_LIGHTMAP_EDITOR_PLUGIN_H
#define BAKED_LIGHTMAP_EDITOR_PLUGIN_H
-#include "editor/editor_node.h"
#include "editor/editor_plugin.h"
#include "scene/3d/lightmap_gi.h"
#include "scene/resources/material.h"
+struct EditorProgress;
+class EditorFileDialog;
+
class LightmapGIEditorPlugin : public EditorPlugin {
GDCLASS(LightmapGIEditorPlugin, EditorPlugin);
LightmapGI *lightmap;
Button *bake;
- EditorNode *editor;
EditorFileDialog *file_dialog;
static EditorProgress *tmp_progress;
@@ -62,7 +63,7 @@ public:
virtual bool handles(Object *p_object) const override;
virtual void make_visible(bool p_visible) override;
- LightmapGIEditorPlugin(EditorNode *p_node);
+ LightmapGIEditorPlugin();
~LightmapGIEditorPlugin();
};
diff --git a/editor/plugins/line_2d_editor_plugin.cpp b/editor/plugins/line_2d_editor_plugin.cpp
index 9d7e22278e..0f81b17cb3 100644
--- a/editor/plugins/line_2d_editor_plugin.cpp
+++ b/editor/plugins/line_2d_editor_plugin.cpp
@@ -56,11 +56,11 @@ void Line2DEditor::_action_set_polygon(int p_idx, const Variant &p_previous, con
undo_redo->add_undo_method(node, "set_points", p_previous);
}
-Line2DEditor::Line2DEditor(EditorNode *p_editor) :
- AbstractPolygon2DEditor(p_editor) {
+Line2DEditor::Line2DEditor() :
+ AbstractPolygon2DEditor() {
node = nullptr;
}
-Line2DEditorPlugin::Line2DEditorPlugin(EditorNode *p_node) :
- AbstractPolygon2DEditorPlugin(p_node, memnew(Line2DEditor(p_node)), "Line2D") {
+Line2DEditorPlugin::Line2DEditorPlugin() :
+ AbstractPolygon2DEditorPlugin(memnew(Line2DEditor), "Line2D") {
}
diff --git a/editor/plugins/line_2d_editor_plugin.h b/editor/plugins/line_2d_editor_plugin.h
index 4497307747..307cf11207 100644
--- a/editor/plugins/line_2d_editor_plugin.h
+++ b/editor/plugins/line_2d_editor_plugin.h
@@ -49,14 +49,14 @@ protected:
virtual void _action_set_polygon(int p_idx, const Variant &p_previous, const Variant &p_polygon) override;
public:
- Line2DEditor(EditorNode *p_editor);
+ Line2DEditor();
};
class Line2DEditorPlugin : public AbstractPolygon2DEditorPlugin {
GDCLASS(Line2DEditorPlugin, AbstractPolygon2DEditorPlugin);
public:
- Line2DEditorPlugin(EditorNode *p_node);
+ Line2DEditorPlugin();
};
#endif // LINE_2D_EDITOR_PLUGIN_H
diff --git a/editor/plugins/material_editor_plugin.cpp b/editor/plugins/material_editor_plugin.cpp
index 9d45c365a8..daa864cfa1 100644
--- a/editor/plugins/material_editor_plugin.cpp
+++ b/editor/plugins/material_editor_plugin.cpp
@@ -30,6 +30,7 @@
#include "material_editor_plugin.h"
+#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "scene/gui/subviewport_container.h"
#include "scene/resources/fog_material.h"
@@ -37,31 +38,33 @@
#include "scene/resources/sky_material.h"
void MaterialEditor::_notification(int p_what) {
- if (p_what == NOTIFICATION_READY) {
- //get_scene()->connect("node_removed",this,"_node_removed");
+ switch (p_what) {
+ case NOTIFICATION_READY: {
+ //get_scene()->connect("node_removed",this,"_node_removed");
- if (first_enter) {
- //it's in propertyeditor so.. could be moved around
+ if (first_enter) {
+ //it's in propertyeditor so.. could be moved around
- light_1_switch->set_normal_texture(get_theme_icon(SNAME("MaterialPreviewLight1"), SNAME("EditorIcons")));
- light_1_switch->set_pressed_texture(get_theme_icon(SNAME("MaterialPreviewLight1Off"), SNAME("EditorIcons")));
- light_2_switch->set_normal_texture(get_theme_icon(SNAME("MaterialPreviewLight2"), SNAME("EditorIcons")));
- light_2_switch->set_pressed_texture(get_theme_icon(SNAME("MaterialPreviewLight2Off"), SNAME("EditorIcons")));
+ light_1_switch->set_normal_texture(get_theme_icon(SNAME("MaterialPreviewLight1"), SNAME("EditorIcons")));
+ light_1_switch->set_pressed_texture(get_theme_icon(SNAME("MaterialPreviewLight1Off"), SNAME("EditorIcons")));
+ light_2_switch->set_normal_texture(get_theme_icon(SNAME("MaterialPreviewLight2"), SNAME("EditorIcons")));
+ light_2_switch->set_pressed_texture(get_theme_icon(SNAME("MaterialPreviewLight2Off"), SNAME("EditorIcons")));
- sphere_switch->set_normal_texture(get_theme_icon(SNAME("MaterialPreviewSphereOff"), SNAME("EditorIcons")));
- sphere_switch->set_pressed_texture(get_theme_icon(SNAME("MaterialPreviewSphere"), SNAME("EditorIcons")));
- box_switch->set_normal_texture(get_theme_icon(SNAME("MaterialPreviewCubeOff"), SNAME("EditorIcons")));
- box_switch->set_pressed_texture(get_theme_icon(SNAME("MaterialPreviewCube"), SNAME("EditorIcons")));
+ sphere_switch->set_normal_texture(get_theme_icon(SNAME("MaterialPreviewSphereOff"), SNAME("EditorIcons")));
+ sphere_switch->set_pressed_texture(get_theme_icon(SNAME("MaterialPreviewSphere"), SNAME("EditorIcons")));
+ box_switch->set_normal_texture(get_theme_icon(SNAME("MaterialPreviewCubeOff"), SNAME("EditorIcons")));
+ box_switch->set_pressed_texture(get_theme_icon(SNAME("MaterialPreviewCube"), SNAME("EditorIcons")));
- first_enter = false;
- }
- }
+ first_enter = false;
+ }
+ } break;
- if (p_what == NOTIFICATION_DRAW) {
- Ref<Texture2D> checkerboard = get_theme_icon(SNAME("Checkerboard"), SNAME("EditorIcons"));
- Size2 size = get_size();
+ case NOTIFICATION_DRAW: {
+ Ref<Texture2D> checkerboard = get_theme_icon(SNAME("Checkerboard"), SNAME("EditorIcons"));
+ Size2 size = get_size();
- draw_texture_rect(checkerboard, Rect2(Point2(), size), true);
+ draw_texture_rect(checkerboard, Rect2(Point2(), size), true);
+ } break;
}
}
@@ -302,7 +305,7 @@ EditorInspectorPluginMaterial::EditorInspectorPluginMaterial() {
EditorNode::get_singleton()->get_editor_data().add_undo_redo_inspector_hook_callback(callable_mp(this, &EditorInspectorPluginMaterial::_undo_redo_inspector_callback));
}
-MaterialEditorPlugin::MaterialEditorPlugin(EditorNode *p_node) {
+MaterialEditorPlugin::MaterialEditorPlugin() {
Ref<EditorInspectorPluginMaterial> plugin;
plugin.instantiate();
add_inspector_plugin(plugin);
diff --git a/editor/plugins/material_editor_plugin.h b/editor/plugins/material_editor_plugin.h
index 53f4513396..9c6247d59b 100644
--- a/editor/plugins/material_editor_plugin.h
+++ b/editor/plugins/material_editor_plugin.h
@@ -31,16 +31,14 @@
#ifndef MATERIAL_EDITOR_PLUGIN_H
#define MATERIAL_EDITOR_PLUGIN_H
-#include "editor/property_editor.h"
-#include "scene/resources/primitive_meshes.h"
-
-#include "editor/editor_node.h"
#include "editor/editor_plugin.h"
+#include "editor/property_editor.h"
#include "scene/3d/camera_3d.h"
#include "scene/3d/light_3d.h"
#include "scene/3d/mesh_instance_3d.h"
#include "scene/gui/color_rect.h"
#include "scene/resources/material.h"
+#include "scene/resources/primitive_meshes.h"
class SubViewportContainer;
@@ -103,7 +101,7 @@ class MaterialEditorPlugin : public EditorPlugin {
public:
virtual String get_name() const override { return "Material"; }
- MaterialEditorPlugin(EditorNode *p_node);
+ MaterialEditorPlugin();
};
class StandardMaterial3DConversionPlugin : public EditorResourceConversionPlugin {
diff --git a/editor/plugins/mesh_editor_plugin.cpp b/editor/plugins/mesh_editor_plugin.cpp
index daf68f247d..4760b61dc8 100644
--- a/editor/plugins/mesh_editor_plugin.cpp
+++ b/editor/plugins/mesh_editor_plugin.cpp
@@ -49,18 +49,20 @@ void MeshEditor::gui_input(const Ref<InputEvent> &p_event) {
}
void MeshEditor::_notification(int p_what) {
- if (p_what == NOTIFICATION_READY) {
- //get_scene()->connect("node_removed",this,"_node_removed");
-
- if (first_enter) {
- //it's in propertyeditor so. could be moved around
-
- light_1_switch->set_normal_texture(get_theme_icon(SNAME("MaterialPreviewLight1"), SNAME("EditorIcons")));
- light_1_switch->set_pressed_texture(get_theme_icon(SNAME("MaterialPreviewLight1Off"), SNAME("EditorIcons")));
- light_2_switch->set_normal_texture(get_theme_icon(SNAME("MaterialPreviewLight2"), SNAME("EditorIcons")));
- light_2_switch->set_pressed_texture(get_theme_icon(SNAME("MaterialPreviewLight2Off"), SNAME("EditorIcons")));
- first_enter = false;
- }
+ switch (p_what) {
+ case NOTIFICATION_READY: {
+ //get_scene()->connect("node_removed",this,"_node_removed");
+
+ if (first_enter) {
+ //it's in propertyeditor so. could be moved around
+
+ light_1_switch->set_normal_texture(get_theme_icon(SNAME("MaterialPreviewLight1"), SNAME("EditorIcons")));
+ light_1_switch->set_pressed_texture(get_theme_icon(SNAME("MaterialPreviewLight1Off"), SNAME("EditorIcons")));
+ light_2_switch->set_normal_texture(get_theme_icon(SNAME("MaterialPreviewLight2"), SNAME("EditorIcons")));
+ light_2_switch->set_pressed_texture(get_theme_icon(SNAME("MaterialPreviewLight2Off"), SNAME("EditorIcons")));
+ first_enter = false;
+ }
+ } break;
}
}
@@ -176,7 +178,7 @@ void EditorInspectorPluginMesh::parse_begin(Object *p_object) {
add_custom_control(editor);
}
-MeshEditorPlugin::MeshEditorPlugin(EditorNode *p_node) {
+MeshEditorPlugin::MeshEditorPlugin() {
Ref<EditorInspectorPluginMesh> plugin;
plugin.instantiate();
add_inspector_plugin(plugin);
diff --git a/editor/plugins/mesh_editor_plugin.h b/editor/plugins/mesh_editor_plugin.h
index 613680e870..37464c98fe 100644
--- a/editor/plugins/mesh_editor_plugin.h
+++ b/editor/plugins/mesh_editor_plugin.h
@@ -31,7 +31,6 @@
#ifndef MESH_EDITOR_PLUGIN_H
#define MESH_EDITOR_PLUGIN_H
-#include "editor/editor_node.h"
#include "editor/editor_plugin.h"
#include "scene/3d/camera_3d.h"
#include "scene/3d/light_3d.h"
@@ -85,7 +84,7 @@ class MeshEditorPlugin : public EditorPlugin {
public:
virtual String get_name() const override { return "Mesh"; }
- MeshEditorPlugin(EditorNode *p_node);
+ MeshEditorPlugin();
};
#endif
diff --git a/editor/plugins/mesh_instance_3d_editor_plugin.cpp b/editor/plugins/mesh_instance_3d_editor_plugin.cpp
index 75e9cc23a1..64540ac157 100644
--- a/editor/plugins/mesh_instance_3d_editor_plugin.cpp
+++ b/editor/plugins/mesh_instance_3d_editor_plugin.cpp
@@ -30,6 +30,7 @@
#include "mesh_instance_3d_editor_plugin.h"
+#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "node_3d_editor_plugin.h"
#include "scene/3d/collision_shape_3d.h"
@@ -515,10 +516,9 @@ void MeshInstance3DEditorPlugin::make_visible(bool p_visible) {
}
}
-MeshInstance3DEditorPlugin::MeshInstance3DEditorPlugin(EditorNode *p_node) {
- editor = p_node;
+MeshInstance3DEditorPlugin::MeshInstance3DEditorPlugin() {
mesh_editor = memnew(MeshInstance3DEditor);
- editor->get_main_control()->add_child(mesh_editor);
+ EditorNode::get_singleton()->get_main_control()->add_child(mesh_editor);
mesh_editor->options->hide();
}
diff --git a/editor/plugins/mesh_instance_3d_editor_plugin.h b/editor/plugins/mesh_instance_3d_editor_plugin.h
index 1df72d107c..9c59c5fb9f 100644
--- a/editor/plugins/mesh_instance_3d_editor_plugin.h
+++ b/editor/plugins/mesh_instance_3d_editor_plugin.h
@@ -31,7 +31,6 @@
#ifndef MESH_INSTANCE_EDITOR_PLUGIN_H
#define MESH_INSTANCE_EDITOR_PLUGIN_H
-#include "editor/editor_node.h"
#include "editor/editor_plugin.h"
#include "scene/3d/mesh_instance_3d.h"
#include "scene/gui/spin_box.h"
@@ -86,7 +85,6 @@ class MeshInstance3DEditorPlugin : public EditorPlugin {
GDCLASS(MeshInstance3DEditorPlugin, EditorPlugin);
MeshInstance3DEditor *mesh_editor;
- EditorNode *editor;
public:
virtual String get_name() const override { return "MeshInstance3D"; }
@@ -95,7 +93,7 @@ public:
virtual bool handles(Object *p_object) const override;
virtual void make_visible(bool p_visible) override;
- MeshInstance3DEditorPlugin(EditorNode *p_node);
+ MeshInstance3DEditorPlugin();
~MeshInstance3DEditorPlugin();
};
diff --git a/editor/plugins/mesh_library_editor_plugin.cpp b/editor/plugins/mesh_library_editor_plugin.cpp
index e47381b8a0..41e3471a78 100644
--- a/editor/plugins/mesh_library_editor_plugin.cpp
+++ b/editor/plugins/mesh_library_editor_plugin.cpp
@@ -30,6 +30,7 @@
#include "mesh_library_editor_plugin.h"
+#include "editor/editor_file_dialog.h"
#include "editor/editor_node.h"
#include "editor/editor_settings.h"
#include "main/main.h"
@@ -253,7 +254,7 @@ void MeshLibraryEditor::_menu_cbk(int p_option) {
void MeshLibraryEditor::_bind_methods() {
}
-MeshLibraryEditor::MeshLibraryEditor(EditorNode *p_editor) {
+MeshLibraryEditor::MeshLibraryEditor() {
file = memnew(EditorFileDialog);
file->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILE);
//not for now?
@@ -282,15 +283,14 @@ MeshLibraryEditor::MeshLibraryEditor(EditorNode *p_editor) {
menu->get_popup()->connect("id_pressed", callable_mp(this, &MeshLibraryEditor::_menu_cbk));
menu->hide();
- editor = p_editor;
cd_remove = memnew(ConfirmationDialog);
add_child(cd_remove);
cd_remove->get_ok_button()->connect("pressed", callable_mp(this, &MeshLibraryEditor::_menu_remove_confirm));
cd_update = memnew(ConfirmationDialog);
add_child(cd_update);
- cd_update->get_ok_button()->set_text("Apply without Transforms");
+ cd_update->get_ok_button()->set_text(TTR("Apply without Transforms"));
cd_update->get_ok_button()->connect("pressed", callable_mp(this, &MeshLibraryEditor::_menu_update_confirm), varray(false));
- cd_update->add_button("Apply with Transforms")->connect("pressed", callable_mp(this, &MeshLibraryEditor::_menu_update_confirm), varray(true));
+ cd_update->add_button(TTR("Apply with Transforms"))->connect("pressed", callable_mp(this, &MeshLibraryEditor::_menu_update_confirm), varray(true));
}
void MeshLibraryEditorPlugin::edit(Object *p_node) {
@@ -316,14 +316,11 @@ void MeshLibraryEditorPlugin::make_visible(bool p_visible) {
}
}
-MeshLibraryEditorPlugin::MeshLibraryEditorPlugin(EditorNode *p_node) {
- EDITOR_DEF("editors/grid_map/preview_size", 64);
- mesh_library_editor = memnew(MeshLibraryEditor(p_node));
+MeshLibraryEditorPlugin::MeshLibraryEditorPlugin() {
+ mesh_library_editor = memnew(MeshLibraryEditor);
- p_node->get_main_control()->add_child(mesh_library_editor);
+ EditorNode::get_singleton()->get_main_control()->add_child(mesh_library_editor);
mesh_library_editor->set_anchors_and_offsets_preset(Control::PRESET_TOP_WIDE);
mesh_library_editor->set_end(Point2(0, 22));
mesh_library_editor->hide();
-
- editor = nullptr;
}
diff --git a/editor/plugins/mesh_library_editor_plugin.h b/editor/plugins/mesh_library_editor_plugin.h
index 7144f87ba6..6bc992869b 100644
--- a/editor/plugins/mesh_library_editor_plugin.h
+++ b/editor/plugins/mesh_library_editor_plugin.h
@@ -31,15 +31,18 @@
#ifndef MESH_LIBRARY_EDITOR_PLUGIN_H
#define MESH_LIBRARY_EDITOR_PLUGIN_H
-#include "editor/editor_node.h"
+#include "editor/editor_plugin.h"
#include "scene/resources/mesh_library.h"
+class EditorFileDialog;
+class ConfirmationDialog;
+class MenuButton;
+
class MeshLibraryEditor : public Control {
GDCLASS(MeshLibraryEditor, Control);
Ref<MeshLibrary> mesh_library;
- EditorNode *editor;
MenuButton *menu;
ConfirmationDialog *cd_remove;
ConfirmationDialog *cd_update;
@@ -72,14 +75,13 @@ public:
void edit(const Ref<MeshLibrary> &p_mesh_library);
static Error update_library_file(Node *p_base_scene, Ref<MeshLibrary> ml, bool p_merge = true, bool p_apply_xforms = false);
- MeshLibraryEditor(EditorNode *p_editor);
+ MeshLibraryEditor();
};
class MeshLibraryEditorPlugin : public EditorPlugin {
GDCLASS(MeshLibraryEditorPlugin, EditorPlugin);
MeshLibraryEditor *mesh_library_editor;
- EditorNode *editor;
public:
virtual String get_name() const override { return "MeshLibrary"; }
@@ -88,7 +90,7 @@ public:
virtual bool handles(Object *p_node) const override;
virtual void make_visible(bool p_visible) override;
- MeshLibraryEditorPlugin(EditorNode *p_node);
+ MeshLibraryEditorPlugin();
};
#endif // MESH_LIBRARY_EDITOR_PLUGIN_H
diff --git a/editor/plugins/multimesh_editor_plugin.cpp b/editor/plugins/multimesh_editor_plugin.cpp
index 4ec65ea257..72f3b6a06e 100644
--- a/editor/plugins/multimesh_editor_plugin.cpp
+++ b/editor/plugins/multimesh_editor_plugin.cpp
@@ -30,6 +30,8 @@
#include "multimesh_editor_plugin.h"
+#include "editor/editor_node.h"
+#include "editor/scene_tree_editor.h"
#include "node_3d_editor_plugin.h"
#include "scene/3d/mesh_instance_3d.h"
#include "scene/gui/box_container.h"
@@ -375,10 +377,9 @@ void MultiMeshEditorPlugin::make_visible(bool p_visible) {
}
}
-MultiMeshEditorPlugin::MultiMeshEditorPlugin(EditorNode *p_node) {
- editor = p_node;
+MultiMeshEditorPlugin::MultiMeshEditorPlugin() {
multimesh_editor = memnew(MultiMeshEditor);
- editor->get_main_control()->add_child(multimesh_editor);
+ EditorNode::get_singleton()->get_main_control()->add_child(multimesh_editor);
multimesh_editor->options->hide();
}
diff --git a/editor/plugins/multimesh_editor_plugin.h b/editor/plugins/multimesh_editor_plugin.h
index ae18edd90a..846e6d17f3 100644
--- a/editor/plugins/multimesh_editor_plugin.h
+++ b/editor/plugins/multimesh_editor_plugin.h
@@ -31,11 +31,13 @@
#ifndef MULTIMESH_EDITOR_PLUGIN_H
#define MULTIMESH_EDITOR_PLUGIN_H
-#include "editor/editor_node.h"
#include "editor/editor_plugin.h"
#include "scene/3d/multimesh_instance_3d.h"
+#include "scene/gui/slider.h"
#include "scene/gui/spin_box.h"
+class SceneTreeDialog;
+
class MultiMeshEditor : public Control {
GDCLASS(MultiMeshEditor, Control);
@@ -84,7 +86,6 @@ class MultiMeshEditorPlugin : public EditorPlugin {
GDCLASS(MultiMeshEditorPlugin, EditorPlugin);
MultiMeshEditor *multimesh_editor;
- EditorNode *editor;
public:
virtual String get_name() const override { return "MultiMesh"; }
@@ -93,7 +94,7 @@ public:
virtual bool handles(Object *p_object) const override;
virtual void make_visible(bool p_visible) override;
- MultiMeshEditorPlugin(EditorNode *p_node);
+ MultiMeshEditorPlugin();
~MultiMeshEditorPlugin();
};
diff --git a/editor/plugins/navigation_polygon_editor_plugin.cpp b/editor/plugins/navigation_polygon_editor_plugin.cpp
index e9e2a843cd..fe31f254df 100644
--- a/editor/plugins/navigation_polygon_editor_plugin.cpp
+++ b/editor/plugins/navigation_polygon_editor_plugin.cpp
@@ -112,11 +112,11 @@ void NavigationPolygonEditor::_create_resource() {
_menu_option(MODE_CREATE);
}
-NavigationPolygonEditor::NavigationPolygonEditor(EditorNode *p_editor) :
- AbstractPolygon2DEditor(p_editor) {
+NavigationPolygonEditor::NavigationPolygonEditor() :
+ AbstractPolygon2DEditor() {
node = nullptr;
}
-NavigationPolygonEditorPlugin::NavigationPolygonEditorPlugin(EditorNode *p_node) :
- AbstractPolygon2DEditorPlugin(p_node, memnew(NavigationPolygonEditor(p_node)), "NavigationRegion2D") {
+NavigationPolygonEditorPlugin::NavigationPolygonEditorPlugin() :
+ AbstractPolygon2DEditorPlugin(memnew(NavigationPolygonEditor), "NavigationRegion2D") {
}
diff --git a/editor/plugins/navigation_polygon_editor_plugin.h b/editor/plugins/navigation_polygon_editor_plugin.h
index 446083902c..16fbb241e9 100644
--- a/editor/plugins/navigation_polygon_editor_plugin.h
+++ b/editor/plugins/navigation_polygon_editor_plugin.h
@@ -57,14 +57,14 @@ protected:
virtual void _create_resource() override;
public:
- NavigationPolygonEditor(EditorNode *p_editor);
+ NavigationPolygonEditor();
};
class NavigationPolygonEditorPlugin : public AbstractPolygon2DEditorPlugin {
GDCLASS(NavigationPolygonEditorPlugin, AbstractPolygon2DEditorPlugin);
public:
- NavigationPolygonEditorPlugin(EditorNode *p_node);
+ NavigationPolygonEditorPlugin();
};
#endif // NAVIGATIONPOLYGONEDITORPLUGIN_H
diff --git a/editor/plugins/node_3d_editor_gizmos.cpp b/editor/plugins/node_3d_editor_gizmos.cpp
index 59ba49232e..8aa8ba1f00 100644
--- a/editor/plugins/node_3d_editor_gizmos.cpp
+++ b/editor/plugins/node_3d_editor_gizmos.cpp
@@ -33,6 +33,8 @@
#include "core/math/convex_hull.h"
#include "core/math/geometry_2d.h"
#include "core/math/geometry_3d.h"
+#include "editor/editor_node.h"
+#include "editor/editor_settings.h"
#include "editor/plugins/node_3d_editor_plugin.h"
#include "scene/3d/audio_listener_3d.h"
#include "scene/3d/audio_stream_player_3d.h"
@@ -874,7 +876,7 @@ EditorNode3DGizmo::~EditorNode3DGizmo() {
/////
void EditorNode3DGizmoPlugin::create_material(const String &p_name, const Color &p_color, bool p_billboard, bool p_on_top, bool p_use_vertex_color) {
- Color instantiated_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/instantiated", Color(0.7, 0.7, 0.7, 0.6));
+ Color instantiated_color = EDITOR_GET("editors/3d_gizmos/gizmo_colors/instantiated");
Vector<Ref<StandardMaterial3D>> mats;
@@ -916,7 +918,7 @@ void EditorNode3DGizmoPlugin::create_material(const String &p_name, const Color
}
void EditorNode3DGizmoPlugin::create_icon_material(const String &p_name, const Ref<Texture2D> &p_texture, bool p_on_top, const Color &p_albedo) {
- Color instantiated_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/instantiated", Color(0.7, 0.7, 0.7, 0.6));
+ Color instantiated_color = EDITOR_GET("editors/3d_gizmos/gizmo_colors/instantiated");
Vector<Ref<StandardMaterial3D>> icons;
@@ -1067,7 +1069,6 @@ void EditorNode3DGizmoPlugin::_bind_methods() {
GDVIRTUAL_BIND(_get_subgizmo_transform, "gizmo", "subgizmo_id");
GDVIRTUAL_BIND(_set_subgizmo_transform, "gizmo", "subgizmo_id", "transform");
GDVIRTUAL_BIND(_commit_subgizmos, "gizmo", "ids", "restores", "cancel");
- ;
}
bool EditorNode3DGizmoPlugin::has_gizmo(Node3D *p_spatial) {
@@ -1627,7 +1628,7 @@ void AudioStreamPlayer3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
//////
AudioListener3DGizmoPlugin::AudioListener3DGizmoPlugin() {
- create_icon_material("audio_listener_3d_icon", Node3DEditor::get_singleton()->get_theme_icon("GizmoAudioListener3D", "EditorIcons"));
+ create_icon_material("audio_listener_3d_icon", Node3DEditor::get_singleton()->get_theme_icon(SNAME("GizmoAudioListener3D"), SNAME("EditorIcons")));
}
bool AudioListener3DGizmoPlugin::has_gizmo(Node3D *p_spatial) {
@@ -1889,6 +1890,7 @@ void MeshInstance3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
OccluderInstance3DGizmoPlugin::OccluderInstance3DGizmoPlugin() {
create_material("line_material", EDITOR_DEF("editors/3d_gizmos/gizmo_colors/occluder", Color(0.8, 0.5, 1)));
+ create_handle_material("handles");
}
bool OccluderInstance3DGizmoPlugin::has_gizmo(Node3D *p_spatial) {
@@ -1903,6 +1905,189 @@ int OccluderInstance3DGizmoPlugin::get_priority() const {
return -1;
}
+String OccluderInstance3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const {
+ const OccluderInstance3D *cs = Object::cast_to<OccluderInstance3D>(p_gizmo->get_spatial_node());
+
+ Ref<Occluder3D> o = cs->get_occluder();
+ if (o.is_null()) {
+ return "";
+ }
+
+ if (Object::cast_to<SphereOccluder3D>(*o)) {
+ return "Radius";
+ }
+
+ if (Object::cast_to<BoxOccluder3D>(*o) || Object::cast_to<QuadOccluder3D>(*o)) {
+ return "Size";
+ }
+
+ return "";
+}
+
+Variant OccluderInstance3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const {
+ OccluderInstance3D *oi = Object::cast_to<OccluderInstance3D>(p_gizmo->get_spatial_node());
+
+ Ref<Occluder3D> o = oi->get_occluder();
+ if (o.is_null()) {
+ return Variant();
+ }
+
+ if (Object::cast_to<SphereOccluder3D>(*o)) {
+ Ref<SphereOccluder3D> so = o;
+ return so->get_radius();
+ }
+
+ if (Object::cast_to<BoxOccluder3D>(*o)) {
+ Ref<BoxOccluder3D> bo = o;
+ return bo->get_size();
+ }
+
+ if (Object::cast_to<QuadOccluder3D>(*o)) {
+ Ref<QuadOccluder3D> qo = o;
+ return qo->get_size();
+ }
+
+ return Variant();
+}
+
+void OccluderInstance3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) {
+ OccluderInstance3D *oi = Object::cast_to<OccluderInstance3D>(p_gizmo->get_spatial_node());
+
+ Ref<Occluder3D> o = oi->get_occluder();
+ if (o.is_null()) {
+ return;
+ }
+
+ Transform3D gt = oi->get_global_transform();
+ Transform3D gi = gt.affine_inverse();
+
+ Vector3 ray_from = p_camera->project_ray_origin(p_point);
+ Vector3 ray_dir = p_camera->project_ray_normal(p_point);
+
+ Vector3 sg[2] = { gi.xform(ray_from), gi.xform(ray_from + ray_dir * 4096) };
+
+ bool snap_enabled = Node3DEditor::get_singleton()->is_snap_enabled();
+ float snap = Node3DEditor::get_singleton()->get_translate_snap();
+
+ if (Object::cast_to<SphereOccluder3D>(*o)) {
+ Ref<SphereOccluder3D> so = o;
+ Vector3 ra, rb;
+ Geometry3D::get_closest_points_between_segments(Vector3(), Vector3(4096, 0, 0), sg[0], sg[1], ra, rb);
+ float d = ra.x;
+ if (snap_enabled) {
+ d = Math::snapped(d, snap);
+ }
+
+ if (d < 0.001) {
+ d = 0.001;
+ }
+
+ so->set_radius(d);
+ }
+
+ if (Object::cast_to<BoxOccluder3D>(*o)) {
+ Vector3 axis;
+ axis[p_id] = 1.0;
+ Ref<BoxOccluder3D> bo = o;
+ Vector3 ra, rb;
+ Geometry3D::get_closest_points_between_segments(Vector3(), axis * 4096, sg[0], sg[1], ra, rb);
+ float d = ra[p_id];
+ if (snap_enabled) {
+ d = Math::snapped(d, snap);
+ }
+
+ if (d < 0.001) {
+ d = 0.001;
+ }
+
+ Vector3 he = bo->get_size();
+ he[p_id] = d * 2;
+ bo->set_size(he);
+ }
+
+ if (Object::cast_to<QuadOccluder3D>(*o)) {
+ Ref<QuadOccluder3D> qo = o;
+ Plane p = Plane(Vector3(0.0f, 0.0f, 1.0f), 0.0f);
+ Vector3 intersection;
+ if (!p.intersects_segment(sg[0], sg[1], &intersection)) {
+ return;
+ }
+
+ if (p_id == 2) {
+ Vector2 s = Vector2(intersection.x, intersection.y) * 2.0f;
+ if (snap_enabled) {
+ s = s.snapped(Vector2(snap, snap));
+ }
+ s = s.max(Vector2(0.001, 0.001));
+ qo->set_size(s);
+ } else {
+ float d = intersection[p_id];
+ if (snap_enabled) {
+ d = Math::snapped(d, snap);
+ }
+
+ if (d < 0.001) {
+ d = 0.001;
+ }
+
+ Vector2 he = qo->get_size();
+ he[p_id] = d * 2.0f;
+ qo->set_size(he);
+ }
+ }
+}
+
+void OccluderInstance3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel) {
+ OccluderInstance3D *oi = Object::cast_to<OccluderInstance3D>(p_gizmo->get_spatial_node());
+
+ Ref<Occluder3D> o = oi->get_occluder();
+ if (o.is_null()) {
+ return;
+ }
+
+ if (Object::cast_to<SphereOccluder3D>(*o)) {
+ Ref<SphereOccluder3D> so = o;
+ if (p_cancel) {
+ so->set_radius(p_restore);
+ return;
+ }
+
+ UndoRedo *ur = Node3DEditor::get_singleton()->get_undo_redo();
+ ur->create_action(TTR("Change Sphere Shape Radius"));
+ ur->add_do_method(so.ptr(), "set_radius", so->get_radius());
+ ur->add_undo_method(so.ptr(), "set_radius", p_restore);
+ ur->commit_action();
+ }
+
+ if (Object::cast_to<BoxOccluder3D>(*o)) {
+ Ref<BoxOccluder3D> bo = o;
+ if (p_cancel) {
+ bo->set_size(p_restore);
+ return;
+ }
+
+ UndoRedo *ur = Node3DEditor::get_singleton()->get_undo_redo();
+ ur->create_action(TTR("Change Box Shape Size"));
+ ur->add_do_method(bo.ptr(), "set_size", bo->get_size());
+ ur->add_undo_method(bo.ptr(), "set_size", p_restore);
+ ur->commit_action();
+ }
+
+ if (Object::cast_to<QuadOccluder3D>(*o)) {
+ Ref<QuadOccluder3D> qo = o;
+ if (p_cancel) {
+ qo->set_size(p_restore);
+ return;
+ }
+
+ UndoRedo *ur = Node3DEditor::get_singleton()->get_undo_redo();
+ ur->create_action(TTR("Change Box Shape Size"));
+ ur->add_do_method(qo.ptr(), "set_size", qo->get_size());
+ ur->add_undo_method(qo.ptr(), "set_size", p_restore);
+ ur->commit_action();
+ }
+}
+
void OccluderInstance3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
OccluderInstance3D *occluder_instance = Object::cast_to<OccluderInstance3D>(p_gizmo->get_spatial_node());
@@ -1920,6 +2105,35 @@ void OccluderInstance3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
p_gizmo->add_lines(lines, material);
p_gizmo->add_collision_segments(lines);
}
+
+ Ref<Material> handles_material = get_material("handles");
+ if (Object::cast_to<SphereOccluder3D>(*o)) {
+ Ref<SphereOccluder3D> so = o;
+ float r = so->get_radius();
+ Vector<Vector3> handles = { Vector3(r, 0, 0) };
+ p_gizmo->add_handles(handles, handles_material);
+ }
+
+ if (Object::cast_to<BoxOccluder3D>(*o)) {
+ Ref<BoxOccluder3D> bo = o;
+
+ Vector<Vector3> handles;
+ for (int i = 0; i < 3; i++) {
+ Vector3 ax;
+ ax[i] = bo->get_size()[i] / 2;
+ handles.push_back(ax);
+ }
+
+ p_gizmo->add_handles(handles, handles_material);
+ }
+
+ if (Object::cast_to<QuadOccluder3D>(*o)) {
+ Ref<QuadOccluder3D> qo = o;
+ Vector2 size = qo->get_size();
+ Vector3 s = Vector3(size.x, size.y, 0.0f) / 2.0f;
+ Vector<Vector3> handles = { Vector3(s.x, 0.0f, 0.0f), Vector3(0.0f, s.y, 0.0f), Vector3(s.x, s.y, 0.0f) };
+ p_gizmo->add_handles(handles, handles_material);
+ }
}
/////
@@ -2037,7 +2251,7 @@ void Position3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
////
PhysicalBone3DGizmoPlugin::PhysicalBone3DGizmoPlugin() {
- create_material("joint_material", EDITOR_DEF("editors/3d_gizmos/gizmo_colors/joint", Color(0.5, 0.8, 1)));
+ create_material("joint_material", EDITOR_GET("editors/3d_gizmos/gizmo_colors/joint"));
}
bool PhysicalBone3DGizmoPlugin::has_gizmo(Node3D *p_spatial) {
@@ -2170,7 +2384,7 @@ void PhysicalBone3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
/////
RayCast3DGizmoPlugin::RayCast3DGizmoPlugin() {
- const Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/shape", Color(0.5, 0.7, 1));
+ const Color gizmo_color = EDITOR_GET("editors/3d_gizmos/gizmo_colors/shape");
create_material("shape_material", gizmo_color);
const float gizmo_value = gizmo_color.get_v();
const Color gizmo_color_disabled = Color(gizmo_value, gizmo_value, gizmo_value, 0.65);
@@ -2224,7 +2438,7 @@ void SpringArm3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
}
SpringArm3DGizmoPlugin::SpringArm3DGizmoPlugin() {
- Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/shape", Color(0.5, 0.7, 1));
+ Color gizmo_color = EDITOR_GET("editors/3d_gizmos/gizmo_colors/shape");
create_material("shape_material", gizmo_color);
}
@@ -2243,7 +2457,7 @@ int SpringArm3DGizmoPlugin::get_priority() const {
/////
VehicleWheel3DGizmoPlugin::VehicleWheel3DGizmoPlugin() {
- Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/shape", Color(0.5, 0.7, 1));
+ Color gizmo_color = EDITOR_GET("editors/3d_gizmos/gizmo_colors/shape");
create_material("shape_material", gizmo_color);
}
@@ -2314,7 +2528,7 @@ void VehicleWheel3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
///////////
SoftDynamicBody3DGizmoPlugin::SoftDynamicBody3DGizmoPlugin() {
- Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/shape", Color(0.5, 0.7, 1));
+ Color gizmo_color = EDITOR_GET("editors/3d_gizmos/gizmo_colors/shape");
create_material("shape_material", gizmo_color);
create_handle_material("handles");
}
@@ -3455,13 +3669,8 @@ void VoxelGIGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
continue;
}
- Vector2 dir;
- dir[j] = 1.0;
- Vector2 ta, tb;
int j_n1 = (j + 1) % 3;
int j_n2 = (j + 2) % 3;
- ta[j_n1] = 1.0;
- tb[j_n2] = 1.0;
for (int k = 0; k < 4; k++) {
Vector3 from = aabb.position, to = aabb.position;
@@ -3767,7 +3976,7 @@ void LightmapProbeGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
////
CollisionObject3DGizmoPlugin::CollisionObject3DGizmoPlugin() {
- const Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/shape", Color(0.5, 0.7, 1));
+ const Color gizmo_color = EDITOR_GET("editors/3d_gizmos/gizmo_colors/shape");
create_material("shape_material", gizmo_color);
const float gizmo_value = gizmo_color.get_v();
const Color gizmo_color_disabled = Color(gizmo_value, gizmo_value, gizmo_value, 0.65);
@@ -3817,7 +4026,7 @@ void CollisionObject3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
////
CollisionShape3DGizmoPlugin::CollisionShape3DGizmoPlugin() {
- const Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/shape", Color(0.5, 0.7, 1));
+ const Color gizmo_color = EDITOR_GET("editors/3d_gizmos/gizmo_colors/shape");
create_material("shape_material", gizmo_color);
const float gizmo_value = gizmo_color.get_v();
const Color gizmo_color_disabled = Color(gizmo_value, gizmo_value, gizmo_value, 0.65);
@@ -4418,7 +4627,7 @@ void CollisionShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
/////
CollisionPolygon3DGizmoPlugin::CollisionPolygon3DGizmoPlugin() {
- const Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/shape", Color(0.5, 0.7, 1));
+ const Color gizmo_color = EDITOR_GET("editors/3d_gizmos/gizmo_colors/shape");
create_material("shape_material", gizmo_color);
const float gizmo_value = gizmo_color.get_v();
const Color gizmo_color_disabled = Color(gizmo_value, gizmo_value, gizmo_value, 0.65);
@@ -4815,7 +5024,7 @@ void JointGizmosDrawer::draw_cone(const Transform3D &p_offset, const Basis &p_ba
////
Joint3DGizmoPlugin::Joint3DGizmoPlugin() {
- create_material("joint_material", EDITOR_DEF("editors/3d_gizmos/gizmo_colors/joint", Color(0.5, 0.8, 1)));
+ create_material("joint_material", EDITOR_GET("editors/3d_gizmos/gizmo_colors/joint"));
create_material("joint_body_a_material", EDITOR_DEF("editors/3d_gizmos/gizmo_colors/joint_body_a", Color(0.6, 0.8, 1)));
create_material("joint_body_b_material", EDITOR_DEF("editors/3d_gizmos/gizmo_colors/joint_body_b", Color(0.6, 0.9, 1)));
diff --git a/editor/plugins/node_3d_editor_gizmos.h b/editor/plugins/node_3d_editor_gizmos.h
index 66b3f02fcf..fa55651d26 100644
--- a/editor/plugins/node_3d_editor_gizmos.h
+++ b/editor/plugins/node_3d_editor_gizmos.h
@@ -300,6 +300,11 @@ public:
int get_priority() const override;
void redraw(EditorNode3DGizmo *p_gizmo) override;
+ String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const override;
+ Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const override;
+ void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) override;
+ void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel = false) override;
+
OccluderInstance3DGizmoPlugin();
};
diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp
index 0c0188e8d1..3927aaa438 100644
--- a/editor/plugins/node_3d_editor_plugin.cpp
+++ b/editor/plugins/node_3d_editor_plugin.cpp
@@ -32,6 +32,7 @@
#include "core/config/project_settings.h"
#include "core/input/input.h"
+#include "core/input/input_map.h"
#include "core/math/camera_matrix.h"
#include "core/math/math_funcs.h"
#include "core/os/keyboard.h"
@@ -42,6 +43,7 @@
#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"
#include "scene/3d/light_3d.h"
@@ -81,28 +83,32 @@
#define MAX_FOV 179
void ViewportRotationControl::_notification(int p_what) {
- if (p_what == NOTIFICATION_ENTER_TREE) {
- axis_menu_options.clear();
- axis_menu_options.push_back(Node3DEditorViewport::VIEW_RIGHT);
- axis_menu_options.push_back(Node3DEditorViewport::VIEW_TOP);
- axis_menu_options.push_back(Node3DEditorViewport::VIEW_REAR);
- axis_menu_options.push_back(Node3DEditorViewport::VIEW_LEFT);
- axis_menu_options.push_back(Node3DEditorViewport::VIEW_BOTTOM);
- axis_menu_options.push_back(Node3DEditorViewport::VIEW_FRONT);
-
- axis_colors.clear();
- axis_colors.push_back(get_theme_color(SNAME("axis_x_color"), SNAME("Editor")));
- axis_colors.push_back(get_theme_color(SNAME("axis_y_color"), SNAME("Editor")));
- axis_colors.push_back(get_theme_color(SNAME("axis_z_color"), SNAME("Editor")));
- update();
+ switch (p_what) {
+ case NOTIFICATION_ENTER_TREE: {
+ axis_menu_options.clear();
+ axis_menu_options.push_back(Node3DEditorViewport::VIEW_RIGHT);
+ axis_menu_options.push_back(Node3DEditorViewport::VIEW_TOP);
+ axis_menu_options.push_back(Node3DEditorViewport::VIEW_REAR);
+ axis_menu_options.push_back(Node3DEditorViewport::VIEW_LEFT);
+ axis_menu_options.push_back(Node3DEditorViewport::VIEW_BOTTOM);
+ axis_menu_options.push_back(Node3DEditorViewport::VIEW_FRONT);
+
+ axis_colors.clear();
+ axis_colors.push_back(get_theme_color(SNAME("axis_x_color"), SNAME("Editor")));
+ axis_colors.push_back(get_theme_color(SNAME("axis_y_color"), SNAME("Editor")));
+ axis_colors.push_back(get_theme_color(SNAME("axis_z_color"), SNAME("Editor")));
+ update();
- if (!is_connected("mouse_exited", callable_mp(this, &ViewportRotationControl::_on_mouse_exited))) {
- connect("mouse_exited", callable_mp(this, &ViewportRotationControl::_on_mouse_exited));
- }
- }
+ if (!is_connected("mouse_exited", callable_mp(this, &ViewportRotationControl::_on_mouse_exited))) {
+ connect("mouse_exited", callable_mp(this, &ViewportRotationControl::_on_mouse_exited));
+ }
+ } break;
- if (p_what == NOTIFICATION_DRAW && viewport != nullptr) {
- _draw();
+ case NOTIFICATION_DRAW: {
+ if (viewport != nullptr) {
+ _draw();
+ }
+ } break;
}
}
@@ -384,6 +390,27 @@ int Node3DEditorViewport::get_selected_count() const {
return count;
}
+void Node3DEditorViewport::cancel_transform() {
+ List<Node *> &selection = editor_selection->get_selected_node_list();
+
+ for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
+ Node3D *sp = Object::cast_to<Node3D>(E->get());
+ if (!sp) {
+ continue;
+ }
+
+ Node3DEditorSelectedItem *se = editor_selection->get_node_editor_data<Node3DEditorSelectedItem>(sp);
+ if (!se) {
+ continue;
+ }
+
+ sp->set_global_transform(se->original);
+ }
+
+ finish_transform();
+ set_message(TTR("Transform Aborted."), 3);
+}
+
float Node3DEditorViewport::get_znear() const {
return CLAMP(spatial_editor->get_znear(), MIN_Z, MAX_Z);
}
@@ -451,7 +478,7 @@ void Node3DEditorViewport::_select_clicked(bool p_allow_locked) {
if (!p_allow_locked) {
// Replace the node by the group if grouped
- while (node && node != editor->get_edited_scene()->get_parent()) {
+ while (node && node != EditorNode::get_singleton()->get_edited_scene()->get_parent()) {
Node3D *selected_tmp = Object::cast_to<Node3D>(node);
if (selected_tmp && node->has_meta("_edit_group_")) {
selected = selected_tmp;
@@ -471,12 +498,12 @@ void Node3DEditorViewport::_select_clicked(bool p_allow_locked) {
if (!editor_selection->is_selected(selected)) {
editor_selection->clear();
editor_selection->add_node(selected);
- editor->edit_node(selected);
+ EditorNode::get_singleton()->edit_node(selected);
}
}
if (editor_selection->get_selected_node_list().size() == 1) {
- editor->edit_node(editor_selection->get_selected_node_list()[0]);
+ EditorNode::get_singleton()->edit_node(editor_selection->get_selected_node_list()[0]);
}
}
}
@@ -762,7 +789,7 @@ void Node3DEditorViewport::_select_region() {
// Replace the node by the group if grouped
if (item->is_class("Node3D")) {
Node3D *sel = Object::cast_to<Node3D>(item);
- while (item && item != editor->get_edited_scene()->get_parent()) {
+ while (item && item != EditorNode::get_singleton()->get_edited_scene()->get_parent()) {
Node3D *selected_tmp = Object::cast_to<Node3D>(item);
if (selected_tmp && item->has_meta("_edit_group_")) {
sel = selected_tmp;
@@ -796,7 +823,7 @@ void Node3DEditorViewport::_select_region() {
}
if (editor_selection->get_selected_node_list().size() == 1) {
- editor->edit_node(editor_selection->get_selected_node_list()[0]);
+ EditorNode::get_singleton()->edit_node(editor_selection->get_selected_node_list()[0]);
}
}
@@ -865,6 +892,7 @@ void Node3DEditorViewport::_update_name() {
}
void Node3DEditorViewport::_compute_edit(const Point2 &p_point) {
+ _edit.original_local = spatial_editor->are_local_coords_enabled();
_edit.click_ray = _get_ray(p_point);
_edit.click_ray_pos = _get_ray_pos(p_point);
_edit.plane = TRANSFORM_VIEW;
@@ -1018,24 +1046,40 @@ bool Node3DEditorViewport::_transform_gizmo_select(const Vector2 &p_screenpos, b
if (spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_SELECT || spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_ROTATE) {
int col_axis = -1;
- float col_d = 1e20;
- for (int i = 0; i < 3; i++) {
- Plane plane(gt.basis.get_axis(i).normalized(), gt.origin);
- Vector3 r;
- if (!plane.intersects_ray(ray_pos, ray, &r)) {
- continue;
+ Vector3 hit_position;
+ Vector3 hit_normal;
+ real_t ray_length = gt.origin.distance_to(ray_pos) + (GIZMO_CIRCLE_SIZE * gizmo_scale) * 4.0f;
+ if (Geometry3D::segment_intersects_sphere(ray_pos, ray_pos + ray * ray_length, gt.origin, gizmo_scale * (GIZMO_CIRCLE_SIZE), &hit_position, &hit_normal)) {
+ if (hit_normal.dot(_get_camera_normal()) < 0.05) {
+ hit_position = gt.xform_inv(hit_position).abs();
+ int min_axis = hit_position.min_axis_index();
+ if (hit_position[min_axis] < gizmo_scale * GIZMO_RING_HALF_WIDTH) {
+ col_axis = min_axis;
+ }
}
+ }
+
+ if (col_axis == -1) {
+ float col_d = 1e20;
+
+ for (int i = 0; i < 3; i++) {
+ Plane plane(gt.basis.get_axis(i).normalized(), gt.origin);
+ Vector3 r;
+ if (!plane.intersects_ray(ray_pos, ray, &r)) {
+ continue;
+ }
- const real_t dist = r.distance_to(gt.origin);
- const Vector3 r_dir = (r - gt.origin).normalized();
+ const real_t dist = r.distance_to(gt.origin);
+ const Vector3 r_dir = (r - gt.origin).normalized();
- if (_get_camera_normal().dot(r_dir) <= 0.005) {
- if (dist > gizmo_scale * (GIZMO_CIRCLE_SIZE - GIZMO_RING_HALF_WIDTH) && dist < gizmo_scale * (GIZMO_CIRCLE_SIZE + GIZMO_RING_HALF_WIDTH)) {
- const real_t d = ray_pos.distance_to(r);
- if (d < col_d) {
- col_d = d;
- col_axis = i;
+ if (_get_camera_normal().dot(r_dir) <= 0.005) {
+ if (dist > gizmo_scale * (GIZMO_CIRCLE_SIZE - GIZMO_RING_HALF_WIDTH) && dist < gizmo_scale * (GIZMO_CIRCLE_SIZE + GIZMO_RING_HALF_WIDTH)) {
+ const real_t d = ray_pos.distance_to(r);
+ if (d < col_d) {
+ col_d = d;
+ col_axis = i;
+ }
}
}
}
@@ -1227,7 +1271,7 @@ bool Node3DEditorViewport ::_is_node_locked(const Node *p_node) {
void Node3DEditorViewport::_list_select(Ref<InputEventMouseButton> b) {
_find_items_at_pos(b->get_position(), selection_results, spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_SELECT);
- Node *scene = editor->get_edited_scene();
+ Node *scene = EditorNode::get_singleton()->get_edited_scene();
for (int i = 0; i < selection_results.size(); i++) {
Node3D *item = selection_results[i].item;
@@ -1262,7 +1306,7 @@ void Node3DEditorViewport::_list_select(Ref<InputEventMouseButton> b) {
if (_is_node_locked(spat)) {
locked = 1;
} else {
- Node *ed_scene = editor->get_edited_scene();
+ Node *ed_scene = EditorNode::get_singleton()->get_edited_scene();
Node *node = spat;
while (node && node != ed_scene->get_parent()) {
@@ -1299,7 +1343,7 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
EditorPlugin::AfterGUIInput after = EditorPlugin::AFTER_GUI_INPUT_PASS;
{
- EditorNode *en = editor;
+ EditorNode *en = EditorNode::get_singleton();
EditorPluginList *force_input_forwarding_list = en->get_editor_plugins_force_input_forwarding();
if (!force_input_forwarding_list->is_empty()) {
EditorPlugin::AfterGUIInput discard = force_input_forwarding_list->forward_spatial_gui_input(camera, p_event, true);
@@ -1312,7 +1356,7 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
}
}
{
- EditorNode *en = editor;
+ EditorNode *en = EditorNode::get_singleton();
EditorPluginList *over_plugin_list = en->get_editor_plugins_over();
if (!over_plugin_list->is_empty()) {
EditorPlugin::AfterGUIInput discard = over_plugin_list->forward_spatial_gui_input(camera, p_event, false);
@@ -1375,39 +1419,7 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
}
if (_edit.mode != TRANSFORM_NONE && b->is_pressed()) {
- //cancel motion
- _edit.mode = TRANSFORM_NONE;
-
- List<Node *> &selection = editor_selection->get_selected_node_list();
-
- for (Node *E : selection) {
- Node3D *sp = Object::cast_to<Node3D>(E);
- if (!sp) {
- continue;
- }
-
- Node3DEditorSelectedItem *se = editor_selection->get_node_editor_data<Node3DEditorSelectedItem>(sp);
- if (!se) {
- continue;
- }
-
- if (se->gizmo.is_valid()) {
- Vector<int> ids;
- Vector<Transform3D> restore;
-
- for (const KeyValue<int, Transform3D> &GE : se->subgizmos) {
- ids.push_back(GE.key);
- restore.push_back(GE.value);
- }
-
- se->gizmo->commit_subgizmos(ids, restore, true);
- spatial_editor->update_transform_gizmo();
- } else {
- sp->set_global_transform(se->original);
- }
- }
- surface->update();
- set_message(TTR("Transform Aborted."), 3);
+ cancel_transform();
}
if (b->is_pressed()) {
@@ -1461,6 +1473,12 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
} break;
case MouseButton::LEFT: {
if (b->is_pressed()) {
+ clicked_wants_append = b->is_shift_pressed();
+
+ if (_edit.mode != TRANSFORM_NONE && _edit.instant) {
+ commit_transform();
+ break; // just commit the edit, stop processing the event so we don't deselect the object
+ }
NavigationScheme nav_scheme = (NavigationScheme)EditorSettings::get_singleton()->get("editors/3d/navigation/navigation_scheme").operator int();
if ((nav_scheme == NAVIGATION_MAYA || nav_scheme == NAVIGATION_MODO) && b->is_alt_pressed()) {
break;
@@ -1567,42 +1585,24 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
clicked = ObjectID();
if ((spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_SELECT && b->is_command_pressed()) || spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_ROTATE) {
- /* HANDLE ROTATION */
- if (get_selected_count() == 0) {
- break; //bye
- }
- //handle rotate
- _edit.mode = TRANSFORM_ROTATE;
- _compute_edit(b->get_position());
+ begin_transform(TRANSFORM_ROTATE, false);
break;
}
if (spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_MOVE) {
- if (get_selected_count() == 0) {
- break; //bye
- }
- //handle translate
- _edit.mode = TRANSFORM_TRANSLATE;
- _compute_edit(b->get_position());
+ begin_transform(TRANSFORM_TRANSLATE, false);
break;
}
if (spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_SCALE) {
- if (get_selected_count() == 0) {
- break; //bye
- }
- //handle scale
- _edit.mode = TRANSFORM_SCALE;
- _compute_edit(b->get_position());
+ begin_transform(TRANSFORM_SCALE, false);
break;
}
if (after != EditorPlugin::AFTER_GUI_INPUT_DESELECT) {
- clicked = _select_ray(b->get_position());
-
//clicking is always deferred to either move or release
-
- clicked_wants_append = b->is_shift_pressed();
+ clicked = _select_ray(b->get_position());
+ selection_in_progress = true;
if (clicked.is_null()) {
//default to regionselect
@@ -1621,6 +1621,8 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
}
if (after != EditorPlugin::AFTER_GUI_INPUT_DESELECT) {
+ selection_in_progress = false;
+
if (clicked.is_valid()) {
_select_clicked(false);
}
@@ -1648,32 +1650,7 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
se->gizmo->commit_subgizmos(ids, restore, false);
spatial_editor->update_transform_gizmo();
} else {
- static const char *_transform_name[4] = {
- TTRC("None"),
- TTRC("Rotate"),
- // TRANSLATORS: This refers to the movement that changes the position of an object.
- TTRC("Translate"),
- TTRC("Scale"),
- };
- undo_redo->create_action(TTRGET(_transform_name[_edit.mode]));
-
- List<Node *> &selection = editor_selection->get_selected_node_list();
-
- for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
- Node3D *sp = Object::cast_to<Node3D>(E->get());
- if (!sp) {
- continue;
- }
-
- Node3DEditorSelectedItem *sel_item = editor_selection->get_node_editor_data<Node3DEditorSelectedItem>(sp);
- if (!sel_item) {
- continue;
- }
-
- undo_redo->add_do_method(sp, "set_global_transform", sp->get_global_gizmo_transform());
- undo_redo->add_undo_method(sp, "set_global_transform", sel_item->original);
- }
- undo_redo->commit_action();
+ commit_transform();
}
_edit.mode = TRANSFORM_NONE;
set_message("");
@@ -1739,7 +1716,7 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
String n = _edit.gizmo->get_handle_name(_edit.gizmo_handle, _edit.gizmo_handle_secondary);
set_message(n + ": " + String(v));
- } else if ((m->get_button_mask() & MouseButton::MASK_LEFT) != MouseButton::NONE) {
+ } else if ((m->get_button_mask() & MouseButton::MASK_LEFT) != MouseButton::NONE || _edit.instant) {
if (nav_scheme == NAVIGATION_MAYA && m->is_alt_pressed()) {
nav_mode = NAVIGATION_ORBIT;
} else if (nav_scheme == NAVIGATION_MODO && m->is_alt_pressed() && m->is_shift_pressed()) {
@@ -1750,11 +1727,14 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
nav_mode = NAVIGATION_ORBIT;
} else {
const bool movement_threshold_passed = _edit.original_mouse_pos.distance_to(_edit.mouse_pos) > 8 * EDSCALE;
- if (clicked.is_valid() && movement_threshold_passed) {
- _compute_edit(_edit.original_mouse_pos);
- clicked = ObjectID();
- _edit.mode = TRANSFORM_TRANSLATE;
+ // enable region-select if nothing has been selected yet or multi-select (shift key) is active
+ if (selection_in_progress && movement_threshold_passed) {
+ if (get_selected_count() == 0 || clicked_wants_append) {
+ cursor.region_select = true;
+ cursor.region_begin = _edit.original_mouse_pos;
+ clicked = ObjectID();
+ }
}
if (cursor.region_select) {
@@ -1763,328 +1743,17 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
return;
}
+ if (clicked.is_valid() && movement_threshold_passed) {
+ _compute_edit(_edit.original_mouse_pos);
+ clicked = ObjectID();
+ _edit.mode = TRANSFORM_TRANSLATE;
+ }
+
if (_edit.mode == TRANSFORM_NONE) {
return;
}
- Vector3 ray_pos = _get_ray_pos(m->get_position());
- Vector3 ray = _get_ray(m->get_position());
- double snap = EDITOR_GET("interface/inspector/default_float_step");
- int snap_step_decimals = Math::range_step_decimals(snap);
-
- switch (_edit.mode) {
- case TRANSFORM_SCALE: {
- Vector3 motion_mask;
- Plane plane;
- bool plane_mv = false;
-
- switch (_edit.plane) {
- case TRANSFORM_VIEW:
- motion_mask = Vector3(0, 0, 0);
- plane = Plane(_get_camera_normal(), _edit.center);
- break;
- case TRANSFORM_X_AXIS:
- motion_mask = spatial_editor->get_gizmo_transform().basis.get_axis(0).normalized();
- plane = Plane(motion_mask.cross(motion_mask.cross(_get_camera_normal())).normalized(), _edit.center);
- break;
- case TRANSFORM_Y_AXIS:
- motion_mask = spatial_editor->get_gizmo_transform().basis.get_axis(1).normalized();
- plane = Plane(motion_mask.cross(motion_mask.cross(_get_camera_normal())).normalized(), _edit.center);
- break;
- case TRANSFORM_Z_AXIS:
- motion_mask = spatial_editor->get_gizmo_transform().basis.get_axis(2).normalized();
- plane = Plane(motion_mask.cross(motion_mask.cross(_get_camera_normal())).normalized(), _edit.center);
- break;
- case TRANSFORM_YZ:
- motion_mask = spatial_editor->get_gizmo_transform().basis.get_axis(2).normalized() + spatial_editor->get_gizmo_transform().basis.get_axis(1).normalized();
- plane = Plane(spatial_editor->get_gizmo_transform().basis.get_axis(0).normalized(), _edit.center);
- plane_mv = true;
- break;
- case TRANSFORM_XZ:
- motion_mask = spatial_editor->get_gizmo_transform().basis.get_axis(2).normalized() + spatial_editor->get_gizmo_transform().basis.get_axis(0).normalized();
- plane = Plane(spatial_editor->get_gizmo_transform().basis.get_axis(1).normalized(), _edit.center);
- plane_mv = true;
- break;
- case TRANSFORM_XY:
- motion_mask = spatial_editor->get_gizmo_transform().basis.get_axis(0).normalized() + spatial_editor->get_gizmo_transform().basis.get_axis(1).normalized();
- plane = Plane(spatial_editor->get_gizmo_transform().basis.get_axis(2).normalized(), _edit.center);
- plane_mv = true;
- break;
- }
-
- Vector3 intersection;
- if (!plane.intersects_ray(ray_pos, ray, &intersection)) {
- break;
- }
-
- Vector3 click;
- if (!plane.intersects_ray(_edit.click_ray_pos, _edit.click_ray, &click)) {
- break;
- }
-
- Vector3 motion = intersection - click;
- if (_edit.plane != TRANSFORM_VIEW) {
- if (!plane_mv) {
- motion = motion_mask.dot(motion) * motion_mask;
-
- } else {
- // Alternative planar scaling mode
- if (_get_key_modifier(m) != Key::SHIFT) {
- motion = motion_mask.dot(motion) * motion_mask;
- }
- }
-
- } else {
- const real_t center_click_dist = click.distance_to(_edit.center);
- const real_t center_inters_dist = intersection.distance_to(_edit.center);
- if (center_click_dist == 0) {
- break;
- }
-
- const real_t scale = center_inters_dist - center_click_dist;
- motion = Vector3(scale, scale, scale);
- }
-
- motion /= click.distance_to(_edit.center);
-
- // Disable local transformation for TRANSFORM_VIEW
- bool local_coords = (spatial_editor->are_local_coords_enabled() && _edit.plane != TRANSFORM_VIEW);
-
- if (_edit.snap || spatial_editor->is_snap_enabled()) {
- snap = spatial_editor->get_scale_snap() / 100;
- }
- Vector3 motion_snapped = motion;
- motion_snapped.snap(Vector3(snap, snap, snap));
- // This might not be necessary anymore after issue #288 is solved (in 4.0?).
- set_message(TTR("Scaling: ") + "(" + String::num(motion_snapped.x, snap_step_decimals) + ", " +
- String::num(motion_snapped.y, snap_step_decimals) + ", " + String::num(motion_snapped.z, snap_step_decimals) + ")");
- motion = _edit.original.basis.inverse().xform(motion);
-
- List<Node *> &selection = editor_selection->get_selected_node_list();
- for (Node *E : selection) {
- Node3D *sp = Object::cast_to<Node3D>(E);
- if (!sp) {
- continue;
- }
-
- Node3DEditorSelectedItem *se = editor_selection->get_node_editor_data<Node3DEditorSelectedItem>(sp);
- if (!se) {
- continue;
- }
-
- if (sp->has_meta("_edit_lock_")) {
- continue;
- }
-
- if (se->gizmo.is_valid()) {
- for (KeyValue<int, Transform3D> &GE : se->subgizmos) {
- Transform3D xform = GE.value;
- Transform3D new_xform = _compute_transform(TRANSFORM_SCALE, se->original * xform, xform, motion, snap, local_coords, true); // Force orthogonal with subgizmo.
- if (!local_coords) {
- new_xform = se->original.affine_inverse() * new_xform;
- }
- se->gizmo->set_subgizmo_transform(GE.key, new_xform);
- }
- } else {
- Transform3D new_xform = _compute_transform(TRANSFORM_SCALE, se->original, se->original_local, motion, snap, local_coords, sp->get_rotation_edit_mode() != Node3D::ROTATION_EDIT_MODE_BASIS);
- _transform_gizmo_apply(se->sp, new_xform, local_coords);
- }
- }
-
- spatial_editor->update_transform_gizmo();
- surface->update();
-
- } break;
-
- case TRANSFORM_TRANSLATE: {
- Vector3 motion_mask;
- Plane plane;
- bool plane_mv = false;
-
- switch (_edit.plane) {
- case TRANSFORM_VIEW:
- plane = Plane(_get_camera_normal(), _edit.center);
- break;
- case TRANSFORM_X_AXIS:
- motion_mask = spatial_editor->get_gizmo_transform().basis.get_axis(0).normalized();
- plane = Plane(motion_mask.cross(motion_mask.cross(_get_camera_normal())).normalized(), _edit.center);
- break;
- case TRANSFORM_Y_AXIS:
- motion_mask = spatial_editor->get_gizmo_transform().basis.get_axis(1).normalized();
- plane = Plane(motion_mask.cross(motion_mask.cross(_get_camera_normal())).normalized(), _edit.center);
- break;
- case TRANSFORM_Z_AXIS:
- motion_mask = spatial_editor->get_gizmo_transform().basis.get_axis(2).normalized();
- plane = Plane(motion_mask.cross(motion_mask.cross(_get_camera_normal())).normalized(), _edit.center);
- break;
- case TRANSFORM_YZ:
- plane = Plane(spatial_editor->get_gizmo_transform().basis.get_axis(0).normalized(), _edit.center);
- plane_mv = true;
- break;
- case TRANSFORM_XZ:
- plane = Plane(spatial_editor->get_gizmo_transform().basis.get_axis(1).normalized(), _edit.center);
- plane_mv = true;
- break;
- case TRANSFORM_XY:
- plane = Plane(spatial_editor->get_gizmo_transform().basis.get_axis(2).normalized(), _edit.center);
- plane_mv = true;
- break;
- }
-
- Vector3 intersection;
- if (!plane.intersects_ray(ray_pos, ray, &intersection)) {
- break;
- }
-
- Vector3 click;
- if (!plane.intersects_ray(_edit.click_ray_pos, _edit.click_ray, &click)) {
- break;
- }
-
- Vector3 motion = intersection - click;
- if (_edit.plane != TRANSFORM_VIEW) {
- if (!plane_mv) {
- motion = motion_mask.dot(motion) * motion_mask;
- }
- }
-
- // Disable local transformation for TRANSFORM_VIEW
- bool local_coords = (spatial_editor->are_local_coords_enabled() && _edit.plane != TRANSFORM_VIEW);
-
- if (_edit.snap || spatial_editor->is_snap_enabled()) {
- snap = spatial_editor->get_translate_snap();
- }
- Vector3 motion_snapped = motion;
- motion_snapped.snap(Vector3(snap, snap, snap));
- set_message(TTR("Translating: ") + "(" + String::num(motion_snapped.x, snap_step_decimals) + ", " +
- String::num(motion_snapped.y, snap_step_decimals) + ", " + String::num(motion_snapped.z, snap_step_decimals) + ")");
- motion = spatial_editor->get_gizmo_transform().basis.inverse().xform(motion);
-
- List<Node *> &selection = editor_selection->get_selected_node_list();
- for (Node *E : selection) {
- Node3D *sp = Object::cast_to<Node3D>(E);
- if (!sp) {
- continue;
- }
-
- Node3DEditorSelectedItem *se = editor_selection->get_node_editor_data<Node3DEditorSelectedItem>(sp);
- if (!se) {
- continue;
- }
-
- if (sp->has_meta("_edit_lock_")) {
- continue;
- }
-
- if (se->gizmo.is_valid()) {
- for (KeyValue<int, Transform3D> &GE : se->subgizmos) {
- Transform3D xform = GE.value;
- Transform3D new_xform = _compute_transform(TRANSFORM_TRANSLATE, se->original * xform, xform, motion, snap, local_coords, true); // Force orthogonal with subgizmo.
- new_xform = se->original.affine_inverse() * new_xform;
- se->gizmo->set_subgizmo_transform(GE.key, new_xform);
- }
- } else {
- Transform3D new_xform = _compute_transform(TRANSFORM_TRANSLATE, se->original, se->original_local, motion, snap, local_coords, sp->get_rotation_edit_mode() != Node3D::ROTATION_EDIT_MODE_BASIS);
- _transform_gizmo_apply(se->sp, new_xform, false);
- }
- }
-
- spatial_editor->update_transform_gizmo();
- surface->update();
-
- } break;
-
- case TRANSFORM_ROTATE: {
- Plane plane;
- Vector3 axis;
-
- switch (_edit.plane) {
- case TRANSFORM_VIEW:
- plane = Plane(_get_camera_normal(), _edit.center);
- break;
- case TRANSFORM_X_AXIS:
- plane = Plane(spatial_editor->get_gizmo_transform().basis.get_axis(0).normalized(), _edit.center);
- axis = Vector3(1, 0, 0);
- break;
- case TRANSFORM_Y_AXIS:
- plane = Plane(spatial_editor->get_gizmo_transform().basis.get_axis(1).normalized(), _edit.center);
- axis = Vector3(0, 1, 0);
- break;
- case TRANSFORM_Z_AXIS:
- plane = Plane(spatial_editor->get_gizmo_transform().basis.get_axis(2).normalized(), _edit.center);
- axis = Vector3(0, 0, 1);
- break;
- case TRANSFORM_YZ:
- case TRANSFORM_XZ:
- case TRANSFORM_XY:
- break;
- }
-
- Vector3 intersection;
- if (!plane.intersects_ray(ray_pos, ray, &intersection)) {
- break;
- }
-
- Vector3 click;
- if (!plane.intersects_ray(_edit.click_ray_pos, _edit.click_ray, &click)) {
- break;
- }
-
- Vector3 y_axis = (click - _edit.center).normalized();
- Vector3 x_axis = plane.normal.cross(y_axis).normalized();
-
- double angle = Math::atan2(x_axis.dot(intersection - _edit.center), y_axis.dot(intersection - _edit.center));
-
- if (_edit.snap || spatial_editor->is_snap_enabled()) {
- snap = spatial_editor->get_rotate_snap();
- }
- angle = Math::rad2deg(angle) + snap * 0.5; //else it won't reach +180
- angle -= Math::fmod(angle, snap);
- set_message(vformat(TTR("Rotating %s degrees."), String::num(angle, snap_step_decimals)));
- angle = Math::deg2rad(angle);
-
- bool local_coords = (spatial_editor->are_local_coords_enabled() && _edit.plane != TRANSFORM_VIEW); // Disable local transformation for TRANSFORM_VIEW
-
- List<Node *> &selection = editor_selection->get_selected_node_list();
- for (Node *E : selection) {
- Node3D *sp = Object::cast_to<Node3D>(E);
- if (!sp) {
- continue;
- }
-
- Node3DEditorSelectedItem *se = editor_selection->get_node_editor_data<Node3DEditorSelectedItem>(sp);
- if (!se) {
- continue;
- }
-
- if (sp->has_meta("_edit_lock_")) {
- continue;
- }
-
- Vector3 compute_axis = local_coords ? axis : plane.normal;
- if (se->gizmo.is_valid()) {
- for (KeyValue<int, Transform3D> &GE : se->subgizmos) {
- Transform3D xform = GE.value;
-
- Transform3D new_xform = _compute_transform(TRANSFORM_ROTATE, se->original * xform, xform, compute_axis, angle, local_coords, true); // Force orthogonal with subgizmo.
- if (!local_coords) {
- new_xform = se->original.affine_inverse() * new_xform;
- }
- se->gizmo->set_subgizmo_transform(GE.key, new_xform);
- }
- } else {
- Transform3D new_xform = _compute_transform(TRANSFORM_ROTATE, se->original, se->original_local, compute_axis, angle, local_coords, sp->get_rotation_edit_mode() != Node3D::ROTATION_EDIT_MODE_BASIS);
- _transform_gizmo_apply(se->sp, new_xform, local_coords);
- }
- }
-
- spatial_editor->update_transform_gizmo();
- surface->update();
-
- } break;
- default: {
- }
- }
+ update_transform(m->get_position(), _get_key_modifier(m) == Key::SHIFT);
}
} else if ((m->get_button_mask() & MouseButton::MASK_RIGHT) != MouseButton::NONE || freelook_active) {
if (nav_scheme == NAVIGATION_MAYA && m->is_alt_pressed()) {
@@ -2225,6 +1894,56 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
}
}
+ if (_edit.mode == TRANSFORM_NONE) {
+ if (k->get_keycode() == Key::ESCAPE && !cursor.region_select) {
+ _clear_selected();
+ return;
+ }
+ } else {
+ // We're actively transforming, handle keys specially
+ TransformPlane new_plane = TRANSFORM_VIEW;
+ String new_message;
+ if (ED_IS_SHORTCUT("spatial_editor/lock_transform_x", p_event)) {
+ new_plane = TRANSFORM_X_AXIS;
+ new_message = TTR("X-Axis Transform.");
+ } else if (ED_IS_SHORTCUT("spatial_editor/lock_transform_y", p_event)) {
+ new_plane = TRANSFORM_Y_AXIS;
+ new_message = TTR("Y-Axis Transform.");
+ } else if (ED_IS_SHORTCUT("spatial_editor/lock_transform_z", p_event)) {
+ new_plane = TRANSFORM_Z_AXIS;
+ new_message = TTR("Z-Axis Transform.");
+ } else if (_edit.mode != TRANSFORM_ROTATE) { // rotating on a plane doesn't make sense
+ if (ED_IS_SHORTCUT("spatial_editor/lock_transform_yz", p_event)) {
+ new_plane = TRANSFORM_YZ;
+ new_message = TTR("YZ-Plane Transform.");
+ } else if (ED_IS_SHORTCUT("spatial_editor/lock_transform_xz", p_event)) {
+ new_plane = TRANSFORM_XZ;
+ new_message = TTR("XZ-Plane Transform.");
+ } else if (ED_IS_SHORTCUT("spatial_editor/lock_transform_xy", p_event)) {
+ new_plane = TRANSFORM_XY;
+ new_message = TTR("XY-Plane Transform.");
+ }
+ }
+
+ if (new_plane != TRANSFORM_VIEW) {
+ if (new_plane != _edit.plane) {
+ // lock me once and get a global constraint
+ _edit.plane = new_plane;
+ spatial_editor->set_local_coords_enabled(false);
+ } else if (!spatial_editor->are_local_coords_enabled()) {
+ // lock me twice and get a local constraint
+ spatial_editor->set_local_coords_enabled(true);
+ } else {
+ // lock me thrice and we're back where we started
+ _edit.plane = TRANSFORM_VIEW;
+ spatial_editor->set_local_coords_enabled(false);
+ }
+ update_transform(_edit.mouse_pos, Input::get_singleton()->is_key_pressed(Key::SHIFT));
+ set_message(new_message, 2);
+ accept_event();
+ return;
+ }
+ }
if (ED_IS_SHORTCUT("spatial_editor/snap", p_event)) {
if (_edit.mode != TRANSFORM_NONE) {
_edit.snap = !_edit.snap;
@@ -2315,6 +2034,20 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
set_message(TTR("Animation Key Inserted."));
}
+ if (ED_IS_SHORTCUT("spatial_editor/cancel_transform", p_event) && _edit.mode != TRANSFORM_NONE) {
+ cancel_transform();
+ }
+ if (!is_freelook_active()) {
+ if (ED_IS_SHORTCUT("spatial_editor/instant_translate", p_event)) {
+ begin_transform(TRANSFORM_TRANSLATE, true);
+ }
+ if (ED_IS_SHORTCUT("spatial_editor/instant_rotate", p_event)) {
+ begin_transform(TRANSFORM_ROTATE, true);
+ }
+ if (ED_IS_SHORTCUT("spatial_editor/instant_scale", p_event)) {
+ begin_transform(TRANSFORM_SCALE, true);
+ }
+ }
// Freelook doesn't work in orthogonal mode.
if (!orthogonal && ED_IS_SHORTCUT("spatial_editor/freelook_toggle", p_event)) {
@@ -2553,7 +2286,7 @@ void Node3DEditorViewport::scale_freelook_speed(real_t scale) {
Point2i Node3DEditorViewport::_get_warped_mouse_motion(const Ref<InputEventMouseMotion> &p_ev_mouse_motion) const {
Point2i relative;
- if (bool(EDITOR_DEF("editors/3d/navigation/warped_mouse_panning", false))) {
+ if (bool(EDITOR_GET("editors/3d/navigation/warped_mouse_panning"))) {
relative = Input::get_singleton()->warp_mouse_motion(p_ev_mouse_motion, surface->get_global_rect());
} else {
relative = p_ev_mouse_motion->get_relative();
@@ -2561,26 +2294,6 @@ Point2i Node3DEditorViewport::_get_warped_mouse_motion(const Ref<InputEventMouse
return relative;
}
-static bool is_shortcut_pressed(const String &p_path) {
- Ref<Shortcut> shortcut = ED_GET_SHORTCUT(p_path);
- if (shortcut.is_null()) {
- return false;
- }
-
- const Array shortcuts = shortcut->get_events();
- Ref<InputEventKey> k;
- if (shortcuts.size() > 0) {
- k = shortcuts.front();
- }
-
- if (k.is_null()) {
- return false;
- }
- const Input &input = *Input::get_singleton();
- Key keycode = k->get_keycode();
- return input.is_key_pressed(keycode);
-}
-
void Node3DEditorViewport::_update_freelook(real_t delta) {
if (!is_freelook_active()) {
return;
@@ -2610,31 +2323,34 @@ void Node3DEditorViewport::_update_freelook(real_t delta) {
Vector3 direction;
- if (is_shortcut_pressed("spatial_editor/freelook_left")) {
+ // Use actions from the inputmap, as this is the only way to reliably detect input in this method.
+ // See #54469 for more discussion and explanation.
+ Input *inp = Input::get_singleton();
+ if (inp->is_action_pressed("spatial_editor/freelook_left")) {
direction -= right;
}
- if (is_shortcut_pressed("spatial_editor/freelook_right")) {
+ if (inp->is_action_pressed("spatial_editor/freelook_right")) {
direction += right;
}
- if (is_shortcut_pressed("spatial_editor/freelook_forward")) {
+ if (inp->is_action_pressed("spatial_editor/freelook_forward")) {
direction += forward;
}
- if (is_shortcut_pressed("spatial_editor/freelook_backwards")) {
+ if (inp->is_action_pressed("spatial_editor/freelook_backwards")) {
direction -= forward;
}
- if (is_shortcut_pressed("spatial_editor/freelook_up")) {
+ if (inp->is_action_pressed("spatial_editor/freelook_up")) {
direction += up;
}
- if (is_shortcut_pressed("spatial_editor/freelook_down")) {
+ if (inp->is_action_pressed("spatial_editor/freelook_down")) {
direction -= up;
}
real_t speed = freelook_speed;
- if (is_shortcut_pressed("spatial_editor/freelook_speed_modifier")) {
+ if (inp->is_action_pressed("spatial_editor/freelook_speed_modifier")) {
speed *= 3.0;
}
- if (is_shortcut_pressed("spatial_editor/freelook_slow_modifier")) {
+ if (inp->is_action_pressed("spatial_editor/freelook_slow_modifier")) {
speed *= 0.333333;
}
@@ -2696,278 +2412,281 @@ void Node3DEditorViewport::_project_settings_changed() {
}
void Node3DEditorViewport::_notification(int p_what) {
- if (p_what == NOTIFICATION_READY) {
- EditorNode::get_singleton()->connect("project_settings_changed", callable_mp(this, &Node3DEditorViewport::_project_settings_changed));
- }
+ switch (p_what) {
+ case NOTIFICATION_READY: {
+ EditorNode::get_singleton()->connect("project_settings_changed", callable_mp(this, &Node3DEditorViewport::_project_settings_changed));
+ } break;
- if (p_what == NOTIFICATION_VISIBILITY_CHANGED) {
- bool visible = is_visible_in_tree();
+ case NOTIFICATION_VISIBILITY_CHANGED: {
+ bool visible = is_visible_in_tree();
- set_process(visible);
+ set_process(visible);
- if (visible) {
- orthogonal = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_ORTHOGONAL));
- _update_name();
- _update_camera(0);
- } else {
- set_freelook_active(false);
- }
- call_deferred(SNAME("update_transform_gizmo_view"));
- rotation_control->set_visible(EditorSettings::get_singleton()->get("editors/3d/navigation/show_viewport_rotation_gizmo"));
- }
+ if (visible) {
+ orthogonal = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_ORTHOGONAL));
+ _update_name();
+ _update_camera(0);
+ } else {
+ set_freelook_active(false);
+ }
+ call_deferred(SNAME("update_transform_gizmo_view"));
+ rotation_control->set_visible(EditorSettings::get_singleton()->get("editors/3d/navigation/show_viewport_rotation_gizmo"));
+ } break;
- if (p_what == NOTIFICATION_RESIZED) {
- call_deferred(SNAME("update_transform_gizmo_view"));
- }
+ case NOTIFICATION_RESIZED: {
+ call_deferred(SNAME("update_transform_gizmo_view"));
+ } break;
- if (p_what == NOTIFICATION_PROCESS) {
- real_t delta = get_process_delta_time();
+ case NOTIFICATION_PROCESS: {
+ real_t delta = get_process_delta_time();
- if (zoom_indicator_delay > 0) {
- zoom_indicator_delay -= delta;
- if (zoom_indicator_delay <= 0) {
- surface->update();
- zoom_limit_label->hide();
+ if (zoom_indicator_delay > 0) {
+ zoom_indicator_delay -= delta;
+ if (zoom_indicator_delay <= 0) {
+ surface->update();
+ zoom_limit_label->hide();
+ }
}
- }
- _update_freelook(delta);
+ _update_freelook(delta);
- Node *scene_root = SceneTreeDock::get_singleton()->get_editor_data()->get_edited_scene_root();
- if (previewing_cinema && scene_root != nullptr) {
- Camera3D *cam = scene_root->get_viewport()->get_camera_3d();
- if (cam != nullptr && cam != previewing) {
- //then switch the viewport's camera to the scene's viewport camera
- if (previewing != nullptr) {
- previewing->disconnect("tree_exited", callable_mp(this, &Node3DEditorViewport::_preview_exited_scene));
+ Node *scene_root = SceneTreeDock::get_singleton()->get_editor_data()->get_edited_scene_root();
+ if (previewing_cinema && scene_root != nullptr) {
+ Camera3D *cam = scene_root->get_viewport()->get_camera_3d();
+ if (cam != nullptr && cam != previewing) {
+ //then switch the viewport's camera to the scene's viewport camera
+ if (previewing != nullptr) {
+ previewing->disconnect("tree_exited", callable_mp(this, &Node3DEditorViewport::_preview_exited_scene));
+ }
+ previewing = cam;
+ previewing->connect("tree_exited", callable_mp(this, &Node3DEditorViewport::_preview_exited_scene));
+ RS::get_singleton()->viewport_attach_camera(viewport->get_viewport_rid(), cam->get_camera());
+ surface->update();
}
- previewing = cam;
- previewing->connect("tree_exited", callable_mp(this, &Node3DEditorViewport::_preview_exited_scene));
- RS::get_singleton()->viewport_attach_camera(viewport->get_viewport_rid(), cam->get_camera());
- surface->update();
}
- }
- _update_camera(delta);
+ _update_camera(delta);
- Map<Node *, Object *> &selection = editor_selection->get_selection();
+ Map<Node *, Object *> &selection = editor_selection->get_selection();
- bool changed = false;
- bool exist = false;
+ bool changed = false;
+ bool exist = false;
- for (const KeyValue<Node *, Object *> &E : selection) {
- Node3D *sp = Object::cast_to<Node3D>(E.key);
- if (!sp) {
- continue;
- }
+ for (const KeyValue<Node *, Object *> &E : selection) {
+ Node3D *sp = Object::cast_to<Node3D>(E.key);
+ if (!sp) {
+ continue;
+ }
- Node3DEditorSelectedItem *se = editor_selection->get_node_editor_data<Node3DEditorSelectedItem>(sp);
- if (!se) {
- continue;
- }
+ Node3DEditorSelectedItem *se = editor_selection->get_node_editor_data<Node3DEditorSelectedItem>(sp);
+ if (!se) {
+ continue;
+ }
- Transform3D t = sp->get_global_gizmo_transform();
- VisualInstance3D *vi = Object::cast_to<VisualInstance3D>(sp);
- AABB new_aabb = vi ? vi->get_aabb() : _calculate_spatial_bounds(sp);
+ Transform3D t = sp->get_global_gizmo_transform();
+ VisualInstance3D *vi = Object::cast_to<VisualInstance3D>(sp);
+ AABB new_aabb = vi ? vi->get_aabb() : _calculate_spatial_bounds(sp);
- exist = true;
- if (se->last_xform == t && se->aabb == new_aabb && !se->last_xform_dirty) {
- continue;
- }
- changed = true;
- se->last_xform_dirty = false;
- se->last_xform = t;
+ exist = true;
+ if (se->last_xform == t && se->aabb == new_aabb && !se->last_xform_dirty) {
+ continue;
+ }
+ changed = true;
+ se->last_xform_dirty = false;
+ se->last_xform = t;
- se->aabb = new_aabb;
+ se->aabb = new_aabb;
- Transform3D t_offset = t;
+ Transform3D t_offset = t;
- // apply AABB scaling before item's global transform
- {
- const Vector3 offset(0.005, 0.005, 0.005);
- Basis aabb_s;
- aabb_s.scale(se->aabb.size + offset);
- t.translate(se->aabb.position - offset / 2);
- t.basis = t.basis * aabb_s;
- }
- {
- const Vector3 offset(0.01, 0.01, 0.01);
- Basis aabb_s;
- aabb_s.scale(se->aabb.size + offset);
- t_offset.translate(se->aabb.position - offset / 2);
- t_offset.basis = t_offset.basis * aabb_s;
+ // apply AABB scaling before item's global transform
+ {
+ const Vector3 offset(0.005, 0.005, 0.005);
+ Basis aabb_s;
+ aabb_s.scale(se->aabb.size + offset);
+ t.translate(se->aabb.position - offset / 2);
+ t.basis = t.basis * aabb_s;
+ }
+ {
+ const Vector3 offset(0.01, 0.01, 0.01);
+ Basis aabb_s;
+ aabb_s.scale(se->aabb.size + offset);
+ t_offset.translate(se->aabb.position - offset / 2);
+ t_offset.basis = t_offset.basis * aabb_s;
+ }
+
+ RenderingServer::get_singleton()->instance_set_transform(se->sbox_instance, t);
+ RenderingServer::get_singleton()->instance_set_transform(se->sbox_instance_offset, t_offset);
+ RenderingServer::get_singleton()->instance_set_transform(se->sbox_instance_xray, t);
+ RenderingServer::get_singleton()->instance_set_transform(se->sbox_instance_xray_offset, t_offset);
}
- RenderingServer::get_singleton()->instance_set_transform(se->sbox_instance, t);
- RenderingServer::get_singleton()->instance_set_transform(se->sbox_instance_offset, t_offset);
- RenderingServer::get_singleton()->instance_set_transform(se->sbox_instance_xray, t);
- RenderingServer::get_singleton()->instance_set_transform(se->sbox_instance_xray_offset, t_offset);
- }
+ if (changed || (spatial_editor->is_gizmo_visible() && !exist)) {
+ spatial_editor->update_transform_gizmo();
+ }
- if (changed || (spatial_editor->is_gizmo_visible() && !exist)) {
- spatial_editor->update_transform_gizmo();
- }
+ if (message_time > 0) {
+ if (message != last_message) {
+ surface->update();
+ last_message = message;
+ }
- if (message_time > 0) {
- if (message != last_message) {
- surface->update();
- last_message = message;
+ message_time -= get_physics_process_delta_time();
+ if (message_time < 0) {
+ surface->update();
+ }
}
- message_time -= get_physics_process_delta_time();
- if (message_time < 0) {
- surface->update();
+ bool show_info = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_INFORMATION));
+ if (show_info != info_label->is_visible()) {
+ info_label->set_visible(show_info);
}
- }
- bool show_info = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_INFORMATION));
- if (show_info != info_label->is_visible()) {
- info_label->set_visible(show_info);
- }
+ Camera3D *current_camera;
- Camera3D *current_camera;
-
- if (previewing) {
- current_camera = previewing;
- } else {
- current_camera = camera;
- }
-
- if (show_info) {
- const String viewport_size = vformat(String::utf8("%d × %d"), viewport->get_size().x, viewport->get_size().y);
- String text;
- text += vformat(TTR("X: %s\n"), rtos(current_camera->get_position().x).pad_decimals(1));
- text += vformat(TTR("Y: %s\n"), rtos(current_camera->get_position().y).pad_decimals(1));
- text += vformat(TTR("Z: %s\n"), rtos(current_camera->get_position().z).pad_decimals(1));
- text += "\n";
- text += vformat(
- TTR("Size: %s (%.1fMP)\n"),
- viewport_size,
- viewport->get_size().x * viewport->get_size().y * 0.000001);
-
- text += "\n";
- text += vformat(TTR("Objects: %d\n"), viewport->get_render_info(Viewport::RENDER_INFO_TYPE_VISIBLE, Viewport::RENDER_INFO_OBJECTS_IN_FRAME));
- text += vformat(TTR("Primitives: %d\n"), viewport->get_render_info(Viewport::RENDER_INFO_TYPE_VISIBLE, Viewport::RENDER_INFO_PRIMITIVES_IN_FRAME));
- text += vformat(TTR("Draw Calls: %d"), viewport->get_render_info(Viewport::RENDER_INFO_TYPE_VISIBLE, Viewport::RENDER_INFO_DRAW_CALLS_IN_FRAME));
-
- info_label->set_text(text);
- }
-
- // FPS Counter.
- bool show_fps = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_FRAME_TIME));
-
- if (show_fps != fps_label->is_visible()) {
- cpu_time_label->set_visible(show_fps);
- gpu_time_label->set_visible(show_fps);
- fps_label->set_visible(show_fps);
- RS::get_singleton()->viewport_set_measure_render_time(viewport->get_viewport_rid(), show_fps);
- for (int i = 0; i < FRAME_TIME_HISTORY; i++) {
- cpu_time_history[i] = 0;
- gpu_time_history[i] = 0;
- }
- cpu_time_history_index = 0;
- gpu_time_history_index = 0;
- }
- if (show_fps) {
- cpu_time_history[cpu_time_history_index] = RS::get_singleton()->viewport_get_measured_render_time_cpu(viewport->get_viewport_rid());
- cpu_time_history_index = (cpu_time_history_index + 1) % FRAME_TIME_HISTORY;
- double cpu_time = 0.0;
- for (int i = 0; i < FRAME_TIME_HISTORY; i++) {
- cpu_time += cpu_time_history[i];
- }
- cpu_time /= FRAME_TIME_HISTORY;
- // Prevent unrealistically low values.
- cpu_time = MAX(0.01, cpu_time);
-
- gpu_time_history[gpu_time_history_index] = RS::get_singleton()->viewport_get_measured_render_time_gpu(viewport->get_viewport_rid());
- gpu_time_history_index = (gpu_time_history_index + 1) % FRAME_TIME_HISTORY;
- double gpu_time = 0.0;
- for (int i = 0; i < FRAME_TIME_HISTORY; i++) {
- gpu_time += gpu_time_history[i];
- }
- gpu_time /= FRAME_TIME_HISTORY;
- // Prevent division by zero for the FPS counter (and unrealistically low values).
- // This limits the reported FPS to 100000.
- gpu_time = MAX(0.01, gpu_time);
-
- // Color labels depending on performance level ("good" = green, "OK" = yellow, "bad" = red).
- // Middle point is at 15 ms.
- cpu_time_label->set_text(vformat(TTR("CPU Time: %s ms"), rtos(cpu_time).pad_decimals(2)));
- cpu_time_label->add_theme_color_override(
- "font_color",
- frame_time_gradient->get_color_at_offset(
- Math::range_lerp(cpu_time, 0, 30, 0, 1)));
-
- gpu_time_label->set_text(vformat(TTR("GPU Time: %s ms"), rtos(gpu_time).pad_decimals(2)));
- // Middle point is at 15 ms.
- gpu_time_label->add_theme_color_override(
- "font_color",
- frame_time_gradient->get_color_at_offset(
- Math::range_lerp(gpu_time, 0, 30, 0, 1)));
-
- const double fps = 1000.0 / gpu_time;
- fps_label->set_text(vformat(TTR("FPS: %d"), fps));
- // Middle point is at 60 FPS.
- fps_label->add_theme_color_override(
- "font_color",
- frame_time_gradient->get_color_at_offset(
- Math::range_lerp(fps, 110, 10, 0, 1)));
- }
-
- bool show_cinema = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_CINEMATIC_PREVIEW));
- cinema_label->set_visible(show_cinema);
- if (show_cinema) {
- float cinema_half_width = cinema_label->get_size().width / 2.0f;
- cinema_label->set_anchor_and_offset(SIDE_LEFT, 0.5f, -cinema_half_width);
- }
-
- if (lock_rotation) {
- float locked_half_width = locked_label->get_size().width / 2.0f;
- locked_label->set_anchor_and_offset(SIDE_LEFT, 0.5f, -locked_half_width);
- }
- }
-
- if (p_what == NOTIFICATION_ENTER_TREE) {
- surface->connect("draw", callable_mp(this, &Node3DEditorViewport::_draw));
- surface->connect("gui_input", callable_mp(this, &Node3DEditorViewport::_sinput));
- surface->connect("mouse_entered", callable_mp(this, &Node3DEditorViewport::_surface_mouse_enter));
- surface->connect("mouse_exited", callable_mp(this, &Node3DEditorViewport::_surface_mouse_exit));
- surface->connect("focus_entered", callable_mp(this, &Node3DEditorViewport::_surface_focus_enter));
- surface->connect("focus_exited", callable_mp(this, &Node3DEditorViewport::_surface_focus_exit));
-
- _init_gizmo_instance(index);
- }
-
- if (p_what == NOTIFICATION_EXIT_TREE) {
- _finish_gizmo_instances();
- }
+ if (previewing) {
+ current_camera = previewing;
+ } else {
+ current_camera = camera;
+ }
+
+ if (show_info) {
+ const String viewport_size = vformat(String::utf8("%d × %d"), viewport->get_size().x, viewport->get_size().y);
+ String text;
+ text += vformat(TTR("X: %s\n"), rtos(current_camera->get_position().x).pad_decimals(1));
+ text += vformat(TTR("Y: %s\n"), rtos(current_camera->get_position().y).pad_decimals(1));
+ text += vformat(TTR("Z: %s\n"), rtos(current_camera->get_position().z).pad_decimals(1));
+ text += "\n";
+ text += vformat(
+ TTR("Size: %s (%.1fMP)\n"),
+ viewport_size,
+ viewport->get_size().x * viewport->get_size().y * 0.000001);
+
+ text += "\n";
+ text += vformat(TTR("Objects: %d\n"), viewport->get_render_info(Viewport::RENDER_INFO_TYPE_VISIBLE, Viewport::RENDER_INFO_OBJECTS_IN_FRAME));
+ text += vformat(TTR("Primitives: %d\n"), viewport->get_render_info(Viewport::RENDER_INFO_TYPE_VISIBLE, Viewport::RENDER_INFO_PRIMITIVES_IN_FRAME));
+ text += vformat(TTR("Draw Calls: %d"), viewport->get_render_info(Viewport::RENDER_INFO_TYPE_VISIBLE, Viewport::RENDER_INFO_DRAW_CALLS_IN_FRAME));
+
+ info_label->set_text(text);
+ }
+
+ // FPS Counter.
+ bool show_fps = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_FRAME_TIME));
+
+ if (show_fps != fps_label->is_visible()) {
+ cpu_time_label->set_visible(show_fps);
+ gpu_time_label->set_visible(show_fps);
+ fps_label->set_visible(show_fps);
+ RS::get_singleton()->viewport_set_measure_render_time(viewport->get_viewport_rid(), show_fps);
+ for (int i = 0; i < FRAME_TIME_HISTORY; i++) {
+ cpu_time_history[i] = 0;
+ gpu_time_history[i] = 0;
+ }
+ cpu_time_history_index = 0;
+ gpu_time_history_index = 0;
+ }
+ if (show_fps) {
+ cpu_time_history[cpu_time_history_index] = RS::get_singleton()->viewport_get_measured_render_time_cpu(viewport->get_viewport_rid());
+ cpu_time_history_index = (cpu_time_history_index + 1) % FRAME_TIME_HISTORY;
+ double cpu_time = 0.0;
+ for (int i = 0; i < FRAME_TIME_HISTORY; i++) {
+ cpu_time += cpu_time_history[i];
+ }
+ cpu_time /= FRAME_TIME_HISTORY;
+ // Prevent unrealistically low values.
+ cpu_time = MAX(0.01, cpu_time);
+
+ gpu_time_history[gpu_time_history_index] = RS::get_singleton()->viewport_get_measured_render_time_gpu(viewport->get_viewport_rid());
+ gpu_time_history_index = (gpu_time_history_index + 1) % FRAME_TIME_HISTORY;
+ double gpu_time = 0.0;
+ for (int i = 0; i < FRAME_TIME_HISTORY; i++) {
+ gpu_time += gpu_time_history[i];
+ }
+ gpu_time /= FRAME_TIME_HISTORY;
+ // Prevent division by zero for the FPS counter (and unrealistically low values).
+ // This limits the reported FPS to 100000.
+ gpu_time = MAX(0.01, gpu_time);
+
+ // Color labels depending on performance level ("good" = green, "OK" = yellow, "bad" = red).
+ // Middle point is at 15 ms.
+ cpu_time_label->set_text(vformat(TTR("CPU Time: %s ms"), rtos(cpu_time).pad_decimals(2)));
+ cpu_time_label->add_theme_color_override(
+ "font_color",
+ frame_time_gradient->get_color_at_offset(
+ Math::range_lerp(cpu_time, 0, 30, 0, 1)));
+
+ gpu_time_label->set_text(vformat(TTR("GPU Time: %s ms"), rtos(gpu_time).pad_decimals(2)));
+ // Middle point is at 15 ms.
+ gpu_time_label->add_theme_color_override(
+ "font_color",
+ frame_time_gradient->get_color_at_offset(
+ Math::range_lerp(gpu_time, 0, 30, 0, 1)));
+
+ const double fps = 1000.0 / gpu_time;
+ fps_label->set_text(vformat(TTR("FPS: %d"), fps));
+ // Middle point is at 60 FPS.
+ fps_label->add_theme_color_override(
+ "font_color",
+ frame_time_gradient->get_color_at_offset(
+ Math::range_lerp(fps, 110, 10, 0, 1)));
+ }
+
+ bool show_cinema = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_CINEMATIC_PREVIEW));
+ cinema_label->set_visible(show_cinema);
+ if (show_cinema) {
+ float cinema_half_width = cinema_label->get_size().width / 2.0f;
+ cinema_label->set_anchor_and_offset(SIDE_LEFT, 0.5f, -cinema_half_width);
+ }
- if (p_what == NOTIFICATION_THEME_CHANGED) {
- view_menu->set_icon(get_theme_icon(SNAME("GuiTabMenuHl"), SNAME("EditorIcons")));
- preview_camera->set_icon(get_theme_icon(SNAME("Camera3D"), SNAME("EditorIcons")));
+ if (lock_rotation) {
+ float locked_half_width = locked_label->get_size().width / 2.0f;
+ locked_label->set_anchor_and_offset(SIDE_LEFT, 0.5f, -locked_half_width);
+ }
+ } break;
- view_menu->add_theme_style_override("normal", editor->get_gui_base()->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
- view_menu->add_theme_style_override("hover", editor->get_gui_base()->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
- view_menu->add_theme_style_override("pressed", editor->get_gui_base()->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
- view_menu->add_theme_style_override("focus", editor->get_gui_base()->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
- view_menu->add_theme_style_override("disabled", editor->get_gui_base()->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
+ case NOTIFICATION_ENTER_TREE: {
+ surface->connect("draw", callable_mp(this, &Node3DEditorViewport::_draw));
+ surface->connect("gui_input", callable_mp(this, &Node3DEditorViewport::_sinput));
+ surface->connect("mouse_entered", callable_mp(this, &Node3DEditorViewport::_surface_mouse_enter));
+ surface->connect("mouse_exited", callable_mp(this, &Node3DEditorViewport::_surface_mouse_exit));
+ surface->connect("focus_entered", callable_mp(this, &Node3DEditorViewport::_surface_focus_enter));
+ surface->connect("focus_exited", callable_mp(this, &Node3DEditorViewport::_surface_focus_exit));
+
+ _init_gizmo_instance(index);
+ } break;
- preview_camera->add_theme_style_override("normal", editor->get_gui_base()->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
- preview_camera->add_theme_style_override("hover", editor->get_gui_base()->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
- preview_camera->add_theme_style_override("pressed", editor->get_gui_base()->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
- preview_camera->add_theme_style_override("focus", editor->get_gui_base()->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
- preview_camera->add_theme_style_override("disabled", editor->get_gui_base()->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
-
- frame_time_gradient->set_color(0, get_theme_color(SNAME("success_color"), SNAME("Editor")));
- frame_time_gradient->set_color(1, get_theme_color(SNAME("warning_color"), SNAME("Editor")));
- frame_time_gradient->set_color(2, get_theme_color(SNAME("error_color"), SNAME("Editor")));
+ case NOTIFICATION_EXIT_TREE: {
+ _finish_gizmo_instances();
+ } break;
- info_label->add_theme_style_override("normal", editor->get_gui_base()->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
- cpu_time_label->add_theme_style_override("normal", editor->get_gui_base()->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
- gpu_time_label->add_theme_style_override("normal", editor->get_gui_base()->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
- fps_label->add_theme_style_override("normal", editor->get_gui_base()->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
- cinema_label->add_theme_style_override("normal", editor->get_gui_base()->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
- locked_label->add_theme_style_override("normal", editor->get_gui_base()->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
+ case NOTIFICATION_THEME_CHANGED: {
+ view_menu->set_icon(get_theme_icon(SNAME("GuiTabMenuHl"), SNAME("EditorIcons")));
+ preview_camera->set_icon(get_theme_icon(SNAME("Camera3D"), SNAME("EditorIcons")));
+ Control *gui_base = EditorNode::get_singleton()->get_gui_base();
+
+ view_menu->add_theme_style_override("normal", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
+ view_menu->add_theme_style_override("hover", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
+ view_menu->add_theme_style_override("pressed", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
+ view_menu->add_theme_style_override("focus", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
+ view_menu->add_theme_style_override("disabled", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
+
+ preview_camera->add_theme_style_override("normal", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
+ preview_camera->add_theme_style_override("hover", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
+ preview_camera->add_theme_style_override("pressed", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
+ preview_camera->add_theme_style_override("focus", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
+ preview_camera->add_theme_style_override("disabled", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
+
+ frame_time_gradient->set_color(0, get_theme_color(SNAME("success_color"), SNAME("Editor")));
+ frame_time_gradient->set_color(1, get_theme_color(SNAME("warning_color"), SNAME("Editor")));
+ frame_time_gradient->set_color(2, get_theme_color(SNAME("error_color"), SNAME("Editor")));
+
+ info_label->add_theme_style_override("normal", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
+ cpu_time_label->add_theme_style_override("normal", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
+ gpu_time_label->add_theme_style_override("normal", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
+ fps_label->add_theme_style_override("normal", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
+ cinema_label->add_theme_style_override("normal", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
+ locked_label->add_theme_style_override("normal", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles")));
+ } break;
}
}
@@ -3000,7 +2719,7 @@ void Node3DEditorViewport::_draw() {
over_plugin_list->forward_spatial_draw_over_viewport(surface);
}
- EditorPluginList *force_over_plugin_list = editor->get_editor_plugins_force_over();
+ EditorPluginList *force_over_plugin_list = EditorNode::get_singleton()->get_editor_plugins_force_over();
if (!force_over_plugin_list->is_empty()) {
force_over_plugin_list->forward_spatial_force_draw_over_viewport(surface);
}
@@ -3036,7 +2755,7 @@ void Node3DEditorViewport::_draw() {
font->draw_string(ci, msgpos, message, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, Color(1, 1, 1, 1));
}
- if (_edit.mode == TRANSFORM_ROTATE) {
+ if (_edit.mode == TRANSFORM_ROTATE && _edit.show_rotation_line) {
Point2 center = _point_to_screen(_edit.center);
Color handle_color;
@@ -3544,6 +3263,13 @@ void Node3DEditorViewport::_init_gizmo_instance(int p_idx) {
RS::get_singleton()->instance_geometry_set_cast_shadows_setting(scale_plane_gizmo_instance[i], RS::SHADOW_CASTING_SETTING_OFF);
RS::get_singleton()->instance_set_layer_mask(scale_plane_gizmo_instance[i], layer);
RS::get_singleton()->instance_geometry_set_flag(scale_plane_gizmo_instance[i], RS::INSTANCE_FLAG_IGNORE_OCCLUSION_CULLING, true);
+
+ axis_gizmo_instance[i] = RS::get_singleton()->instance_create();
+ RS::get_singleton()->instance_set_base(axis_gizmo_instance[i], spatial_editor->get_axis_gizmo(i)->get_rid());
+ RS::get_singleton()->instance_set_scenario(axis_gizmo_instance[i], get_tree()->get_root()->get_world_3d()->get_scenario());
+ RS::get_singleton()->instance_set_visible(axis_gizmo_instance[i], true);
+ RS::get_singleton()->instance_geometry_set_cast_shadows_setting(axis_gizmo_instance[i], RS::SHADOW_CASTING_SETTING_OFF);
+ RS::get_singleton()->instance_set_layer_mask(axis_gizmo_instance[i], layer);
}
// Rotation white outline
@@ -3563,6 +3289,7 @@ void Node3DEditorViewport::_finish_gizmo_instances() {
RS::get_singleton()->free(rotate_gizmo_instance[i]);
RS::get_singleton()->free(scale_gizmo_instance[i]);
RS::get_singleton()->free(scale_plane_gizmo_instance[i]);
+ RS::get_singleton()->free(axis_gizmo_instance[i]);
}
// Rotation white outline
RS::get_singleton()->free(rotate_gizmo_instance[3]);
@@ -3655,6 +3382,7 @@ void Node3DEditorViewport::update_transform_gizmo_view() {
RenderingServer::get_singleton()->instance_set_visible(rotate_gizmo_instance[i], false);
RenderingServer::get_singleton()->instance_set_visible(scale_gizmo_instance[i], false);
RenderingServer::get_singleton()->instance_set_visible(scale_plane_gizmo_instance[i], false);
+ RenderingServer::get_singleton()->instance_set_visible(axis_gizmo_instance[i], false);
}
// Rotation white outline
RenderingServer::get_singleton()->instance_set_visible(rotate_gizmo_instance[3], false);
@@ -3711,7 +3439,15 @@ void Node3DEditorViewport::update_transform_gizmo_view() {
RenderingServer::get_singleton()->instance_set_visible(scale_gizmo_instance[i], spatial_editor->is_gizmo_visible() && (spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_SCALE));
RenderingServer::get_singleton()->instance_set_transform(scale_plane_gizmo_instance[i], axis_angle);
RenderingServer::get_singleton()->instance_set_visible(scale_plane_gizmo_instance[i], spatial_editor->is_gizmo_visible() && (spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_SCALE));
+ RenderingServer::get_singleton()->instance_set_transform(axis_gizmo_instance[i], xform);
}
+
+ bool show_axes = spatial_editor->is_gizmo_visible() && _edit.mode != TRANSFORM_NONE;
+ RenderingServer *rs = RenderingServer::get_singleton();
+ rs->instance_set_visible(axis_gizmo_instance[0], show_axes && (_edit.plane == TRANSFORM_X_AXIS || _edit.plane == TRANSFORM_XY || _edit.plane == TRANSFORM_XZ));
+ rs->instance_set_visible(axis_gizmo_instance[1], show_axes && (_edit.plane == TRANSFORM_Y_AXIS || _edit.plane == TRANSFORM_XY || _edit.plane == TRANSFORM_YZ));
+ rs->instance_set_visible(axis_gizmo_instance[2], show_axes && (_edit.plane == TRANSFORM_Z_AXIS || _edit.plane == TRANSFORM_XZ || _edit.plane == TRANSFORM_YZ));
+
// Rotation white outline
xform.orthonormalize();
xform.basis.scale(scale);
@@ -3978,7 +3714,7 @@ AABB Node3DEditorViewport::_calculate_spatial_bounds(const Node3D *p_parent, boo
if (child) {
AABB child_bounds = _calculate_spatial_bounds(child, false);
- if (bounds.size == Vector3() && p_parent->get_class_name() == StringName("Node3D")) {
+ if (bounds.size == Vector3() && Object::cast_to<Node3D>(p_parent)) {
bounds = child_bounds;
} else {
bounds.merge_with(child_bounds);
@@ -3986,7 +3722,7 @@ AABB Node3DEditorViewport::_calculate_spatial_bounds(const Node3D *p_parent, boo
}
}
- if (bounds.size == Vector3() && p_parent->get_class_name() != StringName("Node3D")) {
+ if (bounds.size == Vector3() && !Object::cast_to<Node3D>(p_parent)) {
bounds = AABB(Vector3(-0.2, -0.2, -0.2), Vector3(0.4, 0.4, 0.4));
}
@@ -4049,7 +3785,7 @@ void Node3DEditorViewport::_create_preview(const Vector<String> &files) const {
}
}
}
- editor->get_scene_root()->add_child(preview_node);
+ EditorNode::get_singleton()->get_scene_root()->add_child(preview_node);
}
}
*preview_bounds = _calculate_spatial_bounds(preview_node);
@@ -4062,7 +3798,7 @@ void Node3DEditorViewport::_remove_preview() {
node->queue_delete();
preview_node->remove_child(node);
}
- editor->get_scene_root()->remove_child(preview_node);
+ EditorNode::get_singleton()->get_scene_root()->remove_child(preview_node);
}
}
@@ -4125,8 +3861,8 @@ bool Node3DEditorViewport::_create_instance(Node *parent, String &path, const Po
return false;
}
- if (!editor->get_edited_scene()->get_scene_file_path().is_empty()) { // cyclical instancing
- if (_cyclical_dependency_exists(editor->get_edited_scene()->get_scene_file_path(), instantiated_scene)) {
+ if (!EditorNode::get_singleton()->get_edited_scene()->get_scene_file_path().is_empty()) { // cyclical instancing
+ if (_cyclical_dependency_exists(EditorNode::get_singleton()->get_edited_scene()->get_scene_file_path(), instantiated_scene)) {
memdelete(instantiated_scene);
return false;
}
@@ -4137,14 +3873,14 @@ bool Node3DEditorViewport::_create_instance(Node *parent, String &path, const Po
}
editor_data->get_undo_redo().add_do_method(parent, "add_child", instantiated_scene, true);
- editor_data->get_undo_redo().add_do_method(instantiated_scene, "set_owner", editor->get_edited_scene());
+ editor_data->get_undo_redo().add_do_method(instantiated_scene, "set_owner", EditorNode::get_singleton()->get_edited_scene());
editor_data->get_undo_redo().add_do_reference(instantiated_scene);
editor_data->get_undo_redo().add_undo_method(parent, "remove_child", instantiated_scene);
String new_name = parent->validate_child_name(instantiated_scene);
EditorDebuggerNode *ed = EditorDebuggerNode::get_singleton();
- editor_data->get_undo_redo().add_do_method(ed, "live_debug_instance_node", editor->get_edited_scene()->get_path_to(parent), path, new_name);
- editor_data->get_undo_redo().add_undo_method(ed, "live_debug_remove_node", NodePath(String(editor->get_edited_scene()->get_path_to(parent)) + "/" + new_name));
+ editor_data->get_undo_redo().add_do_method(ed, "live_debug_instance_node", EditorNode::get_singleton()->get_edited_scene()->get_path_to(parent), path, new_name);
+ editor_data->get_undo_redo().add_undo_method(ed, "live_debug_remove_node", NodePath(String(EditorNode::get_singleton()->get_edited_scene()->get_path_to(parent)) + "/" + new_name));
Node3D *node3d = Object::cast_to<Node3D>(instantiated_scene);
if (node3d) {
@@ -4213,27 +3949,19 @@ bool Node3DEditorViewport::can_drop_data_fw(const Point2 &p_point, const Variant
ResourceLoader::get_recognized_extensions_for_type("Mesh", &mesh_extensions);
for (int i = 0; i < files.size(); i++) {
+ // Check if dragged files with mesh or scene extension can be created at least once.
if (mesh_extensions.find(files[i].get_extension()) || scene_extensions.find(files[i].get_extension())) {
RES res = ResourceLoader::load(files[i]);
if (res.is_null()) {
continue;
}
-
- String type = res->get_class();
- if (type == "PackedScene") {
- Ref<PackedScene> sdata = ResourceLoader::load(files[i]);
- Node *instantiated_scene = sdata->instantiate(PackedScene::GEN_EDIT_STATE_INSTANCE);
+ Ref<PackedScene> scn = res;
+ if (scn.is_valid()) {
+ Node *instantiated_scene = scn->instantiate(PackedScene::GEN_EDIT_STATE_INSTANCE);
if (!instantiated_scene) {
continue;
}
memdelete(instantiated_scene);
- } else if (ClassDB::is_parent_class(type, "Mesh")) {
- Ref<Mesh> mesh = ResourceLoader::load(files[i]);
- if (!mesh.is_valid()) {
- continue;
- }
- } else {
- continue;
}
can_instantiate = true;
break;
@@ -4269,8 +3997,8 @@ void Node3DEditorViewport::drop_data_fw(const Point2 &p_point, const Variant &p_
selected_files = d["files"];
}
- List<Node *> selected_nodes = editor->get_editor_selection()->get_selected_node_list();
- Node *root_node = editor->get_edited_scene();
+ List<Node *> selected_nodes = EditorNode::get_singleton()->get_editor_selection()->get_selected_node_list();
+ Node *root_node = EditorNode::get_singleton()->get_edited_scene();
if (selected_nodes.size() == 1) {
Node *selected_node = selected_nodes[0];
target_node = root_node;
@@ -4299,21 +4027,430 @@ void Node3DEditorViewport::drop_data_fw(const Point2 &p_point, const Variant &p_
_perform_drop_data();
}
-Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, EditorNode *p_editor, int p_index) {
+void Node3DEditorViewport::begin_transform(TransformMode p_mode, bool instant) {
+ if (get_selected_count() > 0) {
+ _edit.mode = p_mode;
+ _compute_edit(_edit.mouse_pos);
+ _edit.instant = instant;
+ _edit.snap = spatial_editor->is_snap_enabled();
+ }
+}
+
+void Node3DEditorViewport::commit_transform() {
+ ERR_FAIL_COND(_edit.mode == TRANSFORM_NONE);
+ static const char *_transform_name[4] = {
+ TTRC("None"),
+ TTRC("Rotate"),
+ // TRANSLATORS: This refers to the movement that changes the position of an object.
+ TTRC("Translate"),
+ TTRC("Scale"),
+ };
+ undo_redo->create_action(_transform_name[_edit.mode]);
+
+ List<Node *> &selection = editor_selection->get_selected_node_list();
+
+ for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
+ Node3D *sp = Object::cast_to<Node3D>(E->get());
+ if (!sp) {
+ continue;
+ }
+
+ Node3DEditorSelectedItem *se = editor_selection->get_node_editor_data<Node3DEditorSelectedItem>(sp);
+ if (!se) {
+ continue;
+ }
+
+ undo_redo->add_do_method(sp, "set_global_transform", sp->get_global_gizmo_transform());
+ undo_redo->add_undo_method(sp, "set_global_transform", se->original);
+ }
+ undo_redo->commit_action();
+
+ finish_transform();
+ set_message("");
+}
+
+void Node3DEditorViewport::update_transform(Point2 p_mousepos, bool p_shift) {
+ Vector3 ray_pos = _get_ray_pos(p_mousepos);
+ Vector3 ray = _get_ray(p_mousepos);
+ double snap = EDITOR_GET("interface/inspector/default_float_step");
+ int snap_step_decimals = Math::range_step_decimals(snap);
+
+ switch (_edit.mode) {
+ case TRANSFORM_SCALE: {
+ Vector3 motion_mask;
+ Plane plane;
+ bool plane_mv = false;
+
+ switch (_edit.plane) {
+ case TRANSFORM_VIEW:
+ motion_mask = Vector3(0, 0, 0);
+ plane = Plane(_get_camera_normal(), _edit.center);
+ break;
+ case TRANSFORM_X_AXIS:
+ motion_mask = spatial_editor->get_gizmo_transform().basis.get_axis(0).normalized();
+ plane = Plane(motion_mask.cross(motion_mask.cross(_get_camera_normal())).normalized(), _edit.center);
+ break;
+ case TRANSFORM_Y_AXIS:
+ motion_mask = spatial_editor->get_gizmo_transform().basis.get_axis(1).normalized();
+ plane = Plane(motion_mask.cross(motion_mask.cross(_get_camera_normal())).normalized(), _edit.center);
+ break;
+ case TRANSFORM_Z_AXIS:
+ motion_mask = spatial_editor->get_gizmo_transform().basis.get_axis(2).normalized();
+ plane = Plane(motion_mask.cross(motion_mask.cross(_get_camera_normal())).normalized(), _edit.center);
+ break;
+ case TRANSFORM_YZ:
+ motion_mask = spatial_editor->get_gizmo_transform().basis.get_axis(2).normalized() + spatial_editor->get_gizmo_transform().basis.get_axis(1).normalized();
+ plane = Plane(spatial_editor->get_gizmo_transform().basis.get_axis(0).normalized(), _edit.center);
+ plane_mv = true;
+ break;
+ case TRANSFORM_XZ:
+ motion_mask = spatial_editor->get_gizmo_transform().basis.get_axis(2).normalized() + spatial_editor->get_gizmo_transform().basis.get_axis(0).normalized();
+ plane = Plane(spatial_editor->get_gizmo_transform().basis.get_axis(1).normalized(), _edit.center);
+ plane_mv = true;
+ break;
+ case TRANSFORM_XY:
+ motion_mask = spatial_editor->get_gizmo_transform().basis.get_axis(0).normalized() + spatial_editor->get_gizmo_transform().basis.get_axis(1).normalized();
+ plane = Plane(spatial_editor->get_gizmo_transform().basis.get_axis(2).normalized(), _edit.center);
+ plane_mv = true;
+ break;
+ }
+
+ Vector3 intersection;
+ if (!plane.intersects_ray(ray_pos, ray, &intersection)) {
+ break;
+ }
+
+ Vector3 click;
+ if (!plane.intersects_ray(_edit.click_ray_pos, _edit.click_ray, &click)) {
+ break;
+ }
+
+ Vector3 motion = intersection - click;
+ if (_edit.plane != TRANSFORM_VIEW) {
+ if (!plane_mv) {
+ motion = motion_mask.dot(motion) * motion_mask;
+
+ } else {
+ // Alternative planar scaling mode
+ if (p_shift) {
+ motion = motion_mask.dot(motion) * motion_mask;
+ }
+ }
+
+ } else {
+ const real_t center_click_dist = click.distance_to(_edit.center);
+ const real_t center_inters_dist = intersection.distance_to(_edit.center);
+ if (center_click_dist == 0) {
+ break;
+ }
+
+ const real_t scale = center_inters_dist - center_click_dist;
+ motion = Vector3(scale, scale, scale);
+ }
+
+ motion /= click.distance_to(_edit.center);
+
+ // Disable local transformation for TRANSFORM_VIEW
+ bool local_coords = (spatial_editor->are_local_coords_enabled() && _edit.plane != TRANSFORM_VIEW);
+
+ if (_edit.snap || spatial_editor->is_snap_enabled()) {
+ snap = spatial_editor->get_scale_snap() / 100;
+ }
+ Vector3 motion_snapped = motion;
+ motion_snapped.snap(Vector3(snap, snap, snap));
+ // This might not be necessary anymore after issue #288 is solved (in 4.0?).
+ set_message(TTR("Scaling: ") + "(" + String::num(motion_snapped.x, snap_step_decimals) + ", " +
+ String::num(motion_snapped.y, snap_step_decimals) + ", " + String::num(motion_snapped.z, snap_step_decimals) + ")");
+ motion = _edit.original.basis.inverse().xform(motion);
+
+ List<Node *> &selection = editor_selection->get_selected_node_list();
+ for (Node *E : selection) {
+ Node3D *sp = Object::cast_to<Node3D>(E);
+ if (!sp) {
+ continue;
+ }
+
+ Node3DEditorSelectedItem *se = editor_selection->get_node_editor_data<Node3DEditorSelectedItem>(sp);
+ if (!se) {
+ continue;
+ }
+
+ if (sp->has_meta("_edit_lock_")) {
+ continue;
+ }
+
+ if (se->gizmo.is_valid()) {
+ for (KeyValue<int, Transform3D> &GE : se->subgizmos) {
+ Transform3D xform = GE.value;
+ Transform3D new_xform = _compute_transform(TRANSFORM_SCALE, se->original * xform, xform, motion, snap, local_coords, true); // Force orthogonal with subgizmo.
+ if (!local_coords) {
+ new_xform = se->original.affine_inverse() * new_xform;
+ }
+ se->gizmo->set_subgizmo_transform(GE.key, new_xform);
+ }
+ } else {
+ Transform3D new_xform = _compute_transform(TRANSFORM_SCALE, se->original, se->original_local, motion, snap, local_coords, sp->get_rotation_edit_mode() != Node3D::ROTATION_EDIT_MODE_BASIS);
+ _transform_gizmo_apply(se->sp, new_xform, local_coords);
+ }
+ }
+
+ spatial_editor->update_transform_gizmo();
+ surface->update();
+
+ } break;
+
+ case TRANSFORM_TRANSLATE: {
+ Vector3 motion_mask;
+ Plane plane;
+ bool plane_mv = false;
+
+ switch (_edit.plane) {
+ case TRANSFORM_VIEW:
+ plane = Plane(_get_camera_normal(), _edit.center);
+ break;
+ case TRANSFORM_X_AXIS:
+ motion_mask = spatial_editor->get_gizmo_transform().basis.get_axis(0).normalized();
+ plane = Plane(motion_mask.cross(motion_mask.cross(_get_camera_normal())).normalized(), _edit.center);
+ break;
+ case TRANSFORM_Y_AXIS:
+ motion_mask = spatial_editor->get_gizmo_transform().basis.get_axis(1).normalized();
+ plane = Plane(motion_mask.cross(motion_mask.cross(_get_camera_normal())).normalized(), _edit.center);
+ break;
+ case TRANSFORM_Z_AXIS:
+ motion_mask = spatial_editor->get_gizmo_transform().basis.get_axis(2).normalized();
+ plane = Plane(motion_mask.cross(motion_mask.cross(_get_camera_normal())).normalized(), _edit.center);
+ break;
+ case TRANSFORM_YZ:
+ plane = Plane(spatial_editor->get_gizmo_transform().basis.get_axis(0).normalized(), _edit.center);
+ plane_mv = true;
+ break;
+ case TRANSFORM_XZ:
+ plane = Plane(spatial_editor->get_gizmo_transform().basis.get_axis(1).normalized(), _edit.center);
+ plane_mv = true;
+ break;
+ case TRANSFORM_XY:
+ plane = Plane(spatial_editor->get_gizmo_transform().basis.get_axis(2).normalized(), _edit.center);
+ plane_mv = true;
+ break;
+ }
+
+ Vector3 intersection;
+ if (!plane.intersects_ray(ray_pos, ray, &intersection)) {
+ break;
+ }
+
+ Vector3 click;
+ if (!plane.intersects_ray(_edit.click_ray_pos, _edit.click_ray, &click)) {
+ break;
+ }
+
+ Vector3 motion = intersection - click;
+ if (_edit.plane != TRANSFORM_VIEW) {
+ if (!plane_mv) {
+ motion = motion_mask.dot(motion) * motion_mask;
+ }
+ }
+
+ // Disable local transformation for TRANSFORM_VIEW
+ bool local_coords = (spatial_editor->are_local_coords_enabled() && _edit.plane != TRANSFORM_VIEW);
+
+ if (_edit.snap || spatial_editor->is_snap_enabled()) {
+ snap = spatial_editor->get_translate_snap();
+ }
+ Vector3 motion_snapped = motion;
+ motion_snapped.snap(Vector3(snap, snap, snap));
+ set_message(TTR("Translating: ") + "(" + String::num(motion_snapped.x, snap_step_decimals) + ", " +
+ String::num(motion_snapped.y, snap_step_decimals) + ", " + String::num(motion_snapped.z, snap_step_decimals) + ")");
+ motion = spatial_editor->get_gizmo_transform().basis.inverse().xform(motion);
+
+ List<Node *> &selection = editor_selection->get_selected_node_list();
+ for (Node *E : selection) {
+ Node3D *sp = Object::cast_to<Node3D>(E);
+ if (!sp) {
+ continue;
+ }
+
+ Node3DEditorSelectedItem *se = editor_selection->get_node_editor_data<Node3DEditorSelectedItem>(sp);
+ if (!se) {
+ continue;
+ }
+
+ if (sp->has_meta("_edit_lock_")) {
+ continue;
+ }
+
+ if (se->gizmo.is_valid()) {
+ for (KeyValue<int, Transform3D> &GE : se->subgizmos) {
+ Transform3D xform = GE.value;
+ Transform3D new_xform = _compute_transform(TRANSFORM_TRANSLATE, se->original * xform, xform, motion, snap, local_coords, true); // Force orthogonal with subgizmo.
+ new_xform = se->original.affine_inverse() * new_xform;
+ se->gizmo->set_subgizmo_transform(GE.key, new_xform);
+ }
+ } else {
+ Transform3D new_xform = _compute_transform(TRANSFORM_TRANSLATE, se->original, se->original_local, motion, snap, local_coords, sp->get_rotation_edit_mode() != Node3D::ROTATION_EDIT_MODE_BASIS);
+ _transform_gizmo_apply(se->sp, new_xform, false);
+ }
+ }
+
+ spatial_editor->update_transform_gizmo();
+ surface->update();
+
+ } break;
+
+ case TRANSFORM_ROTATE: {
+ Plane plane = Plane(_get_camera_normal(), _edit.center);
+
+ Vector3 local_axis;
+ Vector3 global_axis;
+ switch (_edit.plane) {
+ case TRANSFORM_VIEW:
+ // local_axis unused
+ global_axis = _get_camera_normal();
+ break;
+ case TRANSFORM_X_AXIS:
+ local_axis = Vector3(1, 0, 0);
+ break;
+ case TRANSFORM_Y_AXIS:
+ local_axis = Vector3(0, 1, 0);
+ break;
+ case TRANSFORM_Z_AXIS:
+ local_axis = Vector3(0, 0, 1);
+ break;
+ case TRANSFORM_YZ:
+ case TRANSFORM_XZ:
+ case TRANSFORM_XY:
+ break;
+ }
+
+ if (_edit.plane != TRANSFORM_VIEW) {
+ global_axis = spatial_editor->get_gizmo_transform().basis.xform(local_axis).normalized();
+ }
+
+ Vector3 intersection;
+ if (!plane.intersects_ray(ray_pos, ray, &intersection)) {
+ break;
+ }
+
+ Vector3 click;
+ if (!plane.intersects_ray(_edit.click_ray_pos, _edit.click_ray, &click)) {
+ break;
+ }
+
+ static const float orthogonal_threshold = Math::cos(Math::deg2rad(87.0f));
+ bool axis_is_orthogonal = ABS(plane.normal.dot(global_axis)) < orthogonal_threshold;
+
+ double angle = 0.0f;
+ if (axis_is_orthogonal) {
+ _edit.show_rotation_line = false;
+ Vector3 projection_axis = plane.normal.cross(global_axis);
+ Vector3 delta = intersection - click;
+ float projection = delta.dot(projection_axis);
+ angle = (projection * (Math_PI / 2.0f)) / (gizmo_scale * GIZMO_CIRCLE_SIZE);
+ } else {
+ _edit.show_rotation_line = true;
+ Vector3 click_axis = (click - _edit.center).normalized();
+ Vector3 current_axis = (intersection - _edit.center).normalized();
+ angle = click_axis.signed_angle_to(current_axis, global_axis);
+ }
+
+ if (_edit.snap || spatial_editor->is_snap_enabled()) {
+ snap = spatial_editor->get_rotate_snap();
+ }
+ angle = Math::rad2deg(angle) + snap * 0.5; //else it won't reach +180
+ angle -= Math::fmod(angle, snap);
+ set_message(vformat(TTR("Rotating %s degrees."), String::num(angle, snap_step_decimals)));
+ angle = Math::deg2rad(angle);
+
+ bool local_coords = (spatial_editor->are_local_coords_enabled() && _edit.plane != TRANSFORM_VIEW); // Disable local transformation for TRANSFORM_VIEW
+
+ List<Node *> &selection = editor_selection->get_selected_node_list();
+ for (Node *E : selection) {
+ Node3D *sp = Object::cast_to<Node3D>(E);
+ if (!sp) {
+ continue;
+ }
+
+ Node3DEditorSelectedItem *se = editor_selection->get_node_editor_data<Node3DEditorSelectedItem>(sp);
+ if (!se) {
+ continue;
+ }
+
+ if (sp->has_meta("_edit_lock_")) {
+ continue;
+ }
+
+ Vector3 compute_axis = local_coords ? local_axis : global_axis;
+ if (se->gizmo.is_valid()) {
+ for (KeyValue<int, Transform3D> &GE : se->subgizmos) {
+ Transform3D xform = GE.value;
+
+ Transform3D new_xform = _compute_transform(TRANSFORM_ROTATE, se->original * xform, xform, compute_axis, angle, local_coords, true); // Force orthogonal with subgizmo.
+ if (!local_coords) {
+ new_xform = se->original.affine_inverse() * new_xform;
+ }
+ se->gizmo->set_subgizmo_transform(GE.key, new_xform);
+ }
+ } else {
+ Transform3D new_xform = _compute_transform(TRANSFORM_ROTATE, se->original, se->original_local, compute_axis, angle, local_coords, sp->get_rotation_edit_mode() != Node3D::ROTATION_EDIT_MODE_BASIS);
+ _transform_gizmo_apply(se->sp, new_xform, local_coords);
+ }
+ }
+
+ spatial_editor->update_transform_gizmo();
+ surface->update();
+
+ } break;
+ default: {
+ }
+ }
+}
+
+void Node3DEditorViewport::finish_transform() {
+ spatial_editor->set_local_coords_enabled(_edit.original_local);
+ spatial_editor->update_transform_gizmo();
+ _edit.mode = TRANSFORM_NONE;
+ _edit.instant = false;
+ surface->update();
+}
+
+// Register a shortcut and also add it as an input action with the same events.
+void Node3DEditorViewport::register_shortcut_action(const String &p_path, const String &p_name, Key p_keycode) {
+ Ref<Shortcut> sc = ED_SHORTCUT(p_path, p_name, p_keycode);
+ shortcut_changed_callback(sc, p_path);
+ // Connect to the change event on the shortcut so the input binding can be updated.
+ sc->connect("changed", callable_mp(this, &Node3DEditorViewport::shortcut_changed_callback), varray(sc, p_path));
+}
+
+// Update the action in the InputMap to the provided shortcut events.
+void Node3DEditorViewport::shortcut_changed_callback(const Ref<Shortcut> p_shortcut, const String &p_shortcut_path) {
+ InputMap *im = InputMap::get_singleton();
+ if (im->has_action(p_shortcut_path)) {
+ im->action_erase_events(p_shortcut_path);
+ } else {
+ im->add_action(p_shortcut_path);
+ }
+
+ for (int i = 0; i < p_shortcut->get_events().size(); i++) {
+ im->action_add_event(p_shortcut_path, p_shortcut->get_events()[i]);
+ }
+}
+
+Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, int p_index) {
cpu_time_history_index = 0;
gpu_time_history_index = 0;
_edit.mode = TRANSFORM_NONE;
_edit.plane = TRANSFORM_VIEW;
_edit.snap = true;
+ _edit.show_rotation_line = true;
+ _edit.instant = false;
_edit.gizmo_handle = -1;
_edit.gizmo_handle_secondary = false;
index = p_index;
- editor = p_editor;
editor_data = SceneTreeDock::get_singleton()->get_editor_data();
- editor_selection = editor->get_editor_selection();
- undo_redo = editor->get_undo_redo();
+ editor_selection = EditorNode::get_singleton()->get_editor_selection();
+ undo_redo = EditorNode::get_singleton()->get_undo_redo();
orthogonal = false;
auto_orthogonal = false;
@@ -4383,7 +4520,7 @@ Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, Edito
display_submenu->add_radio_check_item(TTR("Normal Buffer"), VIEW_DISPLAY_NORMAL_BUFFER);
display_submenu->add_separator();
display_submenu->add_radio_check_item(TTR("Shadow Atlas"), VIEW_DISPLAY_DEBUG_SHADOW_ATLAS);
- display_submenu->add_radio_check_item(TTR("Directional Shadow"), VIEW_DISPLAY_DEBUG_DIRECTIONAL_SHADOW_ATLAS);
+ display_submenu->add_radio_check_item(TTR("Directional Shadow Map"), VIEW_DISPLAY_DEBUG_DIRECTIONAL_SHADOW_ATLAS);
display_submenu->add_separator();
display_submenu->add_radio_check_item(TTR("Decal Atlas"), VIEW_DISPLAY_DEBUG_DECAL_ATLAS);
display_submenu->add_separator();
@@ -4399,14 +4536,14 @@ Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, Edito
display_submenu->add_radio_check_item(TTR("SSAO"), VIEW_DISPLAY_DEBUG_SSAO);
display_submenu->add_radio_check_item(TTR("SSIL"), VIEW_DISPLAY_DEBUG_SSIL);
display_submenu->add_separator();
- display_submenu->add_radio_check_item(TTR("GI Buffer"), VIEW_DISPLAY_DEBUG_GI_BUFFER);
+ display_submenu->add_radio_check_item(TTR("VoxelGI/SDFGI Buffer"), VIEW_DISPLAY_DEBUG_GI_BUFFER);
display_submenu->add_separator();
- display_submenu->add_radio_check_item(TTR("Disable LOD"), VIEW_DISPLAY_DEBUG_DISABLE_LOD);
+ display_submenu->add_radio_check_item(TTR("Disable Mesh LOD"), VIEW_DISPLAY_DEBUG_DISABLE_LOD);
display_submenu->add_separator();
- display_submenu->add_radio_check_item(TTR("Omni Light Cluster"), VIEW_DISPLAY_DEBUG_CLUSTER_OMNI_LIGHTS);
- display_submenu->add_radio_check_item(TTR("Spot Light Cluster"), VIEW_DISPLAY_DEBUG_CLUSTER_SPOT_LIGHTS);
+ display_submenu->add_radio_check_item(TTR("OmniLight3D Cluster"), VIEW_DISPLAY_DEBUG_CLUSTER_OMNI_LIGHTS);
+ display_submenu->add_radio_check_item(TTR("SpotLight3D Cluster"), VIEW_DISPLAY_DEBUG_CLUSTER_SPOT_LIGHTS);
display_submenu->add_radio_check_item(TTR("Decal Cluster"), VIEW_DISPLAY_DEBUG_CLUSTER_DECALS);
- display_submenu->add_radio_check_item(TTR("Reflection Probe Cluster"), VIEW_DISPLAY_DEBUG_CLUSTER_REFLECTION_PROBES);
+ display_submenu->add_radio_check_item(TTR("ReflectionProbe Cluster"), VIEW_DISPLAY_DEBUG_CLUSTER_REFLECTION_PROBES);
display_submenu->add_radio_check_item(TTR("Occlusion Culling Buffer"), VIEW_DISPLAY_DEBUG_OCCLUDERS);
display_submenu->set_name("display_advanced");
@@ -4457,14 +4594,25 @@ Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, Edito
view_menu->get_popup()->set_item_tooltip(shadeless_idx, unsupported_tooltip);
}
- ED_SHORTCUT("spatial_editor/freelook_left", TTR("Freelook Left"), Key::A);
- ED_SHORTCUT("spatial_editor/freelook_right", TTR("Freelook Right"), Key::D);
- ED_SHORTCUT("spatial_editor/freelook_forward", TTR("Freelook Forward"), Key::W);
- ED_SHORTCUT("spatial_editor/freelook_backwards", TTR("Freelook Backwards"), Key::S);
- ED_SHORTCUT("spatial_editor/freelook_up", TTR("Freelook Up"), Key::E);
- ED_SHORTCUT("spatial_editor/freelook_down", TTR("Freelook Down"), Key::Q);
- ED_SHORTCUT("spatial_editor/freelook_speed_modifier", TTR("Freelook Speed Modifier"), Key::SHIFT);
- ED_SHORTCUT("spatial_editor/freelook_slow_modifier", TTR("Freelook Slow Modifier"), Key::ALT);
+ register_shortcut_action("spatial_editor/freelook_left", TTR("Freelook Left"), Key::A);
+ register_shortcut_action("spatial_editor/freelook_right", TTR("Freelook Right"), Key::D);
+ register_shortcut_action("spatial_editor/freelook_forward", TTR("Freelook Forward"), Key::W);
+ register_shortcut_action("spatial_editor/freelook_backwards", TTR("Freelook Backwards"), Key::S);
+ register_shortcut_action("spatial_editor/freelook_up", TTR("Freelook Up"), Key::E);
+ register_shortcut_action("spatial_editor/freelook_down", TTR("Freelook Down"), Key::Q);
+ register_shortcut_action("spatial_editor/freelook_speed_modifier", TTR("Freelook Speed Modifier"), Key::SHIFT);
+ register_shortcut_action("spatial_editor/freelook_slow_modifier", TTR("Freelook Slow Modifier"), Key::ALT);
+
+ ED_SHORTCUT("spatial_editor/lock_transform_x", TTR("Lock Transformation to X axis"), Key::X);
+ ED_SHORTCUT("spatial_editor/lock_transform_y", TTR("Lock Transformation to Y axis"), Key::Y);
+ ED_SHORTCUT("spatial_editor/lock_transform_z", TTR("Lock Transformation to Z axis"), Key::Z);
+ ED_SHORTCUT("spatial_editor/lock_transform_yz", TTR("Lock Transformation to YZ plane"), KeyModifierMask::SHIFT | Key::X);
+ ED_SHORTCUT("spatial_editor/lock_transform_xz", TTR("Lock Transformation to XZ plane"), KeyModifierMask::SHIFT | Key::Y);
+ ED_SHORTCUT("spatial_editor/lock_transform_xy", TTR("Lock Transformation to XY plane"), KeyModifierMask::SHIFT | Key::Z);
+ ED_SHORTCUT("spatial_editor/cancel_transform", TTR("Cancel Transformation"), Key::ESCAPE);
+ ED_SHORTCUT("spatial_editor/instant_translate", TTR("Begin Translate Transformation"));
+ ED_SHORTCUT("spatial_editor/instant_rotate", TTR("Begin Rotate Transformation"));
+ ED_SHORTCUT("spatial_editor/instant_scale", TTR("Begin Scale Transformation"));
preview_camera = memnew(CheckBox);
preview_camera->set_text(TTR("Preview"));
@@ -4666,197 +4814,202 @@ void Node3DEditorViewportContainer::gui_input(const Ref<InputEvent> &p_event) {
}
void Node3DEditorViewportContainer::_notification(int p_what) {
- if (p_what == NOTIFICATION_MOUSE_ENTER || p_what == NOTIFICATION_MOUSE_EXIT) {
- mouseover = (p_what == NOTIFICATION_MOUSE_ENTER);
- update();
- }
+ switch (p_what) {
+ case NOTIFICATION_MOUSE_ENTER:
+ case NOTIFICATION_MOUSE_EXIT: {
+ mouseover = (p_what == NOTIFICATION_MOUSE_ENTER);
+ update();
+ } break;
- if (p_what == NOTIFICATION_DRAW && mouseover) {
- Ref<Texture2D> h_grabber = get_theme_icon(SNAME("grabber"), SNAME("HSplitContainer"));
- Ref<Texture2D> v_grabber = get_theme_icon(SNAME("grabber"), SNAME("VSplitContainer"));
+ case NOTIFICATION_DRAW: {
+ if (mouseover) {
+ Ref<Texture2D> h_grabber = get_theme_icon(SNAME("grabber"), SNAME("HSplitContainer"));
+ Ref<Texture2D> v_grabber = get_theme_icon(SNAME("grabber"), SNAME("VSplitContainer"));
- Ref<Texture2D> hdiag_grabber = get_theme_icon(SNAME("GuiViewportHdiagsplitter"), SNAME("EditorIcons"));
- Ref<Texture2D> vdiag_grabber = get_theme_icon(SNAME("GuiViewportVdiagsplitter"), SNAME("EditorIcons"));
- Ref<Texture2D> vh_grabber = get_theme_icon(SNAME("GuiViewportVhsplitter"), SNAME("EditorIcons"));
+ Ref<Texture2D> hdiag_grabber = get_theme_icon(SNAME("GuiViewportHdiagsplitter"), SNAME("EditorIcons"));
+ Ref<Texture2D> vdiag_grabber = get_theme_icon(SNAME("GuiViewportVdiagsplitter"), SNAME("EditorIcons"));
+ Ref<Texture2D> vh_grabber = get_theme_icon(SNAME("GuiViewportVhsplitter"), SNAME("EditorIcons"));
- Vector2 size = get_size();
+ Vector2 size = get_size();
- int h_sep = get_theme_constant(SNAME("separation"), SNAME("HSplitContainer"));
+ int h_sep = get_theme_constant(SNAME("separation"), SNAME("HSplitContainer"));
- int v_sep = get_theme_constant(SNAME("separation"), SNAME("VSplitContainer"));
+ int v_sep = get_theme_constant(SNAME("separation"), SNAME("VSplitContainer"));
- int mid_w = size.width * ratio_h;
- int mid_h = size.height * ratio_v;
+ int mid_w = size.width * ratio_h;
+ int mid_h = size.height * ratio_v;
- int size_left = mid_w - h_sep / 2;
- int size_bottom = size.height - mid_h - v_sep / 2;
+ int size_left = mid_w - h_sep / 2;
+ int size_bottom = size.height - mid_h - v_sep / 2;
- switch (view) {
- case VIEW_USE_1_VIEWPORT: {
- // Nothing to show.
+ switch (view) {
+ case VIEW_USE_1_VIEWPORT: {
+ // Nothing to show.
- } break;
- case VIEW_USE_2_VIEWPORTS: {
- draw_texture(v_grabber, Vector2((size.width - v_grabber->get_width()) / 2, mid_h - v_grabber->get_height() / 2));
- set_default_cursor_shape(CURSOR_VSPLIT);
+ } break;
+ case VIEW_USE_2_VIEWPORTS: {
+ draw_texture(v_grabber, Vector2((size.width - v_grabber->get_width()) / 2, mid_h - v_grabber->get_height() / 2));
+ set_default_cursor_shape(CURSOR_VSPLIT);
- } break;
- case VIEW_USE_2_VIEWPORTS_ALT: {
- draw_texture(h_grabber, Vector2(mid_w - h_grabber->get_width() / 2, (size.height - h_grabber->get_height()) / 2));
- set_default_cursor_shape(CURSOR_HSPLIT);
+ } break;
+ case VIEW_USE_2_VIEWPORTS_ALT: {
+ draw_texture(h_grabber, Vector2(mid_w - h_grabber->get_width() / 2, (size.height - h_grabber->get_height()) / 2));
+ set_default_cursor_shape(CURSOR_HSPLIT);
- } break;
- case VIEW_USE_3_VIEWPORTS: {
- if ((hovering_v && hovering_h && !dragging_v && !dragging_h) || (dragging_v && dragging_h)) {
- draw_texture(hdiag_grabber, Vector2(mid_w - hdiag_grabber->get_width() / 2, mid_h - v_grabber->get_height() / 4));
- set_default_cursor_shape(CURSOR_DRAG);
- } else if ((hovering_v && !dragging_h) || dragging_v) {
- draw_texture(v_grabber, Vector2((size.width - v_grabber->get_width()) / 2, mid_h - v_grabber->get_height() / 2));
- set_default_cursor_shape(CURSOR_VSPLIT);
- } else if (hovering_h || dragging_h) {
- draw_texture(h_grabber, Vector2(mid_w - h_grabber->get_width() / 2, mid_h + v_grabber->get_height() / 2 + (size_bottom - h_grabber->get_height()) / 2));
- set_default_cursor_shape(CURSOR_HSPLIT);
- }
+ } break;
+ case VIEW_USE_3_VIEWPORTS: {
+ if ((hovering_v && hovering_h && !dragging_v && !dragging_h) || (dragging_v && dragging_h)) {
+ draw_texture(hdiag_grabber, Vector2(mid_w - hdiag_grabber->get_width() / 2, mid_h - v_grabber->get_height() / 4));
+ set_default_cursor_shape(CURSOR_DRAG);
+ } else if ((hovering_v && !dragging_h) || dragging_v) {
+ draw_texture(v_grabber, Vector2((size.width - v_grabber->get_width()) / 2, mid_h - v_grabber->get_height() / 2));
+ set_default_cursor_shape(CURSOR_VSPLIT);
+ } else if (hovering_h || dragging_h) {
+ draw_texture(h_grabber, Vector2(mid_w - h_grabber->get_width() / 2, mid_h + v_grabber->get_height() / 2 + (size_bottom - h_grabber->get_height()) / 2));
+ set_default_cursor_shape(CURSOR_HSPLIT);
+ }
- } break;
- case VIEW_USE_3_VIEWPORTS_ALT: {
- if ((hovering_v && hovering_h && !dragging_v && !dragging_h) || (dragging_v && dragging_h)) {
- draw_texture(vdiag_grabber, Vector2(mid_w - vdiag_grabber->get_width() + v_grabber->get_height() / 4, mid_h - vdiag_grabber->get_height() / 2));
- set_default_cursor_shape(CURSOR_DRAG);
- } else if ((hovering_v && !dragging_h) || dragging_v) {
- draw_texture(v_grabber, Vector2((size_left - v_grabber->get_width()) / 2, mid_h - v_grabber->get_height() / 2));
- set_default_cursor_shape(CURSOR_VSPLIT);
- } else if (hovering_h || dragging_h) {
- draw_texture(h_grabber, Vector2(mid_w - h_grabber->get_width() / 2, (size.height - h_grabber->get_height()) / 2));
- set_default_cursor_shape(CURSOR_HSPLIT);
- }
+ } break;
+ case VIEW_USE_3_VIEWPORTS_ALT: {
+ if ((hovering_v && hovering_h && !dragging_v && !dragging_h) || (dragging_v && dragging_h)) {
+ draw_texture(vdiag_grabber, Vector2(mid_w - vdiag_grabber->get_width() + v_grabber->get_height() / 4, mid_h - vdiag_grabber->get_height() / 2));
+ set_default_cursor_shape(CURSOR_DRAG);
+ } else if ((hovering_v && !dragging_h) || dragging_v) {
+ draw_texture(v_grabber, Vector2((size_left - v_grabber->get_width()) / 2, mid_h - v_grabber->get_height() / 2));
+ set_default_cursor_shape(CURSOR_VSPLIT);
+ } else if (hovering_h || dragging_h) {
+ draw_texture(h_grabber, Vector2(mid_w - h_grabber->get_width() / 2, (size.height - h_grabber->get_height()) / 2));
+ set_default_cursor_shape(CURSOR_HSPLIT);
+ }
- } break;
- case VIEW_USE_4_VIEWPORTS: {
- Vector2 half(mid_w, mid_h);
- if ((hovering_v && hovering_h && !dragging_v && !dragging_h) || (dragging_v && dragging_h)) {
- draw_texture(vh_grabber, half - vh_grabber->get_size() / 2.0);
- set_default_cursor_shape(CURSOR_DRAG);
- } else if ((hovering_v && !dragging_h) || dragging_v) {
- draw_texture(v_grabber, half - v_grabber->get_size() / 2.0);
- set_default_cursor_shape(CURSOR_VSPLIT);
- } else if (hovering_h || dragging_h) {
- draw_texture(h_grabber, half - h_grabber->get_size() / 2.0);
- set_default_cursor_shape(CURSOR_HSPLIT);
- }
+ } break;
+ case VIEW_USE_4_VIEWPORTS: {
+ Vector2 half(mid_w, mid_h);
+ if ((hovering_v && hovering_h && !dragging_v && !dragging_h) || (dragging_v && dragging_h)) {
+ draw_texture(vh_grabber, half - vh_grabber->get_size() / 2.0);
+ set_default_cursor_shape(CURSOR_DRAG);
+ } else if ((hovering_v && !dragging_h) || dragging_v) {
+ draw_texture(v_grabber, half - v_grabber->get_size() / 2.0);
+ set_default_cursor_shape(CURSOR_VSPLIT);
+ } else if (hovering_h || dragging_h) {
+ draw_texture(h_grabber, half - h_grabber->get_size() / 2.0);
+ set_default_cursor_shape(CURSOR_HSPLIT);
+ }
- } break;
- }
- }
+ } break;
+ }
+ }
+ } break;
- if (p_what == NOTIFICATION_SORT_CHILDREN) {
- Node3DEditorViewport *viewports[4];
- int vc = 0;
- for (int i = 0; i < get_child_count(); i++) {
- viewports[vc] = Object::cast_to<Node3DEditorViewport>(get_child(i));
- if (viewports[vc]) {
- vc++;
+ case NOTIFICATION_SORT_CHILDREN: {
+ Node3DEditorViewport *viewports[4];
+ int vc = 0;
+ for (int i = 0; i < get_child_count(); i++) {
+ viewports[vc] = Object::cast_to<Node3DEditorViewport>(get_child(i));
+ if (viewports[vc]) {
+ vc++;
+ }
}
- }
- ERR_FAIL_COND(vc != 4);
+ ERR_FAIL_COND(vc != 4);
- Size2 size = get_size();
+ Size2 size = get_size();
- if (size.x < 10 || size.y < 10) {
- for (int i = 0; i < 4; i++) {
- viewports[i]->hide();
+ if (size.x < 10 || size.y < 10) {
+ for (int i = 0; i < 4; i++) {
+ viewports[i]->hide();
+ }
+ return;
}
- return;
- }
- int h_sep = get_theme_constant(SNAME("separation"), SNAME("HSplitContainer"));
+ int h_sep = get_theme_constant(SNAME("separation"), SNAME("HSplitContainer"));
- int v_sep = get_theme_constant(SNAME("separation"), SNAME("VSplitContainer"));
+ int v_sep = get_theme_constant(SNAME("separation"), SNAME("VSplitContainer"));
- int mid_w = size.width * ratio_h;
- int mid_h = size.height * ratio_v;
+ int mid_w = size.width * ratio_h;
+ int mid_h = size.height * ratio_v;
- int size_left = mid_w - h_sep / 2;
- int size_right = size.width - mid_w - h_sep / 2;
+ int size_left = mid_w - h_sep / 2;
+ int size_right = size.width - mid_w - h_sep / 2;
- int size_top = mid_h - v_sep / 2;
- int size_bottom = size.height - mid_h - v_sep / 2;
+ int size_top = mid_h - v_sep / 2;
+ int size_bottom = size.height - mid_h - v_sep / 2;
- switch (view) {
- case VIEW_USE_1_VIEWPORT: {
- viewports[0]->show();
- for (int i = 1; i < 4; i++) {
- viewports[i]->hide();
- }
+ switch (view) {
+ case VIEW_USE_1_VIEWPORT: {
+ viewports[0]->show();
+ for (int i = 1; i < 4; i++) {
+ viewports[i]->hide();
+ }
- fit_child_in_rect(viewports[0], Rect2(Vector2(), size));
+ fit_child_in_rect(viewports[0], Rect2(Vector2(), size));
- } break;
- case VIEW_USE_2_VIEWPORTS: {
- for (int i = 0; i < 4; i++) {
- if (i == 1 || i == 3) {
- viewports[i]->hide();
- } else {
- viewports[i]->show();
+ } break;
+ case VIEW_USE_2_VIEWPORTS: {
+ for (int i = 0; i < 4; i++) {
+ if (i == 1 || i == 3) {
+ viewports[i]->hide();
+ } else {
+ viewports[i]->show();
+ }
}
- }
- fit_child_in_rect(viewports[0], Rect2(Vector2(), Vector2(size.width, size_top)));
- fit_child_in_rect(viewports[2], Rect2(Vector2(0, mid_h + v_sep / 2), Vector2(size.width, size_bottom)));
+ fit_child_in_rect(viewports[0], Rect2(Vector2(), Vector2(size.width, size_top)));
+ fit_child_in_rect(viewports[2], Rect2(Vector2(0, mid_h + v_sep / 2), Vector2(size.width, size_bottom)));
- } break;
- case VIEW_USE_2_VIEWPORTS_ALT: {
- for (int i = 0; i < 4; i++) {
- if (i == 1 || i == 3) {
- viewports[i]->hide();
- } else {
- viewports[i]->show();
+ } break;
+ case VIEW_USE_2_VIEWPORTS_ALT: {
+ for (int i = 0; i < 4; i++) {
+ if (i == 1 || i == 3) {
+ viewports[i]->hide();
+ } else {
+ viewports[i]->show();
+ }
}
- }
- fit_child_in_rect(viewports[0], Rect2(Vector2(), Vector2(size_left, size.height)));
- fit_child_in_rect(viewports[2], Rect2(Vector2(mid_w + h_sep / 2, 0), Vector2(size_right, size.height)));
+ fit_child_in_rect(viewports[0], Rect2(Vector2(), Vector2(size_left, size.height)));
+ fit_child_in_rect(viewports[2], Rect2(Vector2(mid_w + h_sep / 2, 0), Vector2(size_right, size.height)));
- } break;
- case VIEW_USE_3_VIEWPORTS: {
- for (int i = 0; i < 4; i++) {
- if (i == 1) {
- viewports[i]->hide();
- } else {
- viewports[i]->show();
+ } break;
+ case VIEW_USE_3_VIEWPORTS: {
+ for (int i = 0; i < 4; i++) {
+ if (i == 1) {
+ viewports[i]->hide();
+ } else {
+ viewports[i]->show();
+ }
}
- }
- fit_child_in_rect(viewports[0], Rect2(Vector2(), Vector2(size.width, size_top)));
- fit_child_in_rect(viewports[2], Rect2(Vector2(0, mid_h + v_sep / 2), Vector2(size_left, size_bottom)));
- fit_child_in_rect(viewports[3], Rect2(Vector2(mid_w + h_sep / 2, mid_h + v_sep / 2), Vector2(size_right, size_bottom)));
+ fit_child_in_rect(viewports[0], Rect2(Vector2(), Vector2(size.width, size_top)));
+ fit_child_in_rect(viewports[2], Rect2(Vector2(0, mid_h + v_sep / 2), Vector2(size_left, size_bottom)));
+ fit_child_in_rect(viewports[3], Rect2(Vector2(mid_w + h_sep / 2, mid_h + v_sep / 2), Vector2(size_right, size_bottom)));
- } break;
- case VIEW_USE_3_VIEWPORTS_ALT: {
- for (int i = 0; i < 4; i++) {
- if (i == 1) {
- viewports[i]->hide();
- } else {
- viewports[i]->show();
+ } break;
+ case VIEW_USE_3_VIEWPORTS_ALT: {
+ for (int i = 0; i < 4; i++) {
+ if (i == 1) {
+ viewports[i]->hide();
+ } else {
+ viewports[i]->show();
+ }
}
- }
- fit_child_in_rect(viewports[0], Rect2(Vector2(), Vector2(size_left, size_top)));
- fit_child_in_rect(viewports[2], Rect2(Vector2(0, mid_h + v_sep / 2), Vector2(size_left, size_bottom)));
- fit_child_in_rect(viewports[3], Rect2(Vector2(mid_w + h_sep / 2, 0), Vector2(size_right, size.height)));
+ fit_child_in_rect(viewports[0], Rect2(Vector2(), Vector2(size_left, size_top)));
+ fit_child_in_rect(viewports[2], Rect2(Vector2(0, mid_h + v_sep / 2), Vector2(size_left, size_bottom)));
+ fit_child_in_rect(viewports[3], Rect2(Vector2(mid_w + h_sep / 2, 0), Vector2(size_right, size.height)));
- } break;
- case VIEW_USE_4_VIEWPORTS: {
- for (int i = 0; i < 4; i++) {
- viewports[i]->show();
- }
+ } break;
+ case VIEW_USE_4_VIEWPORTS: {
+ for (int i = 0; i < 4; i++) {
+ viewports[i]->show();
+ }
- fit_child_in_rect(viewports[0], Rect2(Vector2(), Vector2(size_left, size_top)));
- fit_child_in_rect(viewports[1], Rect2(Vector2(mid_w + h_sep / 2, 0), Vector2(size_right, size_top)));
- fit_child_in_rect(viewports[2], Rect2(Vector2(0, mid_h + v_sep / 2), Vector2(size_left, size_bottom)));
- fit_child_in_rect(viewports[3], Rect2(Vector2(mid_w + h_sep / 2, mid_h + v_sep / 2), Vector2(size_right, size_bottom)));
+ fit_child_in_rect(viewports[0], Rect2(Vector2(), Vector2(size_left, size_top)));
+ fit_child_in_rect(viewports[1], Rect2(Vector2(mid_w + h_sep / 2, 0), Vector2(size_right, size_top)));
+ fit_child_in_rect(viewports[2], Rect2(Vector2(0, mid_h + v_sep / 2), Vector2(size_left, size_bottom)));
+ fit_child_in_rect(viewports[3], Rect2(Vector2(mid_w + h_sep / 2, mid_h + v_sep / 2), Vector2(size_right, size_bottom)));
- } break;
- }
+ } break;
+ }
+ } break;
}
}
@@ -5854,6 +6007,7 @@ void fragment() {
rotate_gizmo[i] = Ref<ArrayMesh>(memnew(ArrayMesh));
scale_gizmo[i] = Ref<ArrayMesh>(memnew(ArrayMesh));
scale_plane_gizmo[i] = Ref<ArrayMesh>(memnew(ArrayMesh));
+ axis_gizmo[i] = Ref<ArrayMesh>(memnew(ArrayMesh));
Ref<StandardMaterial3D> mat = memnew(StandardMaterial3D);
mat->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED);
@@ -6175,6 +6329,22 @@ void fragment() {
plane_mat_hl->set_albedo(col.from_hsv(col.get_h(), 0.25, 1.0, 1));
plane_gizmo_color_hl[i] = plane_mat_hl; // needed, so we can draw planes from both sides
}
+
+ // Lines to visualize transforms locked to an axis/plane
+ {
+ Ref<SurfaceTool> surftool = memnew(SurfaceTool);
+ surftool->begin(Mesh::PRIMITIVE_LINE_STRIP);
+
+ Vector3 vec;
+ vec[i] = 1;
+
+ // line extending through infinity(ish)
+ surftool->add_vertex(vec * -1048576);
+ surftool->add_vertex(Vector3());
+ surftool->add_vertex(vec * 1048576);
+ surftool->set_material(mat_hl);
+ surftool->commit(axis_gizmo[i]);
+ }
}
}
@@ -6752,19 +6922,19 @@ void Node3DEditor::_add_environment_to_scene(bool p_already_added_sun) {
}
void Node3DEditor::_update_theme() {
- tool_button[Node3DEditor::TOOL_MODE_SELECT]->set_icon(get_theme_icon(SNAME("ToolSelect"), SNAME("EditorIcons")));
- tool_button[Node3DEditor::TOOL_MODE_MOVE]->set_icon(get_theme_icon(SNAME("ToolMove"), SNAME("EditorIcons")));
- tool_button[Node3DEditor::TOOL_MODE_ROTATE]->set_icon(get_theme_icon(SNAME("ToolRotate"), SNAME("EditorIcons")));
- tool_button[Node3DEditor::TOOL_MODE_SCALE]->set_icon(get_theme_icon(SNAME("ToolScale"), SNAME("EditorIcons")));
- tool_button[Node3DEditor::TOOL_MODE_LIST_SELECT]->set_icon(get_theme_icon(SNAME("ListSelect"), SNAME("EditorIcons")));
- tool_button[Node3DEditor::TOOL_LOCK_SELECTED]->set_icon(get_theme_icon(SNAME("Lock"), SNAME("EditorIcons")));
- tool_button[Node3DEditor::TOOL_UNLOCK_SELECTED]->set_icon(get_theme_icon(SNAME("Unlock"), SNAME("EditorIcons")));
- tool_button[Node3DEditor::TOOL_GROUP_SELECTED]->set_icon(get_theme_icon(SNAME("Group"), SNAME("EditorIcons")));
- tool_button[Node3DEditor::TOOL_UNGROUP_SELECTED]->set_icon(get_theme_icon(SNAME("Ungroup"), SNAME("EditorIcons")));
-
- tool_option_button[Node3DEditor::TOOL_OPT_LOCAL_COORDS]->set_icon(get_theme_icon(SNAME("Object"), SNAME("EditorIcons")));
- tool_option_button[Node3DEditor::TOOL_OPT_USE_SNAP]->set_icon(get_theme_icon(SNAME("Snap"), SNAME("EditorIcons")));
- tool_option_button[Node3DEditor::TOOL_OPT_OVERRIDE_CAMERA]->set_icon(get_theme_icon(SNAME("Camera3D"), SNAME("EditorIcons")));
+ tool_button[TOOL_MODE_SELECT]->set_icon(get_theme_icon(SNAME("ToolSelect"), SNAME("EditorIcons")));
+ tool_button[TOOL_MODE_MOVE]->set_icon(get_theme_icon(SNAME("ToolMove"), SNAME("EditorIcons")));
+ tool_button[TOOL_MODE_ROTATE]->set_icon(get_theme_icon(SNAME("ToolRotate"), SNAME("EditorIcons")));
+ tool_button[TOOL_MODE_SCALE]->set_icon(get_theme_icon(SNAME("ToolScale"), SNAME("EditorIcons")));
+ tool_button[TOOL_MODE_LIST_SELECT]->set_icon(get_theme_icon(SNAME("ListSelect"), SNAME("EditorIcons")));
+ tool_button[TOOL_LOCK_SELECTED]->set_icon(get_theme_icon(SNAME("Lock"), SNAME("EditorIcons")));
+ tool_button[TOOL_UNLOCK_SELECTED]->set_icon(get_theme_icon(SNAME("Unlock"), SNAME("EditorIcons")));
+ tool_button[TOOL_GROUP_SELECTED]->set_icon(get_theme_icon(SNAME("Group"), SNAME("EditorIcons")));
+ tool_button[TOOL_UNGROUP_SELECTED]->set_icon(get_theme_icon(SNAME("Ungroup"), SNAME("EditorIcons")));
+
+ tool_option_button[TOOL_OPT_LOCAL_COORDS]->set_icon(get_theme_icon(SNAME("Object"), SNAME("EditorIcons")));
+ tool_option_button[TOOL_OPT_USE_SNAP]->set_icon(get_theme_icon(SNAME("Snap"), SNAME("EditorIcons")));
+ tool_option_button[TOOL_OPT_OVERRIDE_CAMERA]->set_icon(get_theme_icon(SNAME("Camera3D"), SNAME("EditorIcons")));
view_menu->get_popup()->set_item_icon(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_1_VIEWPORT), get_theme_icon(SNAME("Panels1"), SNAME("EditorIcons")));
view_menu->get_popup()->set_item_icon(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS), get_theme_icon(SNAME("Panels2"), SNAME("EditorIcons")));
@@ -6793,14 +6963,15 @@ void Node3DEditor::_notification(int p_what) {
SceneTreeDock::get_singleton()->get_tree_editor()->connect("node_changed", callable_mp(this, &Node3DEditor::_refresh_menu_icons));
editor_selection->connect("selection_changed", callable_mp(this, &Node3DEditor::_selection_changed));
- editor->connect("stop_pressed", callable_mp(this, &Node3DEditor::_update_camera_override_button), make_binds(false));
- editor->connect("play_pressed", callable_mp(this, &Node3DEditor::_update_camera_override_button), make_binds(true));
+ EditorNode::get_singleton()->connect("stop_pressed", callable_mp(this, &Node3DEditor::_update_camera_override_button), make_binds(false));
+ EditorNode::get_singleton()->connect("play_pressed", callable_mp(this, &Node3DEditor::_update_camera_override_button), make_binds(true));
_update_preview_environment();
sun_state->set_custom_minimum_size(sun_vb->get_combined_minimum_size());
environ_state->set_custom_minimum_size(environ_vb->get_combined_minimum_size());
} break;
+
case NOTIFICATION_ENTER_TREE: {
_update_theme();
_register_all_gizmos();
@@ -6808,9 +6979,11 @@ void Node3DEditor::_notification(int p_what) {
_init_indicators();
update_all_gizmos();
} break;
+
case NOTIFICATION_EXIT_TREE: {
_finish_indicators();
} break;
+
case NOTIFICATION_THEME_CHANGED: {
_update_theme();
_update_gizmos_menu_theme();
@@ -6818,11 +6991,13 @@ void Node3DEditor::_notification(int p_what) {
sun_title->add_theme_font_override("font", get_theme_font(SNAME("title_font"), SNAME("Window")));
environ_title->add_theme_font_override("font", get_theme_font(SNAME("title_font"), SNAME("Window")));
} break;
+
case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
// Update grid color by rebuilding grid.
_finish_grid();
_init_grid();
} break;
+
case NOTIFICATION_VISIBILITY_CHANGED: {
if (!is_visible() && tool_option_button[TOOL_OPT_OVERRIDE_CAMERA]->is_pressed()) {
EditorDebuggerNode *debugger = EditorDebuggerNode::get_singleton();
@@ -6930,7 +7105,8 @@ void Node3DEditor::_request_gizmo(Object *p_obj) {
bool is_selected = (sp == selected);
- if (editor->get_edited_scene() && (sp == editor->get_edited_scene() || (sp->get_owner() && editor->get_edited_scene()->is_ancestor_of(sp)))) {
+ Node *edited_scene = EditorNode::get_singleton()->get_edited_scene();
+ if (edited_scene && (sp == edited_scene || (sp->get_owner() && edited_scene->is_ancestor_of(sp)))) {
for (int i = 0; i < gizmo_plugins_by_priority.size(); ++i) {
Ref<EditorNode3DGizmo> seg = gizmo_plugins_by_priority.write[i]->get_gizmo(sp);
@@ -7210,8 +7386,8 @@ void Node3DEditor::_load_default_preview_settings() {
sun_angle_altitude->set_value(-Math::rad2deg(sun_rotation.x));
sun_angle_azimuth->set_value(180.0 - Math::rad2deg(sun_rotation.y));
sun_direction->update();
- environ_sky_color->set_pick_color(Color::hex(0x91b2ceff));
- environ_ground_color->set_pick_color(Color::hex(0x1f1f21ff));
+ environ_sky_color->set_pick_color(Color(0.385, 0.454, 0.55));
+ environ_ground_color->set_pick_color(Color(0.2, 0.169, 0.133));
environ_energy->set_value(1.0);
environ_glow_button->set_pressed(true);
environ_tonemap_button->set_pressed(true);
@@ -7297,18 +7473,17 @@ void Node3DEditor::_sun_direction_angle_set() {
_preview_settings_changed();
}
-Node3DEditor::Node3DEditor(EditorNode *p_editor) {
+Node3DEditor::Node3DEditor() {
gizmo.visible = true;
gizmo.scale = 1.0;
viewport_environment = Ref<Environment>(memnew(Environment));
- undo_redo = p_editor->get_undo_redo();
+ undo_redo = EditorNode::get_singleton()->get_undo_redo();
VBoxContainer *vbc = this;
custom_camera = nullptr;
singleton = this;
- editor = p_editor;
- editor_selection = editor->get_editor_selection();
+ editor_selection = EditorNode::get_singleton()->get_editor_selection();
editor_selection->add_editor_plugin(this);
snap_enabled = false;
@@ -7540,7 +7715,7 @@ Node3DEditor::Node3DEditor(EditorNode *p_editor) {
p->set_hide_on_checkable_item_selection(false);
accept = memnew(AcceptDialog);
- editor->get_gui_base()->add_child(accept);
+ EditorNode::get_singleton()->get_gui_base()->add_child(accept);
p->add_radio_check_shortcut(ED_SHORTCUT("spatial_editor/1_viewport", TTR("1 Viewport"), KeyModifierMask::CMD + Key::KEY_1), MENU_VIEW_USE_1_VIEWPORT);
p->add_radio_check_shortcut(ED_SHORTCUT("spatial_editor/2_viewports", TTR("2 Viewports"), KeyModifierMask::CMD + Key::KEY_2), MENU_VIEW_USE_2_VIEWPORTS);
@@ -7587,7 +7762,7 @@ Node3DEditor::Node3DEditor(EditorNode *p_editor) {
shader_split->add_child(viewport_base);
viewport_base->set_v_size_flags(SIZE_EXPAND_FILL);
for (uint32_t i = 0; i < VIEWPORTS_COUNT; i++) {
- viewports[i] = memnew(Node3DEditorViewport(this, editor, i));
+ viewports[i] = memnew(Node3DEditorViewport(this, i));
viewports[i]->connect("toggle_maximize_view", callable_mp(this, &Node3DEditor::_toggle_maximize_view));
viewports[i]->connect("clicked", callable_mp(this, &Node3DEditor::_update_camera_override_viewport));
viewports[i]->assign_pending_data_pointers(preview_node, &preview_bounds, accept);
@@ -8036,11 +8211,10 @@ void Node3DEditor::remove_gizmo_plugin(Ref<EditorNode3DGizmoPlugin> p_plugin) {
_update_gizmos_menu();
}
-Node3DEditorPlugin::Node3DEditorPlugin(EditorNode *p_node) {
- editor = p_node;
- spatial_editor = memnew(Node3DEditor(p_node));
+Node3DEditorPlugin::Node3DEditorPlugin() {
+ spatial_editor = memnew(Node3DEditor);
spatial_editor->set_v_size_flags(Control::SIZE_EXPAND_FILL);
- editor->get_main_control()->add_child(spatial_editor);
+ EditorNode::get_singleton()->get_main_control()->add_child(spatial_editor);
spatial_editor->hide();
}
diff --git a/editor/plugins/node_3d_editor_plugin.h b/editor/plugins/node_3d_editor_plugin.h
index 20a782c8a8..5c0bfab34e 100644
--- a/editor/plugins/node_3d_editor_plugin.h
+++ b/editor/plugins/node_3d_editor_plugin.h
@@ -31,19 +31,23 @@
#ifndef NODE_3D_EDITOR_PLUGIN_H
#define NODE_3D_EDITOR_PLUGIN_H
-#include "editor/editor_node.h"
#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/color_picker.h"
#include "scene/gui/panel_container.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 EditorData;
class Node3DEditor;
class Node3DEditorViewport;
class SubViewportContainer;
@@ -194,7 +198,6 @@ private:
Node *target_node;
Point2 drop_pos;
- EditorNode *editor;
EditorData *editor_data;
EditorSelection *editor_selection;
UndoRedo *undo_redo;
@@ -247,6 +250,7 @@ private:
Point2 _point_to_screen(const Vector3 &p_point);
Transform3D _get_camera_transform() const;
int get_selected_count() const;
+ void cancel_transform();
Vector3 _get_camera_position() const;
Vector3 _get_camera_normal() const;
@@ -268,6 +272,7 @@ private:
ObjectID clicked;
Vector<_RayResult> selection_results;
bool clicked_wants_append;
+ bool selection_in_progress = false;
PopupMenu *selection_menu;
@@ -310,10 +315,13 @@ private:
Point2 mouse_pos;
Point2 original_mouse_pos;
bool snap = false;
+ bool show_rotation_line = false;
Ref<EditorNode3DGizmo> gizmo;
int gizmo_handle = 0;
bool gizmo_handle_secondary = false;
Variant gizmo_initial_value;
+ bool original_local;
+ bool instant;
} _edit;
struct Cursor {
@@ -347,7 +355,7 @@ private:
real_t zoom_indicator_delay;
int zoom_failed_attempts_count = 0;
- RID move_gizmo_instance[3], move_plane_gizmo_instance[3], rotate_gizmo_instance[4], scale_gizmo_instance[3], scale_plane_gizmo_instance[3];
+ RID move_gizmo_instance[3], move_plane_gizmo_instance[3], rotate_gizmo_instance[4], scale_gizmo_instance[3], scale_plane_gizmo_instance[3], axis_gizmo_instance[3];
String last_message;
String message;
@@ -370,7 +378,7 @@ private:
Node3DEditor *spatial_editor;
Camera3D *previewing;
- Camera3D *preview;
+ Camera3D *preview = nullptr;
bool previewing_cinema;
bool _is_node_locked(const Node *p_node);
@@ -402,6 +410,14 @@ private:
Transform3D _compute_transform(TransformMode p_mode, const Transform3D &p_original, const Transform3D &p_original_local, Vector3 p_motion, double p_extra, bool p_local, bool p_orthogonal);
+ void begin_transform(TransformMode p_mode, bool instant);
+ void commit_transform();
+ void update_transform(Point2 p_mousepos, bool p_shift);
+ void finish_transform();
+
+ void register_shortcut_action(const String &p_path, const String &p_name, Key p_keycode);
+ void shortcut_changed_callback(const Ref<Shortcut> p_shortcut, const String &p_shortcut_path);
+
protected:
void _notification(int p_what);
static void _bind_methods();
@@ -426,7 +442,7 @@ public:
SubViewport *get_viewport_node() { return viewport; }
Camera3D *get_camera_3d() { return camera; } // return the default camera object.
- Node3DEditorViewport(Node3DEditor *p_spatial_editor, EditorNode *p_editor, int p_index);
+ Node3DEditorViewport(Node3DEditor *p_spatial_editor, int p_index);
~Node3DEditorViewport();
};
@@ -521,7 +537,6 @@ public:
};
private:
- EditorNode *editor;
EditorSelection *editor_selection;
Node3DEditorViewportContainer *viewport_base;
@@ -546,7 +561,7 @@ private:
Camera3D::Projection grid_camera_last_update_perspective = Camera3D::PROJECTION_PERSPECTIVE;
Vector3 grid_camera_last_update_position = Vector3();
- Ref<ArrayMesh> move_gizmo[3], move_plane_gizmo[3], rotate_gizmo[4], scale_gizmo[3], scale_plane_gizmo[3];
+ Ref<ArrayMesh> move_gizmo[3], move_plane_gizmo[3], rotate_gizmo[4], scale_gizmo[3], scale_plane_gizmo[3], axis_gizmo[3];
Ref<StandardMaterial3D> gizmo_color[3];
Ref<StandardMaterial3D> plane_gizmo_color[3];
Ref<ShaderMaterial> rotate_gizmo_color[3];
@@ -773,12 +788,14 @@ public:
ToolMode get_tool_mode() const { return tool_mode; }
bool are_local_coords_enabled() const { return tool_option_button[Node3DEditor::TOOL_OPT_LOCAL_COORDS]->is_pressed(); }
+ void set_local_coords_enabled(bool on) const { tool_option_button[Node3DEditor::TOOL_OPT_LOCAL_COORDS]->set_pressed(on); }
bool is_snap_enabled() const { return snap_enabled ^ snap_key_enabled; }
double get_translate_snap() const;
double get_rotate_snap() const;
double get_scale_snap() const;
Ref<ArrayMesh> get_move_gizmo(int idx) const { return move_gizmo[idx]; }
+ Ref<ArrayMesh> get_axis_gizmo(int idx) const { return axis_gizmo[idx]; }
Ref<ArrayMesh> get_move_plane_gizmo(int idx) const { return move_plane_gizmo[idx]; }
Ref<ArrayMesh> get_rotate_gizmo(int idx) const { return rotate_gizmo[idx]; }
Ref<ArrayMesh> get_scale_gizmo(int idx) const { return scale_gizmo[idx]; }
@@ -844,7 +861,7 @@ public:
void edit(Node3D *p_spatial);
void clear();
- Node3DEditor(EditorNode *p_editor);
+ Node3DEditor();
~Node3DEditor();
};
@@ -852,7 +869,6 @@ class Node3DEditorPlugin : public EditorPlugin {
GDCLASS(Node3DEditorPlugin, EditorPlugin);
Node3DEditor *spatial_editor;
- EditorNode *editor;
public:
Node3DEditor *get_spatial_editor() { return spatial_editor; }
@@ -868,7 +884,7 @@ public:
virtual void edited_scene_changed() override;
- Node3DEditorPlugin(EditorNode *p_node);
+ Node3DEditorPlugin();
~Node3DEditorPlugin();
};
diff --git a/editor/plugins/occluder_instance_3d_editor_plugin.cpp b/editor/plugins/occluder_instance_3d_editor_plugin.cpp
index 2dd760275e..79cf4c394e 100644
--- a/editor/plugins/occluder_instance_3d_editor_plugin.cpp
+++ b/editor/plugins/occluder_instance_3d_editor_plugin.cpp
@@ -30,13 +30,16 @@
#include "occluder_instance_3d_editor_plugin.h"
+#include "editor/editor_file_dialog.h"
+#include "editor/editor_node.h"
+
void OccluderInstance3DEditorPlugin::_bake_select_file(const String &p_file) {
if (occluder_instance) {
OccluderInstance3D::BakeError err;
if (get_tree()->get_edited_scene_root() && get_tree()->get_edited_scene_root() == occluder_instance) {
- err = occluder_instance->bake(occluder_instance, p_file);
+ err = occluder_instance->bake_scene(occluder_instance, p_file);
} else {
- err = occluder_instance->bake(occluder_instance->get_parent(), p_file);
+ err = occluder_instance->bake_scene(occluder_instance->get_parent(), p_file);
}
switch (err) {
@@ -59,6 +62,10 @@ void OccluderInstance3DEditorPlugin::_bake_select_file(const String &p_file) {
EditorNode::get_singleton()->show_warning(TTR("No meshes to bake.\nMake sure there is at least one MeshInstance3D node in the scene whose visual layers are part of the OccluderInstance3D's Bake Mask property."));
break;
}
+ case OccluderInstance3D::BAKE_ERROR_CANT_SAVE: {
+ EditorNode::get_singleton()->show_warning(TTR("Could not save the new occluder at the specified path: ") + p_file);
+ break;
+ }
default: {
}
}
@@ -94,11 +101,10 @@ void OccluderInstance3DEditorPlugin::_bind_methods() {
ClassDB::bind_method("_bake", &OccluderInstance3DEditorPlugin::_bake);
}
-OccluderInstance3DEditorPlugin::OccluderInstance3DEditorPlugin(EditorNode *p_node) {
- editor = p_node;
+OccluderInstance3DEditorPlugin::OccluderInstance3DEditorPlugin() {
bake = memnew(Button);
bake->set_flat(true);
- bake->set_icon(editor->get_gui_base()->get_theme_icon(SNAME("Bake"), SNAME("EditorIcons")));
+ bake->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Bake"), SNAME("EditorIcons")));
bake->set_text(TTR("Bake Occluders"));
bake->hide();
bake->connect("pressed", Callable(this, "_bake"));
diff --git a/editor/plugins/occluder_instance_3d_editor_plugin.h b/editor/plugins/occluder_instance_3d_editor_plugin.h
index a9aa0b74e3..24f31b2ea8 100644
--- a/editor/plugins/occluder_instance_3d_editor_plugin.h
+++ b/editor/plugins/occluder_instance_3d_editor_plugin.h
@@ -31,18 +31,18 @@
#ifndef OCCLUDER_INSTANCE_3D_EDITOR_PLUGIN_H
#define OCCLUDER_INSTANCE_3D_EDITOR_PLUGIN_H
-#include "editor/editor_node.h"
#include "editor/editor_plugin.h"
#include "scene/3d/occluder_instance_3d.h"
#include "scene/resources/material.h"
+class EditorFileDialog;
+
class OccluderInstance3DEditorPlugin : public EditorPlugin {
GDCLASS(OccluderInstance3DEditorPlugin, EditorPlugin);
OccluderInstance3D *occluder_instance;
Button *bake;
- EditorNode *editor;
EditorFileDialog *file_dialog;
@@ -59,7 +59,7 @@ public:
virtual bool handles(Object *p_object) const override;
virtual void make_visible(bool p_visible) override;
- OccluderInstance3DEditorPlugin(EditorNode *p_node);
+ OccluderInstance3DEditorPlugin();
~OccluderInstance3DEditorPlugin();
};
diff --git a/editor/plugins/ot_features_plugin.cpp b/editor/plugins/ot_features_plugin.cpp
index d2daa4fa8d..9cd428a2d4 100644
--- a/editor/plugins/ot_features_plugin.cpp
+++ b/editor/plugins/ot_features_plugin.cpp
@@ -30,8 +30,6 @@
#include "ot_features_plugin.h"
-#include "editor/editor_scale.h"
-
void OpenTypeFeaturesEditor::_value_changed(double val) {
if (setting) {
return;
@@ -48,12 +46,15 @@ void OpenTypeFeaturesEditor::update_property() {
}
void OpenTypeFeaturesEditor::_notification(int p_what) {
- if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) {
- Color base = get_theme_color(SNAME("accent_color"), SNAME("Editor"));
-
- button->set_icon(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")));
- button->set_size(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons"))->get_size());
- spin->set_custom_label_color(true, base);
+ switch (p_what) {
+ case NOTIFICATION_ENTER_TREE:
+ case NOTIFICATION_THEME_CHANGED: {
+ Color base = get_theme_color(SNAME("accent_color"), SNAME("Editor"));
+
+ button->set_icon(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")));
+ button->set_size(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons"))->get_size());
+ spin->add_theme_color_override("label_color", base);
+ } break;
}
}
@@ -141,10 +142,13 @@ void OpenTypeFeaturesAdd::_features_menu() {
}
void OpenTypeFeaturesAdd::_notification(int p_what) {
- if (p_what == NOTIFICATION_THEME_CHANGED || p_what == NOTIFICATION_ENTER_TREE) {
- set_label("");
- button->set_icon(get_theme_icon(SNAME("Add"), SNAME("EditorIcons")));
- button->set_size(get_theme_icon(SNAME("Add"), SNAME("EditorIcons"))->get_size());
+ switch (p_what) {
+ case NOTIFICATION_THEME_CHANGED:
+ case NOTIFICATION_ENTER_TREE: {
+ set_label("");
+ button->set_icon(get_theme_icon(SNAME("Add"), SNAME("EditorIcons")));
+ button->set_size(get_theme_icon(SNAME("Add"), SNAME("EditorIcons"))->get_size());
+ } break;
}
}
@@ -201,7 +205,7 @@ bool EditorInspectorPluginOpenTypeFeatures::parse_property(Object *p_object, con
/*************************************************************************/
-OpenTypeFeaturesEditorPlugin::OpenTypeFeaturesEditorPlugin(EditorNode *p_node) {
+OpenTypeFeaturesEditorPlugin::OpenTypeFeaturesEditorPlugin() {
Ref<EditorInspectorPluginOpenTypeFeatures> ftr_plugin;
ftr_plugin.instantiate();
EditorInspector::add_inspector_plugin(ftr_plugin);
diff --git a/editor/plugins/ot_features_plugin.h b/editor/plugins/ot_features_plugin.h
index 073fe53a52..8c38d888de 100644
--- a/editor/plugins/ot_features_plugin.h
+++ b/editor/plugins/ot_features_plugin.h
@@ -31,7 +31,6 @@
#ifndef OT_FEATURES_PLUGIN_H
#define OT_FEATURES_PLUGIN_H
-#include "editor/editor_node.h"
#include "editor/editor_plugin.h"
#include "editor/editor_properties.h"
@@ -95,7 +94,7 @@ class OpenTypeFeaturesEditorPlugin : public EditorPlugin {
GDCLASS(OpenTypeFeaturesEditorPlugin, EditorPlugin);
public:
- OpenTypeFeaturesEditorPlugin(EditorNode *p_node);
+ OpenTypeFeaturesEditorPlugin();
virtual String get_name() const override { return "OpenTypeFeatures"; }
};
diff --git a/editor/plugins/packed_scene_translation_parser_plugin.cpp b/editor/plugins/packed_scene_translation_parser_plugin.cpp
index b492c27f41..9a8584f4a2 100644
--- a/editor/plugins/packed_scene_translation_parser_plugin.cpp
+++ b/editor/plugins/packed_scene_translation_parser_plugin.cpp
@@ -132,10 +132,7 @@ PackedSceneEditorTranslationParserPlugin::PackedSceneEditorTranslationParserPlug
lookup_properties.insert("script");
// Exception list (to prevent false positives).
- exception_list.insert("LineEdit", Vector<StringName>());
- exception_list["LineEdit"].append("text");
- exception_list.insert("TextEdit", Vector<StringName>());
- exception_list["TextEdit"].append("text");
- exception_list.insert("CodeEdit", Vector<StringName>());
- exception_list["CodeEdit"].append("text");
+ exception_list.insert("LineEdit", { "text" });
+ exception_list.insert("TextEdit", { "text" });
+ exception_list.insert("CodeEdit", { "text" });
}
diff --git a/editor/plugins/packed_scene_translation_parser_plugin.h b/editor/plugins/packed_scene_translation_parser_plugin.h
index fc19496eb6..ecd090b31b 100644
--- a/editor/plugins/packed_scene_translation_parser_plugin.h
+++ b/editor/plugins/packed_scene_translation_parser_plugin.h
@@ -37,9 +37,9 @@ class PackedSceneEditorTranslationParserPlugin : public EditorTranslationParserP
GDCLASS(PackedSceneEditorTranslationParserPlugin, EditorTranslationParserPlugin);
// Scene Node's properties that contain translation strings.
- Set<StringName> lookup_properties;
+ Set<String> lookup_properties;
// Properties from specific Nodes that should be ignored.
- Map<StringName, Vector<StringName>> exception_list;
+ Map<String, Vector<String>> exception_list;
public:
virtual Error parse_file(const String &p_path, Vector<String> *r_ids, Vector<Vector<String>> *r_ids_ctx_plural) override;
diff --git a/editor/plugins/path_2d_editor_plugin.cpp b/editor/plugins/path_2d_editor_plugin.cpp
index 702bc4a8ce..9e666ef70a 100644
--- a/editor/plugins/path_2d_editor_plugin.cpp
+++ b/editor/plugins/path_2d_editor_plugin.cpp
@@ -33,6 +33,7 @@
#include "canvas_item_editor_plugin.h"
#include "core/io/file_access.h"
#include "core/os/keyboard.h"
+#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
@@ -515,10 +516,9 @@ void Path2DEditor::_handle_option_pressed(int p_option) {
}
}
-Path2DEditor::Path2DEditor(EditorNode *p_editor) {
+Path2DEditor::Path2DEditor() {
canvas_item_editor = nullptr;
- editor = p_editor;
- undo_redo = editor->get_undo_redo();
+ undo_redo = EditorNode::get_singleton()->get_undo_redo();
mirror_handle_angle = true;
mirror_handle_length = true;
on_edge = false;
@@ -609,9 +609,8 @@ void Path2DEditorPlugin::make_visible(bool p_visible) {
}
}
-Path2DEditorPlugin::Path2DEditorPlugin(EditorNode *p_node) {
- editor = p_node;
- path2d_editor = memnew(Path2DEditor(p_node));
+Path2DEditorPlugin::Path2DEditorPlugin() {
+ path2d_editor = memnew(Path2DEditor);
CanvasItemEditor::get_singleton()->add_control_to_menu_panel(path2d_editor);
path2d_editor->hide();
}
diff --git a/editor/plugins/path_2d_editor_plugin.h b/editor/plugins/path_2d_editor_plugin.h
index 210a5a140d..926a859f8b 100644
--- a/editor/plugins/path_2d_editor_plugin.h
+++ b/editor/plugins/path_2d_editor_plugin.h
@@ -31,9 +31,9 @@
#ifndef PATH_2D_EDITOR_PLUGIN_H
#define PATH_2D_EDITOR_PLUGIN_H
-#include "editor/editor_node.h"
#include "editor/editor_plugin.h"
#include "scene/2d/path_2d.h"
+#include "scene/gui/separator.h"
class CanvasItemEditor;
@@ -43,7 +43,6 @@ class Path2DEditor : public HBoxContainer {
UndoRedo *undo_redo;
CanvasItemEditor *canvas_item_editor;
- EditorNode *editor;
Panel *panel;
Path2D *node;
@@ -105,14 +104,13 @@ public:
bool forward_gui_input(const Ref<InputEvent> &p_event);
void forward_canvas_draw_over_viewport(Control *p_overlay);
void edit(Node *p_path2d);
- Path2DEditor(EditorNode *p_editor);
+ Path2DEditor();
};
class Path2DEditorPlugin : public EditorPlugin {
GDCLASS(Path2DEditorPlugin, EditorPlugin);
Path2DEditor *path2d_editor;
- EditorNode *editor;
public:
virtual bool forward_canvas_gui_input(const Ref<InputEvent> &p_event) override { return path2d_editor->forward_gui_input(p_event); }
@@ -124,7 +122,7 @@ public:
virtual bool handles(Object *p_object) const override;
virtual void make_visible(bool p_visible) override;
- Path2DEditorPlugin(EditorNode *p_node);
+ Path2DEditorPlugin();
~Path2DEditorPlugin();
};
diff --git a/editor/plugins/path_3d_editor_plugin.cpp b/editor/plugins/path_3d_editor_plugin.cpp
index 7cc926f06c..e52b274908 100644
--- a/editor/plugins/path_3d_editor_plugin.cpp
+++ b/editor/plugins/path_3d_editor_plugin.cpp
@@ -33,6 +33,7 @@
#include "core/math/geometry_2d.h"
#include "core/math/geometry_3d.h"
#include "core/os/keyboard.h"
+#include "editor/editor_node.h"
#include "node_3d_editor_plugin.h"
#include "scene/resources/curve.h"
@@ -378,7 +379,7 @@ EditorPlugin::AfterGUIInput Path3DEditorPlugin::forward_spatial_gui_input(Camera
}
}
- UndoRedo *ur = editor->get_undo_redo();
+ UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
if (closest_seg != -1) {
//subdivide
@@ -420,21 +421,21 @@ EditorPlugin::AfterGUIInput Path3DEditorPlugin::forward_spatial_gui_input(Camera
// Find the offset and point index of the place to break up.
// Also check for the control points.
if (dist_to_p < click_dist) {
- UndoRedo *ur = editor->get_undo_redo();
+ UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
ur->create_action(TTR("Remove Path Point"));
ur->add_do_method(c.ptr(), "remove_point", i);
ur->add_undo_method(c.ptr(), "add_point", c->get_point_position(i), c->get_point_in(i), c->get_point_out(i), i);
ur->commit_action();
return EditorPlugin::AFTER_GUI_INPUT_STOP;
} else if (dist_to_p_out < click_dist) {
- UndoRedo *ur = editor->get_undo_redo();
+ UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
ur->create_action(TTR("Remove Out-Control Point"));
ur->add_do_method(c.ptr(), "set_point_out", i, Vector3());
ur->add_undo_method(c.ptr(), "set_point_out", i, c->get_point_out(i));
ur->commit_action();
return EditorPlugin::AFTER_GUI_INPUT_STOP;
} else if (dist_to_p_in < click_dist) {
- UndoRedo *ur = editor->get_undo_redo();
+ UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
ur->create_action(TTR("Remove In-Control Point"));
ur->add_do_method(c.ptr(), "set_point_in", i, Vector3());
ur->add_undo_method(c.ptr(), "set_point_in", i, c->get_point_in(i));
@@ -513,7 +514,7 @@ void Path3DEditorPlugin::_close_curve() {
if (c->get_point_position(0) == c->get_point_position(c->get_point_count() - 1)) {
return;
}
- UndoRedo *ur = editor->get_undo_redo();
+ UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
ur->create_action(TTR("Close Curve"));
ur->add_do_method(c.ptr(), "add_point", c->get_point_position(0), c->get_point_in(0), c->get_point_out(0), -1);
ur->add_undo_method(c.ptr(), "remove_point", c->get_point_count());
@@ -570,9 +571,8 @@ void Path3DEditorPlugin::_bind_methods() {
Path3DEditorPlugin *Path3DEditorPlugin::singleton = nullptr;
-Path3DEditorPlugin::Path3DEditorPlugin(EditorNode *p_node) {
+Path3DEditorPlugin::Path3DEditorPlugin() {
path = nullptr;
- editor = p_node;
singleton = this;
mirror_handle_angle = true;
mirror_handle_length = true;
diff --git a/editor/plugins/path_3d_editor_plugin.h b/editor/plugins/path_3d_editor_plugin.h
index b877e2ae17..3c6ca65437 100644
--- a/editor/plugins/path_3d_editor_plugin.h
+++ b/editor/plugins/path_3d_editor_plugin.h
@@ -35,6 +35,7 @@
#include "editor/plugins/node_3d_editor_gizmos.h"
#include "scene/3d/camera_3d.h"
#include "scene/3d/path_3d.h"
+#include "scene/gui/separator.h"
class Path3DGizmo : public EditorNode3DGizmo {
GDCLASS(Path3DGizmo, EditorNode3DGizmo);
@@ -76,8 +77,6 @@ class Path3DEditorPlugin : public EditorPlugin {
Button *curve_close;
MenuButton *handle_menu;
- EditorNode *editor;
-
Path3D *path;
void _update_theme();
@@ -115,7 +114,7 @@ public:
bool is_handle_clicked() { return handle_clicked; }
void set_handle_clicked(bool clicked) { handle_clicked = clicked; }
- Path3DEditorPlugin(EditorNode *p_node);
+ Path3DEditorPlugin();
~Path3DEditorPlugin();
};
diff --git a/editor/plugins/physical_bone_3d_editor_plugin.cpp b/editor/plugins/physical_bone_3d_editor_plugin.cpp
index 9d69bbaa0b..e815a9c9f6 100644
--- a/editor/plugins/physical_bone_3d_editor_plugin.cpp
+++ b/editor/plugins/physical_bone_3d_editor_plugin.cpp
@@ -31,7 +31,6 @@
#include "physical_bone_3d_editor_plugin.h"
#include "editor/plugins/node_3d_editor_plugin.h"
-#include "scene/3d/physics_body_3d.h"
void PhysicalBone3DEditor::_bind_methods() {
}
@@ -47,8 +46,7 @@ void PhysicalBone3DEditor::_set_move_joint() {
}
}
-PhysicalBone3DEditor::PhysicalBone3DEditor(EditorNode *p_editor) :
- editor(p_editor) {
+PhysicalBone3DEditor::PhysicalBone3DEditor() {
spatial_editor_hb = memnew(HBoxContainer);
spatial_editor_hb->set_h_size_flags(Control::SIZE_EXPAND_FILL);
spatial_editor_hb->set_alignment(BoxContainer::ALIGNMENT_BEGIN);
@@ -84,9 +82,8 @@ void PhysicalBone3DEditor::show() {
spatial_editor_hb->show();
}
-PhysicalBone3DEditorPlugin::PhysicalBone3DEditorPlugin(EditorNode *p_editor) :
- editor(p_editor),
- physical_bone_editor(editor) {}
+PhysicalBone3DEditorPlugin::PhysicalBone3DEditorPlugin() :
+ physical_bone_editor() {}
void PhysicalBone3DEditorPlugin::make_visible(bool p_visible) {
if (p_visible) {
diff --git a/editor/plugins/physical_bone_3d_editor_plugin.h b/editor/plugins/physical_bone_3d_editor_plugin.h
index d30222d7e6..4051644b54 100644
--- a/editor/plugins/physical_bone_3d_editor_plugin.h
+++ b/editor/plugins/physical_bone_3d_editor_plugin.h
@@ -31,12 +31,14 @@
#ifndef PHYSICAL_BONE_PLUGIN_H
#define PHYSICAL_BONE_PLUGIN_H
-#include "editor/editor_node.h"
+#include "editor/editor_plugin.h"
+#include "scene/3d/physics_body_3d.h"
+#include "scene/gui/box_container.h"
+#include "scene/gui/button.h"
class PhysicalBone3DEditor : public Object {
GDCLASS(PhysicalBone3DEditor, Object);
- EditorNode *editor;
HBoxContainer *spatial_editor_hb;
Button *button_transform_joint;
@@ -50,7 +52,7 @@ private:
void _set_move_joint();
public:
- PhysicalBone3DEditor(EditorNode *p_editor);
+ PhysicalBone3DEditor();
~PhysicalBone3DEditor() {}
void set_selected(PhysicalBone3D *p_pb);
@@ -62,7 +64,6 @@ public:
class PhysicalBone3DEditorPlugin : public EditorPlugin {
GDCLASS(PhysicalBone3DEditorPlugin, EditorPlugin);
- EditorNode *editor;
PhysicalBone3D *selected = nullptr;
PhysicalBone3DEditor physical_bone_editor;
@@ -72,7 +73,7 @@ public:
virtual void make_visible(bool p_visible) override;
virtual void edit(Object *p_node) override;
- PhysicalBone3DEditorPlugin(EditorNode *p_editor);
+ PhysicalBone3DEditorPlugin();
};
#endif
diff --git a/editor/plugins/polygon_2d_editor_plugin.cpp b/editor/plugins/polygon_2d_editor_plugin.cpp
index b116f8ff6d..2812c4aaaf 100644
--- a/editor/plugins/polygon_2d_editor_plugin.cpp
+++ b/editor/plugins/polygon_2d_editor_plugin.cpp
@@ -30,15 +30,16 @@
#include "polygon_2d_editor_plugin.h"
-#include "canvas_item_editor_plugin.h"
-#include "core/input/input.h"
-#include "core/io/file_access.h"
+#include "core/input/input_event.h"
#include "core/math/geometry_2d.h"
-#include "core/os/keyboard.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/plugins/canvas_item_editor_plugin.h"
#include "scene/2d/skeleton_2d.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/view_panner.h"
Node2D *Polygon2DEditor::_get_node() const {
@@ -68,6 +69,7 @@ void Polygon2DEditor::_notification(int p_what) {
case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
uv_panner->setup((ViewPanner::ControlScheme)EDITOR_GET("editors/panning/sub_editors_panning_scheme").operator int(), ED_GET_SHORTCUT("canvas_item_editor/pan_view"), bool(EditorSettings::get_singleton()->get("editors/panning/simple_panning")));
} break;
+
case NOTIFICATION_READY: {
button_uv->set_icon(get_theme_icon(SNAME("Uv"), SNAME("EditorIcons")));
@@ -95,6 +97,7 @@ void Polygon2DEditor::_notification(int p_what) {
uv_edit_draw->add_theme_style_override("panel", get_theme_stylebox(SNAME("bg"), SNAME("Tree")));
bone_scroll->add_theme_style_override("bg", get_theme_stylebox(SNAME("bg"), SNAME("Tree")));
} break;
+
case NOTIFICATION_VISIBILITY_CHANGED: {
if (!is_visible()) {
uv_edit->hide();
@@ -1059,7 +1062,7 @@ void Polygon2DEditor::_uv_draw() {
for (int i = 0; i < uvs.size(); i++) {
int next = uv_draw_max > 0 ? (i + 1) % uv_draw_max : 0;
- if (i < uv_draw_max && uv_drag && uv_move_current == UV_MODE_EDIT_POINT && EDITOR_DEF("editors/polygon_editor/show_previous_outline", true)) {
+ if (i < uv_draw_max && uv_drag && uv_move_current == UV_MODE_EDIT_POINT && EDITOR_GET("editors/polygon_editor/show_previous_outline")) {
uv_edit_draw->draw_line(mtx.xform(points_prev[i]), mtx.xform(points_prev[next]), prev_color, Math::round(EDSCALE));
}
@@ -1067,7 +1070,7 @@ void Polygon2DEditor::_uv_draw() {
if (uv_create && i == uvs.size() - 1) {
next_point = uv_create_to;
}
- if (i < uv_draw_max /*&& polygons.size() == 0 && polygon_create.size() == 0*/) { //if using or creating polygons, do not show outline (will show polygons instead)
+ if (i < uv_draw_max) { // If using or creating polygons, do not show outline (will show polygons instead).
uv_edit_draw->draw_line(mtx.xform(uvs[i]), mtx.xform(next_point), poly_line_color, Math::round(EDSCALE));
}
}
@@ -1225,8 +1228,8 @@ Vector2 Polygon2DEditor::snap_point(Vector2 p_target) const {
return p_target;
}
-Polygon2DEditor::Polygon2DEditor(EditorNode *p_editor) :
- AbstractPolygon2DEditor(p_editor) {
+Polygon2DEditor::Polygon2DEditor() :
+ AbstractPolygon2DEditor() {
node = nullptr;
snap_offset = EditorSettings::get_singleton()->get_project_metadata("polygon_2d_uv_editor", "snap_offset", Vector2());
snap_step = EditorSettings::get_singleton()->get_project_metadata("polygon_2d_uv_editor", "snap_step", Vector2(10, 10));
@@ -1486,6 +1489,6 @@ Polygon2DEditor::Polygon2DEditor(EditorNode *p_editor) :
uv_edit_draw->set_clip_contents(true);
}
-Polygon2DEditorPlugin::Polygon2DEditorPlugin(EditorNode *p_node) :
- AbstractPolygon2DEditorPlugin(p_node, memnew(Polygon2DEditor(p_node)), "Polygon2D") {
+Polygon2DEditorPlugin::Polygon2DEditorPlugin() :
+ AbstractPolygon2DEditorPlugin(memnew(Polygon2DEditor), "Polygon2D") {
}
diff --git a/editor/plugins/polygon_2d_editor_plugin.h b/editor/plugins/polygon_2d_editor_plugin.h
index 0f10b6b645..0a5def902c 100644
--- a/editor/plugins/polygon_2d_editor_plugin.h
+++ b/editor/plugins/polygon_2d_editor_plugin.h
@@ -33,8 +33,11 @@
#include "editor/plugins/abstract_polygon_2d_editor.h"
-class ViewPanner;
+class HSlider;
+class Panel;
class ScrollContainer;
+class SpinBox;
+class ViewPanner;
class Polygon2DEditor : public AbstractPolygon2DEditor {
GDCLASS(Polygon2DEditor, AbstractPolygon2DEditor);
@@ -167,14 +170,14 @@ protected:
Vector2 snap_point(Vector2 p_target) const;
public:
- Polygon2DEditor(EditorNode *p_editor);
+ Polygon2DEditor();
};
class Polygon2DEditorPlugin : public AbstractPolygon2DEditorPlugin {
GDCLASS(Polygon2DEditorPlugin, AbstractPolygon2DEditorPlugin);
public:
- Polygon2DEditorPlugin(EditorNode *p_node);
+ Polygon2DEditorPlugin();
};
#endif // POLYGON_2D_EDITOR_PLUGIN_H
diff --git a/editor/plugins/collision_polygon_3d_editor_plugin.cpp b/editor/plugins/polygon_3d_editor_plugin.cpp
index 52651ae380..2d4812c55b 100644
--- a/editor/plugins/collision_polygon_3d_editor_plugin.cpp
+++ b/editor/plugins/polygon_3d_editor_plugin.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* collision_polygon_3d_editor_plugin.cpp */
+/* polygon_3d_editor_plugin.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,26 +28,29 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "collision_polygon_3d_editor_plugin.h"
+#include "polygon_3d_editor_plugin.h"
#include "canvas_item_editor_plugin.h"
+#include "core/core_string_names.h"
#include "core/input/input.h"
#include "core/io/file_access.h"
#include "core/math/geometry_2d.h"
#include "core/os/keyboard.h"
+#include "editor/editor_node.h"
#include "editor/editor_settings.h"
#include "node_3d_editor_plugin.h"
#include "scene/3d/camera_3d.h"
-void CollisionPolygon3DEditor::_notification(int p_what) {
+void Polygon3DEditor::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_READY: {
button_create->set_icon(get_theme_icon(SNAME("Edit"), SNAME("EditorIcons")));
button_edit->set_icon(get_theme_icon(SNAME("MovePoint"), SNAME("EditorIcons")));
button_edit->set_pressed(true);
- get_tree()->connect("node_removed", callable_mp(this, &CollisionPolygon3DEditor::_node_removed));
+ get_tree()->connect("node_removed", callable_mp(this, &Polygon3DEditor::_node_removed));
} break;
+
case NOTIFICATION_PROCESS: {
if (!node) {
return;
@@ -62,7 +65,7 @@ void CollisionPolygon3DEditor::_notification(int p_what) {
}
}
-void CollisionPolygon3DEditor::_node_removed(Node *p_node) {
+void Polygon3DEditor::_node_removed(Node *p_node) {
if (p_node == node) {
node = nullptr;
if (imgeom->get_parent() == p_node) {
@@ -73,7 +76,7 @@ void CollisionPolygon3DEditor::_node_removed(Node *p_node) {
}
}
-void CollisionPolygon3DEditor::_menu_option(int p_option) {
+void Polygon3DEditor::_menu_option(int p_option) {
switch (p_option) {
case MODE_CREATE: {
mode = MODE_CREATE;
@@ -88,10 +91,12 @@ void CollisionPolygon3DEditor::_menu_option(int p_option) {
}
}
-void CollisionPolygon3DEditor::_wip_close() {
+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.");
undo_redo->create_action(TTR("Create Polygon3D"));
- undo_redo->add_undo_method(node, "set_polygon", node->call("get_polygon"));
- undo_redo->add_do_method(node, "set_polygon", wip);
+ undo_redo->add_undo_method(obj, "set_polygon", obj->call("get_polygon"));
+ undo_redo->add_do_method(obj, "set_polygon", wip);
undo_redo->add_do_method(this, "_polygon_draw");
undo_redo->add_undo_method(this, "_polygon_draw");
wip.clear();
@@ -103,11 +108,12 @@ void CollisionPolygon3DEditor::_wip_close() {
undo_redo->commit_action();
}
-EditorPlugin::AfterGUIInput CollisionPolygon3DEditor::forward_spatial_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event) {
+EditorPlugin::AfterGUIInput Polygon3DEditor::forward_spatial_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event) {
if (!node) {
return EditorPlugin::AFTER_GUI_INPUT_PASS;
}
+ Object *obj = node_resource.is_valid() ? (Object *)node_resource.ptr() : node;
Transform3D gt = node->get_global_transform();
Transform3D gi = gt.affine_inverse();
float depth = _get_depth() * 0.5;
@@ -135,7 +141,7 @@ EditorPlugin::AfterGUIInput CollisionPolygon3DEditor::forward_spatial_gui_input(
//Let the snap happen when the point is being moved, instead.
//cpoint = CanvasItemEditor::get_singleton()->snap_point(cpoint);
- Vector<Vector2> poly = node->call("get_polygon");
+ PackedVector2Array poly = _get_polygon();
//first check if a point is to be added (segment split)
real_t grab_threshold = EDITOR_GET("editors/polygon_editor/point_grab_radius");
@@ -178,9 +184,9 @@ EditorPlugin::AfterGUIInput CollisionPolygon3DEditor::forward_spatial_gui_input(
if (mb->is_ctrl_pressed()) {
if (poly.size() < 3) {
undo_redo->create_action(TTR("Edit Poly"));
- undo_redo->add_undo_method(node, "set_polygon", poly);
+ undo_redo->add_undo_method(obj, "set_polygon", poly);
poly.push_back(cpoint);
- undo_redo->add_do_method(node, "set_polygon", poly);
+ undo_redo->add_do_method(obj, "set_polygon", poly);
undo_redo->add_do_method(this, "_polygon_draw");
undo_redo->add_undo_method(this, "_polygon_draw");
undo_redo->commit_action();
@@ -215,7 +221,7 @@ EditorPlugin::AfterGUIInput CollisionPolygon3DEditor::forward_spatial_gui_input(
poly.insert(closest_idx + 1, cpoint);
edited_point = closest_idx + 1;
edited_point_pos = cpoint;
- node->call("set_polygon", poly);
+ _set_polygon(poly);
_polygon_draw();
snap_ignore = true;
@@ -256,8 +262,8 @@ EditorPlugin::AfterGUIInput CollisionPolygon3DEditor::forward_spatial_gui_input(
ERR_FAIL_INDEX_V(edited_point, poly.size(), EditorPlugin::AFTER_GUI_INPUT_PASS);
poly.write[edited_point] = edited_point_pos;
undo_redo->create_action(TTR("Edit Poly"));
- undo_redo->add_do_method(node, "set_polygon", poly);
- undo_redo->add_undo_method(node, "set_polygon", pre_move_edit);
+ undo_redo->add_do_method(obj, "set_polygon", poly);
+ undo_redo->add_undo_method(obj, "set_polygon", pre_move_edit);
undo_redo->add_do_method(this, "_polygon_draw");
undo_redo->add_undo_method(this, "_polygon_draw");
undo_redo->commit_action();
@@ -284,9 +290,9 @@ EditorPlugin::AfterGUIInput CollisionPolygon3DEditor::forward_spatial_gui_input(
if (closest_idx >= 0) {
undo_redo->create_action(TTR("Edit Poly (Remove Point)"));
- undo_redo->add_undo_method(node, "set_polygon", poly);
+ undo_redo->add_undo_method(obj, "set_polygon", poly);
poly.remove_at(closest_idx);
- undo_redo->add_do_method(node, "set_polygon", poly);
+ undo_redo->add_do_method(obj, "set_polygon", poly);
undo_redo->add_do_method(this, "_polygon_draw");
undo_redo->add_undo_method(this, "_polygon_draw");
undo_redo->commit_action();
@@ -335,25 +341,40 @@ EditorPlugin::AfterGUIInput CollisionPolygon3DEditor::forward_spatial_gui_input(
return EditorPlugin::AFTER_GUI_INPUT_PASS;
}
-float CollisionPolygon3DEditor::_get_depth() {
- if (bool(node->call("_has_editable_3d_polygon_no_depth"))) {
- return 0;
+float Polygon3DEditor::_get_depth() {
+ Object *obj = node_resource.is_valid() ? (Object *)node_resource.ptr() : node;
+ ERR_FAIL_COND_V_MSG(!obj, 0.0f, "Edited object is not valid.");
+
+ if (bool(obj->call("_has_editable_3d_polygon_no_depth"))) {
+ return 0.0f;
}
- return float(node->call("get_depth"));
+ return float(obj->call("get_depth"));
}
-void CollisionPolygon3DEditor::_polygon_draw() {
+PackedVector2Array Polygon3DEditor::_get_polygon() {
+ Object *obj = node_resource.is_valid() ? (Object *)node_resource.ptr() : node;
+ ERR_FAIL_COND_V_MSG(!obj, PackedVector2Array(), "Edited object is not valid.");
+ return PackedVector2Array(obj->call("get_polygon"));
+}
+
+void Polygon3DEditor::_set_polygon(PackedVector2Array p_poly) {
+ Object *obj = node_resource.is_valid() ? (Object *)node_resource.ptr() : node;
+ ERR_FAIL_COND_MSG(!obj, "Edited object is not valid.");
+ obj->call("set_polygon", p_poly);
+}
+
+void Polygon3DEditor::_polygon_draw() {
if (!node) {
return;
}
- Vector<Vector2> poly;
+ PackedVector2Array poly;
if (wip_active) {
poly = wip;
} else {
- poly = node->call("get_polygon");
+ poly = _get_polygon();
}
float depth = _get_depth() * 0.5;
@@ -464,23 +485,32 @@ void CollisionPolygon3DEditor::_polygon_draw() {
m->surface_set_material(0, handle_material);
}
-void CollisionPolygon3DEditor::edit(Node *p_collision_polygon) {
- if (p_collision_polygon) {
- node = Object::cast_to<Node3D>(p_collision_polygon);
+void Polygon3DEditor::edit(Node *p_node) {
+ if (p_node) {
+ node = Object::cast_to<Node3D>(p_node);
+ node_resource = node->call("_get_editable_3d_polygon_resource");
+
+ if (node_resource.is_valid()) {
+ node_resource->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Polygon3DEditor::_polygon_draw));
+ }
//Enable the pencil tool if the polygon is empty
- if (Vector<Vector2>(node->call("get_polygon")).size() == 0) {
+ if (_get_polygon().is_empty()) {
_menu_option(MODE_CREATE);
}
wip.clear();
wip_active = false;
edited_point = -1;
- p_collision_polygon->add_child(imgeom);
+ p_node->add_child(imgeom);
_polygon_draw();
set_process(true);
prev_depth = -1;
} else {
node = nullptr;
+ if (node_resource.is_valid()) {
+ node_resource->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Polygon3DEditor::_polygon_draw));
+ }
+ node_resource.unref();
if (imgeom->get_parent()) {
imgeom->get_parent()->remove_child(imgeom);
@@ -490,26 +520,25 @@ void CollisionPolygon3DEditor::edit(Node *p_collision_polygon) {
}
}
-void CollisionPolygon3DEditor::_bind_methods() {
- ClassDB::bind_method(D_METHOD("_polygon_draw"), &CollisionPolygon3DEditor::_polygon_draw);
+void Polygon3DEditor::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("_polygon_draw"), &Polygon3DEditor::_polygon_draw);
}
-CollisionPolygon3DEditor::CollisionPolygon3DEditor(EditorNode *p_editor) {
+Polygon3DEditor::Polygon3DEditor() {
node = nullptr;
- editor = p_editor;
undo_redo = EditorNode::get_undo_redo();
add_child(memnew(VSeparator));
button_create = memnew(Button);
button_create->set_flat(true);
add_child(button_create);
- button_create->connect("pressed", callable_mp(this, &CollisionPolygon3DEditor::_menu_option), varray(MODE_CREATE));
+ button_create->connect("pressed", callable_mp(this, &Polygon3DEditor::_menu_option), varray(MODE_CREATE));
button_create->set_toggle_mode(true);
button_edit = memnew(Button);
button_edit->set_flat(true);
add_child(button_edit);
- button_edit->connect("pressed", callable_mp(this, &CollisionPolygon3DEditor::_menu_option), varray(MODE_EDIT));
+ button_edit->connect("pressed", callable_mp(this, &Polygon3DEditor::_menu_option), varray(MODE_EDIT));
button_edit->set_toggle_mode(true);
mode = MODE_EDIT;
@@ -532,7 +561,7 @@ CollisionPolygon3DEditor::CollisionPolygon3DEditor(EditorNode *p_editor) {
handle_material->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA);
handle_material->set_flag(StandardMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
handle_material->set_flag(StandardMaterial3D::FLAG_SRGB_VERTEX_COLOR, true);
- Ref<Texture2D> handle = editor->get_gui_base()->get_theme_icon(SNAME("Editor3DHandle"), SNAME("EditorIcons"));
+ Ref<Texture2D> handle = EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Editor3DHandle"), SNAME("EditorIcons"));
handle_material->set_point_size(handle->get_width());
handle_material->set_texture(StandardMaterial3D::TEXTURE_ALBEDO, handle);
@@ -545,12 +574,12 @@ CollisionPolygon3DEditor::CollisionPolygon3DEditor(EditorNode *p_editor) {
snap_ignore = false;
}
-CollisionPolygon3DEditor::~CollisionPolygon3DEditor() {
+Polygon3DEditor::~Polygon3DEditor() {
memdelete(imgeom);
}
void Polygon3DEditorPlugin::edit(Object *p_object) {
- collision_polygon_editor->edit(Object::cast_to<Node>(p_object));
+ polygon_editor->edit(Object::cast_to<Node>(p_object));
}
bool Polygon3DEditorPlugin::handles(Object *p_object) const {
@@ -559,19 +588,18 @@ bool Polygon3DEditorPlugin::handles(Object *p_object) const {
void Polygon3DEditorPlugin::make_visible(bool p_visible) {
if (p_visible) {
- collision_polygon_editor->show();
+ polygon_editor->show();
} else {
- collision_polygon_editor->hide();
- collision_polygon_editor->edit(nullptr);
+ polygon_editor->hide();
+ polygon_editor->edit(nullptr);
}
}
-Polygon3DEditorPlugin::Polygon3DEditorPlugin(EditorNode *p_node) {
- editor = p_node;
- collision_polygon_editor = memnew(CollisionPolygon3DEditor(p_node));
- Node3DEditor::get_singleton()->add_control_to_menu_panel(collision_polygon_editor);
+Polygon3DEditorPlugin::Polygon3DEditorPlugin() {
+ polygon_editor = memnew(Polygon3DEditor);
+ Node3DEditor::get_singleton()->add_control_to_menu_panel(polygon_editor);
- collision_polygon_editor->hide();
+ polygon_editor->hide();
}
Polygon3DEditorPlugin::~Polygon3DEditorPlugin() {
diff --git a/editor/plugins/collision_polygon_3d_editor_plugin.h b/editor/plugins/polygon_3d_editor_plugin.h
index cd8c857398..e92dcaf319 100644
--- a/editor/plugins/collision_polygon_3d_editor_plugin.h
+++ b/editor/plugins/polygon_3d_editor_plugin.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* collision_polygon_3d_editor_plugin.h */
+/* polygon_3d_editor_plugin.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,10 +28,9 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef COLLISION_POLYGON_EDITOR_PLUGIN_H
-#define COLLISION_POLYGON_EDITOR_PLUGIN_H
+#ifndef POLYGON_3D_EDITOR_PLUGIN_H
+#define POLYGON_3D_EDITOR_PLUGIN_H
-#include "editor/editor_node.h"
#include "editor/editor_plugin.h"
#include "scene/3d/collision_polygon_3d.h"
#include "scene/3d/mesh_instance_3d.h"
@@ -39,8 +38,8 @@
class CanvasItemEditor;
-class CollisionPolygon3DEditor : public HBoxContainer {
- GDCLASS(CollisionPolygon3DEditor, HBoxContainer);
+class Polygon3DEditor : public HBoxContainer {
+ GDCLASS(Polygon3DEditor, HBoxContainer);
UndoRedo *undo_redo;
enum Mode {
@@ -57,9 +56,9 @@ class CollisionPolygon3DEditor : public HBoxContainer {
Ref<StandardMaterial3D> line_material;
Ref<StandardMaterial3D> handle_material;
- EditorNode *editor;
Panel *panel;
Node3D *node;
+ Ref<Resource> node_resource;
Ref<ImmediateMesh> imesh;
MeshInstance3D *imgeom;
MeshInstance3D *pointsm;
@@ -69,8 +68,8 @@ class CollisionPolygon3DEditor : public HBoxContainer {
int edited_point;
Vector2 edited_point_pos;
- Vector<Vector2> pre_move_edit;
- Vector<Vector2> wip;
+ PackedVector2Array pre_move_edit;
+ PackedVector2Array wip;
bool wip_active;
bool snap_ignore;
@@ -81,6 +80,8 @@ class CollisionPolygon3DEditor : public HBoxContainer {
void _menu_option(int p_option);
float _get_depth();
+ PackedVector2Array _get_polygon();
+ void _set_polygon(PackedVector2Array p_poly);
protected:
void _notification(int p_what);
@@ -89,19 +90,18 @@ protected:
public:
virtual EditorPlugin::AfterGUIInput forward_spatial_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event);
- void edit(Node *p_collision_polygon);
- CollisionPolygon3DEditor(EditorNode *p_editor);
- ~CollisionPolygon3DEditor();
+ void edit(Node *p_node);
+ Polygon3DEditor();
+ ~Polygon3DEditor();
};
class Polygon3DEditorPlugin : public EditorPlugin {
GDCLASS(Polygon3DEditorPlugin, EditorPlugin);
- CollisionPolygon3DEditor *collision_polygon_editor;
- EditorNode *editor;
+ Polygon3DEditor *polygon_editor;
public:
- virtual EditorPlugin::AfterGUIInput forward_spatial_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event) override { return collision_polygon_editor->forward_spatial_gui_input(p_camera, p_event); }
+ virtual EditorPlugin::AfterGUIInput forward_spatial_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event) override { return polygon_editor->forward_spatial_gui_input(p_camera, p_event); }
virtual String get_name() const override { return "Polygon3DEditor"; }
bool has_main_screen() const override { return false; }
@@ -109,8 +109,8 @@ public:
virtual bool handles(Object *p_object) const override;
virtual void make_visible(bool p_visible) override;
- Polygon3DEditorPlugin(EditorNode *p_node);
+ Polygon3DEditorPlugin();
~Polygon3DEditorPlugin();
};
-#endif // COLLISION_POLYGON_EDITOR_PLUGIN_H
+#endif // POLYGON_3D_EDITOR_PLUGIN_H
diff --git a/editor/plugins/replication_editor_plugin.cpp b/editor/plugins/replication_editor_plugin.cpp
index 93f4a853f3..e4c1c69804 100644
--- a/editor/plugins/replication_editor_plugin.cpp
+++ b/editor/plugins/replication_editor_plugin.cpp
@@ -30,6 +30,7 @@
#include "replication_editor_plugin.h"
+#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/inspector_dock.h"
#include "scene/gui/dialogs.h"
@@ -37,8 +38,7 @@
#include "scene/multiplayer/multiplayer_synchronizer.h"
/// ReplicationEditor
-ReplicationEditor::ReplicationEditor(EditorNode *p_editor) {
- editor = p_editor;
+ReplicationEditor::ReplicationEditor() {
set_v_size_flags(SIZE_EXPAND_FILL);
set_custom_minimum_size(Size2(0, 200) * EDSCALE);
@@ -94,10 +94,15 @@ void ReplicationEditor::_bind_methods() {
}
void ReplicationEditor::_notification(int p_what) {
- if (p_what == NOTIFICATION_ENTER_TREE || p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) {
- add_theme_style_override("panel", editor->get_gui_base()->get_theme_stylebox(SNAME("panel"), SNAME("Panel")));
- } else if (p_what == NOTIFICATION_VISIBILITY_CHANGED) {
- update_keying();
+ switch (p_what) {
+ case NOTIFICATION_ENTER_TREE:
+ case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
+ add_theme_style_override("panel", EditorNode::get_singleton()->get_gui_base()->get_theme_stylebox(SNAME("panel"), SNAME("Panel")));
+ } break;
+
+ case NOTIFICATION_VISIBILITY_CHANGED: {
+ update_keying();
+ } break;
}
}
@@ -120,7 +125,7 @@ void ReplicationEditor::_add_pressed() {
if (prop.is_empty()) {
return;
}
- UndoRedo *undo_redo = editor->get_undo_redo();
+ UndoRedo *undo_redo = EditorNode::get_singleton()->get_undo_redo();
undo_redo->create_action(TTR("Add property"));
config = current->get_replication_config();
if (config.is_null()) {
@@ -145,7 +150,7 @@ void ReplicationEditor::_tree_item_edited() {
int column = tree->get_edited_column();
ERR_FAIL_COND(column < 1 || column > 2);
const NodePath prop = ti->get_metadata(0);
- UndoRedo *undo_redo = editor->get_undo_redo();
+ UndoRedo *undo_redo = EditorNode::get_singleton()->get_undo_redo();
bool value = ti->is_checked(column);
String method;
if (column == 1) {
@@ -181,7 +186,7 @@ void ReplicationEditor::_dialog_closed(bool p_confirmed) {
int idx = config->property_get_index(prop);
bool spawn = config->property_get_spawn(prop);
bool sync = config->property_get_sync(prop);
- UndoRedo *undo_redo = editor->get_undo_redo();
+ UndoRedo *undo_redo = EditorNode::get_singleton()->get_undo_redo();
undo_redo->create_action(TTR("Remove Property"));
undo_redo->add_do_method(config.ptr(), "remove_property", prop);
undo_redo->add_undo_method(config.ptr(), "add_property", prop, idx);
@@ -258,7 +263,7 @@ void ReplicationEditor::edit(MultiplayerSynchronizer *p_sync) {
Ref<Texture2D> ReplicationEditor::_get_class_icon(const Node *p_node) {
if (!p_node || !has_theme_icon(p_node->get_class(), "EditorIcons")) {
- return get_theme_icon("ImportFail", "EditorIcons");
+ return get_theme_icon(SNAME("ImportFail"), SNAME("EditorIcons"));
}
return get_theme_icon(p_node->get_class(), "EditorIcons");
}
@@ -285,7 +290,7 @@ void ReplicationEditor::_add_property(const NodePath &p_property, bool p_spawn,
icon = _get_class_icon(node);
}
item->set_icon(0, icon);
- item->add_button(3, get_theme_icon("Remove", "EditorIcons"));
+ item->add_button(3, get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")));
item->set_text_alignment(1, HORIZONTAL_ALIGNMENT_CENTER);
item->set_cell_mode(1, TreeItem::CELL_MODE_CHECK);
item->set_checked(1, p_spawn);
@@ -300,7 +305,7 @@ void ReplicationEditor::property_keyed(const String &p_property) {
ERR_FAIL_COND(!current || config.is_null());
Node *root = current->get_node(current->get_root_path());
ERR_FAIL_COND(!root);
- EditorHistory *history = editor->get_editor_history();
+ EditorHistory *history = EditorNode::get_singleton()->get_editor_history();
ERR_FAIL_COND(history->get_path_size() == 0);
Node *node = Object::cast_to<Node>(ObjectDB::get_instance(history->get_path_object(0)));
ERR_FAIL_COND(!node);
@@ -324,7 +329,7 @@ void ReplicationEditor::property_keyed(const String &p_property) {
path += ":" + p_property;
NodePath prop = path;
- UndoRedo *undo_redo = editor->get_undo_redo();
+ UndoRedo *undo_redo = EditorNode::get_singleton()->get_undo_redo();
undo_redo->create_action(TTR("Add property"));
undo_redo->add_do_method(config.ptr(), "add_property", prop);
undo_redo->add_undo_method(config.ptr(), "remove_property", prop);
@@ -334,10 +339,9 @@ void ReplicationEditor::property_keyed(const String &p_property) {
}
/// ReplicationEditorPlugin
-ReplicationEditorPlugin::ReplicationEditorPlugin(EditorNode *p_node) {
- editor = p_node;
- repl_editor = memnew(ReplicationEditor(editor));
- editor->add_bottom_panel_item(TTR("Replication"), repl_editor);
+ReplicationEditorPlugin::ReplicationEditorPlugin() {
+ repl_editor = memnew(ReplicationEditor);
+ EditorNode::get_singleton()->add_bottom_panel_item(TTR("Replication"), repl_editor);
}
ReplicationEditorPlugin::~ReplicationEditorPlugin() {
@@ -356,13 +360,15 @@ void ReplicationEditorPlugin::_property_keyed(const String &p_keyed, const Varia
}
void ReplicationEditorPlugin::_notification(int p_what) {
- if (p_what == NOTIFICATION_ENTER_TREE) {
- //Node3DEditor::get_singleton()->connect("transform_key_request", callable_mp(this, &AnimationPlayerEditorPlugin::_transform_key_request));
- InspectorDock::get_inspector_singleton()->connect("property_keyed", callable_mp(this, &ReplicationEditorPlugin::_property_keyed));
- repl_editor->connect("keying_changed", callable_mp(this, &ReplicationEditorPlugin::_keying_changed));
- // TODO make lock usable.
- //InspectorDock::get_inspector_singleton()->connect("object_inspected", callable_mp(repl_editor, &ReplicationEditor::update_keying));
- get_tree()->connect("node_removed", callable_mp(this, &ReplicationEditorPlugin::_node_removed));
+ switch (p_what) {
+ case NOTIFICATION_ENTER_TREE: {
+ //Node3DEditor::get_singleton()->connect("transform_key_request", callable_mp(this, &AnimationPlayerEditorPlugin::_transform_key_request));
+ InspectorDock::get_inspector_singleton()->connect("property_keyed", callable_mp(this, &ReplicationEditorPlugin::_property_keyed));
+ repl_editor->connect("keying_changed", callable_mp(this, &ReplicationEditorPlugin::_keying_changed));
+ // TODO make lock usable.
+ //InspectorDock::get_inspector_singleton()->connect("object_inspected", callable_mp(repl_editor, &ReplicationEditor::update_keying));
+ get_tree()->connect("node_removed", callable_mp(this, &ReplicationEditorPlugin::_node_removed));
+ } break;
}
}
@@ -370,7 +376,7 @@ void ReplicationEditorPlugin::_node_removed(Node *p_node) {
if (p_node && p_node == repl_editor->get_current()) {
repl_editor->edit(nullptr);
if (repl_editor->is_visible_in_tree()) {
- editor->hide_bottom_panel();
+ EditorNode::get_singleton()->hide_bottom_panel();
}
}
}
@@ -385,6 +391,6 @@ bool ReplicationEditorPlugin::handles(Object *p_object) const {
void ReplicationEditorPlugin::make_visible(bool p_visible) {
if (p_visible) {
- editor->make_bottom_panel_item_visible(repl_editor);
+ EditorNode::get_singleton()->make_bottom_panel_item_visible(repl_editor);
}
}
diff --git a/editor/plugins/replication_editor_plugin.h b/editor/plugins/replication_editor_plugin.h
index 049eda99cc..46274d188c 100644
--- a/editor/plugins/replication_editor_plugin.h
+++ b/editor/plugins/replication_editor_plugin.h
@@ -31,7 +31,6 @@
#ifndef REPLICATION_EDITOR_PLUGIN_H
#define REPLICATION_EDITOR_PLUGIN_H
-#include "editor/editor_node.h"
#include "editor/editor_plugin.h"
#include "scene/resources/scene_replication_config.h"
@@ -43,7 +42,6 @@ class ReplicationEditor : public VBoxContainer {
GDCLASS(ReplicationEditor, VBoxContainer);
private:
- EditorNode *editor;
MultiplayerSynchronizer *current = nullptr;
AcceptDialog *error_dialog = nullptr;
@@ -78,7 +76,7 @@ public:
MultiplayerSynchronizer *get_current() const { return current; }
void property_keyed(const String &p_property);
- ReplicationEditor(EditorNode *p_node);
+ ReplicationEditor();
~ReplicationEditor() {}
};
@@ -86,7 +84,6 @@ class ReplicationEditorPlugin : public EditorPlugin {
GDCLASS(ReplicationEditorPlugin, EditorPlugin);
private:
- EditorNode *editor;
ReplicationEditor *repl_editor;
void _node_removed(Node *p_node);
@@ -101,7 +98,7 @@ public:
virtual bool handles(Object *p_object) const override;
virtual void make_visible(bool p_visible) override;
- ReplicationEditorPlugin(EditorNode *p_node);
+ ReplicationEditorPlugin();
~ReplicationEditorPlugin();
};
diff --git a/editor/plugins/resource_preloader_editor_plugin.cpp b/editor/plugins/resource_preloader_editor_plugin.cpp
index 786217a5c2..b7aef7f1bb 100644
--- a/editor/plugins/resource_preloader_editor_plugin.cpp
+++ b/editor/plugins/resource_preloader_editor_plugin.cpp
@@ -32,19 +32,16 @@
#include "core/config/project_settings.h"
#include "core/io/resource_loader.h"
+#include "editor/editor_file_dialog.h"
+#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
void ResourcePreloaderEditor::_notification(int p_what) {
- if (p_what == NOTIFICATION_ENTER_TREE) {
- load->set_icon(get_theme_icon(SNAME("Folder"), SNAME("EditorIcons")));
- }
-
- if (p_what == NOTIFICATION_READY) {
- //NodePath("/root")->connect("node_removed", this,"_node_removed",Vector<Variant>(),true);
- }
-
- if (p_what == NOTIFICATION_DRAW) {
+ switch (p_what) {
+ case NOTIFICATION_ENTER_TREE: {
+ load->set_icon(get_theme_icon(SNAME("Folder"), SNAME("EditorIcons")));
+ } break;
}
}
@@ -402,11 +399,11 @@ void ResourcePreloaderEditorPlugin::make_visible(bool p_visible) {
if (p_visible) {
//preloader_editor->show();
button->show();
- editor->make_bottom_panel_item_visible(preloader_editor);
+ EditorNode::get_singleton()->make_bottom_panel_item_visible(preloader_editor);
//preloader_editor->set_process(true);
} else {
if (preloader_editor->is_visible_in_tree()) {
- editor->hide_bottom_panel();
+ EditorNode::get_singleton()->hide_bottom_panel();
}
button->hide();
//preloader_editor->hide();
@@ -414,12 +411,11 @@ void ResourcePreloaderEditorPlugin::make_visible(bool p_visible) {
}
}
-ResourcePreloaderEditorPlugin::ResourcePreloaderEditorPlugin(EditorNode *p_node) {
- editor = p_node;
+ResourcePreloaderEditorPlugin::ResourcePreloaderEditorPlugin() {
preloader_editor = memnew(ResourcePreloaderEditor);
preloader_editor->set_custom_minimum_size(Size2(0, 250) * EDSCALE);
- button = editor->add_bottom_panel_item(TTR("ResourcePreloader"), preloader_editor);
+ button = EditorNode::get_singleton()->add_bottom_panel_item(TTR("ResourcePreloader"), preloader_editor);
button->hide();
//preloader_editor->set_anchor( MARGIN_TOP, Control::ANCHOR_END);
diff --git a/editor/plugins/resource_preloader_editor_plugin.h b/editor/plugins/resource_preloader_editor_plugin.h
index 838d72df41..8e81239f1b 100644
--- a/editor/plugins/resource_preloader_editor_plugin.h
+++ b/editor/plugins/resource_preloader_editor_plugin.h
@@ -31,13 +31,13 @@
#ifndef RESOURCE_PRELOADER_EDITOR_PLUGIN_H
#define RESOURCE_PRELOADER_EDITOR_PLUGIN_H
-#include "editor/editor_node.h"
#include "editor/editor_plugin.h"
#include "scene/gui/dialogs.h"
-#include "scene/gui/file_dialog.h"
#include "scene/gui/tree.h"
#include "scene/main/resource_preloader.h"
+class EditorFileDialog;
+
class ResourcePreloaderEditor : public PanelContainer {
GDCLASS(ResourcePreloaderEditor, PanelContainer);
@@ -88,7 +88,6 @@ class ResourcePreloaderEditorPlugin : public EditorPlugin {
GDCLASS(ResourcePreloaderEditorPlugin, EditorPlugin);
ResourcePreloaderEditor *preloader_editor;
- EditorNode *editor;
Button *button;
public:
@@ -98,7 +97,7 @@ public:
virtual bool handles(Object *p_object) const override;
virtual void make_visible(bool p_visible) override;
- ResourcePreloaderEditorPlugin(EditorNode *p_node);
+ ResourcePreloaderEditorPlugin();
~ResourcePreloaderEditorPlugin();
};
diff --git a/editor/plugins/root_motion_editor_plugin.cpp b/editor/plugins/root_motion_editor_plugin.cpp
index 34b39d2a17..bfb672d694 100644
--- a/editor/plugins/root_motion_editor_plugin.cpp
+++ b/editor/plugins/root_motion_editor_plugin.cpp
@@ -233,9 +233,12 @@ void EditorPropertyRootMotion::setup(const NodePath &p_base_hint) {
}
void EditorPropertyRootMotion::_notification(int p_what) {
- if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) {
- Ref<Texture2D> t = get_theme_icon(SNAME("Clear"), SNAME("EditorIcons"));
- clear->set_icon(t);
+ switch (p_what) {
+ case NOTIFICATION_ENTER_TREE:
+ case NOTIFICATION_THEME_CHANGED: {
+ Ref<Texture2D> t = get_theme_icon(SNAME("Clear"), SNAME("EditorIcons"));
+ clear->set_icon(t);
+ } break;
}
}
diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp
index 26227fa5bb..d506a1f3ab 100644
--- a/editor/plugins/script_editor_plugin.cpp
+++ b/editor/plugins/script_editor_plugin.cpp
@@ -36,8 +36,10 @@
#include "core/io/resource_loader.h"
#include "core/os/keyboard.h"
#include "core/os/os.h"
+#include "core/version.h"
#include "editor/debugger/editor_debugger_node.h"
#include "editor/debugger/script_editor_debugger.h"
+#include "editor/editor_file_dialog.h"
#include "editor/editor_node.h"
#include "editor/editor_run_script.h"
#include "editor/editor_scale.h"
@@ -355,6 +357,7 @@ void ScriptEditorQuickOpen::_notification(int p_what) {
case NOTIFICATION_VISIBILITY_CHANGED: {
search_box->set_right_icon(search_options->get_theme_icon(SNAME("Search"), SNAME("EditorIcons")));
} break;
+
case NOTIFICATION_EXIT_TREE: {
disconnect("confirmed", callable_mp(this, &ScriptEditorQuickOpen::_confirmed));
} break;
@@ -404,8 +407,8 @@ void ScriptEditor::_breaked(bool p_breaked, bool p_can_debug) {
return;
}
- for (int i = 0; i < tab_container->get_child_count(); i++) {
- ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_child(i));
+ for (int i = 0; i < tab_container->get_tab_count(); i++) {
+ ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_tab_control(i));
if (!se) {
continue;
}
@@ -415,7 +418,7 @@ void ScriptEditor::_breaked(bool p_breaked, bool p_can_debug) {
}
void ScriptEditor::_script_created(Ref<Script> p_script) {
- editor->push_item(p_script.operator->());
+ EditorNode::get_singleton()->push_item(p_script.operator->());
}
void ScriptEditor::_goto_script_line2(int p_line) {
@@ -429,7 +432,7 @@ void ScriptEditor::_goto_script_line(REF p_script, int p_line) {
Ref<Script> script = Object::cast_to<Script>(*p_script);
if (script.is_valid() && (script->has_source_code() || script->get_path().is_resource_file())) {
if (edit(p_script, p_line, 0)) {
- editor->push_item(p_script.ptr());
+ EditorNode::get_singleton()->push_item(p_script.ptr());
ScriptEditorBase *current = _get_current_editor();
if (ScriptTextEditor *script_text_editor = Object::cast_to<ScriptTextEditor>(current)) {
@@ -444,8 +447,8 @@ void ScriptEditor::_goto_script_line(REF p_script, int p_line) {
void ScriptEditor::_set_execution(REF p_script, int p_line) {
Ref<Script> script = Object::cast_to<Script>(*p_script);
if (script.is_valid() && (script->has_source_code() || script->get_path().is_resource_file())) {
- for (int i = 0; i < tab_container->get_child_count(); i++) {
- ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_child(i));
+ for (int i = 0; i < tab_container->get_tab_count(); i++) {
+ ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_tab_control(i));
if (!se) {
continue;
}
@@ -460,8 +463,8 @@ void ScriptEditor::_set_execution(REF p_script, int p_line) {
void ScriptEditor::_clear_execution(REF p_script) {
Ref<Script> script = Object::cast_to<Script>(*p_script);
if (script.is_valid() && (script->has_source_code() || script->get_path().is_resource_file())) {
- for (int i = 0; i < tab_container->get_child_count(); i++) {
- ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_child(i));
+ for (int i = 0; i < tab_container->get_tab_count(); i++) {
+ ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_tab_control(i));
if (!se) {
continue;
}
@@ -477,8 +480,8 @@ void ScriptEditor::_set_breakpoint(REF p_script, int p_line, bool p_enabled) {
Ref<Script> script = Object::cast_to<Script>(*p_script);
if (script.is_valid() && (script->has_source_code() || script->get_path().is_resource_file())) {
// Update if open.
- for (int i = 0; i < tab_container->get_child_count(); i++) {
- ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_child(i));
+ for (int i = 0; i < tab_container->get_tab_count(); i++) {
+ ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_tab_control(i));
if (se && se->get_edited_resource()->get_path() == script->get_path()) {
se->set_breakpoint(p_line, p_enabled);
return;
@@ -506,8 +509,8 @@ void ScriptEditor::_set_breakpoint(REF p_script, int p_line, bool p_enabled) {
}
void ScriptEditor::_clear_breakpoints() {
- for (int i = 0; i < tab_container->get_child_count(); i++) {
- ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_child(i));
+ for (int i = 0; i < tab_container->get_tab_count(); i++) {
+ ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_tab_control(i));
if (se) {
se->clear_breakpoints();
}
@@ -544,11 +547,11 @@ Array ScriptEditor::_get_cached_breakpoints_for_script(const String &p_path) con
ScriptEditorBase *ScriptEditor::_get_current_editor() const {
int selected = tab_container->get_current_tab();
- if (selected < 0 || selected >= tab_container->get_child_count()) {
+ if (selected < 0 || selected >= tab_container->get_tab_count()) {
return nullptr;
}
- return Object::cast_to<ScriptEditorBase>(tab_container->get_child(selected));
+ return Object::cast_to<ScriptEditorBase>(tab_container->get_tab_control(selected));
}
void ScriptEditor::_update_history_arrows() {
@@ -587,7 +590,7 @@ void ScriptEditor::_go_to_tab(int p_idx) {
}
}
- Control *c = Object::cast_to<Control>(tab_container->get_child(p_idx));
+ Control *c = Object::cast_to<Control>(tab_container->get_tab_control(p_idx));
if (!c) {
return;
}
@@ -679,7 +682,7 @@ void ScriptEditor::_update_recent_scripts() {
recent_scripts->add_shortcut(ED_SHORTCUT("script_editor/clear_recent", TTR("Clear Recent Files")));
recent_scripts->set_item_disabled(recent_scripts->get_item_id(recent_scripts->get_item_count() - 1), rc.is_empty());
- recent_scripts->set_as_minsize();
+ recent_scripts->reset_size();
}
void ScriptEditor::_open_recent_script(int p_idx) {
@@ -747,11 +750,11 @@ void ScriptEditor::_show_error_dialog(String p_path) {
void ScriptEditor::_close_tab(int p_idx, bool p_save, bool p_history_back) {
int selected = p_idx;
- if (selected < 0 || selected >= tab_container->get_child_count()) {
+ if (selected < 0 || selected >= tab_container->get_tab_count()) {
return;
}
- Node *tselected = tab_container->get_child(selected);
+ Node *tselected = tab_container->get_tab_control(selected);
ScriptEditorBase *current = Object::cast_to<ScriptEditorBase>(tselected);
if (current) {
@@ -759,7 +762,7 @@ void ScriptEditor::_close_tab(int p_idx, bool p_save, bool p_history_back) {
if (p_save && file.is_valid()) {
// Do not try to save internal scripts, but prompt to save in-memory
// scripts which are not saved to disk yet (have empty path).
- if (file->is_built_in()) {
+ if (!file->is_built_in()) {
save_current_script();
}
}
@@ -802,12 +805,12 @@ void ScriptEditor::_close_tab(int p_idx, bool p_save, bool p_history_back) {
_save_editor_state(current);
}
memdelete(tselected);
- if (idx >= tab_container->get_child_count()) {
- idx = tab_container->get_child_count() - 1;
+ if (idx >= tab_container->get_tab_count()) {
+ idx = tab_container->get_tab_count() - 1;
}
if (idx >= 0) {
if (history_pos >= 0) {
- idx = history[history_pos].control->get_index();
+ idx = tab_container->get_tab_idx_from_control(history[history_pos].control);
}
tab_container->set_current_tab(idx);
} else {
@@ -833,9 +836,9 @@ void ScriptEditor::_close_discard_current_tab(const String &p_str) {
}
void ScriptEditor::_close_docs_tab() {
- int child_count = tab_container->get_child_count();
+ int child_count = tab_container->get_tab_count();
for (int i = child_count - 1; i >= 0; i--) {
- EditorHelp *se = Object::cast_to<EditorHelp>(tab_container->get_child(i));
+ EditorHelp *se = Object::cast_to<EditorHelp>(tab_container->get_tab_control(i));
if (se) {
_close_tab(i, true, false);
@@ -853,7 +856,7 @@ void ScriptEditor::_copy_script_path() {
void ScriptEditor::_close_other_tabs() {
int current_idx = tab_container->get_current_tab();
- for (int i = tab_container->get_child_count() - 1; i >= 0; i--) {
+ for (int i = tab_container->get_tab_count() - 1; i >= 0; i--) {
if (i != current_idx) {
script_close_queue.push_back(i);
}
@@ -862,7 +865,7 @@ void ScriptEditor::_close_other_tabs() {
}
void ScriptEditor::_close_all_tabs() {
- for (int i = tab_container->get_child_count() - 1; i >= 0; i--) {
+ for (int i = tab_container->get_tab_count() - 1; i >= 0; i--) {
script_close_queue.push_back(i);
}
_queue_close_tabs();
@@ -874,7 +877,7 @@ void ScriptEditor::_queue_close_tabs() {
script_close_queue.pop_front();
tab_container->set_current_tab(idx);
- ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_child(idx));
+ ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_tab_control(idx));
if (se) {
// Maybe there are unsaved changes.
if (se->is_unsaved()) {
@@ -897,8 +900,8 @@ void ScriptEditor::_ask_close_current_unsaved_tab(ScriptEditorBase *current) {
void ScriptEditor::_resave_scripts(const String &p_str) {
apply_scripts();
- for (int i = 0; i < tab_container->get_child_count(); i++) {
- ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_child(i));
+ for (int i = 0; i < tab_container->get_tab_count(); i++) {
+ ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_tab_control(i));
if (!se) {
continue;
}
@@ -929,7 +932,7 @@ void ScriptEditor::_resave_scripts(const String &p_str) {
_save_text_file(text_file, text_file->get_path());
break;
} else {
- editor->save_resource(script);
+ EditorNode::get_singleton()->save_resource(script);
}
se->tag_saved_version();
}
@@ -938,8 +941,8 @@ void ScriptEditor::_resave_scripts(const String &p_str) {
}
void ScriptEditor::_reload_scripts() {
- for (int i = 0; i < tab_container->get_child_count(); i++) {
- ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_child(i));
+ for (int i = 0; i < tab_container->get_tab_count(); i++) {
+ ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_tab_control(i));
if (!se) {
continue;
}
@@ -982,8 +985,8 @@ void ScriptEditor::_reload_scripts() {
}
void ScriptEditor::_res_saved_callback(const Ref<Resource> &p_res) {
- for (int i = 0; i < tab_container->get_child_count(); i++) {
- ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_child(i));
+ for (int i = 0; i < tab_container->get_tab_count(); i++) {
+ ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_tab_control(i));
if (!se) {
continue;
}
@@ -1001,8 +1004,8 @@ void ScriptEditor::_res_saved_callback(const Ref<Resource> &p_res) {
void ScriptEditor::_scene_saved_callback(const String &p_path) {
// If scene was saved, mark all built-in scripts from that scene as saved.
- for (int i = 0; i < tab_container->get_child_count(); i++) {
- ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_child(i));
+ for (int i = 0; i < tab_container->get_tab_count(); i++) {
+ ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_tab_control(i));
if (!se) {
continue;
}
@@ -1043,10 +1046,10 @@ bool ScriptEditor::_test_script_times_on_disk(RES p_for_script) {
bool need_ask = false;
bool need_reload = false;
- bool use_autoreload = bool(EDITOR_DEF("text_editor/behavior/files/auto_reload_scripts_on_external_change", false));
+ bool use_autoreload = bool(EDITOR_GET("text_editor/behavior/files/auto_reload_scripts_on_external_change"));
- for (int i = 0; i < tab_container->get_child_count(); i++) {
- ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_child(i));
+ for (int i = 0; i < tab_container->get_tab_count(); i++) {
+ ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_tab_control(i));
if (se) {
RES edited_res = se->get_edited_resource();
if (p_for_script.is_valid() && edited_res.is_valid() && p_for_script != edited_res) {
@@ -1090,7 +1093,7 @@ void ScriptEditor::_file_dialog_action(String p_file) {
Error err;
FileAccess *file = FileAccess::open(p_file, FileAccess::WRITE, &err);
if (err) {
- editor->show_warning(TTR("Error writing TextFile:") + "\n" + p_file, TTR("Error!"));
+ EditorNode::get_singleton()->show_warning(TTR("Error writing TextFile:") + "\n" + p_file, TTR("Error!"));
break;
}
file->close();
@@ -1119,7 +1122,7 @@ void ScriptEditor::_file_dialog_action(String p_file) {
Error err = _save_text_file(resource, path);
if (err != OK) {
- editor->show_accept(TTR("Error saving file!"), TTR("OK"));
+ EditorNode::get_singleton()->show_accept(TTR("Error saving file!"), TTR("OK"));
return;
}
@@ -1129,12 +1132,12 @@ void ScriptEditor::_file_dialog_action(String p_file) {
} break;
case THEME_SAVE_AS: {
if (!EditorSettings::get_singleton()->save_text_editor_theme_as(p_file)) {
- editor->show_warning(TTR("Error while saving theme."), TTR("Error Saving"));
+ EditorNode::get_singleton()->show_warning(TTR("Error while saving theme."), TTR("Error Saving"));
}
} break;
case THEME_IMPORT: {
if (!EditorSettings::get_singleton()->import_text_editor_theme(p_file)) {
- editor->show_warning(TTR("Error importing theme."), TTR("Error Importing"));
+ EditorNode::get_singleton()->show_warning(TTR("Error importing theme."), TTR("Error Importing"));
}
} break;
}
@@ -1240,7 +1243,7 @@ void ScriptEditor::_menu_option(int p_option) {
Ref<Script> scr = ResourceLoader::load(path);
if (!scr.is_valid()) {
- editor->show_warning(TTR("Could not load file at:") + "\n\n" + path, TTR("Error!"));
+ EditorNode::get_singleton()->show_warning(TTR("Could not load file at:") + "\n\n" + path, TTR("Error!"));
file_dialog_option = -1;
return;
}
@@ -1252,7 +1255,7 @@ void ScriptEditor::_menu_option(int p_option) {
Error error;
Ref<TextFile> text_file = _load_text_file(path, &error);
if (error != OK) {
- editor->show_warning(TTR("Could not load file at:") + "\n\n" + path, TTR("Error!"));
+ EditorNode::get_singleton()->show_warning(TTR("Could not load file at:") + "\n\n" + path, TTR("Error!"));
}
if (text_file.is_valid()) {
@@ -1279,7 +1282,7 @@ void ScriptEditor::_menu_option(int p_option) {
help_search_dialog->popup_dialog();
} break;
case SEARCH_WEBSITE: {
- OS::get_singleton()->shell_open("https://docs.godotengine.org/");
+ OS::get_singleton()->shell_open(VERSION_DOCS_URL "/");
} break;
case WINDOW_NEXT: {
_history_forward();
@@ -1354,8 +1357,8 @@ void ScriptEditor::_menu_option(int p_option) {
}
}
- editor->push_item(resource.ptr());
- editor->save_resource_as(resource);
+ EditorNode::get_singleton()->push_item(resource.ptr());
+ EditorNode::get_singleton()->save_resource_as(resource);
if (script != nullptr) {
const Vector<DocData::ClassDoc> &documentations = script->get_documentation();
@@ -1426,7 +1429,7 @@ void ScriptEditor::_menu_option(int p_option) {
file_system_dock->navigate_to_path(path);
// Ensure that the FileSystem dock is visible.
TabContainer *tab_container = (TabContainer *)file_system_dock->get_parent_control();
- tab_container->set_current_tab(file_system_dock->get_index());
+ tab_container->set_current_tab(tab_container->get_tab_idx_from_control(file_system_dock));
}
} break;
case CLOSE_DOCS: {
@@ -1446,7 +1449,7 @@ void ScriptEditor::_menu_option(int p_option) {
}
} break;
case WINDOW_MOVE_DOWN: {
- if (tab_container->get_current_tab() < tab_container->get_child_count() - 1) {
+ if (tab_container->get_current_tab() < tab_container->get_tab_count() - 1) {
tab_container->move_child(current, tab_container->get_current_tab() + 1);
tab_container->set_current_tab(tab_container->get_current_tab() + 1);
_update_script_names();
@@ -1492,7 +1495,7 @@ void ScriptEditor::_menu_option(int p_option) {
}
} break;
case WINDOW_MOVE_DOWN: {
- if (tab_container->get_current_tab() < tab_container->get_child_count() - 1) {
+ if (tab_container->get_current_tab() < tab_container->get_tab_count() - 1) {
tab_container->move_child(help, tab_container->get_current_tab() + 1);
tab_container->set_current_tab(tab_container->get_current_tab() + 1);
_update_script_names();
@@ -1521,7 +1524,7 @@ void ScriptEditor::_theme_option(int p_option) {
if (EditorSettings::get_singleton()->is_default_text_editor_theme()) {
ScriptEditor::_show_save_theme_as_dialog();
} else if (!EditorSettings::get_singleton()->save_text_editor_theme()) {
- editor->show_warning(TTR("Error while saving theme"), TTR("Error saving"));
+ EditorNode::get_singleton()->show_warning(TTR("Error while saving theme"), TTR("Error saving"));
}
} break;
case THEME_SAVE_AS: {
@@ -1542,9 +1545,9 @@ void ScriptEditor::_show_save_theme_as_dialog() {
}
bool ScriptEditor::_has_docs_tab() const {
- const int child_count = tab_container->get_child_count();
+ const int child_count = tab_container->get_tab_count();
for (int i = 0; i < child_count; i++) {
- if (Object::cast_to<EditorHelp>(tab_container->get_child(i))) {
+ if (Object::cast_to<EditorHelp>(tab_container->get_tab_control(i))) {
return true;
}
}
@@ -1552,9 +1555,9 @@ bool ScriptEditor::_has_docs_tab() const {
}
bool ScriptEditor::_has_script_tab() const {
- const int child_count = tab_container->get_child_count();
+ const int child_count = tab_container->get_tab_count();
for (int i = 0; i < child_count; i++) {
- if (Object::cast_to<ScriptEditorBase>(tab_container->get_child(i))) {
+ if (Object::cast_to<ScriptEditorBase>(tab_container->get_tab_control(i))) {
return true;
}
}
@@ -1578,9 +1581,9 @@ void ScriptEditor::_prepare_file_menu() {
menu->set_item_disabled(menu->get_item_index(WINDOW_PREV), history_pos <= 0);
menu->set_item_disabled(menu->get_item_index(WINDOW_NEXT), history_pos >= history.size() - 1);
- menu->set_item_disabled(menu->get_item_index(FILE_CLOSE), tab_container->get_child_count() < 1);
- menu->set_item_disabled(menu->get_item_index(CLOSE_ALL), tab_container->get_child_count() < 1);
- menu->set_item_disabled(menu->get_item_index(CLOSE_OTHER_TABS), tab_container->get_child_count() <= 1);
+ menu->set_item_disabled(menu->get_item_index(FILE_CLOSE), tab_container->get_tab_count() < 1);
+ menu->set_item_disabled(menu->get_item_index(CLOSE_ALL), tab_container->get_tab_count() < 1);
+ menu->set_item_disabled(menu->get_item_index(CLOSE_OTHER_TABS), tab_container->get_tab_count() <= 1);
menu->set_item_disabled(menu->get_item_index(CLOSE_DOCS), !_has_docs_tab());
menu->set_item_disabled(menu->get_item_index(FILE_RUN), current_is_doc);
@@ -1593,10 +1596,10 @@ void ScriptEditor::_tab_changed(int p_which) {
void ScriptEditor::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
- editor->connect("stop_pressed", callable_mp(this, &ScriptEditor::_editor_stop));
- editor->connect("script_add_function_request", callable_mp(this, &ScriptEditor::_add_callback));
- editor->connect("resource_saved", callable_mp(this, &ScriptEditor::_res_saved_callback));
- editor->connect("scene_saved", callable_mp(this, &ScriptEditor::_scene_saved_callback));
+ EditorNode::get_singleton()->connect("stop_pressed", callable_mp(this, &ScriptEditor::_editor_stop));
+ EditorNode::get_singleton()->connect("script_add_function_request", callable_mp(this, &ScriptEditor::_add_callback));
+ EditorNode::get_singleton()->connect("resource_saved", callable_mp(this, &ScriptEditor::_res_saved_callback));
+ EditorNode::get_singleton()->connect("scene_saved", callable_mp(this, &ScriptEditor::_scene_saved_callback));
FileSystemDock::get_singleton()->connect("files_moved", callable_mp(this, &ScriptEditor::_files_moved));
FileSystemDock::get_singleton()->connect("file_removed", callable_mp(this, &ScriptEditor::_file_removed));
script_list->connect("item_selected", callable_mp(this, &ScriptEditor::_script_selected));
@@ -1630,9 +1633,9 @@ void ScriptEditor::_notification(int p_what) {
filter_scripts->set_right_icon(get_theme_icon(SNAME("Search"), SNAME("EditorIcons")));
filter_methods->set_right_icon(get_theme_icon(SNAME("Search"), SNAME("EditorIcons")));
- filename->add_theme_style_override("normal", editor->get_gui_base()->get_theme_stylebox(SNAME("normal"), SNAME("LineEdit")));
+ filename->add_theme_style_override("normal", EditorNode::get_singleton()->get_gui_base()->get_theme_stylebox(SNAME("normal"), SNAME("LineEdit")));
- recent_scripts->set_as_minsize();
+ recent_scripts->reset_size();
if (is_inside_tree()) {
_update_script_colors();
@@ -1643,11 +1646,11 @@ void ScriptEditor::_notification(int p_what) {
case NOTIFICATION_READY: {
get_tree()->connect("tree_changed", callable_mp(this, &ScriptEditor::_tree_changed));
InspectorDock::get_singleton()->connect("request_help", callable_mp(this, &ScriptEditor::_help_class_open));
- editor->connect("request_help_search", callable_mp(this, &ScriptEditor::_help_search));
+ EditorNode::get_singleton()->connect("request_help_search", callable_mp(this, &ScriptEditor::_help_search));
} break;
case NOTIFICATION_EXIT_TREE: {
- editor->disconnect("stop_pressed", callable_mp(this, &ScriptEditor::_editor_stop));
+ EditorNode::get_singleton()->disconnect("stop_pressed", callable_mp(this, &ScriptEditor::_editor_stop));
} break;
case NOTIFICATION_WM_WINDOW_FOCUS_IN: {
@@ -1660,15 +1663,12 @@ void ScriptEditor::_notification(int p_what) {
find_in_files_button->show();
} else {
if (find_in_files->is_visible_in_tree()) {
- editor->hide_bottom_panel();
+ EditorNode::get_singleton()->hide_bottom_panel();
}
find_in_files_button->hide();
}
} break;
-
- default:
- break;
}
}
@@ -1682,8 +1682,8 @@ bool ScriptEditor::can_take_away_focus() const {
}
void ScriptEditor::close_builtin_scripts_from_scene(const String &p_scene) {
- for (int i = 0; i < tab_container->get_child_count(); i++) {
- ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_child(i));
+ for (int i = 0; i < tab_container->get_tab_count(); i++) {
+ ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_tab_control(i));
if (se) {
Ref<Script> script = se->get_edited_resource();
@@ -1713,8 +1713,8 @@ void ScriptEditor::notify_script_changed(const Ref<Script> &p_script) {
void ScriptEditor::get_breakpoints(List<String> *p_breakpoints) {
Set<String> loaded_scripts;
- for (int i = 0; i < tab_container->get_child_count(); i++) {
- ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_child(i));
+ for (int i = 0; i < tab_container->get_tab_count(); i++) {
+ ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_tab_control(i));
if (!se) {
continue;
}
@@ -1766,7 +1766,7 @@ void ScriptEditor::_members_overview_selected(int p_idx) {
}
void ScriptEditor::_help_overview_selected(int p_idx) {
- Node *current = tab_container->get_child(tab_container->get_current_tab());
+ Node *current = tab_container->get_tab_control(tab_container->get_current_tab());
EditorHelp *se = Object::cast_to<EditorHelp>(current);
if (!se) {
return;
@@ -1782,7 +1782,7 @@ void ScriptEditor::_script_selected(int p_idx) {
}
void ScriptEditor::ensure_select_current() {
- if (tab_container->get_child_count() && tab_container->get_current_tab() >= 0) {
+ if (tab_container->get_tab_count() && tab_container->get_current_tab() >= 0) {
ScriptEditorBase *se = _get_current_editor();
if (se) {
se->enable_editor();
@@ -1893,12 +1893,12 @@ void ScriptEditor::_update_members_overview() {
void ScriptEditor::_update_help_overview_visibility() {
int selected = tab_container->get_current_tab();
- if (selected < 0 || selected >= tab_container->get_child_count()) {
+ if (selected < 0 || selected >= tab_container->get_tab_count()) {
help_overview->set_visible(false);
return;
}
- Node *current = tab_container->get_child(tab_container->get_current_tab());
+ Node *current = tab_container->get_tab_control(tab_container->get_current_tab());
EditorHelp *se = Object::cast_to<EditorHelp>(current);
if (!se) {
help_overview->set_visible(false);
@@ -1920,11 +1920,11 @@ void ScriptEditor::_update_help_overview() {
help_overview->clear();
int selected = tab_container->get_current_tab();
- if (selected < 0 || selected >= tab_container->get_child_count()) {
+ if (selected < 0 || selected >= tab_container->get_tab_count()) {
return;
}
- Node *current = tab_container->get_child(tab_container->get_current_tab());
+ Node *current = tab_container->get_tab_control(tab_container->get_current_tab());
EditorHelp *se = Object::cast_to<EditorHelp>(current);
if (!se) {
return;
@@ -1947,7 +1947,7 @@ void ScriptEditor::_update_script_colors() {
for (int i = 0; i < script_list->get_item_count(); i++) {
int c = script_list->get_item_metadata(i);
- Node *n = tab_container->get_child(c);
+ Node *n = tab_container->get_tab_control(c);
if (!n) {
continue;
}
@@ -1990,8 +1990,8 @@ void ScriptEditor::_update_script_names() {
Vector<_ScriptEditorItemData> sedata;
- for (int i = 0; i < tab_container->get_child_count(); i++) {
- ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_child(i));
+ for (int i = 0; i < tab_container->get_tab_count(); i++) {
+ ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_tab_control(i));
if (se) {
Ref<Texture2D> icon = se->get_theme_icon();
String path = se->get_edited_resource()->get_path();
@@ -2080,7 +2080,7 @@ void ScriptEditor::_update_script_names() {
}
}
- EditorHelp *eh = Object::cast_to<EditorHelp>(tab_container->get_child(i));
+ EditorHelp *eh = Object::cast_to<EditorHelp>(tab_container->get_tab_control(i));
if (eh) {
String name = eh->get_class();
Ref<Texture2D> icon = get_theme_icon(SNAME("Help"), SNAME("EditorIcons"));
@@ -2172,8 +2172,8 @@ void ScriptEditor::_update_script_names() {
}
void ScriptEditor::_update_script_connections() {
- for (int i = 0; i < tab_container->get_child_count(); i++) {
- ScriptTextEditor *ste = Object::cast_to<ScriptTextEditor>(tab_container->get_child(i));
+ for (int i = 0; i < tab_container->get_tab_count(); i++) {
+ ScriptTextEditor *ste = Object::cast_to<ScriptTextEditor>(tab_container->get_tab_control(i));
if (!ste) {
continue;
}
@@ -2265,7 +2265,7 @@ bool ScriptEditor::edit(const RES &p_resource, int p_line, int p_col, bool p_gra
if (use_external_editor &&
(EditorDebuggerNode::get_singleton()->get_dump_stack_script() != p_resource || EditorDebuggerNode::get_singleton()->get_debug_with_external_editor()) &&
p_resource->get_path().is_resource_file() &&
- p_resource->get_class_name() != StringName("VisualScript")) {
+ !p_resource->is_class("VisualScript")) {
String path = EditorSettings::get_singleton()->get("text_editor/external/exec_path");
String flags = EditorSettings::get_singleton()->get("text_editor/external/exec_flags");
@@ -2322,8 +2322,8 @@ bool ScriptEditor::edit(const RES &p_resource, int p_line, int p_col, bool p_gra
WARN_PRINT("Couldn't open external text editor, using internal");
}
- for (int i = 0; i < tab_container->get_child_count(); i++) {
- ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_child(i));
+ for (int i = 0; i < tab_container->get_tab_count(); i++) {
+ ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_tab_control(i));
if (!se) {
continue;
}
@@ -2364,7 +2364,7 @@ bool ScriptEditor::edit(const RES &p_resource, int p_line, int p_col, bool p_gra
se->set_edited_resource(p_resource);
- if (p_resource->get_class_name() != StringName("VisualScript")) {
+ if (!p_resource->is_class("VisualScript")) {
bool highlighter_set = false;
for (int i = 0; i < syntax_highlighters.size(); i++) {
Ref<EditorSyntaxHighlighter> highlighter = syntax_highlighters[i]->_create();
@@ -2479,10 +2479,10 @@ void ScriptEditor::save_current_script() {
if (!scene_path.is_empty()) {
Vector<String> scene_to_save;
scene_to_save.push_back(scene_path);
- editor->save_scene_list(scene_to_save);
+ EditorNode::get_singleton()->save_scene_list(scene_to_save);
}
} else {
- editor->save_resource(resource);
+ EditorNode::get_singleton()->save_resource(resource);
}
if (script != nullptr) {
@@ -2498,8 +2498,8 @@ void ScriptEditor::save_current_script() {
void ScriptEditor::save_all_scripts() {
Vector<String> scenes_to_save;
- for (int i = 0; i < tab_container->get_child_count(); i++) {
- ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_child(i));
+ for (int i = 0; i < tab_container->get_tab_count(); i++) {
+ ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_tab_control(i));
if (!se) {
continue;
}
@@ -2546,7 +2546,7 @@ void ScriptEditor::save_all_scripts() {
}
}
- editor->save_resource(edited_res); //external script, save it
+ EditorNode::get_singleton()->save_resource(edited_res); //external script, save it
if (script != nullptr) {
const Vector<DocData::ClassDoc> &documentations = script->get_documentation();
@@ -2566,7 +2566,7 @@ void ScriptEditor::save_all_scripts() {
}
if (!scenes_to_save.is_empty()) {
- editor->save_scene_list(scenes_to_save);
+ EditorNode::get_singleton()->save_scene_list(scenes_to_save);
}
_update_script_names();
@@ -2574,8 +2574,8 @@ void ScriptEditor::save_all_scripts() {
}
void ScriptEditor::apply_scripts() const {
- for (int i = 0; i < tab_container->get_child_count(); i++) {
- ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_child(i));
+ for (int i = 0; i < tab_container->get_tab_count(); i++) {
+ ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_tab_control(i));
if (!se) {
continue;
}
@@ -2601,7 +2601,7 @@ RES ScriptEditor::open_file(const String &p_file) {
if (extensions.find(p_file.get_extension())) {
Ref<Script> scr = ResourceLoader::load(p_file);
if (!scr.is_valid()) {
- editor->show_warning(TTR("Could not load file at:") + "\n\n" + p_file, TTR("Error!"));
+ EditorNode::get_singleton()->show_warning(TTR("Could not load file at:") + "\n\n" + p_file, TTR("Error!"));
return RES();
}
@@ -2612,7 +2612,7 @@ RES ScriptEditor::open_file(const String &p_file) {
Error error;
Ref<TextFile> text_file = _load_text_file(p_file, &error);
if (error != OK) {
- editor->show_warning(TTR("Could not load file at:") + "\n\n" + p_file, TTR("Error!"));
+ EditorNode::get_singleton()->show_warning(TTR("Could not load file at:") + "\n\n" + p_file, TTR("Error!"));
return RES();
}
@@ -2624,8 +2624,8 @@ RES ScriptEditor::open_file(const String &p_file) {
}
void ScriptEditor::_editor_stop() {
- for (int i = 0; i < tab_container->get_child_count(); i++) {
- ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_child(i));
+ for (int i = 0; i < tab_container->get_tab_count(); i++) {
+ ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_tab_control(i));
if (!se) {
continue;
}
@@ -2639,10 +2639,10 @@ void ScriptEditor::_add_callback(Object *p_obj, const String &p_function, const
Ref<Script> script = p_obj->get_script();
ERR_FAIL_COND(!script.is_valid());
- editor->push_item(script.ptr());
+ EditorNode::get_singleton()->push_item(script.ptr());
- for (int i = 0; i < tab_container->get_child_count(); i++) {
- ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_child(i));
+ for (int i = 0; i < tab_container->get_tab_count(); i++) {
+ ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_tab_control(i));
if (!se) {
continue;
}
@@ -2684,7 +2684,7 @@ void ScriptEditor::_save_layout() {
return;
}
- editor->save_layout();
+ EditorNode::get_singleton()->save_layout();
}
void ScriptEditor::_editor_settings_changed() {
@@ -2712,8 +2712,8 @@ void ScriptEditor::_editor_settings_changed() {
EditorSettings::get_singleton()->load_text_editor_theme();
}
- for (int i = 0; i < tab_container->get_child_count(); i++) {
- ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_child(i));
+ for (int i = 0; i < tab_container->get_tab_count(); i++) {
+ ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_tab_control(i));
if (!se) {
continue;
}
@@ -2723,7 +2723,7 @@ void ScriptEditor::_editor_settings_changed() {
_update_script_colors();
_update_script_names();
- ScriptServer::set_reload_scripts_on_save(EDITOR_DEF("text_editor/behavior/files/auto_reload_and_parse_scripts_on_save", true));
+ ScriptServer::set_reload_scripts_on_save(EDITOR_GET("text_editor/behavior/files/auto_reload_and_parse_scripts_on_save"));
}
void ScriptEditor::_filesystem_changed() {
@@ -2751,8 +2751,8 @@ void ScriptEditor::_files_moved(const String &p_old_file, const String &p_new_fi
}
void ScriptEditor::_file_removed(const String &p_removed_file) {
- for (int i = 0; i < tab_container->get_child_count(); i++) {
- ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_child(i));
+ for (int i = 0; i < tab_container->get_tab_count(); i++) {
+ ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_tab_control(i));
if (!se) {
continue;
}
@@ -2815,11 +2815,11 @@ void ScriptEditor::_split_dragged(float) {
}
Variant ScriptEditor::get_drag_data_fw(const Point2 &p_point, Control *p_from) {
- if (tab_container->get_child_count() == 0) {
+ if (tab_container->get_tab_count() == 0) {
return Variant();
}
- Node *cur_node = tab_container->get_child(tab_container->get_current_tab());
+ Node *cur_node = tab_container->get_tab_control(tab_container->get_current_tab());
HBoxContainer *drag_preview = memnew(HBoxContainer);
String preview_name = "";
@@ -2975,7 +2975,7 @@ void ScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data, Co
if (script_list->get_item_count() > 0) {
new_index = script_list->get_item_metadata(script_list->get_item_at_position(p_point));
}
- int num_tabs_before = tab_container->get_child_count();
+ int num_tabs_before = tab_container->get_tab_count();
for (int i = 0; i < files.size(); i++) {
String file = files[i];
if (file.is_empty() || !FileAccess::exists(file)) {
@@ -2988,11 +2988,11 @@ void ScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data, Co
RES res = open_file(file);
if (res.is_valid()) {
- if (tab_container->get_child_count() > num_tabs_before) {
- tab_container->move_child(tab_container->get_child(tab_container->get_child_count() - 1), new_index);
- num_tabs_before = tab_container->get_child_count();
+ if (tab_container->get_tab_count() > num_tabs_before) {
+ tab_container->move_child(tab_container->get_tab_control(tab_container->get_tab_count() - 1), new_index);
+ num_tabs_before = tab_container->get_tab_count();
} else { /* Maybe script was already open */
- tab_container->move_child(tab_container->get_child(tab_container->get_current_tab()), new_index);
+ tab_container->move_child(tab_container->get_tab_control(tab_container->get_current_tab()), new_index);
}
}
}
@@ -3081,11 +3081,11 @@ void ScriptEditor::_make_script_list_context_menu() {
context_menu->clear();
int selected = tab_container->get_current_tab();
- if (selected < 0 || selected >= tab_container->get_child_count()) {
+ if (selected < 0 || selected >= tab_container->get_tab_count()) {
return;
}
- ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_child(selected));
+ ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_tab_control(selected));
if (se) {
context_menu->add_shortcut(ED_GET_SHORTCUT("script_editor/save"), FILE_SAVE);
context_menu->add_shortcut(ED_GET_SHORTCUT("script_editor/save_as"), FILE_SAVE_AS);
@@ -3113,11 +3113,11 @@ void ScriptEditor::_make_script_list_context_menu() {
context_menu->add_shortcut(ED_GET_SHORTCUT("script_editor/window_sort"), WINDOW_SORT);
context_menu->add_shortcut(ED_GET_SHORTCUT("script_editor/toggle_scripts_panel"), TOGGLE_SCRIPTS_PANEL);
- context_menu->set_item_disabled(context_menu->get_item_index(CLOSE_ALL), tab_container->get_child_count() <= 0);
- context_menu->set_item_disabled(context_menu->get_item_index(CLOSE_OTHER_TABS), tab_container->get_child_count() <= 1);
+ context_menu->set_item_disabled(context_menu->get_item_index(CLOSE_ALL), tab_container->get_tab_count() <= 0);
+ context_menu->set_item_disabled(context_menu->get_item_index(CLOSE_OTHER_TABS), tab_container->get_tab_count() <= 1);
context_menu->set_item_disabled(context_menu->get_item_index(WINDOW_MOVE_UP), tab_container->get_current_tab() <= 0);
- context_menu->set_item_disabled(context_menu->get_item_index(WINDOW_MOVE_DOWN), tab_container->get_current_tab() >= tab_container->get_child_count() - 1);
- context_menu->set_item_disabled(context_menu->get_item_index(WINDOW_SORT), tab_container->get_child_count() <= 1);
+ context_menu->set_item_disabled(context_menu->get_item_index(WINDOW_MOVE_DOWN), tab_container->get_current_tab() >= tab_container->get_tab_count() - 1);
+ context_menu->set_item_disabled(context_menu->get_item_index(WINDOW_SORT), tab_container->get_tab_count() <= 1);
context_menu->set_position(get_screen_position() + get_local_mouse_position());
context_menu->reset_size();
@@ -3125,7 +3125,7 @@ void ScriptEditor::_make_script_list_context_menu() {
}
void ScriptEditor::set_window_layout(Ref<ConfigFile> p_layout) {
- if (!bool(EDITOR_DEF("text_editor/behavior/files/restore_scripts_on_load", true))) {
+ if (!bool(EDITOR_GET("text_editor/behavior/files/restore_scripts_on_load"))) {
return;
}
@@ -3181,7 +3181,7 @@ void ScriptEditor::set_window_layout(Ref<ConfigFile> p_layout) {
}
if (!script_info.is_empty()) {
- ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_child(tab_container->get_tab_count() - 1));
+ ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_tab_control(tab_container->get_tab_count() - 1));
if (se) {
se->set_edit_state(script_info["state"]);
}
@@ -3196,8 +3196,8 @@ void ScriptEditor::set_window_layout(Ref<ConfigFile> p_layout) {
_help_class_open(path);
}
- for (int i = 0; i < tab_container->get_child_count(); i++) {
- tab_container->get_child(i)->set_meta("__editor_pass", Variant());
+ for (int i = 0; i < tab_container->get_tab_count(); i++) {
+ tab_container->get_tab_control(i)->set_meta("__editor_pass", Variant());
}
if (p_layout->has_section_key("ScriptEditor", "script_split_offset")) {
@@ -3237,8 +3237,8 @@ void ScriptEditor::get_window_layout(Ref<ConfigFile> p_layout) {
Array scripts;
Array helps;
- for (int i = 0; i < tab_container->get_child_count(); i++) {
- ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_child(i));
+ for (int i = 0; i < tab_container->get_tab_count(); i++) {
+ ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_tab_control(i));
if (se) {
String path = se->get_edited_resource()->get_path();
if (!path.is_resource_file()) {
@@ -3249,7 +3249,7 @@ void ScriptEditor::get_window_layout(Ref<ConfigFile> p_layout) {
scripts.push_back(path);
}
- EditorHelp *eh = Object::cast_to<EditorHelp>(tab_container->get_child(i));
+ EditorHelp *eh = Object::cast_to<EditorHelp>(tab_container->get_tab_control(i));
if (eh) {
helps.push_back(eh->get_class());
@@ -3270,8 +3270,8 @@ void ScriptEditor::_help_class_open(const String &p_class) {
return;
}
- for (int i = 0; i < tab_container->get_child_count(); i++) {
- EditorHelp *eh = Object::cast_to<EditorHelp>(tab_container->get_child(i));
+ for (int i = 0; i < tab_container->get_tab_count(); i++) {
+ EditorHelp *eh = Object::cast_to<EditorHelp>(tab_container->get_tab_control(i));
if (eh && eh->get_class() == p_class) {
_go_to_tab(i);
@@ -3296,8 +3296,8 @@ void ScriptEditor::_help_class_open(const String &p_class) {
void ScriptEditor::_help_class_goto(const String &p_desc) {
String cname = p_desc.get_slice(":", 1);
- for (int i = 0; i < tab_container->get_child_count(); i++) {
- EditorHelp *eh = Object::cast_to<EditorHelp>(tab_container->get_child(i));
+ for (int i = 0; i < tab_container->get_tab_count(); i++) {
+ EditorHelp *eh = Object::cast_to<EditorHelp>(tab_container->get_tab_control(i));
if (eh && eh->get_class() == cname) {
_go_to_tab(i);
@@ -3323,8 +3323,8 @@ void ScriptEditor::_help_class_goto(const String &p_desc) {
void ScriptEditor::update_doc(const String &p_name) {
ERR_FAIL_COND(!EditorHelp::get_doc_data()->has_doc(p_name));
- for (int i = 0; i < tab_container->get_child_count(); i++) {
- EditorHelp *eh = Object::cast_to<EditorHelp>(tab_container->get_child(i));
+ for (int i = 0; i < tab_container->get_tab_count(); i++) {
+ EditorHelp *eh = Object::cast_to<EditorHelp>(tab_container->get_tab_control(i));
if (eh && eh->get_class() == p_name) {
eh->update_doc();
return;
@@ -3333,10 +3333,10 @@ void ScriptEditor::update_doc(const String &p_name) {
}
void ScriptEditor::_update_selected_editor_menu() {
- for (int i = 0; i < tab_container->get_child_count(); i++) {
+ for (int i = 0; i < tab_container->get_tab_count(); i++) {
bool current = tab_container->get_current_tab() == i;
- ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_child(i));
+ ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_tab_control(i));
if (se && se->get_edit_menu()) {
if (current) {
se->get_edit_menu()->show();
@@ -3356,7 +3356,7 @@ void ScriptEditor::_update_selected_editor_menu() {
script_search_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/find_in_files", TTR("Find in Files"), KeyModifierMask::CMD | KeyModifierMask::SHIFT | Key::F), SEARCH_IN_FILES);
script_search_menu->show();
} else {
- if (tab_container->get_child_count() == 0) {
+ if (tab_container->get_tab_count() == 0) {
script_search_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/find_in_files", TTR("Find in Files"), KeyModifierMask::CMD | KeyModifierMask::SHIFT | Key::F), SEARCH_IN_FILES);
script_search_menu->show();
} else {
@@ -3376,7 +3376,7 @@ void ScriptEditor::_update_history_pos(int p_new_pos) {
}
history_pos = p_new_pos;
- tab_container->set_current_tab(history[history_pos].control->get_index());
+ tab_container->set_current_tab(tab_container->get_tab_idx_from_control(history[history_pos].control));
n = history[history_pos].control;
@@ -3416,8 +3416,8 @@ void ScriptEditor::_history_back() {
Vector<Ref<Script>> ScriptEditor::get_open_scripts() const {
Vector<Ref<Script>> out_scripts = Vector<Ref<Script>>();
- for (int i = 0; i < tab_container->get_child_count(); i++) {
- ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_child(i));
+ for (int i = 0; i < tab_container->get_tab_count(); i++) {
+ ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_tab_control(i));
if (!se) {
continue;
}
@@ -3433,8 +3433,8 @@ Vector<Ref<Script>> ScriptEditor::get_open_scripts() const {
Array ScriptEditor::_get_open_script_editors() const {
Array script_editors;
- for (int i = 0; i < tab_container->get_child_count(); i++) {
- ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_child(i));
+ for (int i = 0; i < tab_container->get_tab_count(); i++) {
+ ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_tab_control(i));
if (!se) {
continue;
}
@@ -3539,7 +3539,7 @@ void ScriptEditor::_on_find_in_files_result_selected(String fpath, int line_numb
shader_editor->get_shader_editor()->goto_line_selection(line_number - 1, begin, end);
return;
} else if (fpath.get_extension() == "tscn") {
- editor->load_scene(fpath);
+ EditorNode::get_singleton()->load_scene(fpath);
return;
} else {
Ref<Script> script = res;
@@ -3581,7 +3581,7 @@ void ScriptEditor::_start_find_in_files(bool with_replace) {
find_in_files->set_replace_text(find_in_files_dialog->get_replace_text());
find_in_files->start_search();
- editor->make_bottom_panel_item_visible(find_in_files);
+ EditorNode::get_singleton()->make_bottom_panel_item_visible(find_in_files);
}
void ScriptEditor::_on_find_in_files_modified_files(PackedStringArray paths) {
@@ -3629,7 +3629,7 @@ void ScriptEditor::_bind_methods() {
ADD_SIGNAL(MethodInfo("script_close", PropertyInfo(Variant::OBJECT, "script", PROPERTY_HINT_RESOURCE_TYPE, "Script")));
}
-ScriptEditor::ScriptEditor(EditorNode *p_editor) {
+ScriptEditor::ScriptEditor() {
current_theme = "";
script_editor_cache.instantiate();
@@ -3642,7 +3642,6 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) {
auto_reload_running_scripts = true;
members_overview_enabled = EditorSettings::get_singleton()->get("text_editor/script_list/show_members_overview");
help_overview_enabled = EditorSettings::get_singleton()->get("text_editor/help/show_help_index");
- editor = p_editor;
VBoxContainer *main_container = memnew(VBoxContainer);
add_child(main_container);
@@ -3932,7 +3931,7 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) {
find_in_files_dialog->connect(FindInFilesDialog::SIGNAL_REPLACE_REQUESTED, callable_mp(this, &ScriptEditor::_start_find_in_files), varray(true));
add_child(find_in_files_dialog);
find_in_files = memnew(FindInFilesPanel);
- find_in_files_button = editor->add_bottom_panel_item(TTR("Search Results"), find_in_files);
+ find_in_files_button = EditorNode::get_singleton()->add_bottom_panel_item(TTR("Search Results"), find_in_files);
find_in_files->set_custom_minimum_size(Size2(0, 200) * EDSCALE);
find_in_files->connect(FindInFilesPanel::SIGNAL_RESULT_SELECTED, callable_mp(this, &ScriptEditor::_on_find_in_files_result_selected));
find_in_files->connect(FindInFilesPanel::SIGNAL_FILES_MODIFIED, callable_mp(this, &ScriptEditor::_on_find_in_files_modified_files));
@@ -3948,8 +3947,8 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) {
ScriptServer::edit_request_func = _open_script_request;
- add_theme_style_override("panel", editor->get_gui_base()->get_theme_stylebox(SNAME("ScriptEditorPanel"), SNAME("EditorStyles")));
- tab_container->add_theme_style_override("panel", editor->get_gui_base()->get_theme_stylebox(SNAME("ScriptEditor"), SNAME("EditorStyles")));
+ add_theme_style_override("panel", EditorNode::get_singleton()->get_gui_base()->get_theme_stylebox(SNAME("ScriptEditorPanel"), SNAME("EditorStyles")));
+ tab_container->add_theme_style_override("panel", EditorNode::get_singleton()->get_gui_base()->get_theme_stylebox(SNAME("ScriptEditor"), SNAME("EditorStyles")));
}
ScriptEditor::~ScriptEditor() {
@@ -4033,15 +4032,14 @@ void ScriptEditorPlugin::edited_scene_changed() {
script_editor->edited_scene_changed();
}
-ScriptEditorPlugin::ScriptEditorPlugin(EditorNode *p_node) {
- editor = p_node;
- script_editor = memnew(ScriptEditor(p_node));
- editor->get_main_control()->add_child(script_editor);
+ScriptEditorPlugin::ScriptEditorPlugin() {
+ script_editor = memnew(ScriptEditor);
+ EditorNode::get_singleton()->get_main_control()->add_child(script_editor);
script_editor->set_v_size_flags(Control::SIZE_EXPAND_FILL);
script_editor->hide();
- EDITOR_DEF("text_editor/behavior/files/auto_reload_scripts_on_external_change", true);
+ EDITOR_GET("text_editor/behavior/files/auto_reload_scripts_on_external_change");
ScriptServer::set_reload_scripts_on_save(EDITOR_DEF("text_editor/behavior/files/auto_reload_and_parse_scripts_on_save", true));
EDITOR_DEF("text_editor/behavior/files/open_dominant_script_on_scene_change", true);
EDITOR_DEF("text_editor/external/use_external_editor", false);
diff --git a/editor/plugins/script_editor_plugin.h b/editor/plugins/script_editor_plugin.h
index d754f1a378..a99e269d46 100644
--- a/editor/plugins/script_editor_plugin.h
+++ b/editor/plugins/script_editor_plugin.h
@@ -47,6 +47,8 @@
#include "scene/main/timer.h"
#include "scene/resources/text_file.h"
+class EditorFileDialog;
+
class EditorSyntaxHighlighter : public SyntaxHighlighter {
GDCLASS(EditorSyntaxHighlighter, SyntaxHighlighter)
@@ -186,7 +188,6 @@ class FindInFilesPanel;
class ScriptEditor : public PanelContainer {
GDCLASS(ScriptEditor, PanelContainer);
- EditorNode *editor;
enum {
FILE_NEW,
FILE_NEW_TEXTFILE,
@@ -520,7 +521,7 @@ public:
static void register_create_script_editor_function(CreateScriptEditorFunc p_func);
- ScriptEditor(EditorNode *p_editor);
+ ScriptEditor();
~ScriptEditor();
};
@@ -528,7 +529,6 @@ class ScriptEditorPlugin : public EditorPlugin {
GDCLASS(ScriptEditorPlugin, EditorPlugin);
ScriptEditor *script_editor;
- EditorNode *editor;
public:
virtual String get_name() const override { return "Script"; }
@@ -551,7 +551,7 @@ public:
virtual void edited_scene_changed() override;
- ScriptEditorPlugin(EditorNode *p_node);
+ ScriptEditorPlugin();
~ScriptEditorPlugin();
};
diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp
index 19ed11acb4..10b6129864 100644
--- a/editor/plugins/script_text_editor.cpp
+++ b/editor/plugins/script_text_editor.cpp
@@ -30,6 +30,7 @@
#include "script_text_editor.h"
+#include "core/config/project_settings.h"
#include "core/math/expression.h"
#include "core/os/keyboard.h"
#include "editor/debugger/editor_debugger_node.h"
@@ -398,10 +399,10 @@ Ref<Texture2D> ScriptTextEditor::get_theme_icon() {
icon_name += "Internal";
}
- if (get_parent_control()->has_theme_icon(icon_name, "EditorIcons")) {
- return get_parent_control()->get_theme_icon(icon_name, "EditorIcons");
- } else if (get_parent_control()->has_theme_icon(script->get_class(), "EditorIcons")) {
- return get_parent_control()->get_theme_icon(script->get_class(), "EditorIcons");
+ if (get_parent_control()->has_theme_icon(icon_name, SNAME("EditorIcons"))) {
+ return get_parent_control()->get_theme_icon(icon_name, SNAME("EditorIcons"));
+ } else if (get_parent_control()->has_theme_icon(script->get_class(), SNAME("EditorIcons"))) {
+ return get_parent_control()->get_theme_icon(script->get_class(), SNAME("EditorIcons"));
}
}
@@ -520,7 +521,7 @@ void ScriptTextEditor::_update_errors() {
errors_panel->pop(); // Table
CodeEdit *te = code_editor->get_text_editor();
- bool highlight_safe = EDITOR_DEF("text_editor/appearance/gutters/highlight_type_safe_lines", true);
+ bool highlight_safe = EDITOR_GET("text_editor/appearance/gutters/highlight_type_safe_lines");
bool last_is_safe = false;
for (int i = 0; i < te->get_line_count(); i++) {
if (errors.is_empty()) {
@@ -930,21 +931,22 @@ void ScriptTextEditor::_update_connected_methods() {
continue;
}
- if (methods_found.has(connection.callable.get_method())) {
+ const StringName method = connection.callable.get_method();
+ if (methods_found.has(method)) {
continue;
}
- if (!ClassDB::has_method(script->get_instance_base_type(), connection.callable.get_method())) {
+ if (!ClassDB::has_method(script->get_instance_base_type(), method)) {
int line = -1;
for (int j = 0; j < functions.size(); j++) {
String name = functions[j].get_slice(":", 0);
- if (name == connection.callable.get_method()) {
+ if (name == method) {
line = functions[j].get_slice(":", 1).to_int() - 1;
- text_edit->set_line_gutter_metadata(line, connection_gutter, connection.callable.get_method());
+ text_edit->set_line_gutter_metadata(line, connection_gutter, method);
text_edit->set_line_gutter_icon(line, connection_gutter, get_parent_control()->get_theme_icon(SNAME("Slot"), SNAME("EditorIcons")));
text_edit->set_line_gutter_clickable(line, connection_gutter, true);
- methods_found.insert(connection.callable.get_method());
+ methods_found.insert(method);
break;
}
}
@@ -957,7 +959,7 @@ void ScriptTextEditor::_update_connected_methods() {
bool found_inherited_function = false;
Ref<Script> inherited_script = script->get_base_script();
while (!inherited_script.is_null()) {
- if (inherited_script->has_method(connection.callable.get_method())) {
+ if (inherited_script->has_method(method)) {
found_inherited_function = true;
break;
}
@@ -1333,6 +1335,9 @@ void ScriptTextEditor::_change_syntax_highlighter(int p_idx) {
void ScriptTextEditor::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_THEME_CHANGED:
+ if (!editor_enabled) {
+ break;
+ }
if (is_visible_in_tree()) {
_update_warnings();
_update_errors();
@@ -1341,8 +1346,6 @@ void ScriptTextEditor::_notification(int p_what) {
case NOTIFICATION_ENTER_TREE: {
code_editor->get_text_editor()->set_gutter_width(connection_gutter, code_editor->get_text_editor()->get_line_height());
} break;
- default:
- break;
}
}
@@ -1373,7 +1376,7 @@ void ScriptTextEditor::reload(bool p_soft) {
return;
}
scr->set_source_code(te->get_text());
- bool soft = p_soft || scr->get_instance_base_type() == "EditorPlugin"; //always soft-reload editor plugins
+ bool soft = p_soft || scr->get_instance_base_type() == "EditorPlugin"; // Always soft-reload editor plugins.
scr->get_language()->reload_tool_script(scr, soft);
}
diff --git a/editor/plugins/shader_editor_plugin.cpp b/editor/plugins/shader_editor_plugin.cpp
index 4bbeb33406..382138a995 100644
--- a/editor/plugins/shader_editor_plugin.cpp
+++ b/editor/plugins/shader_editor_plugin.cpp
@@ -464,14 +464,6 @@ void ShaderEditor::_bind_methods() {
}
void ShaderEditor::ensure_select_current() {
- /*
- if (tab_container->get_child_count() && tab_container->get_current_tab()>=0) {
- ShaderTextEditor *ste = Object::cast_to<ShaderTextEditor>(tab_container->get_child(tab_container->get_current_tab()));
- if (!ste)
- return;
- Ref<Shader> shader = ste->get_edited_shader();
- get_scene()->get_root_node()->call("_resource_selected",shader);
- }*/
}
void ShaderEditor::goto_line_selection(int p_line, int p_begin, int p_end) {
@@ -528,7 +520,7 @@ void ShaderEditor::_check_for_external_edit() {
return;
}
- bool use_autoreload = bool(EDITOR_DEF("text_editor/behavior/files/auto_reload_scripts_on_external_change", false));
+ bool use_autoreload = bool(EDITOR_GET("text_editor/behavior/files/auto_reload_scripts_on_external_change"));
if (shader->get_last_modified_time() != FileAccess::get_modified_time(shader->get_path())) {
if (use_autoreload) {
_reload_shader_from_disk();
@@ -691,7 +683,7 @@ void ShaderEditor::_make_context_menu(bool p_selection, Vector2 p_position) {
context_menu->popup();
}
-ShaderEditor::ShaderEditor(EditorNode *p_node) {
+ShaderEditor::ShaderEditor() {
GLOBAL_DEF("debug/shader_language/warnings/enable", true);
GLOBAL_DEF("debug/shader_language/warnings/treat_warnings_as_errors", false);
for (int i = 0; i < (int)ShaderWarning::WARNING_MAX; i++) {
@@ -780,7 +772,7 @@ ShaderEditor::ShaderEditor(EditorNode *p_node) {
help_menu = memnew(MenuButton);
help_menu->set_text(TTR("Help"));
help_menu->set_switch_on_hover(true);
- help_menu->get_popup()->add_icon_item(p_node->get_gui_base()->get_theme_icon(SNAME("Instance"), SNAME("EditorIcons")), TTR("Online Docs"), HELP_DOCS);
+ help_menu->get_popup()->add_icon_item(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Instance"), SNAME("EditorIcons")), TTR("Online Docs"), HELP_DOCS);
help_menu->get_popup()->connect("id_pressed", callable_mp(this, &ShaderEditor::_menu_option));
add_child(main_container);
@@ -789,7 +781,7 @@ ShaderEditor::ShaderEditor(EditorNode *p_node) {
hbc->add_child(edit_menu);
hbc->add_child(goto_menu);
hbc->add_child(help_menu);
- hbc->add_theme_style_override("panel", p_node->get_gui_base()->get_theme_stylebox(SNAME("ScriptEditorPanel"), SNAME("EditorStyles")));
+ hbc->add_theme_style_override("panel", EditorNode::get_singleton()->get_gui_base()->get_theme_stylebox(SNAME("ScriptEditorPanel"), SNAME("EditorStyles")));
VSplitContainer *editor_box = memnew(VSplitContainer);
main_container->add_child(editor_box);
@@ -849,12 +841,12 @@ bool ShaderEditorPlugin::handles(Object *p_object) const {
void ShaderEditorPlugin::make_visible(bool p_visible) {
if (p_visible) {
button->show();
- editor->make_bottom_panel_item_visible(shader_editor);
+ EditorNode::get_singleton()->make_bottom_panel_item_visible(shader_editor);
} else {
button->hide();
if (shader_editor->is_visible_in_tree()) {
- editor->hide_bottom_panel();
+ EditorNode::get_singleton()->hide_bottom_panel();
}
shader_editor->apply_shaders();
}
@@ -872,12 +864,11 @@ void ShaderEditorPlugin::apply_changes() {
shader_editor->apply_shaders();
}
-ShaderEditorPlugin::ShaderEditorPlugin(EditorNode *p_node) {
- editor = p_node;
- shader_editor = memnew(ShaderEditor(p_node));
+ShaderEditorPlugin::ShaderEditorPlugin() {
+ shader_editor = memnew(ShaderEditor);
shader_editor->set_custom_minimum_size(Size2(0, 300) * EDSCALE);
- button = editor->add_bottom_panel_item(TTR("Shader"), shader_editor);
+ button = EditorNode::get_singleton()->add_bottom_panel_item(TTR("Shader"), shader_editor);
button->hide();
_2d = false;
diff --git a/editor/plugins/shader_editor_plugin.h b/editor/plugins/shader_editor_plugin.h
index 9196ded921..b1391e4f66 100644
--- a/editor/plugins/shader_editor_plugin.h
+++ b/editor/plugins/shader_editor_plugin.h
@@ -154,7 +154,7 @@ public:
virtual Size2 get_minimum_size() const override { return Size2(0, 200); }
void save_external_data(const String &p_str = "");
- ShaderEditor(EditorNode *p_node);
+ ShaderEditor();
};
class ShaderEditorPlugin : public EditorPlugin {
@@ -162,7 +162,6 @@ class ShaderEditorPlugin : public EditorPlugin {
bool _2d;
ShaderEditor *shader_editor;
- EditorNode *editor;
Button *button;
public:
@@ -178,7 +177,7 @@ public:
virtual void save_external_data() override;
virtual void apply_changes() override;
- ShaderEditorPlugin(EditorNode *p_node);
+ ShaderEditorPlugin();
~ShaderEditorPlugin();
};
diff --git a/editor/plugins/shader_file_editor_plugin.cpp b/editor/plugins/shader_file_editor_plugin.cpp
index 8250164885..4458555de2 100644
--- a/editor/plugins/shader_file_editor_plugin.cpp
+++ b/editor/plugins/shader_file_editor_plugin.cpp
@@ -200,10 +200,12 @@ void ShaderFileEditor::_update_options() {
}
void ShaderFileEditor::_notification(int p_what) {
- if (p_what == NOTIFICATION_WM_WINDOW_FOCUS_IN) {
- if (is_visible_in_tree() && shader_file.is_valid()) {
- _update_options();
- }
+ switch (p_what) {
+ case NOTIFICATION_WM_WINDOW_FOCUS_IN: {
+ if (is_visible_in_tree() && shader_file.is_valid()) {
+ _update_options();
+ }
+ } break;
}
}
@@ -245,7 +247,7 @@ void ShaderFileEditor::_shader_changed() {
ShaderFileEditor *ShaderFileEditor::singleton = nullptr;
-ShaderFileEditor::ShaderFileEditor(EditorNode *p_node) {
+ShaderFileEditor::ShaderFileEditor() {
singleton = this;
HSplitContainer *main_hs = memnew(HSplitContainer);
@@ -301,22 +303,21 @@ bool ShaderFileEditorPlugin::handles(Object *p_object) const {
void ShaderFileEditorPlugin::make_visible(bool p_visible) {
if (p_visible) {
button->show();
- editor->make_bottom_panel_item_visible(shader_editor);
+ EditorNode::get_singleton()->make_bottom_panel_item_visible(shader_editor);
} else {
button->hide();
if (shader_editor->is_visible_in_tree()) {
- editor->hide_bottom_panel();
+ EditorNode::get_singleton()->hide_bottom_panel();
}
}
}
-ShaderFileEditorPlugin::ShaderFileEditorPlugin(EditorNode *p_node) {
- editor = p_node;
- shader_editor = memnew(ShaderFileEditor(p_node));
+ShaderFileEditorPlugin::ShaderFileEditorPlugin() {
+ shader_editor = memnew(ShaderFileEditor);
shader_editor->set_custom_minimum_size(Size2(0, 300) * EDSCALE);
- button = editor->add_bottom_panel_item(TTR("ShaderFile"), shader_editor);
+ button = EditorNode::get_singleton()->add_bottom_panel_item(TTR("ShaderFile"), shader_editor);
button->hide();
}
diff --git a/editor/plugins/shader_file_editor_plugin.h b/editor/plugins/shader_file_editor_plugin.h
index feec0c206e..5ee2d01dbf 100644
--- a/editor/plugins/shader_file_editor_plugin.h
+++ b/editor/plugins/shader_file_editor_plugin.h
@@ -41,6 +41,8 @@
#include "scene/main/timer.h"
#include "servers/rendering/rendering_device_binds.h"
+class ItemList;
+
class ShaderFileEditor : public PanelContainer {
GDCLASS(ShaderFileEditor, PanelContainer);
@@ -66,14 +68,13 @@ public:
static ShaderFileEditor *singleton;
void edit(const Ref<RDShaderFile> &p_shader);
- ShaderFileEditor(EditorNode *p_node);
+ ShaderFileEditor();
};
class ShaderFileEditorPlugin : public EditorPlugin {
GDCLASS(ShaderFileEditorPlugin, EditorPlugin);
ShaderFileEditor *shader_editor;
- EditorNode *editor;
Button *button;
public:
@@ -85,7 +86,7 @@ public:
ShaderFileEditor *get_shader_editor() const { return shader_editor; }
- ShaderFileEditorPlugin(EditorNode *p_node);
+ ShaderFileEditorPlugin();
~ShaderFileEditorPlugin();
};
diff --git a/editor/plugins/skeleton_2d_editor_plugin.cpp b/editor/plugins/skeleton_2d_editor_plugin.cpp
index b6d465ea81..5a1505c232 100644
--- a/editor/plugins/skeleton_2d_editor_plugin.cpp
+++ b/editor/plugins/skeleton_2d_editor_plugin.cpp
@@ -31,6 +31,7 @@
#include "skeleton_2d_editor_plugin.h"
#include "canvas_item_editor_plugin.h"
+#include "editor/editor_node.h"
#include "scene/2d/mesh_instance_2d.h"
#include "scene/gui/box_container.h"
#include "thirdparty/misc/clipper.hpp"
@@ -127,10 +128,9 @@ void Skeleton2DEditorPlugin::make_visible(bool p_visible) {
}
}
-Skeleton2DEditorPlugin::Skeleton2DEditorPlugin(EditorNode *p_node) {
- editor = p_node;
+Skeleton2DEditorPlugin::Skeleton2DEditorPlugin() {
sprite_editor = memnew(Skeleton2DEditor);
- editor->get_main_control()->add_child(sprite_editor);
+ EditorNode::get_singleton()->get_main_control()->add_child(sprite_editor);
make_visible(false);
//sprite_editor->options->hide();
diff --git a/editor/plugins/skeleton_2d_editor_plugin.h b/editor/plugins/skeleton_2d_editor_plugin.h
index 2fa7f02622..004dac7b05 100644
--- a/editor/plugins/skeleton_2d_editor_plugin.h
+++ b/editor/plugins/skeleton_2d_editor_plugin.h
@@ -31,7 +31,6 @@
#ifndef SKELETON_2D_EDITOR_PLUGIN_H
#define SKELETON_2D_EDITOR_PLUGIN_H
-#include "editor/editor_node.h"
#include "editor/editor_plugin.h"
#include "scene/2d/skeleton_2d.h"
#include "scene/gui/spin_box.h"
@@ -67,7 +66,6 @@ class Skeleton2DEditorPlugin : public EditorPlugin {
GDCLASS(Skeleton2DEditorPlugin, EditorPlugin);
Skeleton2DEditor *sprite_editor;
- EditorNode *editor;
public:
virtual String get_name() const override { return "Skeleton2D"; }
@@ -76,7 +74,7 @@ public:
virtual bool handles(Object *p_object) const override;
virtual void make_visible(bool p_visible) override;
- Skeleton2DEditorPlugin(EditorNode *p_node);
+ Skeleton2DEditorPlugin();
~Skeleton2DEditorPlugin();
};
diff --git a/editor/plugins/skeleton_3d_editor_plugin.cpp b/editor/plugins/skeleton_3d_editor_plugin.cpp
index 5dd24983ff..aadc7a2e66 100644
--- a/editor/plugins/skeleton_3d_editor_plugin.cpp
+++ b/editor/plugins/skeleton_3d_editor_plugin.cpp
@@ -32,6 +32,7 @@
#include "core/io/resource_saver.h"
#include "editor/editor_file_dialog.h"
+#include "editor/editor_node.h"
#include "editor/editor_properties.h"
#include "editor/editor_scale.h"
#include "editor/plugins/animation_player_editor_plugin.h"
@@ -102,8 +103,7 @@ void BoneTransformEditor::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
create_editors();
- break;
- }
+ } break;
}
}
@@ -530,18 +530,23 @@ void Skeleton3DEditor::_joint_tree_selection_changed() {
TreeItem *selected = joint_tree->get_selected();
if (selected) {
const String path = selected->get_metadata(0);
-
- if (path.begins_with("bones/")) {
- const int b_idx = path.get_slicec('/', 1).to_int();
+ if (!path.begins_with("bones/")) {
+ return;
+ }
+ const int b_idx = path.get_slicec('/', 1).to_int();
+ selected_bone = b_idx;
+ if (pose_editor) {
const String bone_path = "bones/" + itos(b_idx) + "/";
-
pose_editor->set_target(bone_path);
pose_editor->set_keyable(keyable);
- selected_bone = b_idx;
}
}
- pose_editor->set_visible(selected);
+
+ if (pose_editor && pose_editor->is_inside_tree()) {
+ pose_editor->set_visible(selected);
+ }
set_bone_options_enabled(selected);
+
_update_properties();
_update_gizmo_visible();
}
@@ -786,8 +791,7 @@ void Skeleton3DEditor::edit_mode_toggled(const bool pressed) {
_update_gizmo_visible();
}
-Skeleton3DEditor::Skeleton3DEditor(EditorInspectorPluginSkeleton *e_plugin, EditorNode *p_editor, Skeleton3D *p_skeleton) :
- editor(p_editor),
+Skeleton3DEditor::Skeleton3DEditor(EditorInspectorPluginSkeleton *e_plugin, Skeleton3D *p_skeleton) :
editor_plugin(e_plugin),
skeleton(p_skeleton) {
singleton = this;
@@ -821,7 +825,7 @@ void fragment() {
}
)");
handle_material->set_shader(handle_shader);
- Ref<Texture2D> handle = editor->get_gui_base()->get_theme_icon("EditorBoneHandle", "EditorIcons");
+ Ref<Texture2D> handle = EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("EditorBoneHandle"), SNAME("EditorIcons"));
handle_material->set_shader_param("point_size", handle->get_width());
handle_material->set_shader_param("texture_albedo", handle);
@@ -1012,15 +1016,12 @@ void EditorInspectorPluginSkeleton::parse_begin(Object *p_object) {
Skeleton3D *skeleton = Object::cast_to<Skeleton3D>(p_object);
ERR_FAIL_COND(!skeleton);
- skel_editor = memnew(Skeleton3DEditor(this, editor, skeleton));
+ skel_editor = memnew(Skeleton3DEditor(this, skeleton));
add_custom_control(skel_editor);
}
-Skeleton3DEditorPlugin::Skeleton3DEditorPlugin(EditorNode *p_node) {
- editor = p_node;
-
+Skeleton3DEditorPlugin::Skeleton3DEditorPlugin() {
skeleton_plugin = memnew(EditorInspectorPluginSkeleton);
- skeleton_plugin->editor = editor;
EditorInspector::add_inspector_plugin(skeleton_plugin);
diff --git a/editor/plugins/skeleton_3d_editor_plugin.h b/editor/plugins/skeleton_3d_editor_plugin.h
index d0d81d6498..2dbb552428 100644
--- a/editor/plugins/skeleton_3d_editor_plugin.h
+++ b/editor/plugins/skeleton_3d_editor_plugin.h
@@ -31,7 +31,6 @@
#ifndef SKELETON_3D_EDITOR_PLUGIN_H
#define SKELETON_3D_EDITOR_PLUGIN_H
-#include "editor/editor_node.h"
#include "editor/editor_plugin.h"
#include "editor/editor_properties.h"
#include "node_3d_editor_plugin.h"
@@ -109,7 +108,6 @@ class Skeleton3DEditor : public VBoxContainer {
Transform3D relative_rest; // Relative to skeleton node.
};
- EditorNode *editor;
EditorInspectorPluginSkeleton *editor_plugin;
Skeleton3D *skeleton;
@@ -213,7 +211,7 @@ public:
Quaternion get_bone_original_rotation() const { return bone_original_rotation; };
Vector3 get_bone_original_scale() const { return bone_original_scale; };
- Skeleton3DEditor(EditorInspectorPluginSkeleton *e_plugin, EditorNode *p_editor, Skeleton3D *skeleton);
+ Skeleton3DEditor(EditorInspectorPluginSkeleton *e_plugin, Skeleton3D *skeleton);
~Skeleton3DEditor();
};
@@ -223,7 +221,6 @@ class EditorInspectorPluginSkeleton : public EditorInspectorPlugin {
friend class Skeleton3DEditorPlugin;
Skeleton3DEditor *skel_editor;
- EditorNode *editor;
public:
virtual bool can_handle(Object *p_object) override;
@@ -234,7 +231,6 @@ class Skeleton3DEditorPlugin : public EditorPlugin {
GDCLASS(Skeleton3DEditorPlugin, EditorPlugin);
EditorInspectorPluginSkeleton *skeleton_plugin;
- EditorNode *editor;
public:
virtual EditorPlugin::AfterGUIInput forward_spatial_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event) override;
@@ -244,7 +240,7 @@ public:
virtual String get_name() const override { return "Skeleton3D"; }
- Skeleton3DEditorPlugin(EditorNode *p_node);
+ Skeleton3DEditorPlugin();
};
class Skeleton3DGizmoPlugin : public EditorNode3DGizmoPlugin {
diff --git a/editor/plugins/skeleton_ik_3d_editor_plugin.cpp b/editor/plugins/skeleton_ik_3d_editor_plugin.cpp
index ca8786a385..7dc34a0874 100644
--- a/editor/plugins/skeleton_ik_3d_editor_plugin.cpp
+++ b/editor/plugins/skeleton_ik_3d_editor_plugin.cpp
@@ -30,6 +30,7 @@
#include "skeleton_ik_3d_editor_plugin.h"
+#include "editor/editor_node.h"
#include "scene/3d/skeleton_ik_3d.h"
void SkeletonIK3DEditorPlugin::_play() {
@@ -80,10 +81,9 @@ void SkeletonIK3DEditorPlugin::make_visible(bool p_visible) {
void SkeletonIK3DEditorPlugin::_bind_methods() {
}
-SkeletonIK3DEditorPlugin::SkeletonIK3DEditorPlugin(EditorNode *p_node) {
- editor = p_node;
+SkeletonIK3DEditorPlugin::SkeletonIK3DEditorPlugin() {
play_btn = memnew(Button);
- play_btn->set_icon(editor->get_gui_base()->get_theme_icon(SNAME("Play"), SNAME("EditorIcons")));
+ play_btn->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Play"), SNAME("EditorIcons")));
play_btn->set_text(TTR("Play IK"));
play_btn->set_toggle_mode(true);
play_btn->hide();
diff --git a/editor/plugins/skeleton_ik_3d_editor_plugin.h b/editor/plugins/skeleton_ik_3d_editor_plugin.h
index edc3f6dda4..f71e788232 100644
--- a/editor/plugins/skeleton_ik_3d_editor_plugin.h
+++ b/editor/plugins/skeleton_ik_3d_editor_plugin.h
@@ -31,7 +31,6 @@
#ifndef SKELETON_IK_3D_EDITOR_PLUGIN_H
#define SKELETON_IK_3D_EDITOR_PLUGIN_H
-#include "editor/editor_node.h"
#include "editor/editor_plugin.h"
class SkeletonIK3D;
@@ -42,7 +41,6 @@ class SkeletonIK3DEditorPlugin : public EditorPlugin {
SkeletonIK3D *skeleton_ik;
Button *play_btn;
- EditorNode *editor;
void _play();
@@ -56,7 +54,7 @@ public:
virtual bool handles(Object *p_object) const override;
virtual void make_visible(bool p_visible) override;
- SkeletonIK3DEditorPlugin(EditorNode *p_node);
+ SkeletonIK3DEditorPlugin();
~SkeletonIK3DEditorPlugin();
};
diff --git a/editor/plugins/sprite_2d_editor_plugin.cpp b/editor/plugins/sprite_2d_editor_plugin.cpp
index 85ff20dd23..6a63875324 100644
--- a/editor/plugins/sprite_2d_editor_plugin.cpp
+++ b/editor/plugins/sprite_2d_editor_plugin.cpp
@@ -32,7 +32,9 @@
#include "canvas_item_editor_plugin.h"
#include "core/math/geometry_2d.h"
+#include "editor/editor_node.h"
#include "editor/editor_scale.h"
+#include "editor/scene_tree_dock.h"
#include "scene/2d/collision_polygon_2d.h"
#include "scene/2d/light_occluder_2d.h"
#include "scene/2d/mesh_instance_2d.h"
@@ -120,8 +122,8 @@ void Sprite2DEditor::_menu_option(int p_option) {
switch (p_option) {
case MENU_OPTION_CONVERT_TO_MESH_2D: {
- debug_uv_dialog->get_ok_button()->set_text(TTR("Create Mesh2D"));
- debug_uv_dialog->set_title(TTR("Mesh2D Preview"));
+ debug_uv_dialog->get_ok_button()->set_text(TTR("Create MeshInstance2D"));
+ debug_uv_dialog->set_title(TTR("MeshInstance2D Preview"));
_update_mesh_data();
debug_uv_dialog->popup_centered();
@@ -336,7 +338,7 @@ void Sprite2DEditor::_convert_to_mesh_2d_node() {
mesh_instance->set_mesh(mesh);
UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
- ur->create_action(TTR("Convert to Mesh2D"));
+ ur->create_action(TTR("Convert to MeshInstance2D"));
ur->add_do_method(SceneTreeDock::get_singleton(), "replace_node", node, mesh_instance, true, false);
ur->add_do_reference(mesh_instance);
ur->add_undo_method(SceneTreeDock::get_singleton(), "replace_node", mesh_instance, node, false, false);
@@ -496,6 +498,20 @@ void Sprite2DEditor::_debug_uv_draw() {
}
}
+void Sprite2DEditor::_notification(int p_what) {
+ switch (p_what) {
+ case NOTIFICATION_ENTER_TREE:
+ case NOTIFICATION_THEME_CHANGED: {
+ options->set_icon(get_theme_icon(SNAME("Sprite2D"), SNAME("EditorIcons")));
+
+ options->get_popup()->set_item_icon(MENU_OPTION_CONVERT_TO_MESH_2D, get_theme_icon(SNAME("MeshInstance2D"), SNAME("EditorIcons")));
+ options->get_popup()->set_item_icon(MENU_OPTION_CONVERT_TO_POLYGON_2D, get_theme_icon(SNAME("Polygon2D"), SNAME("EditorIcons")));
+ options->get_popup()->set_item_icon(MENU_OPTION_CREATE_COLLISION_POLY_2D, get_theme_icon(SNAME("CollisionPolygon2D"), SNAME("EditorIcons")));
+ options->get_popup()->set_item_icon(MENU_OPTION_CREATE_LIGHT_OCCLUDER_2D, get_theme_icon(SNAME("LightOccluder2D"), SNAME("EditorIcons")));
+ } break;
+ }
+}
+
void Sprite2DEditor::_bind_methods() {
ClassDB::bind_method("_add_as_sibling_or_child", &Sprite2DEditor::_add_as_sibling_or_child);
}
@@ -506,9 +522,8 @@ Sprite2DEditor::Sprite2DEditor() {
CanvasItemEditor::get_singleton()->add_control_to_menu_panel(options);
options->set_text(TTR("Sprite2D"));
- options->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Sprite2D"), SNAME("EditorIcons")));
- options->get_popup()->add_item(TTR("Convert to Mesh2D"), MENU_OPTION_CONVERT_TO_MESH_2D);
+ options->get_popup()->add_item(TTR("Convert to MeshInstance2D"), MENU_OPTION_CONVERT_TO_MESH_2D);
options->get_popup()->add_item(TTR("Convert to Polygon2D"), MENU_OPTION_CONVERT_TO_POLYGON_2D);
options->get_popup()->add_item(TTR("Create CollisionPolygon2D Sibling"), MENU_OPTION_CREATE_COLLISION_POLY_2D);
options->get_popup()->add_item(TTR("Create LightOccluder2D Sibling"), MENU_OPTION_CREATE_LIGHT_OCCLUDER_2D);
@@ -520,8 +535,6 @@ Sprite2DEditor::Sprite2DEditor() {
add_child(err_dialog);
debug_uv_dialog = memnew(ConfirmationDialog);
- debug_uv_dialog->get_ok_button()->set_text(TTR("Create Mesh2D"));
- debug_uv_dialog->set_title(TTR("Mesh 2D Preview"));
VBoxContainer *vb = memnew(VBoxContainer);
debug_uv_dialog->add_child(vb);
ScrollContainer *scroll = memnew(ScrollContainer);
@@ -583,10 +596,9 @@ void Sprite2DEditorPlugin::make_visible(bool p_visible) {
}
}
-Sprite2DEditorPlugin::Sprite2DEditorPlugin(EditorNode *p_node) {
- editor = p_node;
+Sprite2DEditorPlugin::Sprite2DEditorPlugin() {
sprite_editor = memnew(Sprite2DEditor);
- editor->get_main_control()->add_child(sprite_editor);
+ EditorNode::get_singleton()->get_main_control()->add_child(sprite_editor);
make_visible(false);
//sprite_editor->options->hide();
diff --git a/editor/plugins/sprite_2d_editor_plugin.h b/editor/plugins/sprite_2d_editor_plugin.h
index c93ad1610f..46953b0937 100644
--- a/editor/plugins/sprite_2d_editor_plugin.h
+++ b/editor/plugins/sprite_2d_editor_plugin.h
@@ -31,7 +31,6 @@
#ifndef SPRITE_EDITOR_PLUGIN_H
#define SPRITE_EDITOR_PLUGIN_H
-#include "editor/editor_node.h"
#include "editor/editor_plugin.h"
#include "scene/2d/sprite_2d.h"
#include "scene/gui/spin_box.h"
@@ -88,6 +87,7 @@ class Sprite2DEditor : public Control {
protected:
void _node_removed(Node *p_node);
+ void _notification(int p_what);
static void _bind_methods();
public:
@@ -99,7 +99,6 @@ class Sprite2DEditorPlugin : public EditorPlugin {
GDCLASS(Sprite2DEditorPlugin, EditorPlugin);
Sprite2DEditor *sprite_editor;
- EditorNode *editor;
public:
virtual String get_name() const override { return "Sprite2D"; }
@@ -108,7 +107,7 @@ public:
virtual bool handles(Object *p_object) const override;
virtual void make_visible(bool p_visible) override;
- Sprite2DEditorPlugin(EditorNode *p_node);
+ Sprite2DEditorPlugin();
~Sprite2DEditorPlugin();
};
diff --git a/editor/plugins/sprite_frames_editor_plugin.cpp b/editor/plugins/sprite_frames_editor_plugin.cpp
index 014fa0e7a5..c8db16d3be 100644
--- a/editor/plugins/sprite_frames_editor_plugin.cpp
+++ b/editor/plugins/sprite_frames_editor_plugin.cpp
@@ -33,8 +33,11 @@
#include "core/config/project_settings.h"
#include "core/io/resource_loader.h"
#include "core/os/keyboard.h"
+#include "editor/editor_file_dialog.h"
+#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/scene_tree_dock.h"
#include "scene/3d/sprite_3d.h"
#include "scene/gui/center_container.h"
#include "scene/gui/margin_container.h"
@@ -285,7 +288,7 @@ void SpriteFramesEditor::_sheet_spin_changed(double) {
}
void SpriteFramesEditor::_prepare_sprite_sheet(const String &p_file) {
- Ref<Resource> texture = ResourceLoader::load(p_file);
+ Ref<Texture2D> texture = ResourceLoader::load(p_file);
if (!texture.is_valid()) {
EditorNode::get_singleton()->show_warning(TTR("Unable to load images"));
ERR_FAIL_COND(!texture.is_valid());
@@ -1326,20 +1329,19 @@ bool SpriteFramesEditorPlugin::handles(Object *p_object) const {
void SpriteFramesEditorPlugin::make_visible(bool p_visible) {
if (p_visible) {
button->show();
- editor->make_bottom_panel_item_visible(frames_editor);
+ EditorNode::get_singleton()->make_bottom_panel_item_visible(frames_editor);
} else {
button->hide();
if (frames_editor->is_visible_in_tree()) {
- editor->hide_bottom_panel();
+ EditorNode::get_singleton()->hide_bottom_panel();
}
}
}
-SpriteFramesEditorPlugin::SpriteFramesEditorPlugin(EditorNode *p_node) {
- editor = p_node;
+SpriteFramesEditorPlugin::SpriteFramesEditorPlugin() {
frames_editor = memnew(SpriteFramesEditor);
frames_editor->set_custom_minimum_size(Size2(0, 300) * EDSCALE);
- button = editor->add_bottom_panel_item(TTR("SpriteFrames"), frames_editor);
+ button = EditorNode::get_singleton()->add_bottom_panel_item(TTR("SpriteFrames"), frames_editor);
button->hide();
}
diff --git a/editor/plugins/sprite_frames_editor_plugin.h b/editor/plugins/sprite_frames_editor_plugin.h
index 8767e05a94..461c8dd41a 100644
--- a/editor/plugins/sprite_frames_editor_plugin.h
+++ b/editor/plugins/sprite_frames_editor_plugin.h
@@ -31,16 +31,20 @@
#ifndef SPRITE_FRAMES_EDITOR_PLUGIN_H
#define SPRITE_FRAMES_EDITOR_PLUGIN_H
-#include "editor/editor_node.h"
#include "editor/editor_plugin.h"
#include "scene/2d/animated_sprite_2d.h"
+#include "scene/gui/button.h"
+#include "scene/gui/check_button.h"
#include "scene/gui/dialogs.h"
-#include "scene/gui/file_dialog.h"
+#include "scene/gui/item_list.h"
#include "scene/gui/scroll_container.h"
+#include "scene/gui/spin_box.h"
#include "scene/gui/split_container.h"
#include "scene/gui/texture_rect.h"
#include "scene/gui/tree.h"
+class EditorFileDialog;
+
class SpriteFramesEditor : public HSplitContainer {
GDCLASS(SpriteFramesEditor, HSplitContainer);
@@ -160,7 +164,6 @@ class SpriteFramesEditorPlugin : public EditorPlugin {
GDCLASS(SpriteFramesEditorPlugin, EditorPlugin);
SpriteFramesEditor *frames_editor;
- EditorNode *editor;
Button *button;
public:
@@ -170,7 +173,7 @@ public:
virtual bool handles(Object *p_object) const override;
virtual void make_visible(bool p_visible) override;
- SpriteFramesEditorPlugin(EditorNode *p_node);
+ SpriteFramesEditorPlugin();
~SpriteFramesEditorPlugin();
};
diff --git a/editor/plugins/style_box_editor_plugin.cpp b/editor/plugins/style_box_editor_plugin.cpp
index 5d38352b22..a3cbaf527e 100644
--- a/editor/plugins/style_box_editor_plugin.cpp
+++ b/editor/plugins/style_box_editor_plugin.cpp
@@ -84,7 +84,7 @@ StyleBoxPreview::StyleBoxPreview() {
add_margin_child(TTR("Preview:"), preview);
}
-StyleBoxEditorPlugin::StyleBoxEditorPlugin(EditorNode *p_node) {
+StyleBoxEditorPlugin::StyleBoxEditorPlugin() {
Ref<EditorInspectorPluginStyleBox> inspector_plugin;
inspector_plugin.instantiate();
add_inspector_plugin(inspector_plugin);
diff --git a/editor/plugins/style_box_editor_plugin.h b/editor/plugins/style_box_editor_plugin.h
index 898628fd7f..bdebebbe1c 100644
--- a/editor/plugins/style_box_editor_plugin.h
+++ b/editor/plugins/style_box_editor_plugin.h
@@ -32,7 +32,7 @@
#define STYLE_BOX_EDITOR_PLUGIN_H
#include "editor/editor_inspector.h"
-#include "editor/editor_node.h"
+#include "editor/editor_plugin.h"
#include "scene/gui/option_button.h"
#include "scene/gui/texture_rect.h"
#include "scene/resources/style_box.h"
@@ -69,7 +69,7 @@ class StyleBoxEditorPlugin : public EditorPlugin {
public:
virtual String get_name() const override { return "StyleBox"; }
- StyleBoxEditorPlugin(EditorNode *p_node);
+ StyleBoxEditorPlugin();
};
#endif // STYLE_BOX_EDITOR_PLUGIN_H
diff --git a/editor/plugins/sub_viewport_preview_editor_plugin.cpp b/editor/plugins/sub_viewport_preview_editor_plugin.cpp
index 4498a1d64d..c8bb0cd56f 100644
--- a/editor/plugins/sub_viewport_preview_editor_plugin.cpp
+++ b/editor/plugins/sub_viewport_preview_editor_plugin.cpp
@@ -43,7 +43,7 @@ void EditorInspectorPluginSubViewportPreview::parse_begin(Object *p_object) {
add_custom_control(sub_viewport_preview);
}
-SubViewportPreviewEditorPlugin::SubViewportPreviewEditorPlugin(EditorNode *p_node) {
+SubViewportPreviewEditorPlugin::SubViewportPreviewEditorPlugin() {
Ref<EditorInspectorPluginSubViewportPreview> plugin;
plugin.instantiate();
add_inspector_plugin(plugin);
diff --git a/editor/plugins/sub_viewport_preview_editor_plugin.h b/editor/plugins/sub_viewport_preview_editor_plugin.h
index 7016910ebd..269553ffb1 100644
--- a/editor/plugins/sub_viewport_preview_editor_plugin.h
+++ b/editor/plugins/sub_viewport_preview_editor_plugin.h
@@ -31,7 +31,6 @@
#ifndef SUB_VIEWPORT_PREVIEW_EDITOR_PLUGIN_H
#define SUB_VIEWPORT_PREVIEW_EDITOR_PLUGIN_H
-#include "editor/editor_node.h"
#include "editor/editor_plugin.h"
#include "editor/plugins/texture_editor_plugin.h"
#include "scene/main/viewport.h"
@@ -50,7 +49,7 @@ class SubViewportPreviewEditorPlugin : public EditorPlugin {
public:
virtual String get_name() const override { return "SubViewportPreview"; }
- SubViewportPreviewEditorPlugin(EditorNode *p_node);
+ SubViewportPreviewEditorPlugin();
};
#endif // SUB_VIEWPORT_PREVIEW_EDITOR_PLUGIN_H
diff --git a/editor/plugins/text_control_editor_plugin.cpp b/editor/plugins/text_control_editor_plugin.cpp
index a51b5d3e03..4290888e94 100644
--- a/editor/plugins/text_control_editor_plugin.cpp
+++ b/editor/plugins/text_control_editor_plugin.cpp
@@ -30,10 +30,12 @@
#include "text_control_editor_plugin.h"
+#include "editor/editor_node.h"
#include "editor/editor_scale.h"
+#include "editor/multi_node_edit.h"
-void TextControlEditor::_notification(int p_notification) {
- switch (p_notification) {
+void TextControlEditor::_notification(int p_what) {
+ switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
if (!EditorFileSystem::get_singleton()->is_connected("filesystem_changed", callable_mp(this, &TextControlEditor::_reload_fonts))) {
EditorFileSystem::get_singleton()->connect("filesystem_changed", callable_mp(this, &TextControlEditor::_reload_fonts), make_binds(""));
@@ -43,13 +45,12 @@ void TextControlEditor::_notification(int p_notification) {
case NOTIFICATION_THEME_CHANGED: {
clear_formatting->set_icon(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")));
} break;
+
case NOTIFICATION_EXIT_TREE: {
if (EditorFileSystem::get_singleton()->is_connected("filesystem_changed", callable_mp(this, &TextControlEditor::_reload_fonts))) {
EditorFileSystem::get_singleton()->disconnect("filesystem_changed", callable_mp(this, &TextControlEditor::_reload_fonts));
}
} break;
- default:
- break;
}
}
@@ -109,7 +110,7 @@ void TextControlEditor::_update_styles_menu() {
for (Map<String, String>::Element *E = fonts[name].front(); E; E = E->next()) {
font_style_list->add_item(E->key());
}
- } else {
+ } else if (font_list->get_selected() >= 0) {
font_style_list->add_item("Default");
}
@@ -121,82 +122,157 @@ void TextControlEditor::_update_styles_menu() {
}
void TextControlEditor::_update_control() {
- if (edited_control) {
- // Get override names.
- if (edited_control->is_class("RichTextLabel")) {
- edited_color = "default_color";
- edited_font = "normal_font";
- edited_font_size = "normal_font_size";
- } else {
- edited_color = "font_color";
- edited_font = "font";
- edited_font_size = "font_size";
- }
-
- // Get font override.
- Ref<Font> font;
- if (edited_control->has_theme_font_override(edited_font)) {
- font = edited_control->get_theme_font(edited_font);
- }
- if (font.is_valid()) {
- if (font->get_data_count() != 1) {
- // Composite font, save it to "custom_font" to allow undoing font change.
- custom_font = font;
- _update_fonts_menu();
- font_list->select(FONT_INFO_USER_CUSTOM);
- _update_styles_menu();
- font_style_list->select(0);
+ if (!edited_controls.is_empty()) {
+ String font_selected;
+ bool same_font = true;
+ String style_selected;
+ bool same_style = true;
+ int font_size = 0;
+ bool same_font_size = true;
+ int outline_size = 0;
+ bool same_outline_size = true;
+ Color font_color = Color{ 1.0f, 1.0f, 1.0f };
+ bool same_font_color = true;
+ Color outline_color = Color{ 1.0f, 1.0f, 1.0f };
+ bool same_outline_color = true;
+
+ int count = edited_controls.size();
+ for (int i = 0; i < count; ++i) {
+ Control *edited_control = edited_controls[i];
+
+ StringName edited_color;
+ StringName edited_font;
+ StringName edited_font_size;
+
+ // Get override names.
+ if (Object::cast_to<RichTextLabel>(edited_control)) {
+ edited_color = SNAME("default_color");
+ edited_font = SNAME("normal_font");
+ edited_font_size = SNAME("normal_font_size");
} else {
- // Single face font, search for the font with matching name and style.
- String name = font->get_data(0)->get_font_name();
- String style = font->get_data(0)->get_font_style_name();
- if (fonts.has(name) && fonts[name].has(style)) {
- _update_fonts_menu();
- for (int i = 0; i < font_list->get_item_count(); i++) {
- if (font_list->get_item_text(i) == name) {
- font_list->select(i);
- break;
- }
+ edited_color = SNAME("font_color");
+ edited_font = SNAME("font");
+ edited_font_size = SNAME("font_size");
+ }
+
+ // Get font override.
+ Ref<Font> font;
+ if (edited_control->has_theme_font_override(edited_font)) {
+ font = edited_control->get_theme_font(edited_font);
+ }
+
+ if (font.is_valid()) {
+ if (font->get_data_count() != 1) {
+ if (i > 0) {
+ same_font = same_font && (custom_font == font);
}
- _update_styles_menu();
- for (int i = 0; i < font_style_list->get_item_count(); i++) {
- if (font_style_list->get_item_text(i) == style) {
- font_style_list->select(i);
- break;
+ custom_font = font;
+
+ font_selected = TTR("[Custom Font]");
+ same_style = false;
+ } else {
+ String name = font->get_data(0)->get_font_name();
+ String style = font->get_data(0)->get_font_style_name();
+ if (fonts.has(name) && fonts[name].has(style)) {
+ if (i > 0) {
+ same_font = same_font && (name == font_selected);
+ same_style = same_style && (style == style_selected);
}
+ font_selected = name;
+ style_selected = style;
+ } else {
+ if (i > 0) {
+ same_font = same_font && (custom_font == font);
+ }
+ custom_font = font;
+
+ font_selected = TTR("[Custom Font]");
+ same_style = false;
}
- } else {
- // Unknown font, save it to "custom_font" to allow undoing font change.
- custom_font = font;
- _update_fonts_menu();
- font_list->select(FONT_INFO_USER_CUSTOM);
- _update_styles_menu();
- font_style_list->select(0);
+ }
+ } else {
+ if (i > 0) {
+ same_font = same_font && (font_selected == TTR("[Theme Default]"));
+ }
+
+ font_selected = TTR("[Theme Default]");
+ same_style = false;
+ }
+
+ int current_font_size = edited_control->get_theme_font_size(edited_font_size);
+ int current_outline_size = edited_control->get_theme_constant(SNAME("outline_size"));
+ Color current_font_color = edited_control->get_theme_color(edited_color);
+ Color current_outline_color = edited_control->get_theme_color(SNAME("font_outline_color"));
+ if (i > 0) {
+ same_font_size = same_font_size && (font_size == current_font_size);
+ same_outline_size = same_outline_size && (outline_size == current_outline_size);
+ same_font_color = same_font_color && (font_color == current_font_color);
+ same_outline_color = same_outline_color && (outline_color == current_outline_color);
+ }
+
+ font_size = current_font_size;
+ outline_size = current_outline_size;
+ font_color = current_font_color;
+ outline_color = current_outline_color;
+ }
+ _update_fonts_menu();
+ if (same_font) {
+ for (int j = 0; j < font_list->get_item_count(); j++) {
+ if (font_list->get_item_text(j) == font_selected) {
+ font_list->select(j);
+ break;
+ }
+ }
+ } else {
+ custom_font = Ref<Font>();
+ font_list->select(-1);
+ }
+
+ _update_styles_menu();
+ if (same_style) {
+ for (int j = 0; j < font_style_list->get_item_count(); j++) {
+ if (font_style_list->get_item_text(j) == style_selected) {
+ font_style_list->select(j);
+ break;
}
}
} else {
- // No font override, select "Theme Default".
- _update_fonts_menu();
- font_list->select(FONT_INFO_THEME_DEFAULT);
- _update_styles_menu();
- font_style_list->select(0);
+ font_style_list->select(-1);
}
// Get other theme overrides.
font_size_list->set_block_signals(true);
- font_size_list->set_value(edited_control->get_theme_font_size(edited_font_size));
+ if (same_font_size) {
+ font_size_list->get_line_edit()->set_text(String::num_uint64(font_size));
+ font_size_list->set_value(font_size);
+ } else {
+ font_size_list->get_line_edit()->set_text("");
+ }
font_size_list->set_block_signals(false);
outline_size_list->set_block_signals(true);
- outline_size_list->set_value(edited_control->get_theme_constant("outline_size"));
+ if (same_outline_size) {
+ outline_size_list->get_line_edit()->set_text(String::num_uint64(outline_size));
+ outline_size_list->set_value(outline_size);
+ } else {
+ outline_size_list->get_line_edit()->set_text("");
+ }
outline_size_list->set_block_signals(false);
- font_color_picker->set_pick_color(edited_control->get_theme_color(edited_color));
- outline_color_picker->set_pick_color(edited_control->get_theme_color("font_outline_color"));
+ if (!same_font_color) {
+ font_color = Color{ 1.0f, 1.0f, 1.0f };
+ }
+ font_color_picker->set_pick_color(font_color);
+
+ if (!same_outline_color) {
+ outline_color = Color{ 1.0f, 1.0f, 1.0f };
+ }
+ outline_color_picker->set_pick_color(outline_color);
}
}
void TextControlEditor::_font_selected(int p_id) {
+ _update_styles_menu();
_set_font();
}
@@ -205,42 +281,53 @@ void TextControlEditor::_font_style_selected(int p_id) {
}
void TextControlEditor::_set_font() {
- if (!edited_control) {
+ if (edited_controls.is_empty()) {
return;
}
UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
ur->create_action(TTR("Set Font"));
- if (font_list->get_selected_id() == FONT_INFO_THEME_DEFAULT) {
- // Remove font override.
- ur->add_do_method(edited_control, "remove_theme_font_override", edited_font);
- } else if (font_list->get_selected_id() == FONT_INFO_USER_CUSTOM) {
- // Restore "custom_font".
- ur->add_do_method(edited_control, "add_theme_font_override", edited_font, custom_font);
- } else {
- // Load new font resource using selected name and style.
- String name = font_list->get_item_text(font_list->get_selected());
- String style = font_style_list->get_item_text(font_style_list->get_selected());
- if (style.is_empty()) {
- style = "Default";
+ int count = edited_controls.size();
+ for (int i = 0; i < count; ++i) {
+ Control *edited_control = edited_controls[i];
+
+ StringName edited_font;
+ if (Object::cast_to<RichTextLabel>(edited_control)) {
+ edited_font = SNAME("normal_font");
+ } else {
+ edited_font = SNAME("font");
}
- if (fonts.has(name)) {
- Ref<FontData> fd = ResourceLoader::load(fonts[name][style]);
- if (fd.is_valid()) {
- Ref<Font> font;
- font.instantiate();
- font->add_data(fd);
- ur->add_do_method(edited_control, "add_theme_font_override", edited_font, font);
+ if (font_list->get_selected_id() == FONT_INFO_THEME_DEFAULT) {
+ // Remove font override.
+ ur->add_do_method(edited_control, "remove_theme_font_override", edited_font);
+ } else if (font_list->get_selected_id() == FONT_INFO_USER_CUSTOM) {
+ // Restore "custom_font".
+ ur->add_do_method(edited_control, "add_theme_font_override", edited_font, custom_font);
+ } else if (font_list->get_selected() >= 0) {
+ // Load new font resource using selected name and style.
+ String name = font_list->get_item_text(font_list->get_selected());
+ String style = font_style_list->get_item_text(font_style_list->get_selected());
+ if (style.is_empty()) {
+ style = "Default";
+ }
+ if (fonts.has(name)) {
+ Ref<FontData> fd = ResourceLoader::load(fonts[name][style]);
+ if (fd.is_valid()) {
+ Ref<Font> font;
+ font.instantiate();
+ font->add_data(fd);
+ ur->add_do_method(edited_control, "add_theme_font_override", edited_font, font);
+ }
}
}
- }
- if (edited_control->has_theme_font_override(edited_font)) {
- ur->add_undo_method(edited_control, "add_theme_font_override", edited_font, edited_control->get_theme_font(edited_font));
- } else {
- ur->add_undo_method(edited_control, "remove_theme_font_override", edited_font);
+ if (edited_control->has_theme_font_override(edited_font)) {
+ ur->add_undo_method(edited_control, "add_theme_font_override", edited_font, edited_control->get_theme_font(edited_font));
+ } else {
+ ur->add_undo_method(edited_control, "remove_theme_font_override", edited_font);
+ }
}
ur->add_do_method(this, "_update_control");
@@ -250,18 +337,30 @@ void TextControlEditor::_set_font() {
}
void TextControlEditor::_font_size_selected(double p_size) {
- if (!edited_control) {
+ if (edited_controls.is_empty()) {
return;
}
UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
ur->create_action(TTR("Set Font Size"));
- ur->add_do_method(edited_control, "add_theme_font_size_override", edited_font_size, p_size);
- if (edited_control->has_theme_font_size_override(edited_font_size)) {
- ur->add_undo_method(edited_control, "add_theme_font_size_override", edited_font_size, edited_control->get_theme_font_size(edited_font_size));
- } else {
- ur->add_undo_method(edited_control, "remove_theme_font_size_override", edited_font_size);
+ int count = edited_controls.size();
+ for (int i = 0; i < count; ++i) {
+ Control *edited_control = edited_controls[i];
+
+ StringName edited_font_size;
+ if (Object::cast_to<RichTextLabel>(edited_control)) {
+ edited_font_size = SNAME("normal_font_size");
+ } else {
+ edited_font_size = SNAME("font_size");
+ }
+
+ ur->add_do_method(edited_control, "add_theme_font_size_override", edited_font_size, p_size);
+ if (edited_control->has_theme_font_size_override(edited_font_size)) {
+ ur->add_undo_method(edited_control, "add_theme_font_size_override", edited_font_size, edited_control->get_theme_font_size(edited_font_size));
+ } else {
+ ur->add_undo_method(edited_control, "remove_theme_font_size_override", edited_font_size);
+ }
}
ur->add_do_method(this, "_update_control");
@@ -271,18 +370,23 @@ void TextControlEditor::_font_size_selected(double p_size) {
}
void TextControlEditor::_outline_size_selected(double p_size) {
- if (!edited_control) {
+ if (edited_controls.is_empty()) {
return;
}
UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
ur->create_action(TTR("Set Font Outline Size"));
- ur->add_do_method(edited_control, "add_theme_constant_override", "outline_size", p_size);
- if (edited_control->has_theme_constant_override("outline_size")) {
- ur->add_undo_method(edited_control, "add_theme_constant_override", "outline_size", edited_control->get_theme_constant("outline_size"));
- } else {
- ur->add_undo_method(edited_control, "remove_theme_constant_override", "outline_size");
+ int count = edited_controls.size();
+ for (int i = 0; i < count; ++i) {
+ Control *edited_control = edited_controls[i];
+
+ ur->add_do_method(edited_control, "add_theme_constant_override", "outline_size", p_size);
+ if (edited_control->has_theme_constant_override("outline_size")) {
+ ur->add_undo_method(edited_control, "add_theme_constant_override", "outline_size", edited_control->get_theme_constant(SNAME("outline_size")));
+ } else {
+ ur->add_undo_method(edited_control, "remove_theme_constant_override", "outline_size");
+ }
}
ur->add_do_method(this, "_update_control");
@@ -292,18 +396,30 @@ void TextControlEditor::_outline_size_selected(double p_size) {
}
void TextControlEditor::_font_color_changed(const Color &p_color) {
- if (!edited_control) {
+ if (edited_controls.is_empty()) {
return;
}
UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
ur->create_action(TTR("Set Font Color"), UndoRedo::MERGE_ENDS);
- ur->add_do_method(edited_control, "add_theme_color_override", edited_color, p_color);
- if (edited_control->has_theme_color_override(edited_color)) {
- ur->add_undo_method(edited_control, "add_theme_color_override", edited_color, edited_control->get_theme_color(edited_color));
- } else {
- ur->add_undo_method(edited_control, "remove_theme_color_override", edited_color);
+ int count = edited_controls.size();
+ for (int i = 0; i < count; ++i) {
+ Control *edited_control = edited_controls[i];
+
+ StringName edited_color;
+ if (Object::cast_to<RichTextLabel>(edited_control)) {
+ edited_color = SNAME("default_color");
+ } else {
+ edited_color = SNAME("font_color");
+ }
+
+ ur->add_do_method(edited_control, "add_theme_color_override", edited_color, p_color);
+ if (edited_control->has_theme_color_override(edited_color)) {
+ ur->add_undo_method(edited_control, "add_theme_color_override", edited_color, edited_control->get_theme_color(edited_color));
+ } else {
+ ur->add_undo_method(edited_control, "remove_theme_color_override", edited_color);
+ }
}
ur->add_do_method(this, "_update_control");
@@ -313,18 +429,23 @@ void TextControlEditor::_font_color_changed(const Color &p_color) {
}
void TextControlEditor::_outline_color_changed(const Color &p_color) {
- if (!edited_control) {
+ if (edited_controls.is_empty()) {
return;
}
UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
ur->create_action(TTR("Set Font Outline Color"), UndoRedo::MERGE_ENDS);
- ur->add_do_method(edited_control, "add_theme_color_override", "font_outline_color", p_color);
- if (edited_control->has_theme_color_override("font_outline_color")) {
- ur->add_undo_method(edited_control, "add_theme_color_override", "font_outline_color", edited_control->get_theme_color("font_outline_color"));
- } else {
- ur->add_undo_method(edited_control, "remove_theme_color_override", "font_outline_color");
+ int count = edited_controls.size();
+ for (int i = 0; i < count; ++i) {
+ Control *edited_control = edited_controls[i];
+
+ ur->add_do_method(edited_control, "add_theme_color_override", "font_outline_color", p_color);
+ if (edited_control->has_theme_color_override("font_outline_color")) {
+ ur->add_undo_method(edited_control, "add_theme_color_override", "font_outline_color", edited_control->get_theme_color(SNAME("font_outline_color")));
+ } else {
+ ur->add_undo_method(edited_control, "remove_theme_color_override", "font_outline_color");
+ }
}
ur->add_do_method(this, "_update_control");
@@ -334,43 +455,63 @@ void TextControlEditor::_outline_color_changed(const Color &p_color) {
}
void TextControlEditor::_clear_formatting() {
- if (!edited_control) {
+ if (edited_controls.is_empty()) {
return;
}
UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
ur->create_action(TTR("Clear Control Formatting"));
- ur->add_do_method(edited_control, "begin_bulk_theme_override");
- ur->add_undo_method(edited_control, "begin_bulk_theme_override");
+ int count = edited_controls.size();
+ for (int i = 0; i < count; ++i) {
+ Control *edited_control = edited_controls[i];
- ur->add_do_method(edited_control, "remove_theme_font_override", edited_font);
- if (edited_control->has_theme_font_override(edited_font)) {
- ur->add_undo_method(edited_control, "add_theme_font_override", edited_font, edited_control->get_theme_font(edited_font));
- }
+ StringName edited_color;
+ StringName edited_font;
+ StringName edited_font_size;
- ur->add_do_method(edited_control, "remove_theme_font_size_override", edited_font_size);
- if (edited_control->has_theme_font_size_override(edited_font_size)) {
- ur->add_undo_method(edited_control, "add_theme_font_size_override", edited_font_size, edited_control->get_theme_font_size(edited_font_size));
- }
+ // Get override names.
+ if (Object::cast_to<RichTextLabel>(edited_control)) {
+ edited_color = SNAME("default_color");
+ edited_font = SNAME("normal_font");
+ edited_font_size = SNAME("normal_font_size");
+ } else {
+ edited_color = SNAME("font_color");
+ edited_font = SNAME("font");
+ edited_font_size = SNAME("font_size");
+ }
- ur->add_do_method(edited_control, "remove_theme_color_override", edited_color);
- if (edited_control->has_theme_color_override(edited_color)) {
- ur->add_undo_method(edited_control, "add_theme_color_override", edited_color, edited_control->get_theme_color(edited_color));
- }
+ ur->add_do_method(edited_control, "begin_bulk_theme_override");
+ ur->add_undo_method(edited_control, "begin_bulk_theme_override");
- ur->add_do_method(edited_control, "remove_theme_color_override", "font_outline_color");
- if (edited_control->has_theme_color_override("font_outline_color")) {
- ur->add_undo_method(edited_control, "add_theme_color_override", "font_outline_color", edited_control->get_theme_color("font_outline_color"));
- }
+ ur->add_do_method(edited_control, "remove_theme_font_override", edited_font);
+ if (edited_control->has_theme_font_override(edited_font)) {
+ ur->add_undo_method(edited_control, "add_theme_font_override", edited_font, edited_control->get_theme_font(edited_font));
+ }
- ur->add_do_method(edited_control, "remove_theme_constant_override", "outline_size");
- if (edited_control->has_theme_constant_override("outline_size")) {
- ur->add_undo_method(edited_control, "add_theme_constant_override", "outline_size", edited_control->get_theme_constant("outline_size"));
- }
+ ur->add_do_method(edited_control, "remove_theme_font_size_override", edited_font_size);
+ if (edited_control->has_theme_font_size_override(edited_font_size)) {
+ ur->add_undo_method(edited_control, "add_theme_font_size_override", edited_font_size, edited_control->get_theme_font_size(edited_font_size));
+ }
+
+ ur->add_do_method(edited_control, "remove_theme_color_override", edited_color);
+ if (edited_control->has_theme_color_override(edited_color)) {
+ ur->add_undo_method(edited_control, "add_theme_color_override", edited_color, edited_control->get_theme_color(edited_color));
+ }
+
+ ur->add_do_method(edited_control, "remove_theme_color_override", "font_outline_color");
+ if (edited_control->has_theme_color_override("font_outline_color")) {
+ ur->add_undo_method(edited_control, "add_theme_color_override", "font_outline_color", edited_control->get_theme_color(SNAME("font_outline_color")));
+ }
- ur->add_do_method(edited_control, "end_bulk_theme_override");
- ur->add_undo_method(edited_control, "end_bulk_theme_override");
+ ur->add_do_method(edited_control, "remove_theme_constant_override", "outline_size");
+ if (edited_control->has_theme_constant_override("outline_size")) {
+ ur->add_undo_method(edited_control, "add_theme_constant_override", "outline_size", edited_control->get_theme_constant(SNAME("outline_size")));
+ }
+
+ ur->add_do_method(edited_control, "end_bulk_theme_override");
+ ur->add_undo_method(edited_control, "end_bulk_theme_override");
+ }
ur->add_do_method(this, "_update_control");
ur->add_undo_method(this, "_update_control");
@@ -380,24 +521,54 @@ void TextControlEditor::_clear_formatting() {
void TextControlEditor::edit(Object *p_object) {
Control *ctrl = Object::cast_to<Control>(p_object);
- if (!ctrl) {
- edited_control = nullptr;
- custom_font = Ref<Font>();
- } else {
- edited_control = ctrl;
- custom_font = Ref<Font>();
+ MultiNodeEdit *multi_node = Object::cast_to<MultiNodeEdit>(p_object);
+
+ edited_controls.clear();
+ custom_font = Ref<Font>();
+ if (ctrl) {
+ edited_controls.append(ctrl);
+ _update_control();
+ } else if (multi_node && handles(multi_node)) {
+ int count = multi_node->get_node_count();
+ Node *scene = EditorNode::get_singleton()->get_edited_scene();
+
+ for (int i = 0; i < count; ++i) {
+ Control *child = Object::cast_to<Control>(scene->get_node(multi_node->get_node(i)));
+ edited_controls.append(child);
+ }
_update_control();
}
}
bool TextControlEditor::handles(Object *p_object) const {
Control *ctrl = Object::cast_to<Control>(p_object);
- if (!ctrl) {
+ MultiNodeEdit *multi_node = Object::cast_to<MultiNodeEdit>(p_object);
+
+ if (!ctrl && !multi_node) {
return false;
- } else {
+ } else if (ctrl) {
bool valid = false;
ctrl->get("text", &valid);
return valid;
+ } else {
+ bool valid = true;
+ int count = multi_node->get_node_count();
+ Node *scene = EditorNode::get_singleton()->get_edited_scene();
+
+ for (int i = 0; i < count; ++i) {
+ bool temp_valid = false;
+ Control *child = Object::cast_to<Control>(scene->get_node(multi_node->get_node(i)));
+ if (child) {
+ child->get("text", &temp_valid);
+ }
+ valid = valid && temp_valid;
+
+ if (!valid) {
+ break;
+ }
+ }
+
+ return valid;
}
}
@@ -481,8 +652,7 @@ void TextControlEditorPlugin::make_visible(bool p_visible) {
}
}
-TextControlEditorPlugin::TextControlEditorPlugin(EditorNode *p_node) {
- editor = p_node;
+TextControlEditorPlugin::TextControlEditorPlugin() {
text_ctl_editor = memnew(TextControlEditor);
CanvasItemEditor::get_singleton()->add_control_to_menu_panel(text_ctl_editor);
diff --git a/editor/plugins/text_control_editor_plugin.h b/editor/plugins/text_control_editor_plugin.h
index d284a30f16..1349003a9c 100644
--- a/editor/plugins/text_control_editor_plugin.h
+++ b/editor/plugins/text_control_editor_plugin.h
@@ -34,8 +34,8 @@
#include "canvas_item_editor_plugin.h"
#include "editor/editor_file_system.h"
#include "editor/editor_inspector.h"
-#include "editor/editor_node.h"
#include "editor/editor_plugin.h"
+#include "scene/gui/color_picker.h"
#include "scene/gui/color_rect.h"
#include "scene/gui/menu_button.h"
#include "scene/gui/option_button.h"
@@ -62,14 +62,11 @@ class TextControlEditor : public HBoxContainer {
ColorPickerButton *outline_color_picker = nullptr;
Button *clear_formatting = nullptr;
- Control *edited_control = nullptr;
- String edited_color;
- String edited_font;
- String edited_font_size;
+ Vector<Control *> edited_controls;
Ref<Font> custom_font;
protected:
- void _notification(int p_notification);
+ void _notification(int p_what);
static void _bind_methods();
void _find_resources(EditorFileSystemDirectory *p_dir);
@@ -104,7 +101,6 @@ class TextControlEditorPlugin : public EditorPlugin {
GDCLASS(TextControlEditorPlugin, EditorPlugin);
TextControlEditor *text_ctl_editor;
- EditorNode *editor;
public:
virtual String get_name() const override { return "TextControlFontEditor"; }
@@ -113,7 +109,7 @@ public:
virtual bool handles(Object *p_object) const override;
virtual void make_visible(bool p_visible) override;
- TextControlEditorPlugin(EditorNode *p_node);
+ TextControlEditorPlugin();
};
#endif // TEXT_CONTROL_EDITOR_PLUGIN_H
diff --git a/editor/plugins/texture_3d_editor_plugin.cpp b/editor/plugins/texture_3d_editor_plugin.cpp
index 6080f9df87..0fc7079a24 100644
--- a/editor/plugins/texture_3d_editor_plugin.cpp
+++ b/editor/plugins/texture_3d_editor_plugin.cpp
@@ -30,27 +30,22 @@
#include "texture_3d_editor_plugin.h"
-#include "core/config/project_settings.h"
-#include "core/io/resource_loader.h"
-#include "editor/editor_settings.h"
-
void Texture3DEditor::_texture_rect_draw() {
texture_rect->draw_rect(Rect2(Point2(), texture_rect->get_size()), Color(1, 1, 1, 1));
}
void Texture3DEditor::_notification(int p_what) {
- if (p_what == NOTIFICATION_READY) {
- //get_scene()->connect("node_removed",this,"_node_removed");
- }
- if (p_what == NOTIFICATION_RESIZED) {
- _texture_rect_update_area();
- }
+ switch (p_what) {
+ case NOTIFICATION_RESIZED: {
+ _texture_rect_update_area();
+ } break;
- if (p_what == NOTIFICATION_DRAW) {
- Ref<Texture2D> checkerboard = get_theme_icon(SNAME("Checkerboard"), SNAME("EditorIcons"));
- Size2 size = get_size();
+ case NOTIFICATION_DRAW: {
+ Ref<Texture2D> checkerboard = get_theme_icon(SNAME("Checkerboard"), SNAME("EditorIcons"));
+ Size2 size = get_size();
- draw_texture_rect(checkerboard, Rect2(Point2(), size), true);
+ draw_texture_rect(checkerboard, Rect2(Point2(), size), true);
+ } break;
}
}
@@ -204,7 +199,7 @@ void EditorInspectorPlugin3DTexture::parse_begin(Object *p_object) {
add_custom_control(editor);
}
-Texture3DEditorPlugin::Texture3DEditorPlugin(EditorNode *p_node) {
+Texture3DEditorPlugin::Texture3DEditorPlugin() {
Ref<EditorInspectorPlugin3DTexture> plugin;
plugin.instantiate();
add_inspector_plugin(plugin);
diff --git a/editor/plugins/texture_3d_editor_plugin.h b/editor/plugins/texture_3d_editor_plugin.h
index 5a200f6c11..d418032477 100644
--- a/editor/plugins/texture_3d_editor_plugin.h
+++ b/editor/plugins/texture_3d_editor_plugin.h
@@ -31,8 +31,8 @@
#ifndef TEXTURE_3D_EDITOR_PLUGIN_H
#define TEXTURE_3D_EDITOR_PLUGIN_H
-#include "editor/editor_node.h"
#include "editor/editor_plugin.h"
+#include "scene/gui/spin_box.h"
#include "scene/resources/shader.h"
#include "scene/resources/texture.h"
@@ -88,7 +88,7 @@ class Texture3DEditorPlugin : public EditorPlugin {
public:
virtual String get_name() const override { return "Texture3D"; }
- Texture3DEditorPlugin(EditorNode *p_node);
+ Texture3DEditorPlugin();
};
#endif // TEXTURE_EDITOR_PLUGIN_H
diff --git a/editor/plugins/texture_editor_plugin.cpp b/editor/plugins/texture_editor_plugin.cpp
index 84b33f0986..a7c06ada5c 100644
--- a/editor/plugins/texture_editor_plugin.cpp
+++ b/editor/plugins/texture_editor_plugin.cpp
@@ -64,8 +64,8 @@ void TexturePreview::_update_metadata_label_text() {
String format;
if (Object::cast_to<ImageTexture>(*texture)) {
format = Image::get_format_name(Object::cast_to<ImageTexture>(*texture)->get_format());
- } else if (Object::cast_to<StreamTexture2D>(*texture)) {
- format = Image::get_format_name(Object::cast_to<StreamTexture2D>(*texture)->get_format());
+ } else if (Object::cast_to<CompressedTexture2D>(*texture)) {
+ format = Image::get_format_name(Object::cast_to<CompressedTexture2D>(*texture)->get_format());
} else {
format = texture->get_class();
}
@@ -110,7 +110,7 @@ TexturePreview::TexturePreview(Ref<Texture2D> p_texture, bool p_show_metadata) {
}
bool EditorInspectorPluginTexture::can_handle(Object *p_object) {
- return Object::cast_to<ImageTexture>(p_object) != nullptr || Object::cast_to<AtlasTexture>(p_object) != nullptr || Object::cast_to<StreamTexture2D>(p_object) != nullptr || Object::cast_to<AnimatedTexture>(p_object) != nullptr;
+ return Object::cast_to<ImageTexture>(p_object) != nullptr || Object::cast_to<AtlasTexture>(p_object) != nullptr || Object::cast_to<CompressedTexture2D>(p_object) != nullptr || Object::cast_to<AnimatedTexture>(p_object) != nullptr;
}
void EditorInspectorPluginTexture::parse_begin(Object *p_object) {
@@ -119,7 +119,7 @@ void EditorInspectorPluginTexture::parse_begin(Object *p_object) {
add_custom_control(memnew(TexturePreview(texture, true)));
}
-TextureEditorPlugin::TextureEditorPlugin(EditorNode *p_node) {
+TextureEditorPlugin::TextureEditorPlugin() {
Ref<EditorInspectorPluginTexture> plugin;
plugin.instantiate();
add_inspector_plugin(plugin);
diff --git a/editor/plugins/texture_editor_plugin.h b/editor/plugins/texture_editor_plugin.h
index 5ba077d6fc..9beada556c 100644
--- a/editor/plugins/texture_editor_plugin.h
+++ b/editor/plugins/texture_editor_plugin.h
@@ -31,7 +31,6 @@
#ifndef TEXTURE_EDITOR_PLUGIN_H
#define TEXTURE_EDITOR_PLUGIN_H
-#include "editor/editor_node.h"
#include "editor/editor_plugin.h"
#include "scene/resources/texture.h"
@@ -68,7 +67,7 @@ class TextureEditorPlugin : public EditorPlugin {
public:
virtual String get_name() const override { return "Texture2D"; }
- TextureEditorPlugin(EditorNode *p_node);
+ TextureEditorPlugin();
};
#endif // TEXTURE_EDITOR_PLUGIN_H
diff --git a/editor/plugins/texture_layered_editor_plugin.cpp b/editor/plugins/texture_layered_editor_plugin.cpp
index a8c37d37fe..cb146fd342 100644
--- a/editor/plugins/texture_layered_editor_plugin.cpp
+++ b/editor/plugins/texture_layered_editor_plugin.cpp
@@ -30,10 +30,6 @@
#include "texture_layered_editor_plugin.h"
-#include "core/config/project_settings.h"
-#include "core/io/resource_loader.h"
-#include "editor/editor_settings.h"
-
void TextureLayeredEditor::gui_input(const Ref<InputEvent> &p_event) {
ERR_FAIL_COND(p_event.is_null());
@@ -50,18 +46,17 @@ void TextureLayeredEditor::_texture_rect_draw() {
}
void TextureLayeredEditor::_notification(int p_what) {
- if (p_what == NOTIFICATION_READY) {
- //get_scene()->connect("node_removed",this,"_node_removed");
- }
- if (p_what == NOTIFICATION_RESIZED) {
- _texture_rect_update_area();
- }
+ switch (p_what) {
+ case NOTIFICATION_RESIZED: {
+ _texture_rect_update_area();
+ } break;
- if (p_what == NOTIFICATION_DRAW) {
- Ref<Texture2D> checkerboard = get_theme_icon(SNAME("Checkerboard"), SNAME("EditorIcons"));
- Size2 size = get_size();
+ case NOTIFICATION_DRAW: {
+ Ref<Texture2D> checkerboard = get_theme_icon(SNAME("Checkerboard"), SNAME("EditorIcons"));
+ Size2 size = get_size();
- draw_texture_rect(checkerboard, Rect2(Point2(), size), true);
+ draw_texture_rect(checkerboard, Rect2(Point2(), size), true);
+ } break;
}
}
@@ -277,7 +272,7 @@ void EditorInspectorPluginLayeredTexture::parse_begin(Object *p_object) {
add_custom_control(editor);
}
-TextureLayeredEditorPlugin::TextureLayeredEditorPlugin(EditorNode *p_node) {
+TextureLayeredEditorPlugin::TextureLayeredEditorPlugin() {
Ref<EditorInspectorPluginLayeredTexture> plugin;
plugin.instantiate();
add_inspector_plugin(plugin);
diff --git a/editor/plugins/texture_layered_editor_plugin.h b/editor/plugins/texture_layered_editor_plugin.h
index cd8eba1bfe..1c59ec4db0 100644
--- a/editor/plugins/texture_layered_editor_plugin.h
+++ b/editor/plugins/texture_layered_editor_plugin.h
@@ -31,8 +31,8 @@
#ifndef TEXTURE_LAYERED_EDITOR_PLUGIN_H
#define TEXTURE_LAYERED_EDITOR_PLUGIN_H
-#include "editor/editor_node.h"
#include "editor/editor_plugin.h"
+#include "scene/gui/spin_box.h"
#include "scene/resources/shader.h"
#include "scene/resources/texture.h"
@@ -90,7 +90,7 @@ class TextureLayeredEditorPlugin : public EditorPlugin {
public:
virtual String get_name() const override { return "TextureLayered"; }
- TextureLayeredEditorPlugin(EditorNode *p_node);
+ TextureLayeredEditorPlugin();
};
#endif // TEXTURE_EDITOR_PLUGIN_H
diff --git a/editor/plugins/texture_region_editor_plugin.cpp b/editor/plugins/texture_region_editor_plugin.cpp
index 662c0126ec..adb8590246 100644
--- a/editor/plugins/texture_region_editor_plugin.cpp
+++ b/editor/plugins/texture_region_editor_plugin.cpp
@@ -33,6 +33,7 @@
#include "core/core_string_names.h"
#include "core/input/input.h"
#include "core/os/keyboard.h"
+#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "scene/gui/check_box.h"
#include "scene/gui/view_panner.h"
@@ -84,8 +85,10 @@ void TextureRegionEditor::_region_draw() {
edit_draw->draw_texture(base_tex, Point2());
RS::get_singleton()->canvas_item_add_set_transform(edit_draw->get_canvas_item(), Transform2D());
+ const Color color = get_theme_color(SNAME("mono_color"), SNAME("Editor"));
+
if (snap_mode == SNAP_GRID) {
- Color grid_color = Color(1.0, 1.0, 1.0, 0.15);
+ const Color grid_color = Color(color.r, color.g, color.b, color.a * 0.15);
Size2 s = edit_draw->get_size();
int last_cell = 0;
@@ -171,7 +174,6 @@ void TextureRegionEditor::_region_draw() {
mtx.basis_xform(raw_endpoints[2]),
mtx.basis_xform(raw_endpoints[3])
};
- Color color = get_theme_color(SNAME("mono_color"), SNAME("Editor"));
for (int i = 0; i < 4; i++) {
int prev = (i + 3) % 4;
int next = (i + 1) % 4;
@@ -980,14 +982,13 @@ Vector2 TextureRegionEditor::snap_point(Vector2 p_target) const {
return p_target;
}
-TextureRegionEditor::TextureRegionEditor(EditorNode *p_editor) {
+TextureRegionEditor::TextureRegionEditor() {
node_sprite_2d = nullptr;
node_sprite_3d = nullptr;
node_ninepatch = nullptr;
obj_styleBox = Ref<StyleBoxTexture>(nullptr);
atlas_tex = Ref<AtlasTexture>(nullptr);
- editor = p_editor;
- undo_redo = editor->get_undo_redo();
+ undo_redo = EditorNode::get_singleton()->get_undo_redo();
snap_step = Vector2(10, 10);
snap_separation = Vector2(0, 0);
@@ -1145,11 +1146,11 @@ void TextureRegionEditorPlugin::make_visible(bool p_visible) {
is_node_configured |= region_editor->get_sprite_2d() && region_editor->get_sprite_2d()->is_region_enabled();
is_node_configured |= region_editor->get_sprite_3d() && region_editor->get_sprite_3d()->is_region_enabled();
if ((is_node_configured && !manually_hidden) || texture_region_button->is_pressed()) {
- editor->make_bottom_panel_item_visible(region_editor);
+ EditorNode::get_singleton()->make_bottom_panel_item_visible(region_editor);
}
} else {
if (region_editor->is_visible_in_tree()) {
- editor->hide_bottom_panel();
+ EditorNode::get_singleton()->hide_bottom_panel();
manually_hidden = false;
}
texture_region_button->hide();
@@ -1198,15 +1199,14 @@ void TextureRegionEditorPlugin::set_state(const Dictionary &p_state) {
void TextureRegionEditorPlugin::_bind_methods() {
}
-TextureRegionEditorPlugin::TextureRegionEditorPlugin(EditorNode *p_node) {
+TextureRegionEditorPlugin::TextureRegionEditorPlugin() {
manually_hidden = false;
- editor = p_node;
- region_editor = memnew(TextureRegionEditor(p_node));
+ region_editor = memnew(TextureRegionEditor);
region_editor->set_custom_minimum_size(Size2(0, 200) * EDSCALE);
region_editor->hide();
region_editor->connect("visibility_changed", callable_mp(this, &TextureRegionEditorPlugin::_editor_visiblity_changed));
- texture_region_button = p_node->add_bottom_panel_item(TTR("TextureRegion"), region_editor);
+ texture_region_button = EditorNode::get_singleton()->add_bottom_panel_item(TTR("TextureRegion"), region_editor);
texture_region_button->hide();
}
diff --git a/editor/plugins/texture_region_editor_plugin.h b/editor/plugins/texture_region_editor_plugin.h
index d78ad3891c..041742c28a 100644
--- a/editor/plugins/texture_region_editor_plugin.h
+++ b/editor/plugins/texture_region_editor_plugin.h
@@ -32,7 +32,6 @@
#define TEXTURE_REGION_EDITOR_PLUGIN_H
#include "canvas_item_editor_plugin.h"
-#include "editor/editor_node.h"
#include "editor/editor_plugin.h"
#include "scene/2d/sprite_2d.h"
#include "scene/3d/sprite_3d.h"
@@ -69,7 +68,6 @@ class TextureRegionEditor : public VBoxContainer {
VScrollBar *vscroll;
HScrollBar *hscroll;
- EditorNode *editor;
UndoRedo *undo_redo;
Vector2 draw_ofs;
@@ -141,7 +139,7 @@ public:
Sprite3D *get_sprite_3d();
void edit(Object *p_obj);
- TextureRegionEditor(EditorNode *p_editor);
+ TextureRegionEditor();
};
class TextureRegionEditorPlugin : public EditorPlugin {
@@ -150,7 +148,6 @@ class TextureRegionEditorPlugin : public EditorPlugin {
bool manually_hidden;
Button *texture_region_button;
TextureRegionEditor *region_editor;
- EditorNode *editor;
protected:
static void _bind_methods();
@@ -166,7 +163,7 @@ public:
void set_state(const Dictionary &p_state) override;
Dictionary get_state() const override;
- TextureRegionEditorPlugin(EditorNode *p_node);
+ TextureRegionEditorPlugin();
};
#endif // TEXTURE_REGION_EDITOR_PLUGIN_H
diff --git a/editor/plugins/theme_editor_plugin.cpp b/editor/plugins/theme_editor_plugin.cpp
index aaa09237cf..d313b98a7f 100644
--- a/editor/plugins/theme_editor_plugin.cpp
+++ b/editor/plugins/theme_editor_plugin.cpp
@@ -31,6 +31,8 @@
#include "theme_editor_plugin.h"
#include "core/os/keyboard.h"
+#include "editor/editor_file_dialog.h"
+#include "editor/editor_node.h"
#include "editor/editor_resource_picker.h"
#include "editor/editor_scale.h"
#include "editor/progress_dialog.h"
@@ -1211,7 +1213,8 @@ void ThemeItemEditorDialog::_update_edit_types() {
bool item_reselected = false;
edit_type_list->clear();
- int e_idx = 0;
+ TreeItem *list_root = edit_type_list->create_item();
+
for (const StringName &E : theme_types) {
Ref<Texture2D> item_icon;
if (E == "") {
@@ -1219,19 +1222,21 @@ void ThemeItemEditorDialog::_update_edit_types() {
} else {
item_icon = EditorNode::get_singleton()->get_class_icon(E, "NodeDisabled");
}
- edit_type_list->add_item(E, item_icon);
+ TreeItem *list_item = edit_type_list->create_item(list_root);
+ list_item->set_text(0, E);
+ list_item->set_icon(0, item_icon);
+ list_item->add_button(0, get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), TYPES_TREE_REMOVE_ITEM, false, TTR("Remove Type"));
if (E == edited_item_type) {
- edit_type_list->select(e_idx);
+ list_item->select(0);
item_reselected = true;
}
- e_idx++;
}
if (!item_reselected) {
edited_item_type = "";
- if (edit_type_list->get_item_count() > 0) {
- edit_type_list->select(0);
+ if (list_root->get_child_count() > 0) {
+ list_root->get_child(0)->select(0);
}
}
@@ -1240,9 +1245,9 @@ void ThemeItemEditorDialog::_update_edit_types() {
default_types.sort_custom<StringName::AlphCompare>();
String selected_type = "";
- Vector<int> selected_ids = edit_type_list->get_selected_items();
- if (selected_ids.size() > 0) {
- selected_type = edit_type_list->get_item_text(selected_ids[0]);
+ TreeItem *selected_item = edit_type_list->get_selected();
+ if (selected_item) {
+ selected_type = selected_item->get_text(0);
edit_items_add_color->set_disabled(false);
edit_items_add_constant->set_disabled(false);
@@ -1276,11 +1281,26 @@ void ThemeItemEditorDialog::_update_edit_types() {
_update_edit_item_tree(selected_type);
}
-void ThemeItemEditorDialog::_edited_type_selected(int p_item_idx) {
- String selected_type = edit_type_list->get_item_text(p_item_idx);
+void ThemeItemEditorDialog::_edited_type_selected() {
+ TreeItem *selected_item = edit_type_list->get_selected();
+ String selected_type = selected_item->get_text(0);
_update_edit_item_tree(selected_type);
}
+void ThemeItemEditorDialog::_edited_type_button_pressed(Object *p_item, int p_column, int p_id) {
+ TreeItem *item = Object::cast_to<TreeItem>(p_item);
+ if (!item) {
+ return;
+ }
+
+ switch (p_id) {
+ case TYPES_TREE_REMOVE_ITEM: {
+ String type_name = item->get_text(0);
+ _remove_theme_type(type_name);
+ } break;
+ }
+}
+
void ThemeItemEditorDialog::_update_edit_item_tree(String p_item_type) {
edited_item_type = p_item_type;
@@ -1429,8 +1449,8 @@ void ThemeItemEditorDialog::_update_edit_item_tree(String p_item_type) {
}
// If some type is selected, but it doesn't seem to have any items, show a guiding message.
- Vector<int> selected_ids = edit_type_list->get_selected_items();
- if (selected_ids.size() > 0) {
+ TreeItem *selected_item = edit_type_list->get_selected();
+ if (selected_item) {
if (!has_any_items) {
edit_items_message->set_text(TTR("This theme type is empty.\nAdd more items to it manually or by importing from another theme."));
edit_items_message->show();
@@ -1477,16 +1497,15 @@ void ThemeItemEditorDialog::_add_theme_type(const String &p_new_text) {
const String new_type = edit_add_type_value->get_text().strip_edges();
edit_add_type_value->clear();
- edited_theme->add_icon_type(new_type);
- edited_theme->add_stylebox_type(new_type);
- edited_theme->add_font_type(new_type);
- edited_theme->add_font_size_type(new_type);
- edited_theme->add_color_type(new_type);
- edited_theme->add_constant_type(new_type);
+ UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
+ ur->create_action(TTR("Add Theme Type"));
- _update_edit_types();
+ ur->add_do_method(*edited_theme, "add_type", new_type);
+ ur->add_undo_method(*edited_theme, "remove_type", new_type);
+ ur->add_do_method(this, "_update_edit_types");
+ ur->add_undo_method(this, "_update_edit_types");
- edited_theme->emit_changed();
+ ur->commit_action();
}
void ThemeItemEditorDialog::_add_theme_item(Theme::DataType p_data_type, String p_item_name, String p_item_type) {
@@ -1531,6 +1550,27 @@ void ThemeItemEditorDialog::_add_theme_item(Theme::DataType p_data_type, String
ur->commit_action();
}
+void ThemeItemEditorDialog::_remove_theme_type(const String &p_theme_type) {
+ Ref<Theme> old_snapshot = edited_theme->duplicate();
+ Ref<Theme> new_snapshot = edited_theme->duplicate();
+
+ UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
+ ur->create_action(TTR("Remove Theme Type"));
+
+ new_snapshot->remove_type(p_theme_type);
+
+ ur->add_do_method(*edited_theme, "clear");
+ ur->add_do_method(*edited_theme, "merge_with", new_snapshot);
+ // If the type was empty, it cannot be restored with merge, but thankfully we can fake it.
+ ur->add_undo_method(*edited_theme, "add_type", p_theme_type);
+ ur->add_undo_method(*edited_theme, "merge_with", old_snapshot);
+
+ ur->add_do_method(this, "_update_edit_types");
+ ur->add_undo_method(this, "_update_edit_types");
+
+ ur->commit_action();
+}
+
void ThemeItemEditorDialog::_remove_data_type_items(Theme::DataType p_data_type, String p_item_type) {
List<StringName> names;
@@ -1847,7 +1887,7 @@ ThemeItemEditorDialog::ThemeItemEditorDialog(ThemeTypeEditor *p_theme_type_edito
theme_type_editor = p_theme_type_editor;
tc = memnew(TabContainer);
- tc->set_tab_alignment(TabContainer::ALIGNMENT_LEFT);
+ tc->set_tab_alignment(TabBar::ALIGNMENT_LEFT);
add_child(tc);
// Edit Items tab.
@@ -1863,10 +1903,14 @@ ThemeItemEditorDialog::ThemeItemEditorDialog(ThemeTypeEditor *p_theme_type_edito
edit_type_label->set_text(TTR("Types:"));
edit_dialog_side_vb->add_child(edit_type_label);
- edit_type_list = memnew(ItemList);
+ edit_type_list = memnew(Tree);
+ edit_type_list->set_hide_root(true);
+ edit_type_list->set_hide_folding(true);
+ edit_type_list->set_columns(1);
edit_type_list->set_v_size_flags(Control::SIZE_EXPAND_FILL);
edit_dialog_side_vb->add_child(edit_type_list);
edit_type_list->connect("item_selected", callable_mp(this, &ThemeItemEditorDialog::_edited_type_selected));
+ edit_type_list->connect("button_pressed", callable_mp(this, &ThemeItemEditorDialog::_edited_type_button_pressed));
Label *edit_add_type_label = memnew(Label);
edit_add_type_label->set_text(TTR("Add Type:"));
@@ -2033,7 +2077,7 @@ ThemeItemEditorDialog::ThemeItemEditorDialog(ThemeTypeEditor *p_theme_type_edito
List<String> ext;
ResourceLoader::get_recognized_extensions_for_type("Theme", &ext);
for (const String &E : ext) {
- import_another_theme_dialog->add_filter("*." + E + "; Theme Resource");
+ import_another_theme_dialog->add_filter(vformat("*.%s; %s", E, TTR("Theme Resource")));
}
import_another_file_hb->add_child(import_another_theme_dialog);
import_another_theme_dialog->connect("file_selected", callable_mp(this, &ThemeItemEditorDialog::_select_another_theme_cbk));
@@ -3620,7 +3664,7 @@ ThemeEditor::ThemeEditor() {
List<String> ext;
ResourceLoader::get_recognized_extensions_for_type("PackedScene", &ext);
for (const String &E : ext) {
- preview_scene_dialog->add_filter("*." + E + "; Scene");
+ preview_scene_dialog->add_filter(vformat("*.%s; %s", E, TTR("Scene")));
}
main_hs->add_child(preview_scene_dialog);
preview_scene_dialog->connect("file_selected", callable_mp(this, &ThemeEditor::_preview_scene_dialog_cbk));
@@ -3713,21 +3757,20 @@ bool ThemeEditorPlugin::handles(Object *p_node) const {
void ThemeEditorPlugin::make_visible(bool p_visible) {
if (p_visible) {
button->show();
- editor->make_bottom_panel_item_visible(theme_editor);
+ EditorNode::get_singleton()->make_bottom_panel_item_visible(theme_editor);
} else {
if (theme_editor->is_visible_in_tree()) {
- editor->hide_bottom_panel();
+ EditorNode::get_singleton()->hide_bottom_panel();
}
button->hide();
}
}
-ThemeEditorPlugin::ThemeEditorPlugin(EditorNode *p_node) {
- editor = p_node;
+ThemeEditorPlugin::ThemeEditorPlugin() {
theme_editor = memnew(ThemeEditor);
theme_editor->set_custom_minimum_size(Size2(0, 200) * EDSCALE);
- button = editor->add_bottom_panel_item(TTR("Theme"), theme_editor);
+ button = EditorNode::get_singleton()->add_bottom_panel_item(TTR("Theme"), theme_editor);
button->hide();
}
diff --git a/editor/plugins/theme_editor_plugin.h b/editor/plugins/theme_editor_plugin.h
index c00ce3ae65..7c1b0cda3e 100644
--- a/editor/plugins/theme_editor_plugin.h
+++ b/editor/plugins/theme_editor_plugin.h
@@ -31,16 +31,20 @@
#ifndef THEME_EDITOR_PLUGIN_H
#define THEME_EDITOR_PLUGIN_H
+#include "editor/editor_plugin.h"
+#include "editor/plugins/theme_editor_preview.h"
+#include "scene/gui/check_button.h"
#include "scene/gui/dialogs.h"
+#include "scene/gui/item_list.h"
#include "scene/gui/margin_container.h"
#include "scene/gui/option_button.h"
#include "scene/gui/scroll_container.h"
#include "scene/gui/tab_bar.h"
#include "scene/gui/texture_rect.h"
+#include "scene/gui/tree.h"
#include "scene/resources/theme.h"
-#include "theme_editor_preview.h"
-#include "editor/editor_node.h"
+class EditorFileDialog;
class ThemeItemImportTree : public VBoxContainer {
GDCLASS(ThemeItemImportTree, VBoxContainer);
@@ -188,7 +192,11 @@ class ThemeItemEditorDialog : public AcceptDialog {
TabContainer *tc;
- ItemList *edit_type_list;
+ enum TypesTreeAction {
+ TYPES_TREE_REMOVE_ITEM,
+ };
+
+ Tree *edit_type_list;
LineEdit *edit_add_type_value;
String edited_item_type;
@@ -240,13 +248,15 @@ class ThemeItemEditorDialog : public AcceptDialog {
void _dialog_about_to_show();
void _update_edit_types();
- void _edited_type_selected(int p_item_idx);
+ void _edited_type_selected();
+ void _edited_type_button_pressed(Object *p_item, int p_column, int p_id);
void _update_edit_item_tree(String p_item_type);
void _item_tree_button_pressed(Object *p_item, int p_column, int p_id);
void _add_theme_type(const String &p_new_text);
void _add_theme_item(Theme::DataType p_data_type, String p_item_name, String p_item_type);
+ void _remove_theme_type(const String &p_theme_type);
void _remove_data_type_items(Theme::DataType p_data_type, String p_item_type);
void _remove_class_items();
void _remove_custom_items();
@@ -443,7 +453,6 @@ class ThemeEditorPlugin : public EditorPlugin {
GDCLASS(ThemeEditorPlugin, EditorPlugin);
ThemeEditor *theme_editor;
- EditorNode *editor;
Button *button;
public:
@@ -453,7 +462,7 @@ public:
virtual bool handles(Object *p_node) const override;
virtual void make_visible(bool p_visible) override;
- ThemeEditorPlugin(EditorNode *p_node);
+ ThemeEditorPlugin();
};
#endif // THEME_EDITOR_PLUGIN_H
diff --git a/editor/plugins/theme_editor_preview.cpp b/editor/plugins/theme_editor_preview.cpp
index c4ef6e086d..252a19a7db 100644
--- a/editor/plugins/theme_editor_preview.cpp
+++ b/editor/plugins/theme_editor_preview.cpp
@@ -30,11 +30,15 @@
#include "theme_editor_preview.h"
+#include "core/config/project_settings.h"
#include "core/input/input.h"
#include "core/math/math_funcs.h"
-#include "scene/resources/packed_scene.h"
-
+#include "editor/editor_node.h"
#include "editor/editor_scale.h"
+#include "scene/gui/button.h"
+#include "scene/gui/color_picker.h"
+#include "scene/gui/progress_bar.h"
+#include "scene/resources/packed_scene.h"
constexpr double REFRESH_TIMER = 1.5;
@@ -199,6 +203,7 @@ void ThemeEditorPreview::_notification(int p_what) {
theme_cache.preview_picker_font = get_theme_font(SNAME("status_source"), SNAME("EditorFonts"));
theme_cache.font_size = get_theme_font_size(SNAME("font_size"), SNAME("EditorFonts"));
} break;
+
case NOTIFICATION_PROCESS: {
time_left -= get_process_delta_time();
if (time_left < 0) {
diff --git a/editor/plugins/theme_editor_preview.h b/editor/plugins/theme_editor_preview.h
index a509ae3c50..48111df399 100644
--- a/editor/plugins/theme_editor_preview.h
+++ b/editor/plugins/theme_editor_preview.h
@@ -32,26 +32,12 @@
#define THEME_EDITOR_PREVIEW_H
#include "scene/gui/box_container.h"
-#include "scene/gui/check_box.h"
-#include "scene/gui/check_button.h"
-#include "scene/gui/color_picker.h"
+#include "scene/gui/button.h"
#include "scene/gui/color_rect.h"
-#include "scene/gui/label.h"
#include "scene/gui/margin_container.h"
-#include "scene/gui/menu_button.h"
-#include "scene/gui/option_button.h"
-#include "scene/gui/panel.h"
-#include "scene/gui/progress_bar.h"
#include "scene/gui/scroll_container.h"
-#include "scene/gui/separator.h"
-#include "scene/gui/spin_box.h"
-#include "scene/gui/tab_container.h"
-#include "scene/gui/text_edit.h"
-#include "scene/gui/tree.h"
#include "scene/resources/theme.h"
-#include "editor/editor_node.h"
-
class ThemeEditorPreview : public VBoxContainer {
GDCLASS(ThemeEditorPreview, VBoxContainer);
diff --git a/editor/plugins/tiles/atlas_merging_dialog.cpp b/editor/plugins/tiles/atlas_merging_dialog.cpp
index 677c9759c2..0f8c8c616c 100644
--- a/editor/plugins/tiles/atlas_merging_dialog.cpp
+++ b/editor/plugins/tiles/atlas_merging_dialog.cpp
@@ -30,6 +30,8 @@
#include "atlas_merging_dialog.h"
+#include "editor/editor_file_dialog.h"
+#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "scene/gui/control.h"
@@ -251,6 +253,8 @@ 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 2ae94cf44a..6cf555247d 100644
--- a/editor/plugins/tiles/atlas_merging_dialog.h
+++ b/editor/plugins/tiles/atlas_merging_dialog.h
@@ -31,14 +31,14 @@
#ifndef ATLAS_MERGING_DIALOG_H
#define ATLAS_MERGING_DIALOG_H
-#include "editor/editor_node.h"
#include "editor/editor_properties.h"
-
#include "scene/gui/dialogs.h"
#include "scene/gui/item_list.h"
#include "scene/gui/texture_rect.h"
#include "scene/resources/tile_set.h"
+class EditorFileDialog;
+
class AtlasMergingDialog : public ConfirmationDialog {
GDCLASS(AtlasMergingDialog, ConfirmationDialog);
@@ -49,7 +49,7 @@ private:
LocalVector<Map<Vector2i, Vector2i>> merged_mapping;
Ref<TileSet> tile_set;
- UndoRedo *undo_redo = EditorNode::get_singleton()->get_undo_redo();
+ UndoRedo *undo_redo;
// Settings.
int next_line_after_column = 30;
diff --git a/editor/plugins/tiles/tile_atlas_view.cpp b/editor/plugins/tiles/tile_atlas_view.cpp
index 35496795e0..71947ae185 100644
--- a/editor/plugins/tiles/tile_atlas_view.cpp
+++ b/editor/plugins/tiles/tile_atlas_view.cpp
@@ -36,7 +36,6 @@
#include "scene/gui/box_container.h"
#include "scene/gui/label.h"
#include "scene/gui/panel.h"
-#include "scene/gui/texture_rect.h"
#include "scene/gui/view_panner.h"
#include "editor/editor_scale.h"
@@ -95,6 +94,8 @@ Size2i TileAtlasView::_compute_alternative_tiles_control_size() {
}
void TileAtlasView::_update_zoom_and_panning(bool p_zoom_on_mouse_pos) {
+ // Don't allow zoom to go below 1% or above 10000%
+ zoom_widget->set_zoom(CLAMP(zoom_widget->get_zoom(), 0.01f, 100.f));
float zoom = zoom_widget->get_zoom();
// Compute the minimum sizes.
@@ -523,13 +524,13 @@ void TileAtlasView::update() {
void TileAtlasView::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE:
- case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED:
+ case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
panner->setup((ViewPanner::ControlScheme)EDITOR_GET("editors/panning/sub_editors_panning_scheme").operator int(), ED_GET_SHORTCUT("canvas_item_editor/pan_view"), bool(EditorSettings::get_singleton()->get("editors/panning/simple_panning")));
- break;
+ } break;
- case NOTIFICATION_READY:
+ case NOTIFICATION_READY: {
button_center_view->set_icon(get_theme_icon(SNAME("CenterView"), SNAME("EditorIcons")));
- break;
+ } break;
}
}
diff --git a/editor/plugins/tiles/tile_atlas_view.h b/editor/plugins/tiles/tile_atlas_view.h
index 37ef7d6a2a..caf3ef9e4b 100644
--- a/editor/plugins/tiles/tile_atlas_view.h
+++ b/editor/plugins/tiles/tile_atlas_view.h
@@ -37,8 +37,6 @@
#include "scene/gui/center_container.h"
#include "scene/gui/label.h"
#include "scene/gui/margin_container.h"
-#include "scene/gui/scroll_container.h"
-#include "scene/gui/texture_rect.h"
#include "scene/resources/tile_set.h"
class ViewPanner;
diff --git a/editor/plugins/tiles/tile_data_editors.cpp b/editor/plugins/tiles/tile_data_editors.cpp
index 12003738e7..6c12573cc4 100644
--- a/editor/plugins/tiles/tile_data_editors.cpp
+++ b/editor/plugins/tiles/tile_data_editors.cpp
@@ -35,12 +35,13 @@
#include "core/math/geometry_2d.h"
#include "core/os/keyboard.h"
+#include "editor/editor_node.h"
#include "editor/editor_properties.h"
#include "editor/editor_scale.h"
void TileDataEditor::_tile_set_changed_plan_update() {
_tile_set_changed_update_needed = true;
- call_deferred("_tile_set_changed_deferred_update");
+ call_deferred(SNAME("_tile_set_changed_deferred_update"));
}
void TileDataEditor::_tile_set_changed_deferred_update() {
@@ -743,6 +744,8 @@ void GenericTilePolygonEditor::_bind_methods() {
}
GenericTilePolygonEditor::GenericTilePolygonEditor() {
+ editor_undo_redo = EditorNode::get_undo_redo();
+
toolbar = memnew(HBoxContainer);
add_child(toolbar);
@@ -1157,17 +1160,17 @@ void TileDataDefaultEditor::setup_property_editor(Variant::Type p_type, String p
void TileDataDefaultEditor::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE:
- case NOTIFICATION_THEME_CHANGED:
+ case NOTIFICATION_THEME_CHANGED: {
picker_button->set_icon(get_theme_icon(SNAME("ColorPick"), SNAME("EditorIcons")));
tile_bool_checked = get_theme_icon(SNAME("TileChecked"), SNAME("EditorIcons"));
tile_bool_unchecked = get_theme_icon(SNAME("TileUnchecked"), SNAME("EditorIcons"));
- break;
- default:
- break;
+ } break;
}
}
TileDataDefaultEditor::TileDataDefaultEditor() {
+ undo_redo = EditorNode::get_undo_redo();
+
label = memnew(Label);
label->set_text(TTR("Painting:"));
add_child(label);
@@ -1310,15 +1313,15 @@ void TileDataOcclusionShapeEditor::_tile_set_changed() {
void TileDataOcclusionShapeEditor::_notification(int p_what) {
switch (p_what) {
- case NOTIFICATION_ENTER_TREE:
+ case NOTIFICATION_ENTER_TREE: {
polygon_editor->set_polygons_color(get_tree()->get_debug_collisions_color());
- break;
- default:
- break;
+ } break;
}
}
TileDataOcclusionShapeEditor::TileDataOcclusionShapeEditor() {
+ undo_redo = EditorNode::get_undo_redo();
+
polygon_editor = memnew(GenericTilePolygonEditor);
add_child(polygon_editor);
}
@@ -1507,15 +1510,15 @@ void TileDataCollisionEditor::_tile_set_changed() {
void TileDataCollisionEditor::_notification(int p_what) {
switch (p_what) {
- case NOTIFICATION_ENTER_TREE:
+ case NOTIFICATION_ENTER_TREE: {
polygon_editor->set_polygons_color(get_tree()->get_debug_collisions_color());
- break;
- default:
- break;
+ } break;
}
}
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));
@@ -2478,15 +2481,15 @@ void TileDataTerrainsEditor::draw_over_tile(CanvasItem *p_canvas_item, Transform
void TileDataTerrainsEditor::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE:
- case NOTIFICATION_THEME_CHANGED:
+ case NOTIFICATION_THEME_CHANGED: {
picker_button->set_icon(get_theme_icon(SNAME("ColorPick"), SNAME("EditorIcons")));
- break;
- default:
- break;
+ } break;
}
}
TileDataTerrainsEditor::TileDataTerrainsEditor() {
+ undo_redo = EditorNode::get_undo_redo();
+
label = memnew(Label);
label->set_text("Painting:");
add_child(label);
@@ -2582,15 +2585,15 @@ void TileDataNavigationEditor::_tile_set_changed() {
void TileDataNavigationEditor::_notification(int p_what) {
switch (p_what) {
- case NOTIFICATION_ENTER_TREE:
+ case NOTIFICATION_ENTER_TREE: {
polygon_editor->set_polygons_color(get_tree()->get_debug_navigation_color());
- break;
- default:
- break;
+ } break;
}
}
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 e4551d3302..99724760a7 100644
--- a/editor/plugins/tiles/tile_data_editors.h
+++ b/editor/plugins/tiles/tile_data_editors.h
@@ -33,9 +33,7 @@
#include "tile_atlas_view.h"
-#include "editor/editor_node.h"
#include "editor/editor_properties.h"
-
#include "scene/2d/tile_map.h"
#include "scene/gui/box_container.h"
#include "scene/gui/control.h"
@@ -95,7 +93,7 @@ private:
bool multiple_polygon_mode = false;
bool use_undo_redo = true;
- UndoRedo *editor_undo_redo = EditorNode::get_undo_redo();
+ UndoRedo *editor_undo_redo;
// UI
int hovered_polygon_index = -1;
@@ -216,7 +214,7 @@ private:
protected:
DummyObject *dummy_object = memnew(DummyObject);
- UndoRedo *undo_redo = EditorNode::get_undo_redo();
+ UndoRedo *undo_redo;
StringName type;
String property;
@@ -281,7 +279,7 @@ private:
virtual void _setup_undo_redo_action(TileSetAtlasSource *p_tile_set_atlas_source, Map<TileMapCell, Variant> p_previous_values, Variant p_new_value) override;
protected:
- UndoRedo *undo_redo = EditorNode::get_undo_redo();
+ UndoRedo *undo_redo;
virtual void _tile_set_changed() override;
@@ -316,7 +314,7 @@ class TileDataCollisionEditor : public TileDataDefaultEditor {
virtual void _setup_undo_redo_action(TileSetAtlasSource *p_tile_set_atlas_source, Map<TileMapCell, Variant> p_previous_values, Variant p_new_value) override;
protected:
- UndoRedo *undo_redo = EditorNode::get_undo_redo();
+ UndoRedo *undo_redo;
virtual void _tile_set_changed() override;
@@ -368,7 +366,7 @@ protected:
void _notification(int p_what);
- UndoRedo *undo_redo = EditorNode::get_undo_redo();
+ UndoRedo *undo_redo;
public:
virtual Control *get_toolbar() override { return toolbar; };
@@ -401,7 +399,7 @@ private:
virtual void _setup_undo_redo_action(TileSetAtlasSource *p_tile_set_atlas_source, Map<TileMapCell, Variant> p_previous_values, Variant p_new_value) override;
protected:
- UndoRedo *undo_redo = EditorNode::get_undo_redo();
+ UndoRedo *undo_redo;
virtual void _tile_set_changed() override;
diff --git a/editor/plugins/tiles/tile_map_editor.cpp b/editor/plugins/tiles/tile_map_editor.cpp
index 6e3724ead9..4a0fc0b29f 100644
--- a/editor/plugins/tiles/tile_map_editor.cpp
+++ b/editor/plugins/tiles/tile_map_editor.cpp
@@ -32,6 +32,7 @@
#include "tiles_editor_plugin.h"
+#include "editor/editor_node.h"
#include "editor/editor_resource_preview.h"
#include "editor/editor_scale.h"
#include "editor/plugins/canvas_item_editor_plugin.h"
@@ -1327,15 +1328,35 @@ void TileMapEditorTilesPlugin::_stop_dragging() {
Rect2i rect = Rect2i(tile_map->world_to_map(drag_start_mouse_pos), tile_map->world_to_map(mpos) - tile_map->world_to_map(drag_start_mouse_pos)).abs();
rect.size += Vector2i(1, 1);
+ int picked_source = -1;
TypedArray<Vector2i> coords_array;
for (int x = rect.position.x; x < rect.get_end().x; x++) {
for (int y = rect.position.y; y < rect.get_end().y; y++) {
Vector2i coords = Vector2i(x, y);
- if (tile_map->get_cell_source_id(tile_map_layer, coords) != TileSet::INVALID_SOURCE) {
+
+ int source = tile_map->get_cell_source_id(tile_map_layer, coords);
+ if (source != TileSet::INVALID_SOURCE) {
coords_array.push_back(coords);
+ if (picked_source == -1) {
+ picked_source = source;
+ } else if (picked_source != source) {
+ picked_source = -2;
+ }
}
}
}
+
+ if (picked_source >= 0) {
+ for (int i = 0; i < sources_list->get_item_count(); i++) {
+ if (int(sources_list->get_item_metadata(i)) == picked_source) {
+ sources_list->set_current(i);
+ break;
+ }
+ }
+ sources_list->ensure_current_is_visible();
+ TilesEditorPlugin::get_singleton()->set_sources_lists_current(picked_source);
+ }
+
Ref<TileMapPattern> new_selection_pattern = tile_map->get_pattern(tile_map_layer, coords_array);
if (!new_selection_pattern->is_empty()) {
selection_pattern = new_selection_pattern;
@@ -1978,7 +1999,11 @@ void TileMapEditorTilesPlugin::_bind_methods() {
}
TileMapEditorTilesPlugin::TileMapEditorTilesPlugin() {
- CanvasItemEditor::get_singleton()->get_viewport_control()->connect("mouse_exited", callable_mp(this, &TileMapEditorTilesPlugin::_mouse_exited_viewport));
+ undo_redo = EditorNode::get_undo_redo();
+
+ CanvasItemEditor::get_singleton()
+ ->get_viewport_control()
+ ->connect("mouse_exited", callable_mp(this, &TileMapEditorTilesPlugin::_mouse_exited_viewport));
// --- Shortcuts ---
ED_SHORTCUT("tiles_editor/cut", TTR("Cut"), KeyModifierMask::CMD | Key::X);
@@ -3242,6 +3267,8 @@ 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));
@@ -3352,15 +3379,16 @@ TileMapEditorTerrainsPlugin::~TileMapEditorTerrainsPlugin() {
void TileMapEditor::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE:
- case NOTIFICATION_THEME_CHANGED:
+ case NOTIFICATION_THEME_CHANGED: {
missing_tile_texture = get_theme_icon(SNAME("StatusWarning"), SNAME("EditorIcons"));
warning_pattern_texture = get_theme_icon(SNAME("WarningPattern"), SNAME("EditorIcons"));
advanced_menu_button->set_icon(get_theme_icon(SNAME("Tools"), SNAME("EditorIcons")));
toggle_grid_button->set_icon(get_theme_icon(SNAME("Grid"), SNAME("EditorIcons")));
toggle_grid_button->set_pressed(EditorSettings::get_singleton()->get("editors/tiles_editor/display_grid"));
toogle_highlight_selected_layer_button->set_icon(get_theme_icon(SNAME("TileMapHighlightSelected"), SNAME("EditorIcons")));
- break;
- case NOTIFICATION_INTERNAL_PROCESS:
+ } break;
+
+ case NOTIFICATION_INTERNAL_PROCESS: {
if (is_visible_in_tree() && tileset_changed_needs_update) {
_update_bottom_panel();
_update_layers_selection();
@@ -3368,11 +3396,13 @@ void TileMapEditor::_notification(int p_what) {
CanvasItemEditor::get_singleton()->update_viewport();
tileset_changed_needs_update = false;
}
- break;
- case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED:
+ } break;
+
+ case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
toggle_grid_button->set_pressed(EditorSettings::get_singleton()->get("editors/tiles_editor/display_grid"));
- break;
- case NOTIFICATION_VISIBILITY_CHANGED:
+ } break;
+
+ case NOTIFICATION_VISIBILITY_CHANGED: {
TileMap *tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id));
if (tile_map) {
if (is_visible_in_tree()) {
@@ -3381,7 +3411,7 @@ void TileMapEditor::_notification(int p_what) {
tile_map->set_selected_layer(-1);
}
}
- break;
+ } break;
}
}
@@ -3945,6 +3975,8 @@ void TileMapEditor::edit(TileMap *p_tile_map) {
}
TileMapEditor::TileMapEditor() {
+ undo_redo = EditorNode::get_undo_redo();
+
set_process_internal(true);
// Shortcuts.
@@ -3992,7 +4024,7 @@ TileMapEditor::TileMapEditor() {
// Layer selector.
layers_selection_popup = memnew(PopupMenu);
layers_selection_popup->connect("id_pressed", callable_mp(this, &TileMapEditor::_layers_selection_id_pressed));
- layers_selection_popup->set_close_on_parent_focus(false);
+ layers_selection_popup->set_flag(Window::FLAG_POPUP, false);
layers_selection_button = memnew(Button);
layers_selection_button->set_toggle_mode(true);
diff --git a/editor/plugins/tiles/tile_map_editor.h b/editor/plugins/tiles/tile_map_editor.h
index 6fa0d01612..d09061015f 100644
--- a/editor/plugins/tiles/tile_map_editor.h
+++ b/editor/plugins/tiles/tile_map_editor.h
@@ -35,10 +35,18 @@
#include "core/os/thread.h"
#include "core/typedefs.h"
-#include "editor/editor_node.h"
#include "scene/2d/tile_map.h"
#include "scene/gui/box_container.h"
+#include "scene/gui/check_box.h"
+#include "scene/gui/item_list.h"
+#include "scene/gui/menu_button.h"
+#include "scene/gui/separator.h"
+#include "scene/gui/spin_box.h"
+#include "scene/gui/split_container.h"
#include "scene/gui/tab_bar.h"
+#include "scene/gui/tree.h"
+
+class UndoRedo;
class TileMapEditorPlugin : public Object {
public:
@@ -61,7 +69,7 @@ class TileMapEditorTilesPlugin : public TileMapEditorPlugin {
GDCLASS(TileMapEditorTilesPlugin, TileMapEditorPlugin);
private:
- UndoRedo *undo_redo = EditorNode::get_undo_redo();
+ UndoRedo *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;
@@ -212,7 +220,7 @@ class TileMapEditorTerrainsPlugin : public TileMapEditorPlugin {
GDCLASS(TileMapEditorTerrainsPlugin, TileMapEditorPlugin);
private:
- UndoRedo *undo_redo = EditorNode::get_undo_redo();
+ UndoRedo *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;
@@ -298,7 +306,7 @@ class TileMapEditor : public VBoxContainer {
GDCLASS(TileMapEditor, VBoxContainer);
private:
- UndoRedo *undo_redo = EditorNode::get_undo_redo();
+ UndoRedo *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 ad44da8dc9..62f3bd6356 100644
--- a/editor/plugins/tiles/tile_proxies_manager_dialog.cpp
+++ b/editor/plugins/tiles/tile_proxies_manager_dialog.cpp
@@ -30,6 +30,7 @@
#include "tile_proxies_manager_dialog.h"
+#include "editor/editor_node.h"
#include "editor/editor_scale.h"
void TileProxiesManagerDialog::_right_clicked(int p_item, Vector2 p_local_mouse_pos, Object *p_item_list) {
@@ -312,6 +313,8 @@ 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 b235d44982..3f1461391e 100644
--- a/editor/plugins/tiles/tile_proxies_manager_dialog.h
+++ b/editor/plugins/tiles/tile_proxies_manager_dialog.h
@@ -31,9 +31,7 @@
#ifndef TILE_PROXIES_MANAGER_DIALOG_H
#define TILE_PROXIES_MANAGER_DIALOG_H
-#include "editor/editor_node.h"
#include "editor/editor_properties.h"
-
#include "scene/2d/tile_map.h"
#include "scene/gui/dialogs.h"
#include "scene/gui/item_list.h"
@@ -45,7 +43,7 @@ private:
int commited_actions_count = 0;
Ref<TileSet> tile_set;
- UndoRedo *undo_redo = EditorNode::get_singleton()->get_undo_redo();
+ UndoRedo *undo_redo;
TileMapCell from;
TileMapCell to;
diff --git a/editor/plugins/tiles/tile_set_atlas_source_editor.cpp b/editor/plugins/tiles/tile_set_atlas_source_editor.cpp
index e708b83440..0c78a0f1c0 100644
--- a/editor/plugins/tiles/tile_set_atlas_source_editor.cpp
+++ b/editor/plugins/tiles/tile_set_atlas_source_editor.cpp
@@ -36,6 +36,7 @@
#include "editor/editor_scale.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"
@@ -107,7 +108,7 @@ void TileSetAtlasSourceEditor::TileSetAtlasSourceProxyObject::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_id", "id"), &TileSetAtlasSourceEditor::TileSetAtlasSourceProxyObject::set_id);
ClassDB::bind_method(D_METHOD("get_id"), &TileSetAtlasSourceEditor::TileSetAtlasSourceProxyObject::get_id);
- ADD_PROPERTY(PropertyInfo(Variant::INT, "id"), "set_id", "get_id");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "id", PROPERTY_HINT_RANGE, "0," + itos(INT_MAX) + ",1"), "set_id", "get_id");
ADD_SIGNAL(MethodInfo("changed", PropertyInfo(Variant::STRING, "what")));
}
@@ -2269,7 +2270,7 @@ void TileSetAtlasSourceEditor::_auto_remove_tiles() {
void TileSetAtlasSourceEditor::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE:
- case NOTIFICATION_THEME_CHANGED:
+ case NOTIFICATION_THEME_CHANGED: {
tool_setup_atlas_source_button->set_icon(get_theme_icon(SNAME("Tools"), SNAME("EditorIcons")));
tool_select_button->set_icon(get_theme_icon(SNAME("ToolSelect"), SNAME("EditorIcons")));
tool_paint_button->set_icon(get_theme_icon(SNAME("CanvasItem"), SNAME("EditorIcons")));
@@ -2280,8 +2281,9 @@ void TileSetAtlasSourceEditor::_notification(int p_what) {
resize_handle = get_theme_icon(SNAME("EditorHandle"), SNAME("EditorIcons"));
resize_handle_disabled = get_theme_icon(SNAME("EditorHandleDisabled"), SNAME("EditorIcons"));
- break;
- case NOTIFICATION_INTERNAL_PROCESS:
+ } break;
+
+ case NOTIFICATION_INTERNAL_PROCESS: {
if (tile_set_changed_needs_update) {
// Update everything.
_update_source_inspector();
@@ -2297,9 +2299,7 @@ void TileSetAtlasSourceEditor::_notification(int p_what) {
tile_set_changed_needs_update = false;
}
- break;
- default:
- break;
+ } break;
}
}
@@ -2311,6 +2311,8 @@ void TileSetAtlasSourceEditor::_bind_methods() {
}
TileSetAtlasSourceEditor::TileSetAtlasSourceEditor() {
+ undo_redo = EditorNode::get_undo_redo();
+
set_process_unhandled_key_input(true);
set_process_internal(true);
@@ -2593,7 +2595,7 @@ void EditorPropertyTilePolygon::_polygons_changed() {
changed_properties.push_back(vformat(element_pattern, i));
values.push_back(generic_tile_polygon_editor->get_polygon(i));
}
- emit_signal("multiple_properties_changed", changed_properties, values, false);
+ emit_signal(SNAME("multiple_properties_changed"), changed_properties, values, false);
}
}
}
diff --git a/editor/plugins/tiles/tile_set_atlas_source_editor.h b/editor/plugins/tiles/tile_set_atlas_source_editor.h
index 51771c59ba..4a90b821f8 100644
--- a/editor/plugins/tiles/tile_set_atlas_source_editor.h
+++ b/editor/plugins/tiles/tile_set_atlas_source_editor.h
@@ -34,7 +34,6 @@
#include "tile_atlas_view.h"
#include "tile_data_editors.h"
-#include "editor/editor_node.h"
#include "scene/gui/split_container.h"
#include "scene/resources/tile_set.h"
@@ -115,7 +114,7 @@ private:
TileSetAtlasSource *tile_set_atlas_source = nullptr;
int tile_set_atlas_source_id = TileSet::INVALID_SOURCE;
- UndoRedo *undo_redo = EditorNode::get_undo_redo();
+ UndoRedo *undo_redo;
bool tile_set_changed_needs_update = false;
diff --git a/editor/plugins/tiles/tile_set_editor.cpp b/editor/plugins/tiles/tile_set_editor.cpp
index ab355d4658..49e589c9ef 100644
--- a/editor/plugins/tiles/tile_set_editor.cpp
+++ b/editor/plugins/tiles/tile_set_editor.cpp
@@ -33,6 +33,8 @@
#include "tile_data_editors.h"
#include "tiles_editor_plugin.h"
+#include "editor/editor_file_system.h"
+#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "scene/gui/box_container.h"
@@ -331,14 +333,15 @@ void TileSetEditor::_set_source_sort(int p_sort) {
void TileSetEditor::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE:
- case NOTIFICATION_THEME_CHANGED:
+ case NOTIFICATION_THEME_CHANGED: {
sources_delete_button->set_icon(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")));
sources_add_button->set_icon(get_theme_icon(SNAME("Add"), SNAME("EditorIcons")));
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"));
- break;
- case NOTIFICATION_INTERNAL_PROCESS:
+ } break;
+
+ case NOTIFICATION_INTERNAL_PROCESS: {
if (tile_set_changed_needs_update) {
if (tile_set.is_valid()) {
tile_set->set_edited(true);
@@ -347,9 +350,7 @@ void TileSetEditor::_notification(int p_what) {
_update_patterns_list();
tile_set_changed_needs_update = false;
}
- break;
- default:
- break;
+ } break;
}
}
@@ -657,6 +658,8 @@ 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 a21c951c42..b79b37cf2e 100644
--- a/editor/plugins/tiles/tile_set_editor.h
+++ b/editor/plugins/tiles/tile_set_editor.h
@@ -33,6 +33,7 @@
#include "atlas_merging_dialog.h"
#include "scene/gui/box_container.h"
+#include "scene/gui/tab_bar.h"
#include "scene/resources/tile_set.h"
#include "tile_proxies_manager_dialog.h"
#include "tile_set_atlas_source_editor.h"
@@ -57,7 +58,7 @@ private:
TileSetAtlasSourceEditor *tile_set_atlas_source_editor;
TileSetScenesCollectionSourceEditor *tile_set_scenes_collection_source_editor;
- UndoRedo *undo_redo = EditorNode::get_undo_redo();
+ UndoRedo *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 240c017b84..21ebcbd655 100644
--- a/editor/plugins/tiles/tile_set_scenes_collection_source_editor.cpp
+++ b/editor/plugins/tiles/tile_set_scenes_collection_source_editor.cpp
@@ -30,6 +30,8 @@
#include "tile_set_scenes_collection_source_editor.h"
+#include "editor/editor_file_system.h"
+#include "editor/editor_node.h"
#include "editor/editor_resource_preview.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
@@ -328,12 +330,13 @@ void TileSetScenesCollectionSourceEditor::_update_scenes_list() {
void TileSetScenesCollectionSourceEditor::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE:
- case NOTIFICATION_THEME_CHANGED:
+ case NOTIFICATION_THEME_CHANGED: {
scene_tile_add_button->set_icon(get_theme_icon(SNAME("Add"), SNAME("EditorIcons")));
scene_tile_delete_button->set_icon(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")));
_update_scenes_list();
- break;
- case NOTIFICATION_INTERNAL_PROCESS:
+ } break;
+
+ case NOTIFICATION_INTERNAL_PROCESS: {
if (tile_set_scenes_collection_source_changed_needs_update) {
// Update everything.
_update_source_inspector();
@@ -342,14 +345,13 @@ void TileSetScenesCollectionSourceEditor::_notification(int p_what) {
_update_tile_inspector();
tile_set_scenes_collection_source_changed_needs_update = false;
}
- break;
- case NOTIFICATION_VISIBILITY_CHANGED:
+ } break;
+
+ case NOTIFICATION_VISIBILITY_CHANGED: {
// Update things just in case.
_update_scenes_list();
_update_action_buttons();
- break;
- default:
- break;
+ } break;
}
}
@@ -452,6 +454,8 @@ void TileSetScenesCollectionSourceEditor::_bind_methods() {
}
TileSetScenesCollectionSourceEditor::TileSetScenesCollectionSourceEditor() {
+ undo_redo = EditorNode::get_undo_redo();
+
// -- Right side --
HSplitContainer *split_container_right_side = memnew(HSplitContainer);
split_container_right_side->set_h_size_flags(SIZE_EXPAND_FILL);
diff --git a/editor/plugins/tiles/tile_set_scenes_collection_source_editor.h b/editor/plugins/tiles/tile_set_scenes_collection_source_editor.h
index 5b48ea4762..8904e8524a 100644
--- a/editor/plugins/tiles/tile_set_scenes_collection_source_editor.h
+++ b/editor/plugins/tiles/tile_set_scenes_collection_source_editor.h
@@ -31,10 +31,14 @@
#ifndef TILE_SET_SCENES_COLLECTION_SOURCE_EDITOR_H
#define TILE_SET_SCENES_COLLECTION_SOURCE_EDITOR_H
-#include "editor/editor_node.h"
+#include "editor/editor_inspector.h"
#include "scene/gui/box_container.h"
+#include "scene/gui/button.h"
+#include "scene/gui/item_list.h"
#include "scene/resources/tile_set.h"
+class UndoRedo;
+
class TileSetScenesCollectionSourceEditor : public HBoxContainer {
GDCLASS(TileSetScenesCollectionSourceEditor, HBoxContainer);
@@ -93,7 +97,7 @@ private:
TileSetScenesCollectionSource *tile_set_scenes_collection_source = nullptr;
int tile_set_source_id = -1;
- UndoRedo *undo_redo = EditorNode::get_undo_redo();
+ UndoRedo *undo_redo;
bool tile_set_scenes_collection_source_changed_needs_update = false;
diff --git a/editor/plugins/tiles/tiles_editor_plugin.cpp b/editor/plugins/tiles/tiles_editor_plugin.cpp
index 4c644f33d4..4aabe0e6b7 100644
--- a/editor/plugins/tiles/tiles_editor_plugin.cpp
+++ b/editor/plugins/tiles/tiles_editor_plugin.cpp
@@ -161,9 +161,9 @@ void TilesEditorPlugin::_update_editors() {
// Update visibility of bottom panel buttons.
if (tileset_editor_button->is_pressed() && !tile_set.is_valid()) {
if (tile_map) {
- editor_node->make_bottom_panel_item_visible(tilemap_editor);
+ EditorNode::get_singleton()->make_bottom_panel_item_visible(tilemap_editor);
} else {
- editor_node->hide_bottom_panel();
+ EditorNode::get_singleton()->hide_bottom_panel();
}
}
}
@@ -190,15 +190,15 @@ void TilesEditorPlugin::make_visible(bool p_visible) {
tileset_editor_button->set_visible(tile_set.is_valid());
tilemap_editor_button->set_visible(tile_map);
if (tile_map) {
- editor_node->make_bottom_panel_item_visible(tilemap_editor);
+ EditorNode::get_singleton()->make_bottom_panel_item_visible(tilemap_editor);
} else {
- editor_node->make_bottom_panel_item_visible(tileset_editor);
+ EditorNode::get_singleton()->make_bottom_panel_item_visible(tileset_editor);
}
} else {
tileset_editor_button->hide();
tilemap_editor_button->hide();
- editor_node->hide_bottom_panel();
+ EditorNode::get_singleton()->hide_bottom_panel();
}
}
@@ -353,7 +353,7 @@ void TilesEditorPlugin::edit(Object *p_object) {
tile_map_id = p_object->get_instance_id();
tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id));
tile_set = tile_map->get_tileset();
- editor_node->make_bottom_panel_item_visible(tilemap_editor);
+ EditorNode::get_singleton()->make_bottom_panel_item_visible(tilemap_editor);
} else if (p_object->is_class("TileSet")) {
tile_set = Ref<TileSet>(p_object);
if (tile_map) {
@@ -362,7 +362,7 @@ void TilesEditorPlugin::edit(Object *p_object) {
tile_map_id = ObjectID();
}
}
- editor_node->make_bottom_panel_item_visible(tileset_editor);
+ EditorNode::get_singleton()->make_bottom_panel_item_visible(tileset_editor);
}
}
@@ -379,14 +379,12 @@ bool TilesEditorPlugin::handles(Object *p_object) const {
return p_object->is_class("TileMap") || p_object->is_class("TileSet");
}
-TilesEditorPlugin::TilesEditorPlugin(EditorNode *p_node) {
+TilesEditorPlugin::TilesEditorPlugin() {
set_process_internal(true);
// Update the singleton.
singleton = this;
- editor_node = p_node;
-
// Tileset editor.
tileset_editor = memnew(TileSetEditor);
tileset_editor->set_h_size_flags(Control::SIZE_EXPAND_FILL);
@@ -405,9 +403,9 @@ TilesEditorPlugin::TilesEditorPlugin(EditorNode *p_node) {
pattern_preview_thread.start(_thread_func, this);
// Bottom buttons.
- tileset_editor_button = p_node->add_bottom_panel_item(TTR("TileSet"), tileset_editor);
+ tileset_editor_button = EditorNode::get_singleton()->add_bottom_panel_item(TTR("TileSet"), tileset_editor);
tileset_editor_button->hide();
- tilemap_editor_button = p_node->add_bottom_panel_item(TTR("TileMap"), tilemap_editor);
+ tilemap_editor_button = EditorNode::get_singleton()->add_bottom_panel_item(TTR("TileMap"), tilemap_editor);
tilemap_editor_button->hide();
// Initialization.
diff --git a/editor/plugins/tiles/tiles_editor_plugin.h b/editor/plugins/tiles/tiles_editor_plugin.h
index 487436b98a..eeff4da4e9 100644
--- a/editor/plugins/tiles/tiles_editor_plugin.h
+++ b/editor/plugins/tiles/tiles_editor_plugin.h
@@ -53,8 +53,6 @@ public:
};
private:
- EditorNode *editor_node;
-
bool tile_map_changed_needs_update = false;
ObjectID tile_map_id;
Ref<TileSet> tile_set;
@@ -127,7 +125,7 @@ public:
virtual bool handles(Object *p_object) const override;
virtual void make_visible(bool p_visible) override;
- TilesEditorPlugin(EditorNode *p_node);
+ TilesEditorPlugin();
~TilesEditorPlugin();
};
diff --git a/editor/plugins/version_control_editor_plugin.cpp b/editor/plugins/version_control_editor_plugin.cpp
index b1d5b348c4..443d5975cd 100644
--- a/editor/plugins/version_control_editor_plugin.cpp
+++ b/editor/plugins/version_control_editor_plugin.cpp
@@ -329,7 +329,7 @@ void VersionControlEditorPlugin::register_editor() {
if (!EditorVCSInterface::get_singleton()) {
EditorNode::get_singleton()->add_control_to_dock(EditorNode::DOCK_SLOT_RIGHT_UL, version_commit_dock);
TabContainer *dock_vbc = (TabContainer *)version_commit_dock->get_parent_control();
- dock_vbc->set_tab_title(version_commit_dock->get_index(), TTR("Commit"));
+ dock_vbc->set_tab_title(dock_vbc->get_tab_idx_from_control(version_commit_dock), TTR("Commit"));
Button *vc = EditorNode::get_singleton()->add_bottom_panel_item(TTR("Version Control"), version_control_dock);
set_version_control_tool_button(vc);
diff --git a/editor/plugins/version_control_editor_plugin.h b/editor/plugins/version_control_editor_plugin.h
index 86f98ad3aa..956c5a334f 100644
--- a/editor/plugins/version_control_editor_plugin.h
+++ b/editor/plugins/version_control_editor_plugin.h
@@ -33,8 +33,9 @@
#include "editor/editor_plugin.h"
#include "editor/editor_vcs_interface.h"
-#include "scene/gui/container.h"
+#include "scene/gui/box_container.h"
#include "scene/gui/rich_text_label.h"
+#include "scene/gui/split_container.h"
#include "scene/gui/text_edit.h"
#include "scene/gui/tree.h"
diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp
index 9ab53bf5c3..7f30dd91e5 100644
--- a/editor/plugins/visual_shader_editor_plugin.cpp
+++ b/editor/plugins/visual_shader_editor_plugin.cpp
@@ -37,6 +37,7 @@
#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 "scene/animation/animation_player.h"
@@ -554,7 +555,7 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) {
}
if (custom_editor) {
- if (is_curve || (hb == nullptr && !vsnode->is_use_prop_slots() && vsnode->get_output_port_count() > 0 && vsnode->get_output_port_name(0) == "" && (vsnode->get_input_port_count() == 0 || vsnode->get_input_port_name(0) == ""))) {
+ if (is_curve || (hb == nullptr && !vsnode->is_use_prop_slots() && (vsnode->get_output_port_count() == 0 || vsnode->get_output_port_name(0) == "") && (vsnode->get_input_port_count() == 0 || vsnode->get_input_port_name(0) == ""))) {
//will be embedded in first port
} else {
port_offset++;
@@ -585,14 +586,14 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) {
Button *add_input_btn = memnew(Button);
add_input_btn->set_text(TTR("Add Input"));
- add_input_btn->connect("pressed", callable_mp(editor, &VisualShaderEditor::_add_input_port), varray(p_id, group_node->get_free_input_port_id(), VisualShaderNode::PORT_TYPE_VECTOR, input_port_name), CONNECT_DEFERRED);
+ add_input_btn->connect("pressed", callable_mp(editor, &VisualShaderEditor::_add_input_port), varray(p_id, group_node->get_free_input_port_id(), VisualShaderNode::PORT_TYPE_VECTOR_3D, input_port_name), CONNECT_DEFERRED);
hb2->add_child(add_input_btn);
hb2->add_spacer();
Button *add_output_btn = memnew(Button);
add_output_btn->set_text(TTR("Add Output"));
- add_output_btn->connect("pressed", callable_mp(editor, &VisualShaderEditor::_add_output_port), varray(p_id, group_node->get_free_output_port_id(), VisualShaderNode::PORT_TYPE_VECTOR, output_port_name), CONNECT_DEFERRED);
+ add_output_btn->connect("pressed", callable_mp(editor, &VisualShaderEditor::_add_output_port), varray(p_id, group_node->get_free_output_port_id(), VisualShaderNode::PORT_TYPE_VECTOR_3D, output_port_name), CONNECT_DEFERRED);
hb2->add_child(add_output_btn);
node->add_child(hb2);
@@ -606,7 +607,7 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) {
case VisualShaderNode::PORT_TYPE_VECTOR_2D: {
output_port_count += 2;
} break;
- case VisualShaderNode::PORT_TYPE_VECTOR: {
+ case VisualShaderNode::PORT_TYPE_VECTOR_3D: {
output_port_count += 3;
} break;
default:
@@ -628,7 +629,7 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) {
i -= 2;
}
} break;
- case VisualShaderNode::PORT_TYPE_VECTOR: {
+ case VisualShaderNode::PORT_TYPE_VECTOR_3D: {
if (expanded_port_counter >= 3) {
expanded_type = VisualShaderNode::PORT_TYPE_SCALAR;
expanded_port_counter = 0;
@@ -852,7 +853,7 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) {
expanded_type = VisualShaderNode::PORT_TYPE_VECTOR_2D;
} break;
- case VisualShaderNode::PORT_TYPE_VECTOR: {
+ case VisualShaderNode::PORT_TYPE_VECTOR_3D: {
port_offset++;
valid_left = (i + 1) < vsnode->get_input_port_count();
port_left = VisualShaderNode::PORT_TYPE_SCALAR;
@@ -877,7 +878,7 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) {
}
node->set_slot(i + port_offset, valid_left, port_left, type_color[port_left], true, VisualShaderNode::PORT_TYPE_SCALAR, vector_expanded_color[2]);
- expanded_type = VisualShaderNode::PORT_TYPE_VECTOR;
+ expanded_type = VisualShaderNode::PORT_TYPE_VECTOR_3D;
} break;
default:
break;
@@ -1073,6 +1074,7 @@ void VisualShaderEditor::edit(VisualShader *p_visual_shader) {
hide();
} else {
if (changed) { // to avoid tree collapse
+ _update_varying_tree();
_update_options_menu();
_update_preview();
_update_graph();
@@ -1080,6 +1082,10 @@ 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;
@@ -1163,10 +1169,7 @@ bool VisualShaderEditor::_is_available(int p_mode) {
return (p_mode == -1 || (p_mode & current_mode) != 0);
}
-void VisualShaderEditor::update_custom_nodes() {
- if (members_dialog->is_visible()) {
- return;
- }
+void VisualShaderEditor::_update_nodes() {
clear_custom_types();
List<StringName> class_list;
ScriptServer::get_global_class_list(&class_list);
@@ -1182,6 +1185,9 @@ void VisualShaderEditor::update_custom_nodes() {
Ref<VisualShaderNodeCustom> ref;
ref.instantiate();
ref->set_script(script);
+ if (!ref->is_available(visual_shader->get_mode(), visual_shader->get_shader_type())) {
+ continue;
+ }
String name;
if (ref->has_method("_get_name")) {
@@ -1238,6 +1244,32 @@ void VisualShaderEditor::update_custom_nodes() {
}
}
+ // Disables not-supported copied items.
+ {
+ for (CopyItem &item : copy_items_buffer) {
+ Ref<VisualShaderNodeCustom> custom = Object::cast_to<VisualShaderNodeCustom>(item.node.ptr());
+
+ if (custom.is_valid()) {
+ if (!custom->is_available(visual_shader->get_mode(), visual_shader->get_shader_type())) {
+ item.disabled = true;
+ } else {
+ item.disabled = false;
+ }
+ } else {
+ for (int i = 0; i < add_options.size(); i++) {
+ if (add_options[i].type == item.node->get_class_name()) {
+ if ((add_options[i].func != visual_shader->get_mode() && add_options[i].func != -1) || !_is_available(add_options[i].mode)) {
+ item.disabled = true;
+ } else {
+ item.disabled = false;
+ }
+ break;
+ }
+ }
+ }
+ }
+ }
+
Array keys = added.keys();
keys.sort();
@@ -1432,7 +1464,7 @@ void VisualShaderEditor::_update_options_menu() {
case VisualShaderNode::PORT_TYPE_VECTOR_2D:
item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Vector2"), SNAME("EditorIcons")));
break;
- case VisualShaderNode::PORT_TYPE_VECTOR:
+ case VisualShaderNode::PORT_TYPE_VECTOR_3D:
item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Vector3"), SNAME("EditorIcons")));
break;
case VisualShaderNode::PORT_TYPE_BOOLEAN:
@@ -1459,6 +1491,7 @@ void VisualShaderEditor::_set_mode(int p_which) {
edit_type_fog->set_visible(false);
edit_type = edit_type_sky;
custom_mode_box->set_visible(false);
+ varying_button->hide();
mode = MODE_FLAGS_SKY;
} else if (p_which == VisualShader::MODE_FOG) {
edit_type_standard->set_visible(false);
@@ -1467,6 +1500,7 @@ void VisualShaderEditor::_set_mode(int p_which) {
edit_type_fog->set_visible(true);
edit_type = edit_type_fog;
custom_mode_box->set_visible(false);
+ varying_button->hide();
mode = MODE_FLAGS_FOG;
} else if (p_which == VisualShader::MODE_PARTICLES) {
edit_type_standard->set_visible(false);
@@ -1479,6 +1513,7 @@ void VisualShaderEditor::_set_mode(int p_which) {
} else {
custom_mode_box->set_visible(true);
}
+ varying_button->hide();
mode = MODE_FLAGS_PARTICLES;
} else {
edit_type_particles->set_visible(false);
@@ -1487,6 +1522,7 @@ void VisualShaderEditor::_set_mode(int p_which) {
edit_type_fog->set_visible(false);
edit_type = edit_type_standard;
custom_mode_box->set_visible(false);
+ varying_button->show();
mode = MODE_FLAGS_SPATIAL_CANVASITEM;
}
visual_shader->set_shader_type(get_current_shader_type());
@@ -1615,6 +1651,7 @@ void VisualShaderEditor::_update_graph() {
Vector<int> nodes = visual_shader->get_node_list(type);
_update_uniforms(false);
+ _update_varyings();
graph_plugin->clear_links();
graph_plugin->make_dirty(true);
@@ -1789,7 +1826,7 @@ void VisualShaderEditor::_expand_output_port(int p_node, int p_port, bool p_expa
case VisualShaderNode::PORT_TYPE_VECTOR_2D: {
type_size = 2;
} break;
- case VisualShaderNode::PORT_TYPE_VECTOR: {
+ case VisualShaderNode::PORT_TYPE_VECTOR_3D: {
type_size = 3;
} break;
default:
@@ -2584,7 +2621,7 @@ void VisualShaderEditor::_add_node(int p_idx, const Vector<Variant> &p_ops, Stri
vsnode = Ref<VisualShaderNode>(vsn);
} else {
ERR_FAIL_COND(add_options[p_idx].script.is_null());
- String base_type = add_options[p_idx].script->get_instance_base_type();
+ StringName base_type = add_options[p_idx].script->get_instance_base_type();
VisualShaderNode *vsn = Object::cast_to<VisualShaderNode>(ClassDB::instantiate(base_type));
ERR_FAIL_COND(!vsn);
vsnode = Ref<VisualShaderNode>(vsn);
@@ -2648,7 +2685,7 @@ void VisualShaderEditor::_add_node(int p_idx, const Vector<Variant> &p_ops, Stri
case VisualShaderNode::PORT_TYPE_VECTOR_2D:
initial_expression_code = "output0 = vec2(1.0, 1.0);";
break;
- case VisualShaderNode::PORT_TYPE_VECTOR:
+ case VisualShaderNode::PORT_TYPE_VECTOR_3D:
initial_expression_code = "output0 = vec3(1.0, 1.0, 1.0);";
break;
case VisualShaderNode::PORT_TYPE_BOOLEAN:
@@ -2777,6 +2814,116 @@ 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) {
+ 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);
+ undo_redo->add_undo_method(visual_shader.ptr(), "remove_varying", p_name);
+
+ undo_redo->add_do_method(this, "_update_varyings");
+ undo_redo->add_undo_method(this, "_update_varyings");
+
+ for (int i = 0; i <= VisualShader::TYPE_LIGHT; i++) {
+ if (p_mode == VisualShader::VARYING_MODE_FRAG_TO_LIGHT && i == 0) {
+ continue;
+ }
+
+ VisualShader::Type type = VisualShader::Type(i);
+ Vector<int> nodes = visual_shader->get_node_list(type);
+
+ for (int j = 0; j < nodes.size(); j++) {
+ int node_id = nodes[j];
+ Ref<VisualShaderNode> vsnode = visual_shader->get_node(type, node_id);
+ Ref<VisualShaderNodeVarying> var = vsnode;
+
+ if (var.is_valid()) {
+ undo_redo->add_do_method(graph_plugin.ptr(), "update_node", type, node_id);
+ undo_redo->add_undo_method(graph_plugin.ptr(), "update_node", type, node_id);
+ }
+ }
+ }
+
+ undo_redo->add_do_method(this, "_update_varying_tree");
+ undo_redo->add_undo_method(this, "_update_varying_tree");
+ undo_redo->commit_action();
+}
+
+void VisualShaderEditor::_remove_varying(const String &p_name) {
+ undo_redo->create_action(vformat(TTR("Remove Varying from Visual Shader: %s"), p_name));
+
+ VisualShader::VaryingMode mode = visual_shader->get_varying_mode(p_name);
+
+ undo_redo->add_do_method(visual_shader.ptr(), "remove_varying", p_name);
+ undo_redo->add_undo_method(visual_shader.ptr(), "add_varying", p_name, mode, visual_shader->get_varying_type(p_name));
+
+ undo_redo->add_do_method(this, "_update_varyings");
+ undo_redo->add_undo_method(this, "_update_varyings");
+
+ for (int i = 0; i <= VisualShader::TYPE_LIGHT; i++) {
+ if (mode == VisualShader::VARYING_MODE_FRAG_TO_LIGHT && i == 0) {
+ continue;
+ }
+
+ VisualShader::Type type = VisualShader::Type(i);
+ Vector<int> nodes = visual_shader->get_node_list(type);
+
+ for (int j = 0; j < nodes.size(); j++) {
+ int node_id = nodes[j];
+ Ref<VisualShaderNode> vsnode = visual_shader->get_node(type, node_id);
+ Ref<VisualShaderNodeVarying> var = vsnode;
+
+ if (var.is_valid()) {
+ String var_name = var->get_varying_name();
+
+ if (var_name == p_name) {
+ undo_redo->add_do_method(var.ptr(), "set_varying_name", "[None]");
+ undo_redo->add_undo_method(var.ptr(), "set_varying_name", var_name);
+ undo_redo->add_do_method(var.ptr(), "set_varying_type", VisualShader::VARYING_TYPE_FLOAT);
+ undo_redo->add_undo_method(var.ptr(), "set_varying_type", var->get_varying_type());
+ }
+ undo_redo->add_do_method(graph_plugin.ptr(), "update_node", type, node_id);
+ undo_redo->add_undo_method(graph_plugin.ptr(), "update_node", type, node_id);
+ }
+ }
+
+ List<VisualShader::Connection> connections;
+ visual_shader->get_node_connections(type, &connections);
+
+ for (VisualShader::Connection &E : connections) {
+ Ref<VisualShaderNodeVaryingGetter> var_getter = Object::cast_to<VisualShaderNodeVaryingGetter>(visual_shader->get_node(type, E.from_node).ptr());
+ if (var_getter.is_valid() && E.from_port > 0) {
+ undo_redo->add_do_method(visual_shader.ptr(), "disconnect_nodes", type, E.from_node, E.from_port, E.to_node, E.to_port);
+ undo_redo->add_undo_method(visual_shader.ptr(), "connect_nodes", type, E.from_node, E.from_port, E.to_node, E.to_port);
+ undo_redo->add_do_method(graph_plugin.ptr(), "disconnect_nodes", type, E.from_node, E.from_port, E.to_node, E.to_port);
+ undo_redo->add_undo_method(graph_plugin.ptr(), "connect_nodes", type, E.from_node, E.from_port, E.to_node, E.to_port);
+ }
+ Ref<VisualShaderNodeVaryingSetter> var_setter = Object::cast_to<VisualShaderNodeVaryingSetter>(visual_shader->get_node(type, E.to_node).ptr());
+ if (var_setter.is_valid() && E.to_port > 0) {
+ undo_redo->add_do_method(visual_shader.ptr(), "disconnect_nodes", type, E.from_node, E.from_port, E.to_node, E.to_port);
+ undo_redo->add_undo_method(visual_shader.ptr(), "connect_nodes", type, E.from_node, E.from_port, E.to_node, E.to_port);
+ undo_redo->add_do_method(graph_plugin.ptr(), "disconnect_nodes", type, E.from_node, E.from_port, E.to_node, E.to_port);
+ undo_redo->add_undo_method(graph_plugin.ptr(), "connect_nodes", type, E.from_node, E.from_port, E.to_node, E.to_port);
+ }
+ }
+ }
+
+ undo_redo->add_do_method(this, "_update_varying_tree");
+ undo_redo->add_undo_method(this, "_update_varying_tree");
+ undo_redo->commit_action();
+}
+
+void VisualShaderEditor::_update_varyings() {
+ VisualShaderNodeVarying::clear_varyings();
+
+ for (int i = 0; i < visual_shader->get_varyings_count(); i++) {
+ const VisualShader::Varying *var = visual_shader->get_varying_by_index(i);
+
+ if (var != nullptr) {
+ VisualShaderNodeVarying::add_varying(var->name, var->mode, var->type);
+ }
+ }
+}
+
void VisualShaderEditor::_node_dragged(const Vector2 &p_from, const Vector2 &p_to, int p_node) {
VisualShader::Type type = get_current_shader_type();
drag_buffer.push_back({ type, p_node, p_from, p_to });
@@ -3253,15 +3400,23 @@ void VisualShaderEditor::_graph_gui_input(const Ref<InputEvent> &p_event) {
selected_float_constant = -1;
}
- if (to_change.is_empty() && copy_items_buffer.is_empty()) {
+ bool copy_buffer_empty = true;
+ for (const CopyItem &item : copy_items_buffer) {
+ if (!item.disabled) {
+ copy_buffer_empty = false;
+ break;
+ }
+ }
+
+ if (to_change.is_empty() && copy_buffer_empty) {
_show_members_dialog(true);
} else {
popup_menu->set_item_disabled(NodeMenuOptions::CUT, to_change.is_empty());
popup_menu->set_item_disabled(NodeMenuOptions::COPY, to_change.is_empty());
- popup_menu->set_item_disabled(NodeMenuOptions::PASTE, copy_items_buffer.is_empty());
+ popup_menu->set_item_disabled(NodeMenuOptions::PASTE, copy_buffer_empty);
popup_menu->set_item_disabled(NodeMenuOptions::DELETE, to_change.is_empty());
popup_menu->set_item_disabled(NodeMenuOptions::DUPLICATE, to_change.is_empty());
- popup_menu->set_item_disabled(NodeMenuOptions::CLEAR_COPY_BUFFER, copy_items_buffer.is_empty());
+ popup_menu->set_item_disabled(NodeMenuOptions::CLEAR_COPY_BUFFER, copy_buffer_empty);
int temp = popup_menu->get_item_index(NodeMenuOptions::SEPARATOR2);
if (temp != -1) {
@@ -3363,6 +3518,49 @@ void VisualShaderEditor::_show_members_dialog(bool at_mouse_pos, VisualShaderNod
node_filter->select_all();
}
+void VisualShaderEditor::_show_varying_menu() {
+ varying_options->set_item_disabled(int(VaryingMenuOptions::REMOVE), visual_shader->get_varyings_count() == 0);
+ varying_options->set_position(graph->get_screen_position() + varying_button->get_position() + Size2(0, varying_button->get_size().height));
+ varying_options->popup();
+}
+
+void VisualShaderEditor::_varying_menu_id_pressed(int p_idx) {
+ switch (VaryingMenuOptions(p_idx)) {
+ case VaryingMenuOptions::ADD: {
+ _show_add_varying_dialog();
+ } break;
+ case VaryingMenuOptions::REMOVE: {
+ _show_remove_varying_dialog();
+ } break;
+ default:
+ break;
+ }
+}
+
+void VisualShaderEditor::_show_add_varying_dialog() {
+ _varying_name_changed(varying_name->get_text());
+
+ add_varying_dialog->set_position(graph->get_screen_position() + varying_button->get_position() + Point2(5 * EDSCALE, 65 * EDSCALE));
+ add_varying_dialog->popup();
+
+ // Keep dialog within window bounds.
+ Rect2 window_rect = Rect2(DisplayServer::get_singleton()->window_get_position(), DisplayServer::get_singleton()->window_get_size());
+ Rect2 dialog_rect = Rect2(add_varying_dialog->get_position(), add_varying_dialog->get_size());
+ Vector2 difference = (dialog_rect.get_end() - window_rect.get_end()).max(Vector2());
+ add_varying_dialog->set_position(add_varying_dialog->get_position() - difference);
+}
+
+void VisualShaderEditor::_show_remove_varying_dialog() {
+ remove_varying_dialog->set_position(graph->get_screen_position() + varying_button->get_position() + Point2(5 * EDSCALE, 65 * EDSCALE));
+ remove_varying_dialog->popup();
+
+ // Keep dialog within window bounds.
+ Rect2 window_rect = Rect2(DisplayServer::get_singleton()->window_get_position(), DisplayServer::get_singleton()->window_get_size());
+ Rect2 dialog_rect = Rect2(remove_varying_dialog->get_position(), remove_varying_dialog->get_size());
+ Vector2 difference = (dialog_rect.get_end() - window_rect.get_end()).max(Vector2());
+ remove_varying_dialog->set_position(remove_varying_dialog->get_position() - difference);
+}
+
void VisualShaderEditor::_sbox_input(const Ref<InputEvent> &p_ie) {
Ref<InputEventKey> ie = p_ie;
if (ie.is_valid() && (ie->get_keycode() == Key::UP || ie->get_keycode() == Key::DOWN || ie->get_keycode() == Key::ENTER || ie->get_keycode() == Key::KP_ENTER)) {
@@ -3372,91 +3570,100 @@ void VisualShaderEditor::_sbox_input(const Ref<InputEvent> &p_ie) {
}
void VisualShaderEditor::_notification(int p_what) {
- if (p_what == NOTIFICATION_ENTER_TREE) {
- node_filter->set_clear_button_enabled(true);
-
- // collapse tree by default
-
- TreeItem *category = members->get_root()->get_first_child();
- while (category) {
- category->set_collapsed(true);
- TreeItem *sub_category = category->get_first_child();
- while (sub_category) {
- sub_category->set_collapsed(true);
- sub_category = sub_category->get_next();
- }
- category = category->get_next();
- }
- }
-
- if (p_what == NOTIFICATION_ENTER_TREE || p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) {
- graph->get_panner()->setup((ViewPanner::ControlScheme)EDITOR_GET("editors/panning/sub_editors_panning_scheme").operator int(), ED_GET_SHORTCUT("canvas_item_editor/pan_view"), bool(EditorSettings::get_singleton()->get("editors/panning/simple_panning")));
- graph->set_warped_panning(bool(EditorSettings::get_singleton()->get("editors/panning/warped_mouse_panning")));
- }
-
- if (p_what == NOTIFICATION_DRAG_BEGIN) {
- Dictionary dd = get_viewport()->gui_get_drag_data();
- if (members->is_visible_in_tree() && dd.has("id")) {
- members->set_drop_mode_flags(Tree::DROP_MODE_ON_ITEM);
- }
- } else if (p_what == NOTIFICATION_DRAG_END) {
- members->set_drop_mode_flags(0);
- }
-
- if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) {
- highend_label->set_modulate(get_theme_color(SNAME("vulkan_color"), SNAME("Editor")));
-
- node_filter->set_right_icon(Control::get_theme_icon(SNAME("Search"), SNAME("EditorIcons")));
-
- preview_shader->set_icon(Control::get_theme_icon(SNAME("Shader"), SNAME("EditorIcons")));
+ switch (p_what) {
+ case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
+ graph->get_panner()->setup((ViewPanner::ControlScheme)EDITOR_GET("editors/panning/sub_editors_panning_scheme").operator int(), ED_GET_SHORTCUT("canvas_item_editor/pan_view"), bool(EditorSettings::get_singleton()->get("editors/panning/simple_panning")));
+ graph->set_warped_panning(bool(EditorSettings::get_singleton()->get("editors/panning/warped_mouse_panning")));
+ } break;
- {
- Color background_color = EDITOR_GET("text_editor/theme/highlighting/background_color");
- Color text_color = EDITOR_GET("text_editor/theme/highlighting/text_color");
- Color keyword_color = EDITOR_GET("text_editor/theme/highlighting/keyword_color");
- Color control_flow_keyword_color = EDITOR_GET("text_editor/theme/highlighting/control_flow_keyword_color");
- Color comment_color = EDITOR_GET("text_editor/theme/highlighting/comment_color");
- Color symbol_color = EDITOR_GET("text_editor/theme/highlighting/symbol_color");
- Color function_color = EDITOR_GET("text_editor/theme/highlighting/function_color");
- Color number_color = EDITOR_GET("text_editor/theme/highlighting/number_color");
- Color members_color = EDITOR_GET("text_editor/theme/highlighting/member_variable_color");
+ case NOTIFICATION_ENTER_TREE: {
+ node_filter->set_clear_button_enabled(true);
- preview_text->add_theme_color_override("background_color", background_color);
+ // collapse tree by default
- for (const String &E : keyword_list) {
- if (ShaderLanguage::is_control_flow_keyword(E)) {
- syntax_highlighter->add_keyword_color(E, control_flow_keyword_color);
- } else {
- syntax_highlighter->add_keyword_color(E, keyword_color);
+ TreeItem *category = members->get_root()->get_first_child();
+ while (category) {
+ category->set_collapsed(true);
+ TreeItem *sub_category = category->get_first_child();
+ while (sub_category) {
+ sub_category->set_collapsed(true);
+ sub_category = sub_category->get_next();
}
+ category = category->get_next();
}
- preview_text->add_theme_font_override("font", get_theme_font(SNAME("expression"), SNAME("EditorFonts")));
- preview_text->add_theme_font_size_override("font_size", get_theme_font_size(SNAME("expression_size"), SNAME("EditorFonts")));
- preview_text->add_theme_color_override("font_color", text_color);
- syntax_highlighter->set_number_color(number_color);
- syntax_highlighter->set_symbol_color(symbol_color);
- syntax_highlighter->set_function_color(function_color);
- syntax_highlighter->set_member_variable_color(members_color);
- syntax_highlighter->clear_color_regions();
- syntax_highlighter->add_color_region("/*", "*/", comment_color, false);
- syntax_highlighter->add_color_region("//", "", comment_color, true);
+ graph->get_panner()->setup((ViewPanner::ControlScheme)EDITOR_GET("editors/panning/sub_editors_panning_scheme").operator int(), ED_GET_SHORTCUT("canvas_item_editor/pan_view"), bool(EditorSettings::get_singleton()->get("editors/panning/simple_panning")));
+ graph->set_warped_panning(bool(EditorSettings::get_singleton()->get("editors/panning/warped_mouse_panning")));
+ [[fallthrough]];
+ }
+ case NOTIFICATION_THEME_CHANGED: {
+ highend_label->set_modulate(get_theme_color(SNAME("vulkan_color"), SNAME("Editor")));
+
+ node_filter->set_right_icon(Control::get_theme_icon(SNAME("Search"), SNAME("EditorIcons")));
+
+ preview_shader->set_icon(Control::get_theme_icon(SNAME("Shader"), SNAME("EditorIcons")));
+
+ {
+ Color background_color = EDITOR_GET("text_editor/theme/highlighting/background_color");
+ Color text_color = EDITOR_GET("text_editor/theme/highlighting/text_color");
+ Color keyword_color = EDITOR_GET("text_editor/theme/highlighting/keyword_color");
+ Color control_flow_keyword_color = EDITOR_GET("text_editor/theme/highlighting/control_flow_keyword_color");
+ Color comment_color = EDITOR_GET("text_editor/theme/highlighting/comment_color");
+ Color symbol_color = EDITOR_GET("text_editor/theme/highlighting/symbol_color");
+ Color function_color = EDITOR_GET("text_editor/theme/highlighting/function_color");
+ Color number_color = EDITOR_GET("text_editor/theme/highlighting/number_color");
+ Color members_color = EDITOR_GET("text_editor/theme/highlighting/member_variable_color");
+ Color error_color = get_theme_color(SNAME("error_color"), SNAME("Editor"));
+
+ preview_text->add_theme_color_override("background_color", background_color);
+ varying_error_label->add_theme_color_override("font_color", error_color);
+
+ for (const String &E : keyword_list) {
+ if (ShaderLanguage::is_control_flow_keyword(E)) {
+ syntax_highlighter->add_keyword_color(E, control_flow_keyword_color);
+ } else {
+ syntax_highlighter->add_keyword_color(E, keyword_color);
+ }
+ }
- preview_text->clear_comment_delimiters();
- preview_text->add_comment_delimiter("/*", "*/", false);
- preview_text->add_comment_delimiter("//", "", true);
+ preview_text->add_theme_font_override("font", get_theme_font(SNAME("expression"), SNAME("EditorFonts")));
+ preview_text->add_theme_font_size_override("font_size", get_theme_font_size(SNAME("expression_size"), SNAME("EditorFonts")));
+ preview_text->add_theme_color_override("font_color", text_color);
+ syntax_highlighter->set_number_color(number_color);
+ syntax_highlighter->set_symbol_color(symbol_color);
+ syntax_highlighter->set_function_color(function_color);
+ syntax_highlighter->set_member_variable_color(members_color);
+ syntax_highlighter->clear_color_regions();
+ syntax_highlighter->add_color_region("/*", "*/", comment_color, false);
+ syntax_highlighter->add_color_region("//", "", comment_color, true);
+
+ preview_text->clear_comment_delimiters();
+ preview_text->add_comment_delimiter("/*", "*/", false);
+ preview_text->add_comment_delimiter("//", "", true);
+
+ error_panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("panel"), SNAME("Panel")));
+ error_label->add_theme_font_override("font", get_theme_font(SNAME("status_source"), SNAME("EditorFonts")));
+ error_label->add_theme_font_size_override("font_size", get_theme_font_size(SNAME("status_source_size"), SNAME("EditorFonts")));
+ error_label->add_theme_color_override("font_color", error_color);
+ }
- error_panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("panel"), SNAME("Panel")));
- error_label->add_theme_font_override("font", get_theme_font(SNAME("status_source"), SNAME("EditorFonts")));
- error_label->add_theme_font_size_override("font_size", get_theme_font_size(SNAME("status_source_size"), SNAME("EditorFonts")));
- error_label->add_theme_color_override("font_color", get_theme_color(SNAME("error_color"), SNAME("Editor")));
- }
+ tools->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Tools"), SNAME("EditorIcons")));
- tools->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Tools"), SNAME("EditorIcons")));
+ if (p_what == NOTIFICATION_THEME_CHANGED && is_visible_in_tree()) {
+ _update_graph();
+ }
+ } break;
- if (p_what == NOTIFICATION_THEME_CHANGED && is_visible_in_tree()) {
- _update_graph();
- }
+ case NOTIFICATION_DRAG_BEGIN: {
+ Dictionary dd = get_viewport()->gui_get_drag_data();
+ if (members->is_visible_in_tree() && dd.has("id")) {
+ members->set_drop_mode_flags(Tree::DROP_MODE_ON_ITEM);
+ }
+ } break;
+
+ case NOTIFICATION_DRAG_END: {
+ members->set_drop_mode_flags(0);
+ } break;
}
}
@@ -3546,6 +3753,17 @@ void VisualShaderEditor::_dup_paste_nodes(int p_type, List<CopyItem> &r_items, c
if (p_duplicate) {
undo_redo->create_action(TTR("Duplicate VisualShader Node(s)"));
} else {
+ bool copy_buffer_empty = true;
+ for (const CopyItem &item : copy_items_buffer) {
+ if (!item.disabled) {
+ copy_buffer_empty = false;
+ break;
+ }
+ }
+ if (copy_buffer_empty) {
+ return;
+ }
+
undo_redo->create_action(TTR("Paste VisualShader Node(s)"));
}
@@ -3558,16 +3776,7 @@ void VisualShaderEditor::_dup_paste_nodes(int p_type, List<CopyItem> &r_items, c
Set<int> added_set;
for (CopyItem &item : r_items) {
- bool unsupported = false;
- for (int i = 0; i < add_options.size(); i++) {
- if (add_options[i].type == item.node->get_class_name()) {
- if (!_is_available(add_options[i].mode)) {
- unsupported = true;
- }
- break;
- }
- }
- if (unsupported) {
+ if (item.disabled) {
unsupported_set.insert(item.id);
continue;
}
@@ -3608,7 +3817,10 @@ void VisualShaderEditor::_dup_paste_nodes(int p_type, List<CopyItem> &r_items, c
}
id_from = base_id;
- for (int i = 0; i < r_items.size(); i++) {
+ for (const CopyItem &item : r_items) {
+ if (item.disabled) {
+ continue;
+ }
undo_redo->add_undo_method(visual_shader.ptr(), "remove_node", type, id_from);
undo_redo->add_undo_method(graph_plugin.ptr(), "remove_node", type, id_from);
id_from++;
@@ -3709,7 +3921,7 @@ void VisualShaderEditor::_mode_selected(int p_id) {
}
visual_shader->set_shader_type(VisualShader::Type(p_id + offset));
- _update_options_menu();
+ _update_nodes();
_update_graph();
graph->grab_focus();
@@ -3820,6 +4032,75 @@ void VisualShaderEditor::_uniform_select_item(Ref<VisualShaderNodeUniformRef> p_
undo_redo->commit_action();
}
+void VisualShaderEditor::_varying_select_item(Ref<VisualShaderNodeVarying> p_varying, String p_name) {
+ String prev_name = p_varying->get_varying_name();
+
+ if (p_name == prev_name) {
+ return;
+ }
+
+ bool is_getter = Ref<VisualShaderNodeVaryingGetter>(p_varying.ptr()).is_valid();
+
+ UndoRedo *undo_redo = EditorNode::get_singleton()->get_undo_redo();
+ undo_redo->create_action(TTR("Varying Name Changed"));
+
+ undo_redo->add_do_method(p_varying.ptr(), "set_varying_name", p_name);
+ undo_redo->add_undo_method(p_varying.ptr(), "set_varying_name", prev_name);
+
+ VisualShader::VaryingType vtype = p_varying->get_varying_type_by_name(p_name);
+ VisualShader::VaryingType prev_vtype = p_varying->get_varying_type_by_name(prev_name);
+
+ bool type_changed = vtype != prev_vtype;
+
+ if (type_changed) {
+ undo_redo->add_do_method(p_varying.ptr(), "set_varying_type", vtype);
+ undo_redo->add_undo_method(p_varying.ptr(), "set_varying_type", prev_vtype);
+ }
+
+ // update ports
+ for (int type_id = 0; type_id < VisualShader::TYPE_MAX; type_id++) {
+ VisualShader::Type type = VisualShader::Type(type_id);
+ int id = visual_shader->find_node_id(type, p_varying);
+
+ if (id != VisualShader::NODE_ID_INVALID) {
+ if (type_changed) {
+ List<VisualShader::Connection> conns;
+ visual_shader->get_node_connections(type, &conns);
+
+ for (const VisualShader::Connection &E : conns) {
+ if (is_getter) {
+ if (E.from_node == id) {
+ if (visual_shader->is_port_types_compatible(p_varying->get_varying_type_by_name(p_name), visual_shader->get_node(type, E.to_node)->get_input_port_type(E.to_port))) {
+ continue;
+ }
+ undo_redo->add_do_method(visual_shader.ptr(), "disconnect_nodes", type, E.from_node, E.from_port, E.to_node, E.to_port);
+ undo_redo->add_undo_method(visual_shader.ptr(), "connect_nodes", type, E.from_node, E.from_port, E.to_node, E.to_port);
+ undo_redo->add_do_method(graph_plugin.ptr(), "disconnect_nodes", type, E.from_node, E.from_port, E.to_node, E.to_port);
+ undo_redo->add_undo_method(graph_plugin.ptr(), "connect_nodes", type, E.from_node, E.from_port, E.to_node, E.to_port);
+ }
+ } else {
+ if (E.to_node == id) {
+ if (visual_shader->is_port_types_compatible(p_varying->get_varying_type_by_name(p_name), visual_shader->get_node(type, E.from_node)->get_output_port_type(E.from_port))) {
+ continue;
+ }
+ undo_redo->add_do_method(visual_shader.ptr(), "disconnect_nodes", type, E.from_node, E.from_port, E.to_node, E.to_port);
+ undo_redo->add_undo_method(visual_shader.ptr(), "connect_nodes", type, E.from_node, E.from_port, E.to_node, E.to_port);
+ undo_redo->add_do_method(graph_plugin.ptr(), "disconnect_nodes", type, E.from_node, E.from_port, E.to_node, E.to_port);
+ undo_redo->add_undo_method(graph_plugin.ptr(), "connect_nodes", type, E.from_node, E.from_port, E.to_node, E.to_port);
+ }
+ }
+ }
+ }
+
+ undo_redo->add_do_method(graph_plugin.ptr(), "update_node", type_id, id);
+ undo_redo->add_undo_method(graph_plugin.ptr(), "update_node", type_id, id);
+ break;
+ }
+ }
+
+ undo_redo->commit_action();
+}
+
void VisualShaderEditor::_float_constant_selected(int p_which) {
ERR_FAIL_INDEX(p_which, MAX_FLOAT_CONST_DEFS);
@@ -3874,6 +4155,92 @@ void VisualShaderEditor::_member_cancel() {
from_slot = -1;
}
+void VisualShaderEditor::_update_varying_tree() {
+ varyings->clear();
+ TreeItem *root = varyings->create_item();
+
+ int count = visual_shader->get_varyings_count();
+
+ for (int i = 0; i < count; i++) {
+ const VisualShader::Varying *varying = visual_shader->get_varying_by_index(i);
+
+ if (varying) {
+ TreeItem *item = varyings->create_item(root);
+ item->set_text(0, varying->name);
+
+ if (i == 0) {
+ item->select(0);
+ }
+
+ switch (varying->type) {
+ case VisualShader::VARYING_TYPE_FLOAT:
+ item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("float"), SNAME("EditorIcons")));
+ break;
+ case VisualShader::VARYING_TYPE_VECTOR_2D:
+ item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Vector2"), SNAME("EditorIcons")));
+ break;
+ case VisualShader::VARYING_TYPE_VECTOR_3D:
+ item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Vector3"), SNAME("EditorIcons")));
+ break;
+ case VisualShader::VARYING_TYPE_COLOR:
+ item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Color"), SNAME("EditorIcons")));
+ break;
+ case VisualShader::VARYING_TYPE_TRANSFORM:
+ item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Transform3D"), SNAME("EditorIcons")));
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ varying_options->set_item_disabled(int(VaryingMenuOptions::REMOVE), count == 0);
+}
+
+void VisualShaderEditor::_varying_create() {
+ _add_varying(varying_name->get_text(), (VisualShader::VaryingMode)varying_mode->get_selected(), (VisualShader::VaryingType)varying_type->get_selected());
+ add_varying_dialog->hide();
+}
+
+void VisualShaderEditor::_varying_name_changed(const String &p_text) {
+ String name = p_text;
+
+ if (!name.is_valid_identifier()) {
+ varying_error_label->show();
+ varying_error_label->set_text(TTR("Invalid name for varying."));
+ add_varying_dialog->get_ok_button()->set_disabled(true);
+ return;
+ }
+ if (visual_shader->has_varying(name)) {
+ varying_error_label->show();
+ varying_error_label->set_text(TTR("Varying with that name is already exist."));
+ add_varying_dialog->get_ok_button()->set_disabled(true);
+ return;
+ }
+ if (varying_error_label->is_visible()) {
+ varying_error_label->hide();
+ add_varying_dialog->set_size(Size2(add_varying_dialog->get_size().x, 0));
+ }
+ add_varying_dialog->get_ok_button()->set_disabled(false);
+}
+
+void VisualShaderEditor::_varying_deleted() {
+ TreeItem *item = varyings->get_selected();
+
+ if (item != nullptr) {
+ _remove_varying(item->get_text(0));
+ remove_varying_dialog->hide();
+ }
+}
+
+void VisualShaderEditor::_varying_selected() {
+ add_varying_dialog->get_ok_button()->set_disabled(false);
+}
+
+void VisualShaderEditor::_varying_unselected() {
+ add_varying_dialog->get_ok_button()->set_disabled(true);
+}
+
void VisualShaderEditor::_tools_menu_option(int p_idx) {
TreeItem *category = members->get_root()->get_first_child();
@@ -4141,15 +4508,18 @@ void VisualShaderEditor::_visibility_changed() {
}
void VisualShaderEditor::_bind_methods() {
+ ClassDB::bind_method("_update_nodes", &VisualShaderEditor::_update_nodes);
ClassDB::bind_method("_update_graph", &VisualShaderEditor::_update_graph);
- ClassDB::bind_method("_update_options_menu", &VisualShaderEditor::_update_options_menu);
ClassDB::bind_method("_add_node", &VisualShaderEditor::_add_node);
ClassDB::bind_method("_node_changed", &VisualShaderEditor::_node_changed);
ClassDB::bind_method("_input_select_item", &VisualShaderEditor::_input_select_item);
ClassDB::bind_method("_uniform_select_item", &VisualShaderEditor::_uniform_select_item);
+ ClassDB::bind_method("_varying_select_item", &VisualShaderEditor::_varying_select_item);
ClassDB::bind_method("_set_node_size", &VisualShaderEditor::_set_node_size);
ClassDB::bind_method("_clear_copy_buffer", &VisualShaderEditor::_clear_copy_buffer);
ClassDB::bind_method("_update_uniforms", &VisualShaderEditor::_update_uniforms);
+ ClassDB::bind_method("_update_varyings", &VisualShaderEditor::_update_varyings);
+ ClassDB::bind_method("_update_varying_tree", &VisualShaderEditor::_update_varying_tree);
ClassDB::bind_method("_set_mode", &VisualShaderEditor::_set_mode);
ClassDB::bind_method("_nodes_dragged", &VisualShaderEditor::_nodes_dragged);
ClassDB::bind_method("_float_constant_selected", &VisualShaderEditor::_float_constant_selected);
@@ -4182,7 +4552,7 @@ VisualShaderEditor::VisualShaderEditor() {
graph->add_valid_right_disconnect_type(VisualShaderNode::PORT_TYPE_SCALAR_INT);
graph->add_valid_right_disconnect_type(VisualShaderNode::PORT_TYPE_BOOLEAN);
graph->add_valid_right_disconnect_type(VisualShaderNode::PORT_TYPE_VECTOR_2D);
- graph->add_valid_right_disconnect_type(VisualShaderNode::PORT_TYPE_VECTOR);
+ graph->add_valid_right_disconnect_type(VisualShaderNode::PORT_TYPE_VECTOR_3D);
graph->add_valid_right_disconnect_type(VisualShaderNode::PORT_TYPE_TRANSFORM);
graph->add_valid_right_disconnect_type(VisualShaderNode::PORT_TYPE_SAMPLER);
//graph->add_valid_left_disconnect_type(0);
@@ -4202,27 +4572,27 @@ VisualShaderEditor::VisualShaderEditor() {
graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_SCALAR, VisualShaderNode::PORT_TYPE_SCALAR);
graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_SCALAR, VisualShaderNode::PORT_TYPE_SCALAR_INT);
graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_SCALAR, VisualShaderNode::PORT_TYPE_VECTOR_2D);
- graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_SCALAR, VisualShaderNode::PORT_TYPE_VECTOR);
+ graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_SCALAR, VisualShaderNode::PORT_TYPE_VECTOR_3D);
graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_SCALAR, VisualShaderNode::PORT_TYPE_BOOLEAN);
graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_SCALAR_INT, VisualShaderNode::PORT_TYPE_SCALAR_INT);
graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_SCALAR_INT, VisualShaderNode::PORT_TYPE_SCALAR);
graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_SCALAR_INT, VisualShaderNode::PORT_TYPE_VECTOR_2D);
- graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_SCALAR_INT, VisualShaderNode::PORT_TYPE_VECTOR);
+ graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_SCALAR_INT, VisualShaderNode::PORT_TYPE_VECTOR_3D);
graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_SCALAR_INT, VisualShaderNode::PORT_TYPE_BOOLEAN);
graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_VECTOR_2D, VisualShaderNode::PORT_TYPE_SCALAR);
graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_VECTOR_2D, VisualShaderNode::PORT_TYPE_SCALAR_INT);
graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_VECTOR_2D, VisualShaderNode::PORT_TYPE_VECTOR_2D);
- graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_VECTOR_2D, VisualShaderNode::PORT_TYPE_VECTOR);
+ graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_VECTOR_2D, VisualShaderNode::PORT_TYPE_VECTOR_3D);
graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_VECTOR_2D, VisualShaderNode::PORT_TYPE_BOOLEAN);
- graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_VECTOR, VisualShaderNode::PORT_TYPE_SCALAR);
- graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_VECTOR, VisualShaderNode::PORT_TYPE_SCALAR_INT);
- graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_VECTOR, VisualShaderNode::PORT_TYPE_VECTOR_2D);
- graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_VECTOR, VisualShaderNode::PORT_TYPE_VECTOR);
- graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_VECTOR, VisualShaderNode::PORT_TYPE_BOOLEAN);
+ graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_VECTOR_3D, VisualShaderNode::PORT_TYPE_SCALAR);
+ graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_VECTOR_3D, VisualShaderNode::PORT_TYPE_SCALAR_INT);
+ graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_VECTOR_3D, VisualShaderNode::PORT_TYPE_VECTOR_2D);
+ graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_VECTOR_3D, VisualShaderNode::PORT_TYPE_VECTOR_3D);
+ graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_VECTOR_3D, VisualShaderNode::PORT_TYPE_BOOLEAN);
graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_BOOLEAN, VisualShaderNode::PORT_TYPE_SCALAR);
graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_BOOLEAN, VisualShaderNode::PORT_TYPE_SCALAR_INT);
graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_BOOLEAN, VisualShaderNode::PORT_TYPE_VECTOR_2D);
- graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_BOOLEAN, VisualShaderNode::PORT_TYPE_VECTOR);
+ graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_BOOLEAN, VisualShaderNode::PORT_TYPE_VECTOR_3D);
graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_BOOLEAN, VisualShaderNode::PORT_TYPE_BOOLEAN);
graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_TRANSFORM, VisualShaderNode::PORT_TYPE_TRANSFORM);
graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_SAMPLER, VisualShaderNode::PORT_TYPE_SAMPLER);
@@ -4276,11 +4646,23 @@ VisualShaderEditor::VisualShaderEditor() {
add_node = memnew(Button);
add_node->set_flat(true);
- graph->get_zoom_hbox()->add_child(add_node);
add_node->set_text(TTR("Add Node..."));
+ graph->get_zoom_hbox()->add_child(add_node);
graph->get_zoom_hbox()->move_child(add_node, 0);
add_node->connect("pressed", callable_mp(this, &VisualShaderEditor::_show_members_dialog), varray(false, VisualShaderNode::PORT_TYPE_MAX, VisualShaderNode::PORT_TYPE_MAX));
+ varying_button = memnew(Button);
+ varying_button->set_flat(true);
+ varying_button->set_text(TTR("Manage Varyings"));
+ graph->get_zoom_hbox()->add_child(varying_button);
+ varying_button->connect("pressed", callable_mp(this, &VisualShaderEditor::_show_varying_menu));
+
+ varying_options = memnew(PopupMenu);
+ add_child(varying_options);
+ varying_options->add_item(TTR("Add Varying"), int(VaryingMenuOptions::ADD));
+ varying_options->add_item(TTR("Remove Varying"), int(VaryingMenuOptions::REMOVE));
+ varying_options->connect("id_pressed", callable_mp(this, &VisualShaderEditor::_varying_menu_id_pressed));
+
preview_shader = memnew(Button);
preview_shader->set_flat(true);
preview_shader->set_toggle_mode(true);
@@ -4404,6 +4786,74 @@ VisualShaderEditor::VisualShaderEditor() {
members_dialog->connect("cancelled", callable_mp(this, &VisualShaderEditor::_member_cancel));
add_child(members_dialog);
+ // add varyings dialog
+ {
+ add_varying_dialog = memnew(ConfirmationDialog);
+ add_varying_dialog->set_title(TTR("Create Shader Varying"));
+ add_varying_dialog->set_exclusive(false);
+ add_varying_dialog->get_ok_button()->set_text(TTR("Create"));
+ add_varying_dialog->get_ok_button()->connect("pressed", callable_mp(this, &VisualShaderEditor::_varying_create));
+ add_varying_dialog->get_ok_button()->set_disabled(true);
+ add_child(add_varying_dialog);
+
+ VBoxContainer *vb = memnew(VBoxContainer);
+ add_varying_dialog->add_child(vb);
+
+ HBoxContainer *hb = memnew(HBoxContainer);
+ vb->add_child(hb);
+ hb->set_h_size_flags(SIZE_EXPAND_FILL);
+
+ varying_type = memnew(OptionButton);
+ hb->add_child(varying_type);
+ varying_type->add_item("Float");
+ varying_type->add_item("Vector2");
+ varying_type->add_item("Vector3");
+ varying_type->add_item("Color");
+ varying_type->add_item("Transform");
+
+ varying_name = memnew(LineEdit);
+ hb->add_child(varying_name);
+ varying_name->set_custom_minimum_size(Size2(150 * EDSCALE, 0));
+ varying_name->set_h_size_flags(SIZE_EXPAND_FILL);
+ varying_name->connect("text_changed", callable_mp(this, &VisualShaderEditor::_varying_name_changed));
+
+ varying_mode = memnew(OptionButton);
+ hb->add_child(varying_mode);
+ varying_mode->add_item("Vertex -> [Fragment, Light]");
+ varying_mode->add_item("Fragment -> Light");
+
+ varying_error_label = memnew(Label);
+ vb->add_child(varying_error_label);
+ varying_error_label->set_h_size_flags(SIZE_EXPAND_FILL);
+
+ varying_error_label->hide();
+ }
+
+ // remove varying dialog
+ {
+ remove_varying_dialog = memnew(ConfirmationDialog);
+ remove_varying_dialog->set_title(TTR("Delete Shader Varying"));
+ remove_varying_dialog->set_exclusive(false);
+ remove_varying_dialog->get_ok_button()->set_text(TTR("Delete"));
+ remove_varying_dialog->get_ok_button()->connect("pressed", callable_mp(this, &VisualShaderEditor::_varying_deleted));
+ add_child(remove_varying_dialog);
+
+ VBoxContainer *vb = memnew(VBoxContainer);
+ remove_varying_dialog->add_child(vb);
+
+ varyings = memnew(Tree);
+ vb->add_child(varyings);
+ varyings->set_h_size_flags(SIZE_EXPAND_FILL);
+ varyings->set_v_size_flags(SIZE_EXPAND_FILL);
+ varyings->set_hide_root(true);
+ varyings->set_allow_reselect(true);
+ varyings->set_hide_folding(false);
+ varyings->set_custom_minimum_size(Size2(180 * EDSCALE, 200 * EDSCALE));
+ varyings->connect("item_activated", callable_mp(this, &VisualShaderEditor::_varying_deleted));
+ varyings->connect("item_selected", callable_mp(this, &VisualShaderEditor::_varying_selected));
+ varyings->connect("nothing_selected", callable_mp(this, &VisualShaderEditor::_varying_unselected));
+ }
+
alert = memnew(AcceptDialog);
alert->get_label()->set_autowrap_mode(Label::AUTOWRAP_WORD);
alert->get_label()->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
@@ -4446,23 +4896,23 @@ VisualShaderEditor::VisualShaderEditor() {
// COLOR
- add_options.push_back(AddOption("ColorFunc", "Color", "Common", "VisualShaderNodeColorFunc", TTR("Color function."), {}, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("ColorOp", "Color", "Common", "VisualShaderNodeColorOp", TTR("Color operator."), {}, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("ColorFunc", "Color", "Common", "VisualShaderNodeColorFunc", TTR("Color function."), {}, VisualShaderNode::PORT_TYPE_VECTOR_3D));
+ add_options.push_back(AddOption("ColorOp", "Color", "Common", "VisualShaderNodeColorOp", TTR("Color operator."), {}, VisualShaderNode::PORT_TYPE_VECTOR_3D));
- add_options.push_back(AddOption("Grayscale", "Color", "Functions", "VisualShaderNodeColorFunc", TTR("Grayscale function."), { VisualShaderNodeColorFunc::FUNC_GRAYSCALE }, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("HSV2RGB", "Color", "Functions", "VisualShaderNodeVectorFunc", TTR("Converts HSV vector to RGB equivalent."), { VisualShaderNodeVectorFunc::FUNC_HSV2RGB }, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("RGB2HSV", "Color", "Functions", "VisualShaderNodeVectorFunc", TTR("Converts RGB vector to HSV equivalent."), { VisualShaderNodeVectorFunc::FUNC_RGB2HSV }, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("Sepia", "Color", "Functions", "VisualShaderNodeColorFunc", TTR("Sepia function."), { VisualShaderNodeColorFunc::FUNC_SEPIA }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Grayscale", "Color", "Functions", "VisualShaderNodeColorFunc", TTR("Grayscale function."), { VisualShaderNodeColorFunc::FUNC_GRAYSCALE }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
+ add_options.push_back(AddOption("HSV2RGB", "Color", "Functions", "VisualShaderNodeVectorFunc", TTR("Converts HSV vector to RGB equivalent."), { VisualShaderNodeVectorFunc::FUNC_HSV2RGB, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
+ add_options.push_back(AddOption("RGB2HSV", "Color", "Functions", "VisualShaderNodeVectorFunc", TTR("Converts RGB vector to HSV equivalent."), { VisualShaderNodeVectorFunc::FUNC_RGB2HSV, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
+ add_options.push_back(AddOption("Sepia", "Color", "Functions", "VisualShaderNodeColorFunc", TTR("Sepia function."), { VisualShaderNodeColorFunc::FUNC_SEPIA }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
- add_options.push_back(AddOption("Burn", "Color", "Operators", "VisualShaderNodeColorOp", TTR("Burn operator."), { VisualShaderNodeColorOp::OP_BURN }, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("Darken", "Color", "Operators", "VisualShaderNodeColorOp", TTR("Darken operator."), { VisualShaderNodeColorOp::OP_DARKEN }, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("Difference", "Color", "Operators", "VisualShaderNodeColorOp", TTR("Difference operator."), { VisualShaderNodeColorOp::OP_DIFFERENCE }, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("Dodge", "Color", "Operators", "VisualShaderNodeColorOp", TTR("Dodge operator."), { VisualShaderNodeColorOp::OP_DODGE }, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("HardLight", "Color", "Operators", "VisualShaderNodeColorOp", TTR("HardLight operator."), { VisualShaderNodeColorOp::OP_HARD_LIGHT }, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("Lighten", "Color", "Operators", "VisualShaderNodeColorOp", TTR("Lighten operator."), { VisualShaderNodeColorOp::OP_LIGHTEN }, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("Overlay", "Color", "Operators", "VisualShaderNodeColorOp", TTR("Overlay operator."), { VisualShaderNodeColorOp::OP_OVERLAY }, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("Screen", "Color", "Operators", "VisualShaderNodeColorOp", TTR("Screen operator."), { VisualShaderNodeColorOp::OP_SCREEN }, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("SoftLight", "Color", "Operators", "VisualShaderNodeColorOp", TTR("SoftLight operator."), { VisualShaderNodeColorOp::OP_SOFT_LIGHT }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Burn", "Color", "Operators", "VisualShaderNodeColorOp", TTR("Burn operator."), { VisualShaderNodeColorOp::OP_BURN }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
+ add_options.push_back(AddOption("Darken", "Color", "Operators", "VisualShaderNodeColorOp", TTR("Darken operator."), { VisualShaderNodeColorOp::OP_DARKEN }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
+ add_options.push_back(AddOption("Difference", "Color", "Operators", "VisualShaderNodeColorOp", TTR("Difference operator."), { VisualShaderNodeColorOp::OP_DIFFERENCE }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
+ add_options.push_back(AddOption("Dodge", "Color", "Operators", "VisualShaderNodeColorOp", TTR("Dodge operator."), { VisualShaderNodeColorOp::OP_DODGE }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
+ add_options.push_back(AddOption("HardLight", "Color", "Operators", "VisualShaderNodeColorOp", TTR("HardLight operator."), { VisualShaderNodeColorOp::OP_HARD_LIGHT }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
+ add_options.push_back(AddOption("Lighten", "Color", "Operators", "VisualShaderNodeColorOp", TTR("Lighten operator."), { VisualShaderNodeColorOp::OP_LIGHTEN }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
+ add_options.push_back(AddOption("Overlay", "Color", "Operators", "VisualShaderNodeColorOp", TTR("Overlay operator."), { VisualShaderNodeColorOp::OP_OVERLAY }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
+ add_options.push_back(AddOption("Screen", "Color", "Operators", "VisualShaderNodeColorOp", TTR("Screen operator."), { VisualShaderNodeColorOp::OP_SCREEN }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
+ add_options.push_back(AddOption("SoftLight", "Color", "Operators", "VisualShaderNodeColorOp", TTR("SoftLight operator."), { VisualShaderNodeColorOp::OP_SOFT_LIGHT }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
add_options.push_back(AddOption("ColorConstant", "Color", "Variables", "VisualShaderNodeColorConstant", TTR("Color constant.")));
add_options.push_back(AddOption("ColorUniform", "Color", "Variables", "VisualShaderNodeColorUniform", TTR("Color uniform.")));
@@ -4478,13 +4928,13 @@ VisualShaderEditor::VisualShaderEditor() {
add_options.push_back(AddOption("Equal", "Conditional", "Functions", "VisualShaderNodeCompare", vformat(compare_func_desc, TTR("Equal (==)")), { VisualShaderNodeCompare::FUNC_EQUAL }, VisualShaderNode::PORT_TYPE_BOOLEAN));
add_options.push_back(AddOption("GreaterThan", "Conditional", "Functions", "VisualShaderNodeCompare", vformat(compare_func_desc, TTR("Greater Than (>)")), { VisualShaderNodeCompare::FUNC_GREATER_THAN }, VisualShaderNode::PORT_TYPE_BOOLEAN));
add_options.push_back(AddOption("GreaterThanEqual", "Conditional", "Functions", "VisualShaderNodeCompare", vformat(compare_func_desc, TTR("Greater Than or Equal (>=)")), { VisualShaderNodeCompare::FUNC_GREATER_THAN_EQUAL }, VisualShaderNode::PORT_TYPE_BOOLEAN));
- add_options.push_back(AddOption("If", "Conditional", "Functions", "VisualShaderNodeIf", TTR("Returns an associated vector if the provided scalars are equal, greater or less."), {}, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("If", "Conditional", "Functions", "VisualShaderNodeIf", TTR("Returns an associated vector if the provided scalars are equal, greater or less."), {}, VisualShaderNode::PORT_TYPE_VECTOR_3D));
add_options.push_back(AddOption("IsInf", "Conditional", "Functions", "VisualShaderNodeIs", TTR("Returns the boolean result of the comparison between INF and a scalar parameter."), { VisualShaderNodeIs::FUNC_IS_INF }, VisualShaderNode::PORT_TYPE_BOOLEAN));
add_options.push_back(AddOption("IsNaN", "Conditional", "Functions", "VisualShaderNodeIs", TTR("Returns the boolean result of the comparison between NaN and a scalar parameter."), { VisualShaderNodeIs::FUNC_IS_NAN }, VisualShaderNode::PORT_TYPE_BOOLEAN));
add_options.push_back(AddOption("LessThan", "Conditional", "Functions", "VisualShaderNodeCompare", vformat(compare_func_desc, TTR("Less Than (<)")), { VisualShaderNodeCompare::FUNC_LESS_THAN }, VisualShaderNode::PORT_TYPE_BOOLEAN));
add_options.push_back(AddOption("LessThanEqual", "Conditional", "Functions", "VisualShaderNodeCompare", vformat(compare_func_desc, TTR("Less Than or Equal (<=)")), { VisualShaderNodeCompare::FUNC_LESS_THAN_EQUAL }, VisualShaderNode::PORT_TYPE_BOOLEAN));
add_options.push_back(AddOption("NotEqual", "Conditional", "Functions", "VisualShaderNodeCompare", vformat(compare_func_desc, TTR("Not Equal (!=)")), { VisualShaderNodeCompare::FUNC_NOT_EQUAL }, VisualShaderNode::PORT_TYPE_BOOLEAN));
- add_options.push_back(AddOption("Switch", "Conditional", "Functions", "VisualShaderNodeSwitch", TTR("Returns an associated 3D vector if the provided boolean value is true or false."), { VisualShaderNodeSwitch::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Switch", "Conditional", "Functions", "VisualShaderNodeSwitch", TTR("Returns an associated 3D vector if the provided boolean value is true or false."), { VisualShaderNodeSwitch::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
add_options.push_back(AddOption("Switch2D", "Conditional", "Functions", "VisualShaderNodeSwitch", TTR("Returns an associated 2D vector if the provided boolean value is true or false."), { VisualShaderNodeSwitch::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
add_options.push_back(AddOption("SwitchBool", "Conditional", "Functions", "VisualShaderNodeSwitch", TTR("Returns an associated boolean if the provided boolean value is true or false."), { VisualShaderNodeSwitch::OP_TYPE_BOOLEAN }, VisualShaderNode::PORT_TYPE_BOOLEAN));
add_options.push_back(AddOption("SwitchFloat", "Conditional", "Functions", "VisualShaderNodeSwitch", TTR("Returns an associated floating-point scalar if the provided boolean value is true or false."), { VisualShaderNodeSwitch::OP_TYPE_FLOAT }, VisualShaderNode::PORT_TYPE_SCALAR));
@@ -4506,7 +4956,7 @@ VisualShaderEditor::VisualShaderEditor() {
add_options.push_back(AddOption("Camera", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "camera"), { "camera" }, VisualShaderNode::PORT_TYPE_TRANSFORM, -1, Shader::MODE_SPATIAL));
add_options.push_back(AddOption("InvCamera", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "inv_camera"), { "inv_camera" }, VisualShaderNode::PORT_TYPE_TRANSFORM, -1, Shader::MODE_SPATIAL));
add_options.push_back(AddOption("InvProjection", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "inv_projection"), { "inv_projection" }, VisualShaderNode::PORT_TYPE_TRANSFORM, -1, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("Normal", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "normal"), { "normal" }, VisualShaderNode::PORT_TYPE_VECTOR, -1, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("Normal", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "normal"), { "normal" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, -1, Shader::MODE_SPATIAL));
add_options.push_back(AddOption("OutputIsSRGB", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "output_is_srgb"), { "output_is_srgb" }, VisualShaderNode::PORT_TYPE_BOOLEAN, -1, Shader::MODE_SPATIAL));
add_options.push_back(AddOption("Projection", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "projection"), { "projection" }, VisualShaderNode::PORT_TYPE_TRANSFORM, -1, Shader::MODE_SPATIAL));
add_options.push_back(AddOption("Time", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "time"), { "time" }, VisualShaderNode::PORT_TYPE_SCALAR, -1, Shader::MODE_SPATIAL));
@@ -4518,7 +4968,7 @@ VisualShaderEditor::VisualShaderEditor() {
// CANVASITEM-FOR-ALL
add_options.push_back(AddOption("Alpha", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "alpha"), { "alpha" }, VisualShaderNode::PORT_TYPE_SCALAR, -1, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("Color", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "color"), { "color" }, VisualShaderNode::PORT_TYPE_VECTOR, -1, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("Color", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "color"), { "color" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, -1, Shader::MODE_CANVAS_ITEM));
add_options.push_back(AddOption("TexturePixelSize", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "texture_pixel_size"), { "texture_pixel_size" }, VisualShaderNode::PORT_TYPE_VECTOR_2D, -1, Shader::MODE_CANVAS_ITEM));
add_options.push_back(AddOption("Time", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "time"), { "time" }, VisualShaderNode::PORT_TYPE_SCALAR, -1, Shader::MODE_CANVAS_ITEM));
add_options.push_back(AddOption("UV", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "uv"), { "uv" }, VisualShaderNode::PORT_TYPE_VECTOR_2D, -1, Shader::MODE_CANVAS_ITEM));
@@ -4527,9 +4977,9 @@ VisualShaderEditor::VisualShaderEditor() {
add_options.push_back(AddOption("Active", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "active"), { "active" }, VisualShaderNode::PORT_TYPE_BOOLEAN, -1, Shader::MODE_PARTICLES));
add_options.push_back(AddOption("Alpha", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "alpha"), { "alpha" }, VisualShaderNode::PORT_TYPE_SCALAR, -1, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("AttractorForce", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "attractor_force"), { "attractor_force" }, VisualShaderNode::PORT_TYPE_VECTOR, -1, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("Color", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "color"), { "color" }, VisualShaderNode::PORT_TYPE_VECTOR, -1, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("Custom", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "custom"), { "custom" }, VisualShaderNode::PORT_TYPE_VECTOR, -1, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("AttractorForce", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "attractor_force"), { "attractor_force" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, -1, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("Color", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "color"), { "color" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, -1, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("Custom", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "custom"), { "custom" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, -1, Shader::MODE_PARTICLES));
add_options.push_back(AddOption("CustomAlpha", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "custom_alpha"), { "custom_alpha" }, VisualShaderNode::PORT_TYPE_SCALAR, -1, Shader::MODE_PARTICLES));
add_options.push_back(AddOption("Delta", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "delta"), { "delta" }, VisualShaderNode::PORT_TYPE_SCALAR, -1, Shader::MODE_PARTICLES));
add_options.push_back(AddOption("EmissionTransform", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "emission_transform"), { "emission_transform" }, VisualShaderNode::PORT_TYPE_TRANSFORM, -1, Shader::MODE_PARTICLES));
@@ -4538,7 +4988,7 @@ VisualShaderEditor::VisualShaderEditor() {
add_options.push_back(AddOption("Restart", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "restart"), { "restart" }, VisualShaderNode::PORT_TYPE_BOOLEAN, -1, Shader::MODE_PARTICLES));
add_options.push_back(AddOption("Time", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "time"), { "time" }, VisualShaderNode::PORT_TYPE_SCALAR, -1, Shader::MODE_PARTICLES));
add_options.push_back(AddOption("Transform", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "transform"), { "transform" }, VisualShaderNode::PORT_TYPE_TRANSFORM, -1, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("Velocity", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "velocity"), { "velocity" }, VisualShaderNode::PORT_TYPE_VECTOR, -1, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("Velocity", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "velocity"), { "velocity" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, -1, Shader::MODE_PARTICLES));
/////////////////
@@ -4561,78 +5011,88 @@ VisualShaderEditor::VisualShaderEditor() {
// NODE3D INPUTS
add_options.push_back(AddOption("Alpha", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "alpha"), { "alpha" }, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("Binormal", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "binormal"), { "binormal" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("Color", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "color"), { "color" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("Binormal", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "binormal"), { "binormal" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("Color", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "color"), { "color" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL));
add_options.push_back(AddOption("InstanceId", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "instance_id"), { "instance_id" }, VisualShaderNode::PORT_TYPE_SCALAR_INT, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("InstanceCustom", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "instance_custom"), { "instance_custom" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("InstanceCustom", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "instance_custom"), { "instance_custom" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL));
add_options.push_back(AddOption("InstanceCustomAlpha", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "instance_custom_alpha"), { "instance_custom_alpha" }, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL));
add_options.push_back(AddOption("ModelView", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "modelview"), { "modelview" }, VisualShaderNode::PORT_TYPE_TRANSFORM, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL));
add_options.push_back(AddOption("PointSize", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "point_size"), { "point_size" }, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("Tangent", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_mode, "tangent"), { "tangent" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("Vertex", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "vertex"), { "vertex" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("Tangent", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_mode, "tangent"), { "tangent" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("Vertex", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "vertex"), { "vertex" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("VertexId", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "vertex_id"), { "vertex_id" }, VisualShaderNode::PORT_TYPE_SCALAR_INT, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("ViewIndex", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "view_index"), { "view_index" }, VisualShaderNode::PORT_TYPE_SCALAR_INT, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("ViewMonoLeft", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "view_mono_left"), { "view_mono_left" }, VisualShaderNode::PORT_TYPE_SCALAR_INT, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("ViewRight", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "view_right"), { "view_right" }, VisualShaderNode::PORT_TYPE_SCALAR_INT, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL));
add_options.push_back(AddOption("Alpha", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "alpha"), { "alpha" }, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("Binormal", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "binormal"), { "binormal" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("Color", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "color"), { "color" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("Binormal", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "binormal"), { "binormal" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("Color", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "color"), { "color" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
add_options.push_back(AddOption("DepthTexture", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "depth_texture"), { "depth_texture" }, VisualShaderNode::PORT_TYPE_SAMPLER, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("FragCoord", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "fragcoord"), { "fragcoord" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("FragCoord", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "fragcoord"), { "fragcoord" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
add_options.push_back(AddOption("FrontFacing", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "front_facing"), { "front_facing" }, VisualShaderNode::PORT_TYPE_BOOLEAN, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
add_options.push_back(AddOption("PointCoord", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "point_coord"), { "point_coord" }, VisualShaderNode::PORT_TYPE_VECTOR_2D, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
add_options.push_back(AddOption("ScreenTexture", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "screen_texture"), { "screen_texture" }, VisualShaderNode::PORT_TYPE_SAMPLER, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
add_options.push_back(AddOption("ScreenUV", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "screen_uv"), { "screen_uv" }, VisualShaderNode::PORT_TYPE_VECTOR_2D, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("Tangent", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "tangent"), { "tangent" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("Vertex", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "vertex"), { "vertex" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("View", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "view"), { "view" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
-
- add_options.push_back(AddOption("Albedo", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "albedo"), { "albedo" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("Tangent", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "tangent"), { "tangent" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("Vertex", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "vertex"), { "vertex" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("View", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "view"), { "view" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("ViewIndex", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "view_index"), { "view_index" }, VisualShaderNode::PORT_TYPE_SCALAR_INT, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("ViewMonoLeft", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "view_mono_left"), { "view_mono_left" }, VisualShaderNode::PORT_TYPE_SCALAR_INT, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("ViewRight", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "view_right"), { "view_right" }, VisualShaderNode::PORT_TYPE_SCALAR_INT, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
+
+ add_options.push_back(AddOption("Albedo", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "albedo"), { "albedo" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL));
add_options.push_back(AddOption("Attenuation", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "attenuation"), { "attenuation" }, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("Backlight", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "backlight"), { "backlight" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("Diffuse", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "diffuse"), { "diffuse" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("FragCoord", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "fragcoord"), { "fragcoord" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("Light", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "light"), { "light" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("LightColor", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "light_color"), { "light_color" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("Backlight", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "backlight"), { "backlight" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("Diffuse", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "diffuse"), { "diffuse" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("FragCoord", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "fragcoord"), { "fragcoord" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("Light", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "light"), { "light" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("LightColor", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "light_color"), { "light_color" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL));
add_options.push_back(AddOption("Metallic", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "metallic"), { "metallic" }, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL));
add_options.push_back(AddOption("Roughness", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "roughness"), { "roughness" }, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("Specular", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "specular"), { "specular" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("View", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "view"), { "view" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("ShadowAttenuation", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "shadow_attenuation"), { "shadow_attenuation" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("Specular", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "specular"), { "specular" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("View", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "view"), { "view" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL));
// CANVASITEM INPUTS
add_options.push_back(AddOption("AtLightPass", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "at_light_pass"), { "at_light_pass" }, VisualShaderNode::PORT_TYPE_BOOLEAN, TYPE_FLAGS_VERTEX, Shader::MODE_CANVAS_ITEM));
add_options.push_back(AddOption("Canvas", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "canvas"), { "canvas" }, VisualShaderNode::PORT_TYPE_TRANSFORM, TYPE_FLAGS_VERTEX, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("InstanceCustom", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "instance_custom"), { "instance_custom" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_VERTEX, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("InstanceCustom", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "instance_custom"), { "instance_custom" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_VERTEX, Shader::MODE_CANVAS_ITEM));
add_options.push_back(AddOption("InstanceCustomAlpha", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "instance_custom_alpha"), { "instance_custom_alpha" }, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_VERTEX, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("InstanceId", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "instance_id"), { "instance_id" }, VisualShaderNode::PORT_TYPE_SCALAR_INT, TYPE_FLAGS_VERTEX, Shader::MODE_CANVAS_ITEM));
add_options.push_back(AddOption("PointSize", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "point_size"), { "point_size" }, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_VERTEX, Shader::MODE_CANVAS_ITEM));
add_options.push_back(AddOption("Screen", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "screen"), { "screen" }, VisualShaderNode::PORT_TYPE_TRANSFORM, TYPE_FLAGS_VERTEX, Shader::MODE_CANVAS_ITEM));
add_options.push_back(AddOption("Vertex", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_mode, "vertex"), { "vertex" }, VisualShaderNode::PORT_TYPE_VECTOR_2D, TYPE_FLAGS_VERTEX, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("VertexId", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "vertex_id"), { "vertex_id" }, VisualShaderNode::PORT_TYPE_SCALAR_INT, TYPE_FLAGS_VERTEX, Shader::MODE_CANVAS_ITEM));
add_options.push_back(AddOption("World", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "world"), { "world" }, VisualShaderNode::PORT_TYPE_TRANSFORM, TYPE_FLAGS_VERTEX, Shader::MODE_CANVAS_ITEM));
add_options.push_back(AddOption("AtLightPass", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "at_light_pass"), { "at_light_pass" }, VisualShaderNode::PORT_TYPE_BOOLEAN, TYPE_FLAGS_FRAGMENT, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("FragCoord", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "fragcoord"), { "fragcoord" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("FragCoord", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "fragcoord"), { "fragcoord" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_FRAGMENT, Shader::MODE_CANVAS_ITEM));
add_options.push_back(AddOption("NormalTexture", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "normal_texture"), { "normal_texture" }, VisualShaderNode::PORT_TYPE_SAMPLER, TYPE_FLAGS_FRAGMENT, Shader::MODE_CANVAS_ITEM));
add_options.push_back(AddOption("PointCoord", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "point_coord"), { "point_coord" }, VisualShaderNode::PORT_TYPE_VECTOR_2D, TYPE_FLAGS_FRAGMENT, Shader::MODE_CANVAS_ITEM));
add_options.push_back(AddOption("ScreenPixelSize", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "screen_pixel_size"), { "screen_pixel_size" }, VisualShaderNode::PORT_TYPE_VECTOR_2D, TYPE_FLAGS_FRAGMENT, Shader::MODE_CANVAS_ITEM));
add_options.push_back(AddOption("ScreenTexture", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "screen_texture"), { "screen_texture" }, VisualShaderNode::PORT_TYPE_SAMPLER, TYPE_FLAGS_FRAGMENT, Shader::MODE_CANVAS_ITEM));
add_options.push_back(AddOption("ScreenUV", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "screen_uv"), { "screen_uv" }, VisualShaderNode::PORT_TYPE_VECTOR_2D, TYPE_FLAGS_FRAGMENT, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("SpecularShininess", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "specular_shininess"), { "specular_shininess" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("SpecularShininess", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "specular_shininess"), { "specular_shininess" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_FRAGMENT, Shader::MODE_CANVAS_ITEM));
add_options.push_back(AddOption("SpecularShininessAlpha", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "specular_shininess_alpha"), { "specular_shininess_alpha" }, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_FRAGMENT, Shader::MODE_CANVAS_ITEM));
add_options.push_back(AddOption("SpecularShininessTexture", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "specular_shininess_texture"), { "specular_shininess_texture" }, VisualShaderNode::PORT_TYPE_SAMPLER, TYPE_FLAGS_FRAGMENT, Shader::MODE_CANVAS_ITEM));
add_options.push_back(AddOption("Texture", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "texture"), { "texture" }, VisualShaderNode::PORT_TYPE_SAMPLER, TYPE_FLAGS_FRAGMENT, Shader::MODE_CANVAS_ITEM));
add_options.push_back(AddOption("Vertex", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_mode, "vertex"), { "vertex" }, VisualShaderNode::PORT_TYPE_VECTOR_2D, TYPE_FLAGS_FRAGMENT, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("FragCoord", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "fragcoord"), { "fragcoord" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("Light", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "light"), { "light" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("FragCoord", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "fragcoord"), { "fragcoord" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("Light", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "light"), { "light" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
add_options.push_back(AddOption("LightAlpha", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "light_alpha"), { "light_alpha" }, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("LightColor", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "light_color"), { "light_color" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("LightColor", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "light_color"), { "light_color" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
add_options.push_back(AddOption("LightColorAlpha", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "light_color_alpha"), { "light_color_alpha" }, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("LightPosition", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "light_position"), { "light_position" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("LightVertex", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "light_vertex"), { "light_vertex" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("Normal", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "normal"), { "normal" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("LightPosition", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "light_position"), { "light_position" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("LightVertex", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "light_vertex"), { "light_vertex" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("Normal", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "normal"), { "normal" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
add_options.push_back(AddOption("PointCoord", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "point_coord"), { "point_coord" }, VisualShaderNode::PORT_TYPE_VECTOR_2D, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
add_options.push_back(AddOption("ScreenUV", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "screen_uv"), { "screen_uv" }, VisualShaderNode::PORT_TYPE_VECTOR_2D, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("Shadow", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "shadow"), { "shadow" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("Shadow", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "shadow"), { "shadow" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
add_options.push_back(AddOption("ShadowAlpha", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "shadow_alpha"), { "shadow_alpha" }, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("SpecularShininess", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "specular_shininess"), { "specular_shininess" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("SpecularShininess", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "specular_shininess"), { "specular_shininess" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
add_options.push_back(AddOption("SpecularShininessAlpha", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "specular_shininess_alpha"), { "specular_shininess_alpha" }, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
add_options.push_back(AddOption("Texture", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "texture"), { "texture" }, VisualShaderNode::PORT_TYPE_SAMPLER, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
@@ -4641,27 +5101,27 @@ VisualShaderEditor::VisualShaderEditor() {
add_options.push_back(AddOption("AtCubeMapPass", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "at_cubemap_pass"), { "at_cubemap_pass" }, VisualShaderNode::PORT_TYPE_BOOLEAN, TYPE_FLAGS_SKY, Shader::MODE_SKY));
add_options.push_back(AddOption("AtHalfResPass", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "at_half_res_pass"), { "at_half_res_pass" }, VisualShaderNode::PORT_TYPE_BOOLEAN, TYPE_FLAGS_SKY, Shader::MODE_SKY));
add_options.push_back(AddOption("AtQuarterResPass", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "at_quarter_res_pass"), { "at_quarter_res_pass" }, VisualShaderNode::PORT_TYPE_BOOLEAN, TYPE_FLAGS_SKY, Shader::MODE_SKY));
- add_options.push_back(AddOption("EyeDir", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "eyedir"), { "eyedir" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_SKY, Shader::MODE_SKY));
- add_options.push_back(AddOption("HalfResColor", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "half_res_color"), { "half_res_color" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_SKY, Shader::MODE_SKY));
+ add_options.push_back(AddOption("EyeDir", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "eyedir"), { "eyedir" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_SKY, Shader::MODE_SKY));
+ add_options.push_back(AddOption("HalfResColor", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "half_res_color"), { "half_res_color" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_SKY, Shader::MODE_SKY));
add_options.push_back(AddOption("HalfResAlpha", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "half_res_alpha"), { "half_res_alpha" }, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_SKY, Shader::MODE_SKY));
- add_options.push_back(AddOption("Light0Color", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light0_color"), { "light0_color" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_SKY, Shader::MODE_SKY));
- add_options.push_back(AddOption("Light0Direction", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light0_direction"), { "light0_direction" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_SKY, Shader::MODE_SKY));
+ add_options.push_back(AddOption("Light0Color", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light0_color"), { "light0_color" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_SKY, Shader::MODE_SKY));
+ add_options.push_back(AddOption("Light0Direction", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light0_direction"), { "light0_direction" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_SKY, Shader::MODE_SKY));
add_options.push_back(AddOption("Light0Enabled", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light0_enabled"), { "light0_enabled" }, VisualShaderNode::PORT_TYPE_BOOLEAN, TYPE_FLAGS_SKY, Shader::MODE_SKY));
add_options.push_back(AddOption("Light0Energy", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light0_energy"), { "light0_energy" }, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_SKY, Shader::MODE_SKY));
- add_options.push_back(AddOption("Light1Color", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light1_color"), { "light1_color" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_SKY, Shader::MODE_SKY));
- add_options.push_back(AddOption("Light1Direction", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light1_direction"), { "light1_direction" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_SKY, Shader::MODE_SKY));
+ add_options.push_back(AddOption("Light1Color", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light1_color"), { "light1_color" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_SKY, Shader::MODE_SKY));
+ add_options.push_back(AddOption("Light1Direction", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light1_direction"), { "light1_direction" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_SKY, Shader::MODE_SKY));
add_options.push_back(AddOption("Light1Enabled", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light1_enabled"), { "light1_enabled" }, VisualShaderNode::PORT_TYPE_BOOLEAN, TYPE_FLAGS_SKY, Shader::MODE_SKY));
add_options.push_back(AddOption("Light1Energy", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light1_energy"), { "light1_energy" }, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_SKY, Shader::MODE_SKY));
- add_options.push_back(AddOption("Light2Color", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light2_color"), { "light2_color" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_SKY, Shader::MODE_SKY));
- add_options.push_back(AddOption("Light2Direction", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light2_direction"), { "light2_direction" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_SKY, Shader::MODE_SKY));
+ add_options.push_back(AddOption("Light2Color", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light2_color"), { "light2_color" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_SKY, Shader::MODE_SKY));
+ add_options.push_back(AddOption("Light2Direction", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light2_direction"), { "light2_direction" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_SKY, Shader::MODE_SKY));
add_options.push_back(AddOption("Light2Enabled", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light2_enabled"), { "light2_enabled" }, VisualShaderNode::PORT_TYPE_BOOLEAN, TYPE_FLAGS_SKY, Shader::MODE_SKY));
add_options.push_back(AddOption("Light2Energy", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light2_energy"), { "light2_energy" }, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_SKY, Shader::MODE_SKY));
- add_options.push_back(AddOption("Light3Color", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light3_color"), { "light3_color" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_SKY, Shader::MODE_SKY));
- add_options.push_back(AddOption("Light3Direction", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light3_direction"), { "light3_direction" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_SKY, Shader::MODE_SKY));
+ add_options.push_back(AddOption("Light3Color", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light3_color"), { "light3_color" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_SKY, Shader::MODE_SKY));
+ add_options.push_back(AddOption("Light3Direction", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light3_direction"), { "light3_direction" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_SKY, Shader::MODE_SKY));
add_options.push_back(AddOption("Light3Enabled", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light3_enabled"), { "light3_enabled" }, VisualShaderNode::PORT_TYPE_BOOLEAN, TYPE_FLAGS_SKY, Shader::MODE_SKY));
add_options.push_back(AddOption("Light3Energy", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light3_energy"), { "light3_energy" }, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_SKY, Shader::MODE_SKY));
- add_options.push_back(AddOption("Position", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "position"), { "position" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_SKY, Shader::MODE_SKY));
- add_options.push_back(AddOption("QuarterResColor", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "quarter_res_color"), { "quarter_res_color" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_SKY, Shader::MODE_SKY));
+ add_options.push_back(AddOption("Position", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "position"), { "position" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_SKY, Shader::MODE_SKY));
+ add_options.push_back(AddOption("QuarterResColor", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "quarter_res_color"), { "quarter_res_color" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_SKY, Shader::MODE_SKY));
add_options.push_back(AddOption("QuarterResAlpha", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "quarter_res_alpha"), { "quarter_res_alpha" }, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_SKY, Shader::MODE_SKY));
add_options.push_back(AddOption("Radiance", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "radiance"), { "radiance" }, VisualShaderNode::PORT_TYPE_SAMPLER, TYPE_FLAGS_SKY, Shader::MODE_SKY));
add_options.push_back(AddOption("ScreenUV", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "screen_uv"), { "screen_uv" }, VisualShaderNode::PORT_TYPE_VECTOR_2D, TYPE_FLAGS_SKY, Shader::MODE_SKY));
@@ -4670,31 +5130,31 @@ VisualShaderEditor::VisualShaderEditor() {
// FOG INPUTS
- add_options.push_back(AddOption("WorldPosition", "Input", "Fog", "VisualShaderNodeInput", vformat(input_param_for_fog_shader_mode, "world_position"), { "world_position" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FOG, Shader::MODE_FOG));
- add_options.push_back(AddOption("ObjectPosition", "Input", "Fog", "VisualShaderNodeInput", vformat(input_param_for_fog_shader_mode, "object_position"), { "object_position" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FOG, Shader::MODE_FOG));
- add_options.push_back(AddOption("UVW", "Input", "Fog", "VisualShaderNodeInput", vformat(input_param_for_fog_shader_mode, "uvw"), { "uvw" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FOG, Shader::MODE_FOG));
- add_options.push_back(AddOption("Extents", "Input", "Fog", "VisualShaderNodeInput", vformat(input_param_for_fog_shader_mode, "extents"), { "extents" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FOG, Shader::MODE_FOG));
+ add_options.push_back(AddOption("WorldPosition", "Input", "Fog", "VisualShaderNodeInput", vformat(input_param_for_fog_shader_mode, "world_position"), { "world_position" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_FOG, Shader::MODE_FOG));
+ add_options.push_back(AddOption("ObjectPosition", "Input", "Fog", "VisualShaderNodeInput", vformat(input_param_for_fog_shader_mode, "object_position"), { "object_position" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_FOG, Shader::MODE_FOG));
+ add_options.push_back(AddOption("UVW", "Input", "Fog", "VisualShaderNodeInput", vformat(input_param_for_fog_shader_mode, "uvw"), { "uvw" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_FOG, Shader::MODE_FOG));
+ add_options.push_back(AddOption("Extents", "Input", "Fog", "VisualShaderNodeInput", vformat(input_param_for_fog_shader_mode, "extents"), { "extents" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_FOG, Shader::MODE_FOG));
add_options.push_back(AddOption("SDF", "Input", "Fog", "VisualShaderNodeInput", vformat(input_param_for_fog_shader_mode, "sdf"), { "sdf" }, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_FOG, Shader::MODE_FOG));
add_options.push_back(AddOption("Time", "Input", "Fog", "VisualShaderNodeInput", vformat(input_param_for_fog_shader_mode, "time"), { "time" }, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_FOG, Shader::MODE_FOG));
// PARTICLES INPUTS
add_options.push_back(AddOption("CollisionDepth", "Input", "Collide", "VisualShaderNodeInput", vformat(input_param_for_collide_shader_mode, "collision_depth"), { "collision_depth" }, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_COLLIDE, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("CollisionNormal", "Input", "Collide", "VisualShaderNodeInput", vformat(input_param_for_collide_shader_mode, "collision_normal"), { "collision_normal" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_COLLIDE, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("CollisionNormal", "Input", "Collide", "VisualShaderNodeInput", vformat(input_param_for_collide_shader_mode, "collision_normal"), { "collision_normal" }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_COLLIDE, Shader::MODE_PARTICLES));
// PARTICLES
add_options.push_back(AddOption("EmitParticle", "Particles", "", "VisualShaderNodeParticleEmit", "", {}, -1, TYPE_FLAGS_PROCESS | TYPE_FLAGS_PROCESS_CUSTOM | TYPE_FLAGS_COLLIDE, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("ParticleAccelerator", "Particles", "", "VisualShaderNodeParticleAccelerator", "", {}, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_PROCESS, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("ParticleAccelerator", "Particles", "", "VisualShaderNodeParticleAccelerator", "", {}, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_PROCESS, Shader::MODE_PARTICLES));
add_options.push_back(AddOption("ParticleRandomness", "Particles", "", "VisualShaderNodeParticleRandomness", "", {}, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_EMIT | TYPE_FLAGS_PROCESS | TYPE_FLAGS_COLLIDE, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("MultiplyByAxisAngle", "Particles", "Transform", "VisualShaderNodeParticleMultiplyByAxisAngle", TTR("A node for help to multiply a position input vector by rotation using specific axis. Intended to work with emitters."), {}, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_EMIT | TYPE_FLAGS_PROCESS | TYPE_FLAGS_COLLIDE, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("MultiplyByAxisAngle", "Particles", "Transform", "VisualShaderNodeParticleMultiplyByAxisAngle", TTR("A node for help to multiply a position input vector by rotation using specific axis. Intended to work with emitters."), {}, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_EMIT | TYPE_FLAGS_PROCESS | TYPE_FLAGS_COLLIDE, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("BoxEmitter", "Particles", "Emitters", "VisualShaderNodeParticleBoxEmitter", "", {}, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("MeshEmitter", "Particles", "Emitters", "VisualShaderNodeParticleMeshEmitter", "", {}, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("RingEmitter", "Particles", "Emitters", "VisualShaderNodeParticleRingEmitter", "", {}, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("SphereEmitter", "Particles", "Emitters", "VisualShaderNodeParticleSphereEmitter", "", {}, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("BoxEmitter", "Particles", "Emitters", "VisualShaderNodeParticleBoxEmitter", "", {}, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("MeshEmitter", "Particles", "Emitters", "VisualShaderNodeParticleMeshEmitter", "", {}, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("RingEmitter", "Particles", "Emitters", "VisualShaderNodeParticleRingEmitter", "", {}, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("SphereEmitter", "Particles", "Emitters", "VisualShaderNodeParticleSphereEmitter", "", {}, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("ConeVelocity", "Particles", "Velocity", "VisualShaderNodeParticleConeVelocity", "", {}, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("ConeVelocity", "Particles", "Velocity", "VisualShaderNodeParticleConeVelocity", "", {}, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES));
// SCALAR
@@ -4783,11 +5243,11 @@ VisualShaderEditor::VisualShaderEditor() {
// SDF
{
- add_options.push_back(AddOption("ScreenUVToSDF", "SDF", "", "VisualShaderNodeScreenUVToSDF", TTR("Converts screen UV to a SDF."), {}, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("ScreenUVToSDF", "SDF", "", "VisualShaderNodeScreenUVToSDF", TTR("Converts screen UV to a SDF."), {}, VisualShaderNode::PORT_TYPE_VECTOR_2D, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
add_options.push_back(AddOption("SDFRaymarch", "SDF", "", "VisualShaderNodeSDFRaymarch", TTR("Casts a ray against the screen SDF and returns the distance travelled."), {}, -1, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("SDFToScreenUV", "SDF", "", "VisualShaderNodeSDFToScreenUV", TTR("Converts a SDF to screen UV."), {}, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("SDFToScreenUV", "SDF", "", "VisualShaderNodeSDFToScreenUV", TTR("Converts a SDF to screen UV."), {}, VisualShaderNode::PORT_TYPE_VECTOR_2D, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
add_options.push_back(AddOption("TextureSDF", "SDF", "", "VisualShaderNodeTextureSDF", TTR("Performs a SDF texture lookup."), {}, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("TextureSDFNormal", "SDF", "", "VisualShaderNodeTextureSDFNormal", TTR("Performs a SDF normal texture lookup."), {}, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("TextureSDFNormal", "SDF", "", "VisualShaderNodeTextureSDFNormal", TTR("Performs a SDF normal texture lookup."), {}, VisualShaderNode::PORT_TYPE_VECTOR_2D, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
}
// TEXTURES
@@ -4834,146 +5294,146 @@ VisualShaderEditor::VisualShaderEditor() {
add_options.push_back(AddOption("Multiply", "Transform", "Operators", "VisualShaderNodeTransformOp", TTR("Multiplies two transforms."), { VisualShaderNodeTransformOp::OP_AxB }, VisualShaderNode::PORT_TYPE_TRANSFORM));
add_options.push_back(AddOption("MultiplyComp", "Transform", "Operators", "VisualShaderNodeTransformOp", TTR("Performs per-component multiplication of two transforms."), { VisualShaderNodeTransformOp::OP_AxB_COMP }, VisualShaderNode::PORT_TYPE_TRANSFORM));
add_options.push_back(AddOption("Subtract", "Transform", "Operators", "VisualShaderNodeTransformOp", TTR("Subtracts two transforms."), { VisualShaderNodeTransformOp::OP_A_MINUS_B }, VisualShaderNode::PORT_TYPE_TRANSFORM));
- add_options.push_back(AddOption("TransformVectorMult", "Transform", "Operators", "VisualShaderNodeTransformVecMult", TTR("Multiplies vector by transform."), {}, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("TransformVectorMult", "Transform", "Operators", "VisualShaderNodeTransformVecMult", TTR("Multiplies vector by transform."), {}, VisualShaderNode::PORT_TYPE_VECTOR_3D));
add_options.push_back(AddOption("TransformConstant", "Transform", "Variables", "VisualShaderNodeTransformConstant", TTR("Transform constant."), {}, VisualShaderNode::PORT_TYPE_TRANSFORM));
add_options.push_back(AddOption("TransformUniform", "Transform", "Variables", "VisualShaderNodeTransformUniform", TTR("Transform uniform."), {}, VisualShaderNode::PORT_TYPE_TRANSFORM));
// VECTOR
- add_options.push_back(AddOption("VectorFunc", "Vector", "Common", "VisualShaderNodeVectorFunc", TTR("Vector function."), {}, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("VectorOp", "Vector", "Common", "VisualShaderNodeVectorOp", TTR("Vector operator."), {}, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("VectorFunc", "Vector", "Common", "VisualShaderNodeVectorFunc", TTR("Vector function."), {}, VisualShaderNode::PORT_TYPE_VECTOR_3D));
+ add_options.push_back(AddOption("VectorOp", "Vector", "Common", "VisualShaderNodeVectorOp", TTR("Vector operator."), {}, VisualShaderNode::PORT_TYPE_VECTOR_3D));
add_options.push_back(AddOption("VectorCompose", "Vector", "Common", "VisualShaderNodeVectorCompose", TTR("Composes vector from three scalars.")));
add_options.push_back(AddOption("VectorDecompose", "Vector", "Common", "VisualShaderNodeVectorDecompose", TTR("Decomposes vector to three scalars.")));
add_options.push_back(AddOption("Vector2Compose", "Vector", "Composition", "VisualShaderNodeVectorCompose", TTR("Composes 2D vector from three scalars."), { VisualShaderNodeVectorCompose::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
add_options.push_back(AddOption("Vector2Decompose", "Vector", "Composition", "VisualShaderNodeVectorDecompose", TTR("Decomposes 2D vector to three scalars."), { VisualShaderNodeVectorCompose::OP_TYPE_VECTOR_2D }));
- add_options.push_back(AddOption("Vector3Compose", "Vector", "Composition", "VisualShaderNodeVectorCompose", TTR("Composes 3D vector from three scalars."), { VisualShaderNodeVectorCompose::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Vector3Compose", "Vector", "Composition", "VisualShaderNodeVectorCompose", TTR("Composes 3D vector from three scalars."), { VisualShaderNodeVectorCompose::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
add_options.push_back(AddOption("Vector3Decompose", "Vector", "Composition", "VisualShaderNodeVectorDecompose", TTR("Decomposes 3D vector to three scalars."), { VisualShaderNodeVectorCompose::OP_TYPE_VECTOR_3D }));
add_options.push_back(AddOption("Abs", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the absolute value of the parameter."), { VisualShaderNodeVectorFunc::FUNC_ABS, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
- add_options.push_back(AddOption("Abs", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the absolute value of the parameter."), { VisualShaderNodeVectorFunc::FUNC_ABS, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Abs", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the absolute value of the parameter."), { VisualShaderNodeVectorFunc::FUNC_ABS, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
add_options.push_back(AddOption("ACos", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the arc-cosine of the parameter."), { VisualShaderNodeVectorFunc::FUNC_ACOS, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
- add_options.push_back(AddOption("ACos", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the arc-cosine of the parameter."), { VisualShaderNodeVectorFunc::FUNC_ACOS, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("ACos", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the arc-cosine of the parameter."), { VisualShaderNodeVectorFunc::FUNC_ACOS, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
add_options.push_back(AddOption("ACosH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the inverse hyperbolic cosine of the parameter."), { VisualShaderNodeVectorFunc::FUNC_ACOSH, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
- add_options.push_back(AddOption("ACosH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the inverse hyperbolic cosine of the parameter."), { VisualShaderNodeVectorFunc::FUNC_ACOSH, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("ACosH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the inverse hyperbolic cosine of the parameter."), { VisualShaderNodeVectorFunc::FUNC_ACOSH, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
add_options.push_back(AddOption("ASin", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the arc-sine of the parameter."), { VisualShaderNodeVectorFunc::FUNC_ASIN, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
- add_options.push_back(AddOption("ASin", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the arc-sine of the parameter."), { VisualShaderNodeVectorFunc::FUNC_ASIN, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("ASin", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the arc-sine of the parameter."), { VisualShaderNodeVectorFunc::FUNC_ASIN, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
add_options.push_back(AddOption("ASinH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the inverse hyperbolic sine of the parameter."), { VisualShaderNodeVectorFunc::FUNC_ASINH, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
- add_options.push_back(AddOption("ASinH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the inverse hyperbolic sine of the parameter."), { VisualShaderNodeVectorFunc::FUNC_ASINH, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("ASinH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the inverse hyperbolic sine of the parameter."), { VisualShaderNodeVectorFunc::FUNC_ASINH, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
add_options.push_back(AddOption("ATan", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the arc-tangent of the parameter."), { VisualShaderNodeVectorFunc::FUNC_ATAN, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
- add_options.push_back(AddOption("ATan", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the arc-tangent of the parameter."), { VisualShaderNodeVectorFunc::FUNC_ATAN, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("ATan", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the arc-tangent of the parameter."), { VisualShaderNodeVectorFunc::FUNC_ATAN, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
add_options.push_back(AddOption("ATan2", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Returns the arc-tangent of the parameters."), { VisualShaderNodeVectorOp::OP_ATAN2, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
- add_options.push_back(AddOption("ATan2", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Returns the arc-tangent of the parameters."), { VisualShaderNodeVectorOp::OP_ATAN2, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("ATan2", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Returns the arc-tangent of the parameters."), { VisualShaderNodeVectorOp::OP_ATAN2, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
add_options.push_back(AddOption("ATanH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the inverse hyperbolic tangent of the parameter."), { VisualShaderNodeVectorFunc::FUNC_ATANH, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
- add_options.push_back(AddOption("ATanH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the inverse hyperbolic tangent of the parameter."), { VisualShaderNodeVectorFunc::FUNC_ATANH, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("ATanH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the inverse hyperbolic tangent of the parameter."), { VisualShaderNodeVectorFunc::FUNC_ATANH, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
add_options.push_back(AddOption("Ceil", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Finds the nearest integer that is greater than or equal to the parameter."), { VisualShaderNodeVectorFunc::FUNC_CEIL }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
- add_options.push_back(AddOption("Ceil", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Finds the nearest integer that is greater than or equal to the parameter."), { VisualShaderNodeVectorFunc::FUNC_CEIL, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Ceil", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Finds the nearest integer that is greater than or equal to the parameter."), { VisualShaderNodeVectorFunc::FUNC_CEIL, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
add_options.push_back(AddOption("Clamp", "Vector", "Functions", "VisualShaderNodeClamp", TTR("Constrains a value to lie between two further values."), { VisualShaderNodeClamp::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
- add_options.push_back(AddOption("Clamp", "Vector", "Functions", "VisualShaderNodeClamp", TTR("Constrains a value to lie between two further values."), { VisualShaderNodeClamp::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Clamp", "Vector", "Functions", "VisualShaderNodeClamp", TTR("Constrains a value to lie between two further values."), { VisualShaderNodeClamp::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
add_options.push_back(AddOption("Cos", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the cosine of the parameter."), { VisualShaderNodeVectorFunc::FUNC_COS, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
- add_options.push_back(AddOption("Cos", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the cosine of the parameter."), { VisualShaderNodeVectorFunc::FUNC_COS, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Cos", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the cosine of the parameter."), { VisualShaderNodeVectorFunc::FUNC_COS, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
add_options.push_back(AddOption("CosH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the hyperbolic cosine of the parameter."), { VisualShaderNodeVectorFunc::FUNC_COSH, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
- add_options.push_back(AddOption("CosH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the hyperbolic cosine of the parameter."), { VisualShaderNodeVectorFunc::FUNC_COSH, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("Cross", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Calculates the cross product of two vectors."), { VisualShaderNodeVectorOp::OP_CROSS, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("CosH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the hyperbolic cosine of the parameter."), { VisualShaderNodeVectorFunc::FUNC_COSH, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
+ add_options.push_back(AddOption("Cross", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Calculates the cross product of two vectors."), { VisualShaderNodeVectorOp::OP_CROSS, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
add_options.push_back(AddOption("Degrees", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Converts a quantity in radians to degrees."), { VisualShaderNodeVectorFunc::FUNC_DEGREES, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
- add_options.push_back(AddOption("Degrees", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Converts a quantity in radians to degrees."), { VisualShaderNodeVectorFunc::FUNC_DEGREES, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Degrees", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Converts a quantity in radians to degrees."), { VisualShaderNodeVectorFunc::FUNC_DEGREES, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
add_options.push_back(AddOption("DFdX", "Vector", "Functions", "VisualShaderNodeDerivativeFunc", TTR("(Fragment/Light mode only) (Vector) Derivative in 'x' using local differencing."), { VisualShaderNodeDerivativeFunc::FUNC_X, VisualShaderNodeDerivativeFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, -1, true));
- add_options.push_back(AddOption("DFdX", "Vector", "Functions", "VisualShaderNodeDerivativeFunc", TTR("(Fragment/Light mode only) (Vector) Derivative in 'x' using local differencing."), { VisualShaderNodeDerivativeFunc::FUNC_X, VisualShaderNodeDerivativeFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, -1, true));
+ add_options.push_back(AddOption("DFdX", "Vector", "Functions", "VisualShaderNodeDerivativeFunc", TTR("(Fragment/Light mode only) (Vector) Derivative in 'x' using local differencing."), { VisualShaderNodeDerivativeFunc::FUNC_X, VisualShaderNodeDerivativeFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, -1, true));
add_options.push_back(AddOption("DFdY", "Vector", "Functions", "VisualShaderNodeDerivativeFunc", TTR("(Fragment/Light mode only) (Vector) Derivative in 'y' using local differencing."), { VisualShaderNodeDerivativeFunc::FUNC_Y, VisualShaderNodeDerivativeFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, -1, true));
- add_options.push_back(AddOption("DFdY", "Vector", "Functions", "VisualShaderNodeDerivativeFunc", TTR("(Fragment/Light mode only) (Vector) Derivative in 'y' using local differencing."), { VisualShaderNodeDerivativeFunc::FUNC_Y, VisualShaderNodeDerivativeFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, -1, true));
+ add_options.push_back(AddOption("DFdY", "Vector", "Functions", "VisualShaderNodeDerivativeFunc", TTR("(Fragment/Light mode only) (Vector) Derivative in 'y' using local differencing."), { VisualShaderNodeDerivativeFunc::FUNC_Y, VisualShaderNodeDerivativeFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, -1, true));
add_options.push_back(AddOption("Distance2D", "Vector", "Functions", "VisualShaderNodeVectorDistance", TTR("Returns the distance between two points."), { VisualShaderNodeVectorDistance::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_SCALAR));
add_options.push_back(AddOption("Distance3D", "Vector", "Functions", "VisualShaderNodeVectorDistance", TTR("Returns the distance between two points."), { VisualShaderNodeVectorDistance::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_SCALAR));
add_options.push_back(AddOption("Dot", "Vector", "Functions", "VisualShaderNodeDotProduct", TTR("Calculates the dot product of two vectors."), {}, VisualShaderNode::PORT_TYPE_SCALAR));
add_options.push_back(AddOption("Exp", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Base-e Exponential."), { VisualShaderNodeVectorFunc::FUNC_EXP, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
- add_options.push_back(AddOption("Exp", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Base-e Exponential."), { VisualShaderNodeVectorFunc::FUNC_EXP, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Exp", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Base-e Exponential."), { VisualShaderNodeVectorFunc::FUNC_EXP, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
add_options.push_back(AddOption("Exp2", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Base-2 Exponential."), { VisualShaderNodeVectorFunc::FUNC_EXP2, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
- add_options.push_back(AddOption("Exp2", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Base-2 Exponential."), { VisualShaderNodeVectorFunc::FUNC_EXP2, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Exp2", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Base-2 Exponential."), { VisualShaderNodeVectorFunc::FUNC_EXP2, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
add_options.push_back(AddOption("FaceForward", "Vector", "Functions", "VisualShaderNodeFaceForward", TTR("Returns the vector that points in the same direction as a reference vector. The function has three vector parameters : N, the vector to orient, I, the incident vector, and Nref, the reference vector. If the dot product of I and Nref is smaller than zero the return value is N. Otherwise -N is returned."), { VisualShaderNodeFaceForward::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
- add_options.push_back(AddOption("FaceForward", "Vector", "Functions", "VisualShaderNodeFaceForward", TTR("Returns the vector that points in the same direction as a reference vector. The function has three vector parameters : N, the vector to orient, I, the incident vector, and Nref, the reference vector. If the dot product of I and Nref is smaller than zero the return value is N. Otherwise -N is returned."), { VisualShaderNodeFaceForward::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("FaceForward", "Vector", "Functions", "VisualShaderNodeFaceForward", TTR("Returns the vector that points in the same direction as a reference vector. The function has three vector parameters : N, the vector to orient, I, the incident vector, and Nref, the reference vector. If the dot product of I and Nref is smaller than zero the return value is N. Otherwise -N is returned."), { VisualShaderNodeFaceForward::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
add_options.push_back(AddOption("Floor", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Finds the nearest integer less than or equal to the parameter."), { VisualShaderNodeVectorFunc::FUNC_FLOOR, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
- add_options.push_back(AddOption("Floor", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Finds the nearest integer less than or equal to the parameter."), { VisualShaderNodeVectorFunc::FUNC_FLOOR, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Floor", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Finds the nearest integer less than or equal to the parameter."), { VisualShaderNodeVectorFunc::FUNC_FLOOR, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
add_options.push_back(AddOption("Fract", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Computes the fractional part of the argument."), { VisualShaderNodeVectorFunc::FUNC_FRAC, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
- add_options.push_back(AddOption("Fract", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Computes the fractional part of the argument."), { VisualShaderNodeVectorFunc::FUNC_FRAC, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Fract", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Computes the fractional part of the argument."), { VisualShaderNodeVectorFunc::FUNC_FRAC, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
add_options.push_back(AddOption("Fresnel", "Vector", "Functions", "VisualShaderNodeFresnel", TTR("Returns falloff based on the dot product of surface normal and view direction of camera (pass associated inputs to it)."), {}, VisualShaderNode::PORT_TYPE_SCALAR));
add_options.push_back(AddOption("InverseSqrt", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the inverse of the square root of the parameter."), { VisualShaderNodeVectorFunc::FUNC_INVERSE_SQRT, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
- add_options.push_back(AddOption("InverseSqrt", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the inverse of the square root of the parameter."), { VisualShaderNodeVectorFunc::FUNC_INVERSE_SQRT, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("InverseSqrt", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the inverse of the square root of the parameter."), { VisualShaderNodeVectorFunc::FUNC_INVERSE_SQRT, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
add_options.push_back(AddOption("Length", "Vector", "Functions", "VisualShaderNodeVectorLen", TTR("Calculates the length of a vector."), { VisualShaderNodeVectorLen::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_SCALAR));
add_options.push_back(AddOption("Length", "Vector", "Functions", "VisualShaderNodeVectorLen", TTR("Calculates the length of a vector."), { VisualShaderNodeVectorLen::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_SCALAR));
add_options.push_back(AddOption("Log", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Natural logarithm."), { VisualShaderNodeVectorFunc::FUNC_LOG, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
- add_options.push_back(AddOption("Log", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Natural logarithm."), { VisualShaderNodeVectorFunc::FUNC_LOG, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Log", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Natural logarithm."), { VisualShaderNodeVectorFunc::FUNC_LOG, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
add_options.push_back(AddOption("Log2", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Base-2 logarithm."), { VisualShaderNodeVectorFunc::FUNC_LOG2, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
- add_options.push_back(AddOption("Log2", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Base-2 logarithm."), { VisualShaderNodeVectorFunc::FUNC_LOG2, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Log2", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Base-2 logarithm."), { VisualShaderNodeVectorFunc::FUNC_LOG2, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
add_options.push_back(AddOption("Max", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Returns the greater of two values."), { VisualShaderNodeVectorOp::OP_MAX, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
- add_options.push_back(AddOption("Max", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Returns the greater of two values."), { VisualShaderNodeVectorOp::OP_MAX, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Max", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Returns the greater of two values."), { VisualShaderNodeVectorOp::OP_MAX, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
add_options.push_back(AddOption("Min", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Returns the lesser of two values."), { VisualShaderNodeVectorOp::OP_MIN, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
- add_options.push_back(AddOption("Min", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Returns the lesser of two values."), { VisualShaderNodeVectorOp::OP_MIN, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Min", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Returns the lesser of two values."), { VisualShaderNodeVectorOp::OP_MIN, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
add_options.push_back(AddOption("Mix", "Vector", "Functions", "VisualShaderNodeMix", TTR("Linear interpolation between two vectors."), { VisualShaderNodeMix::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
- add_options.push_back(AddOption("Mix", "Vector", "Functions", "VisualShaderNodeMix", TTR("Linear interpolation between two vectors."), { VisualShaderNodeMix::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Mix", "Vector", "Functions", "VisualShaderNodeMix", TTR("Linear interpolation between two vectors."), { VisualShaderNodeMix::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
add_options.push_back(AddOption("MixS", "Vector", "Functions", "VisualShaderNodeMix", TTR("Linear interpolation between two vectors using scalar."), { VisualShaderNodeMix::OP_TYPE_VECTOR_2D_SCALAR }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
- add_options.push_back(AddOption("MixS", "Vector", "Functions", "VisualShaderNodeMix", TTR("Linear interpolation between two vectors using scalar."), { VisualShaderNodeMix::OP_TYPE_VECTOR_3D_SCALAR }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("MixS", "Vector", "Functions", "VisualShaderNodeMix", TTR("Linear interpolation between two vectors using scalar."), { VisualShaderNodeMix::OP_TYPE_VECTOR_3D_SCALAR }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
add_options.push_back(AddOption("MultiplyAdd", "Vector", "Functions", "VisualShaderNodeMultiplyAdd", TTR("Performs a fused multiply-add operation (a * b + c) on vectors."), { VisualShaderNodeMultiplyAdd::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
- add_options.push_back(AddOption("MultiplyAdd", "Vector", "Functions", "VisualShaderNodeMultiplyAdd", TTR("Performs a fused multiply-add operation (a * b + c) on vectors."), { VisualShaderNodeMultiplyAdd::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("MultiplyAdd", "Vector", "Functions", "VisualShaderNodeMultiplyAdd", TTR("Performs a fused multiply-add operation (a * b + c) on vectors."), { VisualShaderNodeMultiplyAdd::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
add_options.push_back(AddOption("Negate", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the opposite value of the parameter."), { VisualShaderNodeVectorFunc::FUNC_NEGATE, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
- add_options.push_back(AddOption("Negate", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the opposite value of the parameter."), { VisualShaderNodeVectorFunc::FUNC_NEGATE, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Negate", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the opposite value of the parameter."), { VisualShaderNodeVectorFunc::FUNC_NEGATE, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
add_options.push_back(AddOption("Normalize", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Calculates the normalize product of vector."), { VisualShaderNodeVectorFunc::FUNC_NORMALIZE, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
- add_options.push_back(AddOption("Normalize", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Calculates the normalize product of vector."), { VisualShaderNodeVectorFunc::FUNC_NORMALIZE, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Normalize", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Calculates the normalize product of vector."), { VisualShaderNodeVectorFunc::FUNC_NORMALIZE, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
add_options.push_back(AddOption("OneMinus", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("1.0 - vector"), { VisualShaderNodeVectorFunc::FUNC_ONEMINUS, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
- add_options.push_back(AddOption("OneMinus", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("1.0 - vector"), { VisualShaderNodeVectorFunc::FUNC_ONEMINUS, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("OneMinus", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("1.0 - vector"), { VisualShaderNodeVectorFunc::FUNC_ONEMINUS, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
add_options.push_back(AddOption("Pow", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Returns the value of the first parameter raised to the power of the second."), { VisualShaderNodeVectorOp::OP_POW, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
- add_options.push_back(AddOption("Pow", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Returns the value of the first parameter raised to the power of the second."), { VisualShaderNodeVectorOp::OP_POW, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Pow", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Returns the value of the first parameter raised to the power of the second."), { VisualShaderNodeVectorOp::OP_POW, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
add_options.push_back(AddOption("Radians", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Converts a quantity in degrees to radians."), { VisualShaderNodeVectorFunc::FUNC_RADIANS, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
- add_options.push_back(AddOption("Radians", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Converts a quantity in degrees to radians."), { VisualShaderNodeVectorFunc::FUNC_RADIANS, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Radians", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Converts a quantity in degrees to radians."), { VisualShaderNodeVectorFunc::FUNC_RADIANS, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
add_options.push_back(AddOption("Reciprocal", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("1.0 / vector"), { VisualShaderNodeVectorFunc::FUNC_RECIPROCAL, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
- add_options.push_back(AddOption("Reciprocal", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("1.0 / vector"), { VisualShaderNodeVectorFunc::FUNC_RECIPROCAL, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("Reflect", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Returns the vector that points in the direction of reflection ( a : incident vector, b : normal vector )."), { VisualShaderNodeVectorOp::OP_REFLECT, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("Refract", "Vector", "Functions", "VisualShaderNodeVectorRefract", TTR("Returns the vector that points in the direction of refraction."), {}, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Reciprocal", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("1.0 / vector"), { VisualShaderNodeVectorFunc::FUNC_RECIPROCAL, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
+ add_options.push_back(AddOption("Reflect", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Returns the vector that points in the direction of reflection ( a : incident vector, b : normal vector )."), { VisualShaderNodeVectorOp::OP_REFLECT, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
+ add_options.push_back(AddOption("Refract", "Vector", "Functions", "VisualShaderNodeVectorRefract", TTR("Returns the vector that points in the direction of refraction."), {}, VisualShaderNode::PORT_TYPE_VECTOR_3D));
add_options.push_back(AddOption("Round", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Finds the nearest integer to the parameter."), { VisualShaderNodeVectorFunc::FUNC_ROUND, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
- add_options.push_back(AddOption("Round", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Finds the nearest integer to the parameter."), { VisualShaderNodeVectorFunc::FUNC_ROUND, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Round", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Finds the nearest integer to the parameter."), { VisualShaderNodeVectorFunc::FUNC_ROUND, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
add_options.push_back(AddOption("RoundEven", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Finds the nearest even integer to the parameter."), { VisualShaderNodeVectorFunc::FUNC_ROUNDEVEN, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
- add_options.push_back(AddOption("RoundEven", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Finds the nearest even integer to the parameter."), { VisualShaderNodeVectorFunc::FUNC_ROUNDEVEN, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("RoundEven", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Finds the nearest even integer to the parameter."), { VisualShaderNodeVectorFunc::FUNC_ROUNDEVEN, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
add_options.push_back(AddOption("Saturate", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Clamps the value between 0.0 and 1.0."), { VisualShaderNodeVectorFunc::FUNC_SATURATE, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
- add_options.push_back(AddOption("Saturate", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Clamps the value between 0.0 and 1.0."), { VisualShaderNodeVectorFunc::FUNC_SATURATE, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Saturate", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Clamps the value between 0.0 and 1.0."), { VisualShaderNodeVectorFunc::FUNC_SATURATE, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
add_options.push_back(AddOption("Sign", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Extracts the sign of the parameter."), { VisualShaderNodeVectorFunc::FUNC_SIGN, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
- add_options.push_back(AddOption("Sign", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Extracts the sign of the parameter."), { VisualShaderNodeVectorFunc::FUNC_SIGN, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Sign", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Extracts the sign of the parameter."), { VisualShaderNodeVectorFunc::FUNC_SIGN, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
add_options.push_back(AddOption("Sin", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the sine of the parameter."), { VisualShaderNodeVectorFunc::FUNC_SIN, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
- add_options.push_back(AddOption("Sin", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the sine of the parameter."), { VisualShaderNodeVectorFunc::FUNC_SIN, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Sin", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the sine of the parameter."), { VisualShaderNodeVectorFunc::FUNC_SIN, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
add_options.push_back(AddOption("SinH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the hyperbolic sine of the parameter."), { VisualShaderNodeVectorFunc::FUNC_SINH, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
- add_options.push_back(AddOption("SinH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the hyperbolic sine of the parameter."), { VisualShaderNodeVectorFunc::FUNC_SINH, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("SinH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the hyperbolic sine of the parameter."), { VisualShaderNodeVectorFunc::FUNC_SINH, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
add_options.push_back(AddOption("Sqrt", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the square root of the parameter."), { VisualShaderNodeVectorFunc::FUNC_SQRT, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
- add_options.push_back(AddOption("Sqrt", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the square root of the parameter."), { VisualShaderNodeVectorFunc::FUNC_SQRT, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Sqrt", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the square root of the parameter."), { VisualShaderNodeVectorFunc::FUNC_SQRT, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
add_options.push_back(AddOption("SmoothStep", "Vector", "Functions", "VisualShaderNodeSmoothStep", TTR("SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than 'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 using Hermite polynomials."), { VisualShaderNodeSmoothStep::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
- add_options.push_back(AddOption("SmoothStep", "Vector", "Functions", "VisualShaderNodeSmoothStep", TTR("SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than 'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 using Hermite polynomials."), { VisualShaderNodeSmoothStep::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("SmoothStep", "Vector", "Functions", "VisualShaderNodeSmoothStep", TTR("SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than 'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 using Hermite polynomials."), { VisualShaderNodeSmoothStep::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
add_options.push_back(AddOption("SmoothStepS", "Vector", "Functions", "VisualShaderNodeSmoothStep", TTR("SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than 'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 using Hermite polynomials."), { VisualShaderNodeSmoothStep::OP_TYPE_VECTOR_2D_SCALAR }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
- add_options.push_back(AddOption("SmoothStepS", "Vector", "Functions", "VisualShaderNodeSmoothStep", TTR("SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than 'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 using Hermite polynomials."), { VisualShaderNodeSmoothStep::OP_TYPE_VECTOR_3D_SCALAR }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("SmoothStepS", "Vector", "Functions", "VisualShaderNodeSmoothStep", TTR("SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than 'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 using Hermite polynomials."), { VisualShaderNodeSmoothStep::OP_TYPE_VECTOR_3D_SCALAR }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
add_options.push_back(AddOption("Step", "Vector", "Functions", "VisualShaderNodeStep", TTR("Step function( vector(edge), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."), { VisualShaderNodeStep::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
- add_options.push_back(AddOption("Step", "Vector", "Functions", "VisualShaderNodeStep", TTR("Step function( vector(edge), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."), { VisualShaderNodeStep::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Step", "Vector", "Functions", "VisualShaderNodeStep", TTR("Step function( vector(edge), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."), { VisualShaderNodeStep::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
add_options.push_back(AddOption("StepS", "Vector", "Functions", "VisualShaderNodeStep", TTR("Step function( scalar(edge), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."), { VisualShaderNodeStep::OP_TYPE_VECTOR_2D_SCALAR }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
- add_options.push_back(AddOption("StepS", "Vector", "Functions", "VisualShaderNodeStep", TTR("Step function( scalar(edge), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."), { VisualShaderNodeStep::OP_TYPE_VECTOR_3D_SCALAR }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("StepS", "Vector", "Functions", "VisualShaderNodeStep", TTR("Step function( scalar(edge), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."), { VisualShaderNodeStep::OP_TYPE_VECTOR_3D_SCALAR }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
add_options.push_back(AddOption("Sum", "Vector", "Functions", "VisualShaderNodeDerivativeFunc", TTR("(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and 'y'."), { VisualShaderNodeDerivativeFunc::FUNC_SUM, VisualShaderNodeDerivativeFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, -1, true));
- add_options.push_back(AddOption("Sum", "Vector", "Functions", "VisualShaderNodeDerivativeFunc", TTR("(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and 'y'."), { VisualShaderNodeDerivativeFunc::FUNC_SUM, VisualShaderNodeDerivativeFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, -1, true));
+ add_options.push_back(AddOption("Sum", "Vector", "Functions", "VisualShaderNodeDerivativeFunc", TTR("(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and 'y'."), { VisualShaderNodeDerivativeFunc::FUNC_SUM, VisualShaderNodeDerivativeFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, -1, true));
add_options.push_back(AddOption("Tan", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the tangent of the parameter."), { VisualShaderNodeVectorFunc::FUNC_TAN, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
- add_options.push_back(AddOption("Tan", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the tangent of the parameter."), { VisualShaderNodeVectorFunc::FUNC_TAN, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Tan", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the tangent of the parameter."), { VisualShaderNodeVectorFunc::FUNC_TAN, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
add_options.push_back(AddOption("TanH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the hyperbolic tangent of the parameter."), { VisualShaderNodeVectorFunc::FUNC_TANH, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
- add_options.push_back(AddOption("TanH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the hyperbolic tangent of the parameter."), { VisualShaderNodeVectorFunc::FUNC_TANH, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("TanH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the hyperbolic tangent of the parameter."), { VisualShaderNodeVectorFunc::FUNC_TANH, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
add_options.push_back(AddOption("Trunc", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Finds the truncated value of the parameter."), { VisualShaderNodeVectorFunc::FUNC_TRUNC, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
- add_options.push_back(AddOption("Trunc", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Finds the truncated value of the parameter."), { VisualShaderNodeVectorFunc::FUNC_TRUNC, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Trunc", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Finds the truncated value of the parameter."), { VisualShaderNodeVectorFunc::FUNC_TRUNC, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
add_options.push_back(AddOption("Add", "Vector", "Operators", "VisualShaderNodeVectorOp", TTR("Adds 2D vector to 2D vector."), { VisualShaderNodeVectorOp::OP_ADD, VisualShaderNodeVectorOp::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
- add_options.push_back(AddOption("Add", "Vector", "Operators", "VisualShaderNodeVectorOp", TTR("Adds 3D vector to 3D vector."), { VisualShaderNodeVectorOp::OP_ADD, VisualShaderNodeVectorOp::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Add", "Vector", "Operators", "VisualShaderNodeVectorOp", TTR("Adds 3D vector to 3D vector."), { VisualShaderNodeVectorOp::OP_ADD, VisualShaderNodeVectorOp::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
add_options.push_back(AddOption("Divide", "Vector", "Operators", "VisualShaderNodeVectorOp", TTR("Divides 2D vector by 2D vector."), { VisualShaderNodeVectorOp::OP_DIV, VisualShaderNodeVectorOp::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
- add_options.push_back(AddOption("Divide", "Vector", "Operators", "VisualShaderNodeVectorOp", TTR("Divides 3D vector by 3D vector."), { VisualShaderNodeVectorOp::OP_DIV, VisualShaderNodeVectorOp::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Divide", "Vector", "Operators", "VisualShaderNodeVectorOp", TTR("Divides 3D vector by 3D vector."), { VisualShaderNodeVectorOp::OP_DIV, VisualShaderNodeVectorOp::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
add_options.push_back(AddOption("Multiply", "Vector", "Operators", "VisualShaderNodeVectorOp", TTR("Multiplies 2D vector by 2D vector."), { VisualShaderNodeVectorOp::OP_MUL, VisualShaderNodeVectorOp::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
- add_options.push_back(AddOption("Multiply", "Vector", "Operators", "VisualShaderNodeVectorOp", TTR("Multiplies 3D vector by 3D vector."), { VisualShaderNodeVectorOp::OP_MUL, VisualShaderNodeVectorOp::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Multiply", "Vector", "Operators", "VisualShaderNodeVectorOp", TTR("Multiplies 3D vector by 3D vector."), { VisualShaderNodeVectorOp::OP_MUL, VisualShaderNodeVectorOp::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
add_options.push_back(AddOption("Remainder", "Vector", "Operators", "VisualShaderNodeVectorOp", TTR("Returns the remainder of the two 2D vectors."), { VisualShaderNodeVectorOp::OP_MOD, VisualShaderNodeVectorOp::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
- add_options.push_back(AddOption("Remainder", "Vector", "Operators", "VisualShaderNodeVectorOp", TTR("Returns the remainder of the two 3D vectors."), { VisualShaderNodeVectorOp::OP_MOD, VisualShaderNodeVectorOp::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Remainder", "Vector", "Operators", "VisualShaderNodeVectorOp", TTR("Returns the remainder of the two 3D vectors."), { VisualShaderNodeVectorOp::OP_MOD, VisualShaderNodeVectorOp::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
add_options.push_back(AddOption("Subtract", "Vector", "Operators", "VisualShaderNodeVectorOp", TTR("Subtracts 2D vector from 2D vector."), { VisualShaderNodeVectorOp::OP_SUB, VisualShaderNodeVectorOp::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
- add_options.push_back(AddOption("Subtract", "Vector", "Operators", "VisualShaderNodeVectorOp", TTR("Subtracts 3D vector from 3D vector."), { VisualShaderNodeVectorOp::OP_SUB, VisualShaderNodeVectorOp::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Subtract", "Vector", "Operators", "VisualShaderNodeVectorOp", TTR("Subtracts 3D vector from 3D vector."), { VisualShaderNodeVectorOp::OP_SUB, VisualShaderNodeVectorOp::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
add_options.push_back(AddOption("Vector2Constant", "Vector", "Variables", "VisualShaderNodeVec2Constant", TTR("2D vector constant."), {}, VisualShaderNode::PORT_TYPE_VECTOR_2D));
- add_options.push_back(AddOption("Vector3Constant", "Vector", "Variables", "VisualShaderNodeVec3Constant", TTR("3D vector constant."), {}, VisualShaderNode::PORT_TYPE_VECTOR));
add_options.push_back(AddOption("Vector2Uniform", "Vector", "Variables", "VisualShaderNodeVec2Uniform", TTR("2D vector uniform."), {}, VisualShaderNode::PORT_TYPE_VECTOR_2D));
- add_options.push_back(AddOption("Vector3Uniform", "Vector", "Variables", "VisualShaderNodeVec3Uniform", TTR("3D vector uniform."), {}, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Vector3Constant", "Vector", "Variables", "VisualShaderNodeVec3Constant", TTR("3D vector constant."), {}, VisualShaderNode::PORT_TYPE_VECTOR_3D));
+ add_options.push_back(AddOption("Vector3Uniform", "Vector", "Variables", "VisualShaderNodeVec3Uniform", TTR("3D vector uniform."), {}, VisualShaderNode::PORT_TYPE_VECTOR_3D));
// SPECIAL
@@ -4981,6 +5441,10 @@ VisualShaderEditor::VisualShaderEditor() {
add_options.push_back(AddOption("Expression", "Special", "", "VisualShaderNodeExpression", TTR("Custom Godot Shader Language expression, with custom amount of input and output ports. This is a direct injection of code into the vertex/fragment/light function, do not use it to write the function declarations inside.")));
add_options.push_back(AddOption("GlobalExpression", "Special", "", "VisualShaderNodeGlobalExpression", TTR("Custom Godot Shader Language expression, which is placed on top of the resulted shader. You can place various function definitions inside and call it later in the Expressions. You can also declare varyings, uniforms and constants.")));
add_options.push_back(AddOption("UniformRef", "Special", "", "VisualShaderNodeUniformRef", TTR("A reference to an existing uniform.")));
+ add_options.push_back(AddOption("VaryingGetter", "Special", "", "VisualShaderNodeVaryingGetter", TTR("Get varying parameter."), {}, -1, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("VaryingSetter", "Special", "", "VisualShaderNodeVaryingSetter", TTR("Set varying parameter."), {}, -1, TYPE_FLAGS_VERTEX | TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("VaryingGetter", "Special", "", "VisualShaderNodeVaryingGetter", TTR("Get varying parameter."), {}, -1, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("VaryingSetter", "Special", "", "VisualShaderNodeVaryingSetter", TTR("Set varying parameter."), {}, -1, TYPE_FLAGS_VERTEX | TYPE_FLAGS_FRAGMENT, Shader::MODE_CANVAS_ITEM));
custom_node_option_idx = add_options.size();
@@ -5017,13 +5481,13 @@ void VisualShaderEditorPlugin::make_visible(bool p_visible) {
//editor->hide_animation_player_editors();
//editor->animation_panel_make_visible(true);
button->show();
- editor->make_bottom_panel_item_visible(visual_shader_editor);
- visual_shader_editor->update_custom_nodes();
+ EditorNode::get_singleton()->make_bottom_panel_item_visible(visual_shader_editor);
+ visual_shader_editor->update_nodes();
visual_shader_editor->set_process_input(true);
//visual_shader_editor->set_process(true);
} else {
if (visual_shader_editor->is_visible_in_tree()) {
- editor->hide_bottom_panel();
+ EditorNode::get_singleton()->hide_bottom_panel();
}
button->hide();
visual_shader_editor->set_process_input(false);
@@ -5031,12 +5495,11 @@ void VisualShaderEditorPlugin::make_visible(bool p_visible) {
}
}
-VisualShaderEditorPlugin::VisualShaderEditorPlugin(EditorNode *p_node) {
- editor = p_node;
+VisualShaderEditorPlugin::VisualShaderEditorPlugin() {
visual_shader_editor = memnew(VisualShaderEditor);
visual_shader_editor->set_custom_minimum_size(Size2(0, 300) * EDSCALE);
- button = editor->add_bottom_panel_item(TTR("VisualShader"), visual_shader_editor);
+ button = EditorNode::get_singleton()->add_bottom_panel_item(TTR("VisualShader"), visual_shader_editor);
button->hide();
}
@@ -5052,8 +5515,10 @@ class VisualShaderNodePluginInputEditor : public OptionButton {
public:
void _notification(int p_what) {
- if (p_what == NOTIFICATION_READY) {
- connect("item_selected", callable_mp(this, &VisualShaderNodePluginInputEditor::_item_selected));
+ switch (p_what) {
+ case NOTIFICATION_READY: {
+ connect("item_selected", callable_mp(this, &VisualShaderNodePluginInputEditor::_item_selected));
+ } break;
}
}
@@ -5093,6 +5558,82 @@ public:
////////////////
+class VisualShaderNodePluginVaryingEditor : public OptionButton {
+ GDCLASS(VisualShaderNodePluginVaryingEditor, OptionButton);
+
+ Ref<VisualShaderNodeVarying> varying;
+
+public:
+ void _notification(int p_what) {
+ if (p_what == NOTIFICATION_READY) {
+ connect("item_selected", callable_mp(this, &VisualShaderNodePluginVaryingEditor::_item_selected));
+ }
+ }
+
+ void _item_selected(int p_item) {
+ VisualShaderEditor *editor = VisualShaderEditor::get_singleton();
+ if (editor) {
+ editor->call_deferred(SNAME("_varying_select_item"), varying, get_item_text(p_item));
+ }
+ }
+
+ void setup(const Ref<VisualShaderNodeVarying> &p_varying, VisualShader::Type p_type) {
+ varying = p_varying;
+
+ Ref<Texture2D> type_icon[] = {
+ EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("float"), SNAME("EditorIcons")),
+ EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Vector2"), SNAME("EditorIcons")),
+ EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Vector3"), SNAME("EditorIcons")),
+ EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Color"), SNAME("EditorIcons")),
+ EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Transform3D"), SNAME("EditorIcons")),
+ };
+
+ bool is_getter = Ref<VisualShaderNodeVaryingGetter>(p_varying.ptr()).is_valid();
+
+ add_item("[None]");
+
+ int to_select = -1;
+ for (int i = 0, j = 0; i < varying->get_varyings_count(); i++) {
+ VisualShader::VaryingMode mode = varying->get_varying_mode_by_index(i);
+ if (is_getter) {
+ if (mode == VisualShader::VARYING_MODE_FRAG_TO_LIGHT) {
+ if (p_type != VisualShader::TYPE_LIGHT) {
+ j++;
+ continue;
+ }
+ } else {
+ if (p_type != VisualShader::TYPE_FRAGMENT && p_type != VisualShader::TYPE_LIGHT) {
+ j++;
+ continue;
+ }
+ }
+ } else {
+ if (mode == VisualShader::VARYING_MODE_FRAG_TO_LIGHT) {
+ if (p_type != VisualShader::TYPE_FRAGMENT) {
+ j++;
+ continue;
+ }
+ } else {
+ if (p_type != VisualShader::TYPE_VERTEX) {
+ j++;
+ continue;
+ }
+ }
+ }
+ if (varying->get_varying_name() == varying->get_varying_name_by_index(i)) {
+ to_select = i - j + 1;
+ }
+ add_icon_item(type_icon[varying->get_varying_type_by_index(i)], varying->get_varying_name_by_index(i));
+ }
+
+ if (to_select >= 0) {
+ select(to_select);
+ }
+ }
+};
+
+////////////////
+
class VisualShaderNodePluginUniformRefEditor : public OptionButton {
GDCLASS(VisualShaderNodePluginUniformRefEditor, OptionButton);
@@ -5100,8 +5641,10 @@ class VisualShaderNodePluginUniformRefEditor : public OptionButton {
public:
void _notification(int p_what) {
- if (p_what == NOTIFICATION_READY) {
- connect("item_selected", callable_mp(this, &VisualShaderNodePluginUniformRefEditor::_item_selected));
+ switch (p_what) {
+ case NOTIFICATION_READY: {
+ connect("item_selected", callable_mp(this, &VisualShaderNodePluginUniformRefEditor::_item_selected));
+ } break;
}
}
@@ -5269,18 +5812,24 @@ public:
};
Control *VisualShaderNodePluginDefault::create_editor(const Ref<Resource> &p_parent_resource, const Ref<VisualShaderNode> &p_node) {
+ Ref<VisualShader> p_shader = Ref<VisualShader>(p_parent_resource.ptr());
+
+ if (p_shader.is_valid() && (p_node->is_class("VisualShaderNodeVaryingGetter") || p_node->is_class("VisualShaderNodeVaryingSetter"))) {
+ VisualShaderNodePluginVaryingEditor *editor = memnew(VisualShaderNodePluginVaryingEditor);
+ editor->setup(p_node, p_shader->get_shader_type());
+ return editor;
+ }
+
if (p_node->is_class("VisualShaderNodeUniformRef")) {
- //create input
- VisualShaderNodePluginUniformRefEditor *uniform_editor = memnew(VisualShaderNodePluginUniformRefEditor);
- uniform_editor->setup(p_node);
- return uniform_editor;
+ VisualShaderNodePluginUniformRefEditor *editor = memnew(VisualShaderNodePluginUniformRefEditor);
+ editor->setup(p_node);
+ return editor;
}
if (p_node->is_class("VisualShaderNodeInput")) {
- //create input
- VisualShaderNodePluginInputEditor *input_editor = memnew(VisualShaderNodePluginInputEditor);
- input_editor->setup(p_node);
- return input_editor;
+ VisualShaderNodePluginInputEditor *editor = memnew(VisualShaderNodePluginInputEditor);
+ editor->setup(p_node);
+ return editor;
}
Vector<StringName> properties = p_node->get_editable_properties();
@@ -5397,8 +5946,24 @@ void EditorPropertyShaderMode::_option_selected(int p_which) {
}
}
- undo_redo->add_do_method(editor, "_update_options_menu");
- undo_redo->add_undo_method(editor, "_update_options_menu");
+ //4. delete varyings (if needed)
+ if (p_which == VisualShader::MODE_PARTICLES || p_which == VisualShader::MODE_SKY || p_which == VisualShader::MODE_FOG) {
+ int var_count = visual_shader->get_varyings_count();
+
+ if (var_count > 0) {
+ for (int i = 0; i < var_count; i++) {
+ const VisualShader::Varying *var = visual_shader->get_varying_by_index(i);
+ undo_redo->add_do_method(visual_shader.ptr(), "remove_varying", var->name);
+ undo_redo->add_undo_method(visual_shader.ptr(), "add_varying", var->name, var->mode, var->type);
+ }
+
+ undo_redo->add_do_method(editor, "_update_varyings");
+ undo_redo->add_undo_method(editor, "_update_varyings");
+ }
+ }
+
+ undo_redo->add_do_method(editor, "_update_nodes");
+ undo_redo->add_undo_method(editor, "_update_nodes");
undo_redo->add_do_method(editor, "_update_graph");
undo_redo->add_undo_method(editor, "_update_graph");
@@ -5514,29 +6079,31 @@ Size2 VisualShaderNodePortPreview::get_minimum_size() const {
}
void VisualShaderNodePortPreview::_notification(int p_what) {
- if (p_what == NOTIFICATION_DRAW) {
- Vector<Vector2> points = {
- Vector2(),
- Vector2(get_size().width, 0),
- get_size(),
- Vector2(0, get_size().height)
- };
-
- Vector<Vector2> uvs = {
- Vector2(0, 0),
- Vector2(1, 0),
- Vector2(1, 1),
- Vector2(0, 1)
- };
-
- Vector<Color> colors = {
- Color(1, 1, 1, 1),
- Color(1, 1, 1, 1),
- Color(1, 1, 1, 1),
- Color(1, 1, 1, 1)
- };
-
- draw_primitive(points, colors, uvs);
+ switch (p_what) {
+ case NOTIFICATION_DRAW: {
+ Vector<Vector2> points = {
+ Vector2(),
+ Vector2(get_size().width, 0),
+ get_size(),
+ Vector2(0, get_size().height)
+ };
+
+ Vector<Vector2> uvs = {
+ Vector2(0, 0),
+ Vector2(1, 0),
+ Vector2(1, 1),
+ Vector2(0, 1)
+ };
+
+ Vector<Color> colors = {
+ Color(1, 1, 1, 1),
+ Color(1, 1, 1, 1),
+ Color(1, 1, 1, 1),
+ Color(1, 1, 1, 1)
+ };
+
+ draw_primitive(points, colors, uvs);
+ } break;
}
}
diff --git a/editor/plugins/visual_shader_editor_plugin.h b/editor/plugins/visual_shader_editor_plugin.h
index c5037853cd..4087fc583c 100644
--- a/editor/plugins/visual_shader_editor_plugin.h
+++ b/editor/plugins/visual_shader_editor_plugin.h
@@ -31,13 +31,14 @@
#ifndef VISUAL_SHADER_EDITOR_PLUGIN_H
#define VISUAL_SHADER_EDITOR_PLUGIN_H
-#include "editor/editor_node.h"
#include "editor/editor_plugin.h"
#include "editor/plugins/curve_editor_plugin.h"
#include "editor/property_editor.h"
#include "scene/gui/button.h"
+#include "scene/gui/code_edit.h"
#include "scene/gui/graph_edit.h"
#include "scene/gui/popup.h"
+#include "scene/gui/rich_text_label.h"
#include "scene/gui/tree.h"
#include "scene/resources/visual_shader.h"
@@ -138,6 +139,8 @@ class VisualShaderEditor : public VBoxContainer {
Ref<VisualShader> visual_shader;
GraphEdit *graph = nullptr;
Button *add_node = nullptr;
+ Button *varying_button = nullptr;
+ PopupMenu *varying_options = nullptr;
Button *preview_shader = nullptr;
OptionButton *edit_type = nullptr;
@@ -168,6 +171,15 @@ class VisualShaderEditor : public VBoxContainer {
PopupMenu *constants_submenu = nullptr;
MenuButton *tools = nullptr;
+ ConfirmationDialog *add_varying_dialog = nullptr;
+ OptionButton *varying_type = nullptr;
+ LineEdit *varying_name = nullptr;
+ OptionButton *varying_mode = nullptr;
+ Label *varying_error_label = nullptr;
+
+ ConfirmationDialog *remove_varying_dialog = nullptr;
+ Tree *varyings = nullptr;
+
PopupPanel *comment_title_change_popup = nullptr;
LineEdit *comment_title_change_edit = nullptr;
@@ -231,6 +243,11 @@ class VisualShaderEditor : public VBoxContainer {
SET_COMMENT_DESCRIPTION,
};
+ enum class VaryingMenuOptions {
+ ADD,
+ REMOVE,
+ };
+
Tree *members = nullptr;
AcceptDialog *alert = nullptr;
LineEdit *node_filter = nullptr;
@@ -240,6 +257,12 @@ class VisualShaderEditor : public VBoxContainer {
void _tools_menu_option(int p_idx);
void _show_members_dialog(bool at_mouse_pos, VisualShaderNode::PortType p_input_port_type = VisualShaderNode::PORT_TYPE_MAX, VisualShaderNode::PortType p_output_port_type = VisualShaderNode::PORT_TYPE_MAX);
+ void _show_varying_menu();
+ void _varying_menu_id_pressed(int p_idx);
+ void _show_add_varying_dialog();
+ void _show_remove_varying_dialog();
+
+ void _update_nodes();
void _update_graph();
struct AddOption {
@@ -290,6 +313,8 @@ class VisualShaderEditor : public VBoxContainer {
void _setup_node(VisualShaderNode *p_node, const Vector<Variant> &p_ops);
void _add_node(int p_idx, const Vector<Variant> &p_ops, String p_resource_path = "", int p_node_idx = -1);
+ void _add_varying(const String &p_name, VisualShader::VaryingMode p_mode, VisualShader::VaryingType p_type);
+ void _remove_varying(const String &p_name);
void _update_options_menu();
void _set_mode(int p_which);
@@ -370,6 +395,7 @@ class VisualShaderEditor : public VBoxContainer {
String group_inputs;
String group_outputs;
String expression;
+ bool disabled = false;
};
void _dup_copy_nodes(int p_type, List<CopyItem> &r_nodes, List<VisualShader::Connection> &r_connections);
@@ -393,6 +419,7 @@ class VisualShaderEditor : public VBoxContainer {
void _input_select_item(Ref<VisualShaderNodeInput> input, String name);
void _uniform_select_item(Ref<VisualShaderNodeUniformRef> p_uniform, String p_name);
+ void _varying_select_item(Ref<VisualShaderNodeVarying> p_varying, String p_name);
void _float_constant_selected(int p_which);
@@ -424,6 +451,13 @@ class VisualShaderEditor : public VBoxContainer {
void _member_create();
void _member_cancel();
+ void _varying_create();
+ void _varying_name_changed(const String &p_text);
+ void _varying_deleted();
+ void _varying_selected();
+ void _varying_unselected();
+ void _update_varying_tree();
+
Vector2 menu_point;
void _node_menu_id_pressed(int p_idx);
@@ -435,6 +469,7 @@ class VisualShaderEditor : public VBoxContainer {
void _update_created_node(GraphNode *node);
void _update_uniforms(bool p_update_refs);
void _update_uniform_refs(Set<String> &p_names);
+ void _update_varyings();
void _visibility_changed();
@@ -443,7 +478,7 @@ protected:
static void _bind_methods();
public:
- void update_custom_nodes();
+ void update_nodes();
void add_plugin(const Ref<VisualShaderNodePlugin> &p_plugin);
void remove_plugin(const Ref<VisualShaderNodePlugin> &p_plugin);
@@ -462,7 +497,6 @@ class VisualShaderEditorPlugin : public EditorPlugin {
GDCLASS(VisualShaderEditorPlugin, EditorPlugin);
VisualShaderEditor *visual_shader_editor = nullptr;
- EditorNode *editor = nullptr;
Button *button = nullptr;
public:
@@ -472,7 +506,7 @@ public:
virtual bool handles(Object *p_object) const override;
virtual void make_visible(bool p_visible) override;
- VisualShaderEditorPlugin(EditorNode *p_node);
+ VisualShaderEditorPlugin();
~VisualShaderEditorPlugin();
};
diff --git a/editor/plugins/voxel_gi_editor_plugin.cpp b/editor/plugins/voxel_gi_editor_plugin.cpp
index cef29032b2..6fc6c1ad39 100644
--- a/editor/plugins/voxel_gi_editor_plugin.cpp
+++ b/editor/plugins/voxel_gi_editor_plugin.cpp
@@ -30,6 +30,9 @@
#include "voxel_gi_editor_plugin.h"
+#include "editor/editor_file_dialog.h"
+#include "editor/editor_node.h"
+
void VoxelGIEditorPlugin::_bake() {
if (voxel_gi) {
if (voxel_gi->get_probe_data().is_null()) {
@@ -62,41 +65,43 @@ bool VoxelGIEditorPlugin::handles(Object *p_object) const {
}
void VoxelGIEditorPlugin::_notification(int p_what) {
- if (p_what == NOTIFICATION_PROCESS) {
- if (!voxel_gi) {
- return;
- }
+ switch (p_what) {
+ case NOTIFICATION_PROCESS: {
+ if (!voxel_gi) {
+ return;
+ }
- // Set information tooltip on the Bake button. This information is useful
- // to optimize performance (video RAM size) and reduce light leaking (individual cell size).
+ // Set information tooltip on the Bake button. This information is useful
+ // to optimize performance (video RAM size) and reduce light leaking (individual cell size).
- const Vector3i size = voxel_gi->get_estimated_cell_size();
+ const Vector3i size = voxel_gi->get_estimated_cell_size();
- const Vector3 extents = voxel_gi->get_extents();
+ const Vector3 extents = voxel_gi->get_extents();
- const int data_size = 4;
- const double size_mb = size.x * size.y * size.z * data_size / (1024.0 * 1024.0);
- // Add a qualitative measurement to help the user assess whether a VoxelGI node is using a lot of VRAM.
- String size_quality;
- if (size_mb < 16.0) {
- size_quality = TTR("Low");
- } else if (size_mb < 64.0) {
- size_quality = TTR("Moderate");
- } else {
- size_quality = TTR("High");
- }
+ const int data_size = 4;
+ const double size_mb = size.x * size.y * size.z * data_size / (1024.0 * 1024.0);
+ // Add a qualitative measurement to help the user assess whether a VoxelGI node is using a lot of VRAM.
+ String size_quality;
+ if (size_mb < 16.0) {
+ size_quality = TTR("Low");
+ } else if (size_mb < 64.0) {
+ size_quality = TTR("Moderate");
+ } else {
+ size_quality = TTR("High");
+ }
- String text;
- text += vformat(TTR("Subdivisions: %s"), vformat(String::utf8("%d × %d × %d"), size.x, size.y, size.z)) + "\n";
- text += vformat(TTR("Cell size: %s"), vformat(String::utf8("%.3f × %.3f × %.3f"), extents.x / size.x, extents.y / size.y, extents.z / size.z)) + "\n";
- text += vformat(TTR("Video RAM size: %s MB (%s)"), String::num(size_mb, 2), size_quality);
+ String text;
+ text += vformat(TTR("Subdivisions: %s"), vformat(String::utf8("%d × %d × %d"), size.x, size.y, size.z)) + "\n";
+ text += vformat(TTR("Cell size: %s"), vformat(String::utf8("%.3f × %.3f × %.3f"), extents.x / size.x, extents.y / size.y, extents.z / size.z)) + "\n";
+ text += vformat(TTR("Video RAM size: %s MB (%s)"), String::num(size_mb, 2), size_quality);
- // Only update the tooltip when needed to avoid constant redrawing.
- if (bake->get_tooltip(Point2()) == text) {
- return;
- }
+ // Only update the tooltip when needed to avoid constant redrawing.
+ if (bake->get_tooltip(Point2()) == text) {
+ return;
+ }
- bake->set_tooltip(text);
+ bake->set_tooltip(text);
+ } break;
}
}
@@ -141,14 +146,13 @@ void VoxelGIEditorPlugin::_voxel_gi_save_path_and_bake(const String &p_path) {
void VoxelGIEditorPlugin::_bind_methods() {
}
-VoxelGIEditorPlugin::VoxelGIEditorPlugin(EditorNode *p_node) {
- editor = p_node;
+VoxelGIEditorPlugin::VoxelGIEditorPlugin() {
bake_hb = memnew(HBoxContainer);
bake_hb->set_h_size_flags(Control::SIZE_EXPAND_FILL);
bake_hb->hide();
bake = memnew(Button);
bake->set_flat(true);
- bake->set_icon(editor->get_gui_base()->get_theme_icon(SNAME("Bake"), SNAME("EditorIcons")));
+ bake->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Bake"), SNAME("EditorIcons")));
bake->set_text(TTR("Bake VoxelGI"));
bake->connect("pressed", callable_mp(this, &VoxelGIEditorPlugin::_bake));
bake_hb->add_child(bake);
diff --git a/editor/plugins/voxel_gi_editor_plugin.h b/editor/plugins/voxel_gi_editor_plugin.h
index 4c7865d868..67bd1d5105 100644
--- a/editor/plugins/voxel_gi_editor_plugin.h
+++ b/editor/plugins/voxel_gi_editor_plugin.h
@@ -31,11 +31,13 @@
#ifndef VOXEL_GIEDITORPLUGIN_H
#define VOXEL_GIEDITORPLUGIN_H
-#include "editor/editor_node.h"
#include "editor/editor_plugin.h"
#include "scene/3d/voxel_gi.h"
#include "scene/resources/material.h"
+class EditorFileDialog;
+struct EditorProgress;
+
class VoxelGIEditorPlugin : public EditorPlugin {
GDCLASS(VoxelGIEditorPlugin, EditorPlugin);
@@ -43,7 +45,6 @@ class VoxelGIEditorPlugin : public EditorPlugin {
HBoxContainer *bake_hb;
Button *bake;
- EditorNode *editor;
EditorFileDialog *probe_file;
@@ -66,7 +67,7 @@ public:
virtual bool handles(Object *p_object) const override;
virtual void make_visible(bool p_visible) override;
- VoxelGIEditorPlugin(EditorNode *p_node);
+ VoxelGIEditorPlugin();
~VoxelGIEditorPlugin();
};