diff options
Diffstat (limited to 'editor')
-rw-r--r-- | editor/animation_track_editor.cpp | 2 | ||||
-rw-r--r-- | editor/editor_audio_buses.cpp | 2 | ||||
-rw-r--r-- | editor/editor_data.cpp | 8 | ||||
-rw-r--r-- | editor/editor_file_dialog.cpp | 15 | ||||
-rw-r--r-- | editor/editor_inspector.cpp | 10 | ||||
-rw-r--r-- | editor/editor_spin_slider.cpp | 2 | ||||
-rw-r--r-- | editor/import/editor_scene_importer_gltf.cpp | 151 | ||||
-rw-r--r-- | editor/plugins/canvas_item_editor_plugin.cpp | 66 | ||||
-rw-r--r-- | editor/plugins/node_3d_editor_plugin.cpp | 6 | ||||
-rw-r--r-- | editor/plugins/node_3d_editor_plugin.h | 2 | ||||
-rw-r--r-- | editor/plugins/visual_shader_editor_plugin.cpp | 8 | ||||
-rw-r--r-- | editor/plugins/visual_shader_editor_plugin.h | 1 | ||||
-rw-r--r-- | editor/scene_tree_dock.cpp | 36 | ||||
-rw-r--r-- | editor/scene_tree_editor.cpp | 2 |
14 files changed, 200 insertions, 111 deletions
diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp index 39e863ae0f..52c984cbc0 100644 --- a/editor/animation_track_editor.cpp +++ b/editor/animation_track_editor.cpp @@ -5758,7 +5758,7 @@ AnimationTrackEditor::AnimationTrackEditor() { box_selection = memnew(Control); add_child(box_selection); - box_selection->set_as_toplevel(true); + box_selection->set_as_top_level(true); box_selection->set_mouse_filter(MOUSE_FILTER_IGNORE); box_selection->hide(); box_selection->connect("draw", callable_mp(this, &AnimationTrackEditor::_box_selection_draw)); diff --git a/editor/editor_audio_buses.cpp b/editor/editor_audio_buses.cpp index adb09532eb..a3deb95130 100644 --- a/editor/editor_audio_buses.cpp +++ b/editor/editor_audio_buses.cpp @@ -846,7 +846,7 @@ EditorAudioBus::EditorAudioBus(EditorAudioBuses *p_buses, bool p_is_master) { audioprev_hbc->add_child(audio_value_preview_label); slider->add_child(audio_value_preview_box); - audio_value_preview_box->set_as_toplevel(true); + audio_value_preview_box->set_as_top_level(true); Ref<StyleBoxFlat> panel_style = memnew(StyleBoxFlat); panel_style->set_bg_color(Color(0.0f, 0.0f, 0.0f, 0.8f)); audio_value_preview_box->add_theme_style_override("panel", panel_style); diff --git a/editor/editor_data.cpp b/editor/editor_data.cpp index 5118ccacad..1002c4917b 100644 --- a/editor/editor_data.cpp +++ b/editor/editor_data.cpp @@ -936,7 +936,13 @@ void EditorData::script_class_save_icon_paths() { } } - ProjectSettings::get_singleton()->set("_global_script_class_icons", d); + if (d.empty()) { + if (ProjectSettings::get_singleton()->has_setting("_global_script_class_icons")) { + ProjectSettings::get_singleton()->clear("_global_script_class_icons"); + } + } else { + ProjectSettings::get_singleton()->set("_global_script_class_icons", d); + } ProjectSettings::get_singleton()->save(); } diff --git a/editor/editor_file_dialog.cpp b/editor/editor_file_dialog.cpp index ba9f27f65f..2140b6bd13 100644 --- a/editor/editor_file_dialog.cpp +++ b/editor/editor_file_dialog.cpp @@ -60,7 +60,7 @@ VBoxContainer *EditorFileDialog::get_vbox() { void EditorFileDialog::_notification(int p_what) { if (p_what == NOTIFICATION_READY || p_what == NOTIFICATION_THEME_CHANGED) { - // update icons + // Update icons. mode_thumbnails->set_icon(item_list->get_theme_icon("FileThumbnail", "EditorIcons")); mode_list->set_icon(item_list->get_theme_icon("FileList", "EditorIcons")); dir_prev->set_icon(item_list->get_theme_icon("Back", "EditorIcons")); @@ -94,7 +94,7 @@ void EditorFileDialog::_notification(int p_what) { } set_display_mode((DisplayMode)EditorSettings::get_singleton()->get("filesystem/file_dialog/display_mode").operator int()); - // update icons + // Update icons. mode_thumbnails->set_icon(item_list->get_theme_icon("FileThumbnail", "EditorIcons")); mode_list->set_icon(item_list->get_theme_icon("FileList", "EditorIcons")); dir_prev->set_icon(item_list->get_theme_icon("Back", "EditorIcons")); @@ -138,9 +138,7 @@ void EditorFileDialog::_unhandled_input(const Ref<InputEvent> &p_event) { handled = true; } if (ED_IS_SHORTCUT("file_dialog/toggle_hidden_files", p_event)) { - bool show = !show_hidden_files; - set_show_hidden_files(show); - EditorSettings::get_singleton()->set("filesystem/file_dialog/show_hidden_files", show); + set_show_hidden_files(!show_hidden_files); handled = true; } if (ED_IS_SHORTCUT("file_dialog/toggle_favorite", p_event)) { @@ -1385,6 +1383,11 @@ void EditorFileDialog::_bind_methods() { } void EditorFileDialog::set_show_hidden_files(bool p_show) { + if (p_show == show_hidden_files) { + return; + } + + EditorSettings::get_singleton()->set("filesystem/file_dialog/show_hidden_files", p_show); show_hidden_files = p_show; show_hidden->set_pressed(p_show); invalidate(); @@ -1646,7 +1649,7 @@ EditorFileDialog::EditorFileDialog() { filter->connect("item_selected", callable_mp(this, &EditorFileDialog::_filter_selected)); confirm_save = memnew(ConfirmationDialog); - //confirm_save->set_as_toplevel(true); + //confirm_save->set_as_top_level(true); add_child(confirm_save); confirm_save->connect("confirmed", callable_mp(this, &EditorFileDialog::_save_confirm_pressed)); diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp index 2e716a636e..9900e8184d 100644 --- a/editor/editor_inspector.cpp +++ b/editor/editor_inspector.cpp @@ -48,7 +48,7 @@ Size2 EditorProperty::get_minimum_size() const { if (!c) { continue; } - if (c->is_set_as_toplevel()) { + if (c->is_set_as_top_level()) { continue; } if (!c->is_visible()) { @@ -117,7 +117,7 @@ void EditorProperty::_notification(int p_what) { if (!c) { continue; } - if (c->is_set_as_toplevel()) { + if (c->is_set_as_top_level()) { continue; } if (c == bottom_editor) { @@ -179,7 +179,7 @@ void EditorProperty::_notification(int p_what) { if (!c) { continue; } - if (c->is_set_as_toplevel()) { + if (c->is_set_as_top_level()) { continue; } if (c == bottom_editor) { @@ -1133,7 +1133,7 @@ void EditorInspectorSection::_notification(int p_what) { if (!c) { continue; } - if (c->is_set_as_toplevel()) { + if (c->is_set_as_top_level()) { continue; } if (!c->is_visible_in_tree()) { @@ -1225,7 +1225,7 @@ Size2 EditorInspectorSection::get_minimum_size() const { if (!c) { continue; } - if (c->is_set_as_toplevel()) { + if (c->is_set_as_top_level()) { continue; } if (!c->is_visible()) { diff --git a/editor/editor_spin_slider.cpp b/editor/editor_spin_slider.cpp index ac61a75a6c..efc966c6c4 100644 --- a/editor/editor_spin_slider.cpp +++ b/editor/editor_spin_slider.cpp @@ -483,7 +483,7 @@ EditorSpinSlider::EditorSpinSlider() { grabber = memnew(TextureRect); add_child(grabber); grabber->hide(); - grabber->set_as_toplevel(true); + grabber->set_as_top_level(true); grabber->set_mouse_filter(MOUSE_FILTER_STOP); grabber->connect("mouse_entered", callable_mp(this, &EditorSpinSlider::_grabber_mouse_entered)); grabber->connect("mouse_exited", callable_mp(this, &EditorSpinSlider::_grabber_mouse_exited)); diff --git a/editor/import/editor_scene_importer_gltf.cpp b/editor/import/editor_scene_importer_gltf.cpp index 8caa4aeeaf..266df78949 100644 --- a/editor/import/editor_scene_importer_gltf.cpp +++ b/editor/import/editor_scene_importer_gltf.cpp @@ -184,8 +184,11 @@ String EditorSceneImporterGLTF::_gen_unique_name(GLTFState &state, const String String EditorSceneImporterGLTF::_sanitize_bone_name(const String &name) { String p_name = name.camelcase_to_underscore(true); - RegEx pattern_del("([^a-zA-Z0-9_ ])+"); - p_name = pattern_del.sub(p_name, "", true); + RegEx pattern_nocolon(":"); + p_name = pattern_nocolon.sub(p_name, "_", true); + + RegEx pattern_noslash("/"); + p_name = pattern_noslash.sub(p_name, "_", true); RegEx pattern_nospace(" +"); p_name = pattern_nospace.sub(p_name, "_", true); @@ -200,8 +203,10 @@ String EditorSceneImporterGLTF::_sanitize_bone_name(const String &name) { } String EditorSceneImporterGLTF::_gen_unique_bone_name(GLTFState &state, const GLTFSkeletonIndex skel_i, const String &p_name) { - const String s_name = _sanitize_bone_name(p_name); - + String s_name = _sanitize_bone_name(p_name); + if (s_name.empty()) { + s_name = "bone"; + } String name; int index = 1; while (true) { @@ -379,13 +384,17 @@ Error EditorSceneImporterGLTF::_parse_buffers(GLTFState &state, const String &p_ Vector<uint8_t> buffer_data; String uri = buffer["uri"]; - if (uri.findn("data:application/octet-stream;base64") == 0) { - //embedded data + if (uri.begins_with("data:")) { // Embedded data using base64. + // Validate data MIME types and throw an error if it's one we don't know/support. + if (!uri.begins_with("data:application/octet-stream;base64") && + !uri.begins_with("data:application/gltf-buffer;base64")) { + ERR_PRINT("glTF: Got buffer with an unknown URI data type: " + uri); + } buffer_data = _parse_base64_uri(uri); - } else { - uri = p_base_path.plus_file(uri).replace("\\", "/"); //fix for windows + } else { // Relative path to an external image file. + uri = p_base_path.plus_file(uri).replace("\\", "/"); // Fix for Windows. buffer_data = FileAccess::get_file_as_array(uri); - ERR_FAIL_COND_V(buffer.size() == 0, ERR_PARSE_ERROR); + ERR_FAIL_COND_V_MSG(buffer.size() == 0, ERR_PARSE_ERROR, "glTF: Couldn't load binary file as an array: " + uri); } ERR_FAIL_COND_V(!buffer.has("byteLength"), ERR_PARSE_ERROR); @@ -1261,12 +1270,28 @@ Error EditorSceneImporterGLTF::_parse_images(GLTFState &state, const String &p_b return OK; } + // Ref: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#images + const Array &images = state.json["images"]; for (int i = 0; i < images.size(); i++) { const Dictionary &d = images[i]; + // glTF 2.0 supports PNG and JPEG types, which can be specified as (from spec): + // "- a URI to an external file in one of the supported images formats, or + // - a URI with embedded base64-encoded data, or + // - a reference to a bufferView; in that case mimeType must be defined." + // Since mimeType is optional for external files and base64 data, we'll have to + // fall back on letting Godot parse the data to figure out if it's PNG or JPEG. + + // We'll assume that we use either URI or bufferView, so let's warn the user + // if their image somehow uses both. And fail if it has neither. + ERR_CONTINUE_MSG(!d.has("uri") && !d.has("bufferView"), "Invalid image definition in glTF file, it should specific an 'uri' or 'bufferView'."); + if (d.has("uri") && d.has("bufferView")) { + WARN_PRINT("Invalid image definition in glTF file using both 'uri' and 'bufferView'. 'bufferView' will take precedence."); + } + String mimetype; - if (d.has("mimeType")) { + if (d.has("mimeType")) { // Should be "image/png" or "image/jpeg". mimetype = d["mimeType"]; } @@ -1275,23 +1300,52 @@ Error EditorSceneImporterGLTF::_parse_images(GLTFState &state, const String &p_b int data_size = 0; if (d.has("uri")) { + // Handles the first two bullet points from the spec (embedded data, or external file). String uri = d["uri"]; - if (uri.findn("data:application/octet-stream;base64") == 0 || - uri.findn("data:" + mimetype + ";base64") == 0) { - //embedded data + if (uri.begins_with("data:")) { // Embedded data using base64. + // Validate data MIME types and throw an error if it's one we don't know/support. + if (!uri.begins_with("data:application/octet-stream;base64") && + !uri.begins_with("data:application/gltf-buffer;base64") && + !uri.begins_with("data:image/png;base64") && + !uri.begins_with("data:image/jpeg;base64")) { + ERR_PRINT("glTF: Got image data with an unknown URI data type: " + uri); + } data = _parse_base64_uri(uri); data_ptr = data.ptr(); data_size = data.size(); - } else { - uri = p_base_path.plus_file(uri).replace("\\", "/"); //fix for windows - Ref<Texture2D> texture = ResourceLoader::load(uri); - state.images.push_back(texture); - continue; + // mimeType is optional, but if we have it defined in the URI, let's use it. + if (mimetype.empty()) { + if (uri.begins_with("data:image/png;base64")) { + mimetype = "image/png"; + } else if (uri.begins_with("data:image/jpeg;base64")) { + mimetype = "image/jpeg"; + } + } + } else { // Relative path to an external image file. + uri = p_base_path.plus_file(uri).replace("\\", "/"); // Fix for Windows. + // The spec says that if mimeType is defined, we should enforce it. + // So we should only rely on ResourceLoader::load if mimeType is not defined, + // otherwise we should use the same logic as for buffers. + if (mimetype == "image/png" || mimetype == "image/jpeg") { + // Load data buffer and rely on PNG and JPEG-specific logic below to load the image. + // This makes it possible to load a file with a wrong extension but correct MIME type, + // e.g. "foo.jpg" containing PNG data and with MIME type "image/png". ResourceLoader would fail. + data = FileAccess::get_file_as_array(uri); + ERR_FAIL_COND_V_MSG(data.size() == 0, ERR_PARSE_ERROR, "glTF: Couldn't load image file as an array: " + uri); + data_ptr = data.ptr(); + data_size = data.size(); + } else { + // Good old ResourceLoader will rely on file extension. + Ref<Texture2D> texture = ResourceLoader::load(uri); + state.images.push_back(texture); + continue; + } } - } + } else if (d.has("bufferView")) { + // Handles the third bullet point from the spec (bufferView). + ERR_FAIL_COND_V_MSG(mimetype.empty(), ERR_FILE_CORRUPT, "glTF: Image specifies 'bufferView' but no 'mimeType', which is invalid."); - if (d.has("bufferView")) { const GLTFBufferViewIndex bvi = d["bufferView"]; ERR_FAIL_INDEX_V(bvi, state.buffer_views.size(), ERR_PARAMETER_RANGE_ERROR); @@ -1307,45 +1361,36 @@ Error EditorSceneImporterGLTF::_parse_images(GLTFState &state, const String &p_b data_size = bv.byte_length; } - ERR_FAIL_COND_V(mimetype == "", ERR_FILE_CORRUPT); + Ref<Image> img; - if (mimetype.findn("png") != -1) { - //is a png + if (mimetype == "image/png") { // Load buffer as PNG. ERR_FAIL_COND_V(Image::_png_mem_loader_func == nullptr, ERR_UNAVAILABLE); - - const Ref<Image> img = Image::_png_mem_loader_func(data_ptr, data_size); - - ERR_FAIL_COND_V(img.is_null(), ERR_FILE_CORRUPT); - - Ref<ImageTexture> t; - t.instance(); - t->create_from_image(img); - - state.images.push_back(t); - continue; - } - - if (mimetype.findn("jpeg") != -1) { - //is a jpg + img = Image::_png_mem_loader_func(data_ptr, data_size); + } else if (mimetype == "image/jpeg") { // Loader buffer as JPEG. ERR_FAIL_COND_V(Image::_jpg_mem_loader_func == nullptr, ERR_UNAVAILABLE); + img = Image::_jpg_mem_loader_func(data_ptr, data_size); + } else { + // We can land here if we got an URI with base64-encoded data with application/* MIME type, + // and the optional mimeType property was not defined to tell us how to handle this data (or was invalid). + // So let's try PNG first, then JPEG. + ERR_FAIL_COND_V(Image::_png_mem_loader_func == nullptr, ERR_UNAVAILABLE); + img = Image::_png_mem_loader_func(data_ptr, data_size); + if (img.is_null()) { + ERR_FAIL_COND_V(Image::_jpg_mem_loader_func == nullptr, ERR_UNAVAILABLE); + img = Image::_jpg_mem_loader_func(data_ptr, data_size); + } + } - const Ref<Image> img = Image::_jpg_mem_loader_func(data_ptr, data_size); - - ERR_FAIL_COND_V(img.is_null(), ERR_FILE_CORRUPT); - - Ref<ImageTexture> t; - t.instance(); - t->create_from_image(img); - - state.images.push_back(t); + ERR_FAIL_COND_V_MSG(img.is_null(), ERR_FILE_CORRUPT, "glTF: Couldn't load image with its given mimetype: " + mimetype); - continue; - } + Ref<ImageTexture> t; + t.instance(); + t->create_from_image(img); - ERR_FAIL_V(ERR_FILE_CORRUPT); + state.images.push_back(t); } - print_verbose("Total images: " + itos(state.images.size())); + print_verbose("glTF: Total images: " + itos(state.images.size())); return OK; } @@ -1505,7 +1550,7 @@ Error EditorSceneImporterGLTF::_parse_materials(GLTFState &state) { state.materials.push_back(material); } - print_verbose("Total materials: " + itos(state.materials.size())); + print_verbose("glTF: Total materials: " + itos(state.materials.size())); return OK; } @@ -3056,6 +3101,8 @@ Node3D *EditorSceneImporterGLTF::_generate_scene(GLTFState &state, const int p_b } Node *EditorSceneImporterGLTF::import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, List<String> *r_missing_deps, Error *r_err) { + print_verbose(vformat("glTF: Importing file %s as scene.", p_path)); + GLTFState state; if (p_path.to_lower().ends_with("glb")) { diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index 402ec5d80d..c06580df26 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -548,7 +548,7 @@ void CanvasItemEditor::_expand_encompassing_rect_using_children(Rect2 &r_rect, c const CanvasItem *canvas_item = Object::cast_to<CanvasItem>(p_node); for (int i = p_node->get_child_count() - 1; i >= 0; i--) { - if (canvas_item && !canvas_item->is_set_as_toplevel()) { + if (canvas_item && !canvas_item->is_set_as_top_level()) { _expand_encompassing_rect_using_children(r_rect, p_node->get_child(i), r_first, p_parent_xform * canvas_item->get_transform(), p_canvas_xform); } else { const CanvasLayer *canvas_layer = Object::cast_to<CanvasLayer>(p_node); @@ -591,7 +591,7 @@ void CanvasItemEditor::_find_canvas_items_at_pos(const Point2 &p_pos, Node *p_no for (int i = p_node->get_child_count() - 1; i >= 0; i--) { if (canvas_item) { - if (!canvas_item->is_set_as_toplevel()) { + if (!canvas_item->is_set_as_top_level()) { _find_canvas_items_at_pos(p_pos, p_node->get_child(i), r_items, p_parent_xform * canvas_item->get_transform(), p_canvas_xform); } else { _find_canvas_items_at_pos(p_pos, p_node->get_child(i), r_items, canvas_item->get_transform(), p_canvas_xform); @@ -767,7 +767,7 @@ void CanvasItemEditor::_find_canvas_items_in_rect(const Rect2 &p_rect, Node *p_n if (!lock_children || !editable) { for (int i = p_node->get_child_count() - 1; i >= 0; i--) { if (canvas_item) { - if (!canvas_item->is_set_as_toplevel()) { + if (!canvas_item->is_set_as_top_level()) { _find_canvas_items_in_rect(p_rect, p_node->get_child(i), r_items, p_parent_xform * canvas_item->get_transform(), p_canvas_xform); } else { _find_canvas_items_in_rect(p_rect, p_node->get_child(i), r_items, canvas_item->get_transform(), p_canvas_xform); @@ -2599,12 +2599,28 @@ void CanvasItemEditor::_gui_input_viewport(const Ref<InputEvent> &p_event) { } void CanvasItemEditor::_update_cursor() { - CursorShape c = CURSOR_ARROW; - bool should_switch = false; - if (drag_selection.size() != 0) { - float angle = drag_selection[0]->_edit_get_rotation(); - should_switch = abs(Math::cos(angle)) < Math_SQRT12; + // Compute an eventual rotation of the cursor + CursorShape rotation_array[4] = { CURSOR_HSIZE, CURSOR_BDIAGSIZE, CURSOR_VSIZE, CURSOR_FDIAGSIZE }; + int rotation_array_index = 0; + + List<CanvasItem *> selection = _get_edited_canvas_items(); + if (selection.size() == 1) { + float angle = Math::fposmod((double)selection[0]->get_global_transform_with_canvas().get_rotation(), Math_PI); + if (angle > Math_PI * 7.0 / 8.0) { + rotation_array_index = 0; + } else if (angle > Math_PI * 5.0 / 8.0) { + rotation_array_index = 1; + } else if (angle > Math_PI * 3.0 / 8.0) { + rotation_array_index = 2; + } else if (angle > Math_PI * 1.0 / 8.0) { + rotation_array_index = 3; + } else { + rotation_array_index = 0; + } } + + // Choose the correct cursor + CursorShape c = CURSOR_ARROW; switch (drag_type) { case DRAG_NONE: switch (tool) { @@ -2626,38 +2642,28 @@ void CanvasItemEditor::_update_cursor() { break; case DRAG_LEFT: case DRAG_RIGHT: + c = rotation_array[rotation_array_index]; + break; case DRAG_V_GUIDE: - if (should_switch) { - c = CURSOR_VSIZE; - } else { - c = CURSOR_HSIZE; - } + c = CURSOR_HSIZE; break; case DRAG_TOP: case DRAG_BOTTOM: + c = rotation_array[(rotation_array_index + 2) % 4]; + break; case DRAG_H_GUIDE: - if (should_switch) { - c = CURSOR_HSIZE; - } else { - c = CURSOR_VSIZE; - } + c = CURSOR_VSIZE; break; case DRAG_TOP_LEFT: case DRAG_BOTTOM_RIGHT: + c = rotation_array[(rotation_array_index + 3) % 4]; + break; case DRAG_DOUBLE_GUIDE: - if (should_switch) { - c = CURSOR_BDIAGSIZE; - } else { - c = CURSOR_FDIAGSIZE; - } + c = CURSOR_FDIAGSIZE; break; case DRAG_TOP_RIGHT: case DRAG_BOTTOM_LEFT: - if (should_switch) { - c = CURSOR_FDIAGSIZE; - } else { - c = CURSOR_BDIAGSIZE; - } + c = rotation_array[(rotation_array_index + 1) % 4]; break; case DRAG_MOVE: c = CURSOR_MOVE; @@ -3620,7 +3626,7 @@ void CanvasItemEditor::_draw_invisible_nodes_positions(Node *p_node, const Trans Transform2D parent_xform = p_parent_xform; Transform2D canvas_xform = p_canvas_xform; - if (canvas_item && !canvas_item->is_set_as_toplevel()) { + if (canvas_item && !canvas_item->is_set_as_top_level()) { parent_xform = parent_xform * canvas_item->get_transform(); } else { CanvasLayer *cl = Object::cast_to<CanvasLayer>(p_node); @@ -3689,7 +3695,7 @@ void CanvasItemEditor::_draw_locks_and_groups(Node *p_node, const Transform2D &p Transform2D parent_xform = p_parent_xform; Transform2D canvas_xform = p_canvas_xform; - if (canvas_item && !canvas_item->is_set_as_toplevel()) { + if (canvas_item && !canvas_item->is_set_as_top_level()) { parent_xform = parent_xform * canvas_item->get_transform(); } else { CanvasLayer *cl = Object::cast_to<CanvasLayer>(p_node); diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index 944bf9913c..b2fd855834 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -3566,7 +3566,7 @@ Vector3 Node3DEditorViewport::_get_instance_position(const Point2 &p_pos) const return point + offset; } -AABB Node3DEditorViewport::_calculate_spatial_bounds(const Node3D *p_parent, bool p_exclude_toplevel_transform) { +AABB Node3DEditorViewport::_calculate_spatial_bounds(const Node3D *p_parent, bool p_exclude_top_level_transform) { AABB bounds; const MeshInstance3D *mesh_instance = Object::cast_to<MeshInstance3D>(p_parent); @@ -3591,7 +3591,7 @@ AABB Node3DEditorViewport::_calculate_spatial_bounds(const Node3D *p_parent, boo bounds = AABB(Vector3(-0.2, -0.2, -0.2), Vector3(0.4, 0.4, 0.4)); } - if (!p_exclude_toplevel_transform) { + if (!p_exclude_top_level_transform) { bounds = p_parent->get_transform().xform(bounds); } @@ -6810,7 +6810,7 @@ void EditorNode3DGizmoPlugin::_bind_methods() { ClassDB::bind_method(D_METHOD("get_material", "name", "gizmo"), &EditorNode3DGizmoPlugin::get_material); //, DEFVAL(Ref<EditorNode3DGizmo>())); BIND_VMETHOD(MethodInfo(Variant::STRING, "get_name")); - BIND_VMETHOD(MethodInfo(Variant::STRING, "get_priority")); + BIND_VMETHOD(MethodInfo(Variant::INT, "get_priority")); BIND_VMETHOD(MethodInfo(Variant::BOOL, "can_be_hidden")); BIND_VMETHOD(MethodInfo(Variant::BOOL, "is_selectable_when_hidden")); diff --git a/editor/plugins/node_3d_editor_plugin.h b/editor/plugins/node_3d_editor_plugin.h index b3dc4ef5f2..4f627b1d0c 100644 --- a/editor/plugins/node_3d_editor_plugin.h +++ b/editor/plugins/node_3d_editor_plugin.h @@ -450,7 +450,7 @@ private: Point2i _get_warped_mouse_motion(const Ref<InputEventMouseMotion> &p_ev_mouse_motion) const; Vector3 _get_instance_position(const Point2 &p_pos) const; - static AABB _calculate_spatial_bounds(const Node3D *p_parent, bool p_exclude_toplevel_transform = true); + static AABB _calculate_spatial_bounds(const Node3D *p_parent, bool p_exclude_top_level_transform = true); void _create_preview(const Vector<String> &files) const; void _remove_preview(); bool _cyclical_dependency_exists(const String &p_target_scene_path, Node *p_desired_node); diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp index 35e8f560b0..1651de4048 100644 --- a/editor/plugins/visual_shader_editor_plugin.cpp +++ b/editor/plugins/visual_shader_editor_plugin.cpp @@ -226,6 +226,13 @@ void VisualShaderGraphPlugin::update_constant(VisualShader::Type p_type, int p_n links[p_node_id].graph_node->set_size(Size2(-1, -1)); } +void VisualShaderGraphPlugin::update_node_size(int p_node_id) { + if (!links.has(p_node_id)) { + return; + } + links[p_node_id].graph_node->set_size(Size2(-1, -1)); +} + void VisualShaderGraphPlugin::register_default_input_button(int p_node_id, int p_port_id, Button *p_button) { links[p_node_id].input_ports.insert(p_port_id, { p_button }); } @@ -2516,6 +2523,7 @@ void VisualShaderEditor::_uniform_select_item(Ref<VisualShaderNodeUniformRef> p_ void VisualShaderEditor::_float_constant_selected(int p_index, int p_node) { if (p_index == 0) { + graph_plugin->update_node_size(p_node); return; } diff --git a/editor/plugins/visual_shader_editor_plugin.h b/editor/plugins/visual_shader_editor_plugin.h index 60a354d1fd..d43af82238 100644 --- a/editor/plugins/visual_shader_editor_plugin.h +++ b/editor/plugins/visual_shader_editor_plugin.h @@ -111,6 +111,7 @@ public: void set_uniform_name(VisualShader::Type p_type, int p_node_id, const String &p_name); void update_constant(VisualShader::Type p_type, int p_node_id); int get_constant_index(float p_constant) const; + void update_node_size(int p_node_id); VisualShader::Type get_shader_type() const; VisualShaderGraphPlugin(); diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp index d9c95b1944..75dc840738 100644 --- a/editor/scene_tree_dock.cpp +++ b/editor/scene_tree_dock.cpp @@ -1318,32 +1318,50 @@ void SceneTreeDock::perform_node_renames(Node *p_base, List<Pair<NodePath, NodeP if (si) { List<PropertyInfo> properties; si->get_property_list(&properties); + NodePath root_path = p_base->get_path(); for (List<PropertyInfo>::Element *E = properties.front(); E; E = E->next()) { String propertyname = E->get().name; Variant p = p_base->get(propertyname); if (p.get_type() == Variant::NODE_PATH) { - // Goes through all paths to check if its matching + NodePath root_path_new = root_path; for (List<Pair<NodePath, NodePath>>::Element *F = p_renames->front(); F; F = F->next()) { - NodePath root_path = p_base->get_path(); + if (root_path == F->get().first) { + root_path_new = F->get().second; + break; + } + } + // Goes through all paths to check if its matching + for (List<Pair<NodePath, NodePath>>::Element *F = p_renames->front(); F; F = F->next()) { NodePath rel_path_old = root_path.rel_path_to(F->get().first); - NodePath rel_path_new = F->get().second; - - // if not empty, get new relative path - if (F->get().second != NodePath()) { - rel_path_new = root_path.rel_path_to(F->get().second); - } - // if old path detected, then it needs to be replaced with the new one if (p == rel_path_old) { + NodePath rel_path_new = F->get().second; + + // if not empty, get new relative path + if (!rel_path_new.is_empty()) { + rel_path_new = root_path_new.rel_path_to(F->get().second); + } + editor_data->get_undo_redo().add_do_property(p_base, propertyname, rel_path_new); editor_data->get_undo_redo().add_undo_property(p_base, propertyname, rel_path_old); p_base->set(propertyname, rel_path_new); break; } + + // update if the node itself moved up/down the tree hirarchy + if (root_path == F->get().first) { + NodePath abs_path = NodePath(String(root_path).plus_file(p)).simplified(); + NodePath rel_path_new = F->get().second.rel_path_to(abs_path); + + editor_data->get_undo_redo().add_do_property(p_base, propertyname, rel_path_new); + editor_data->get_undo_redo().add_undo_property(p_base, propertyname, p); + + p_base->set(propertyname, rel_path_new); + } } } } diff --git a/editor/scene_tree_editor.cpp b/editor/scene_tree_editor.cpp index 5a504da397..3dee4a229f 100644 --- a/editor/scene_tree_editor.cpp +++ b/editor/scene_tree_editor.cpp @@ -251,7 +251,7 @@ bool SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) { if (can_rename) { //should be can edit.. String warning = p_node->get_configuration_warning(); - if (warning != String()) { + if (!warning.empty()) { item->add_button(0, get_theme_icon("NodeWarning", "EditorIcons"), BUTTON_WARNING, false, TTR("Node configuration warning:") + "\n" + p_node->get_configuration_warning()); } |