diff options
Diffstat (limited to 'editor')
-rw-r--r-- | editor/create_dialog.cpp | 1 | ||||
-rw-r--r-- | editor/editor_node.cpp | 3 | ||||
-rw-r--r-- | editor/plugins/canvas_item_editor_plugin.cpp | 44 | ||||
-rw-r--r-- | editor/plugins/canvas_item_editor_plugin.h | 10 | ||||
-rw-r--r-- | editor/plugins/node_3d_editor_plugin.cpp | 12 | ||||
-rw-r--r-- | editor/plugins/tile_map_editor_plugin.cpp | 19 | ||||
-rw-r--r-- | editor/scene_tree_dock.cpp | 49 | ||||
-rw-r--r-- | editor/scene_tree_dock.h | 5 |
8 files changed, 128 insertions, 15 deletions
diff --git a/editor/create_dialog.cpp b/editor/create_dialog.cpp index a9ed1bc2b9..711072f4b2 100644 --- a/editor/create_dialog.cpp +++ b/editor/create_dialog.cpp @@ -170,6 +170,7 @@ void CreateDialog::_update_search() { root->set_text(0, base_type); root->set_icon(0, search_options->get_theme_icon(icon_fallback, "EditorIcons")); search_options_types[base_type] = root; + _configure_search_option_item(root, base_type, ClassDB::class_exists(base_type)); const String search_text = search_box->get_text(); bool empty_search = search_text == ""; diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 4cf85a8caf..f0e53e7ef5 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -902,7 +902,8 @@ void EditorNode::_scan_external_changes() { // Check if any edited scene has changed. for (int i = 0; i < editor_data.get_edited_scene_count(); i++) { - if (editor_data.get_scene_path(i) == "") { + DirAccessRef da = DirAccess::create(DirAccess::ACCESS_RESOURCES); + if (editor_data.get_scene_path(i) == "" || !da->file_exists(editor_data.get_scene_path(i))) { continue; } diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index 28926d18c2..82ebf48242 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -1021,6 +1021,32 @@ void CanvasItemEditor::_selection_menu_hide() { selection_menu->set_size(Vector2(0, 0)); } +void CanvasItemEditor::_add_node_pressed(int p_result) { + if (p_result == AddNodeOption::ADD_NODE) { + editor->get_scene_tree_dock()->open_add_child_dialog(); + } else if (p_result == AddNodeOption::ADD_INSTANCE) { + editor->get_scene_tree_dock()->open_instance_child_dialog(); + } +} + +void CanvasItemEditor::_node_created(Node *p_node) { + if (node_create_position == Point2()) { + return; + } + + CanvasItem *c = Object::cast_to<CanvasItem>(p_node); + if (c) { + Transform2D xform = c->get_global_transform_with_canvas().affine_inverse() * c->get_transform(); + c->_edit_set_position(xform.xform(node_create_position)); + } + + call_deferred("_reset_create_position"); // Defer the call in case more than one node is added. +} + +void CanvasItemEditor::_reset_create_position() { + node_create_position = Point2(); +} + bool CanvasItemEditor::_gui_input_rulers_and_guides(const Ref<InputEvent> &p_event) { Ref<InputEventMouseButton> b = p_event; Ref<InputEventMouseMotion> m = p_event; @@ -2463,6 +2489,14 @@ bool CanvasItemEditor::_gui_input_select(const Ref<InputEvent> &p_event) { } } + if (b.is_valid() && b->is_pressed() && b->get_button_index() == BUTTON_RIGHT && b->get_control()) { + add_node_menu->set_position(get_global_transform().xform(get_local_mouse_position())); + add_node_menu->set_size(Vector2(1, 1)); + add_node_menu->popup(); + node_create_position = transform.affine_inverse().xform((get_local_mouse_position())); + return true; + } + if (b.is_valid() && b->get_button_index() == BUTTON_LEFT && b->is_pressed() && tool == TOOL_SELECT) { // Single item selection Point2 click = transform.affine_inverse().xform(b->get_position()); @@ -5364,6 +5398,7 @@ void CanvasItemEditor::_bind_methods() { ClassDB::bind_method("_unhandled_key_input", &CanvasItemEditor::_unhandled_key_input); ClassDB::bind_method("_queue_update_bone_list", &CanvasItemEditor::_update_bone_list); ClassDB::bind_method("_update_bone_list", &CanvasItemEditor::_update_bone_list); + ClassDB::bind_method("_reset_create_position", &CanvasItemEditor::_reset_create_position); ClassDB::bind_method(D_METHOD("set_state"), &CanvasItemEditor::set_state); ClassDB::bind_method(D_METHOD("update_viewport"), &CanvasItemEditor::update_viewport); @@ -5685,6 +5720,9 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) { editor_selection->connect("selection_changed", callable_mp((CanvasItem *)this, &CanvasItem::update)); editor_selection->connect("selection_changed", callable_mp(this, &CanvasItemEditor::_selection_changed)); + editor->get_scene_tree_dock()->connect("node_created", callable_mp(this, &CanvasItemEditor::_node_created)); + editor->get_scene_tree_dock()->connect("add_node_used", callable_mp(this, &CanvasItemEditor::_reset_create_position)); + editor->call_deferred("connect", "play_pressed", Callable(this, "_update_override_camera_button"), make_binds(true)); editor->call_deferred("connect", "stop_pressed", Callable(this, "_update_override_camera_button"), make_binds(false)); @@ -6106,6 +6144,12 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) { selection_menu->connect("id_pressed", callable_mp(this, &CanvasItemEditor::_selection_result_pressed)); selection_menu->connect("popup_hide", callable_mp(this, &CanvasItemEditor::_selection_menu_hide)); + add_node_menu = memnew(PopupMenu); + add_child(add_node_menu); + add_node_menu->add_icon_item(editor->get_scene_tree_dock()->get_theme_icon("Add", "EditorIcons"), TTR("Add Node Here")); + add_node_menu->add_icon_item(editor->get_scene_tree_dock()->get_theme_icon("Instance", "EditorIcons"), TTR("Instance Scene Here")); + add_node_menu->connect("id_pressed", callable_mp(this, &CanvasItemEditor::_add_node_pressed)); + multiply_grid_step_shortcut = ED_SHORTCUT("canvas_item_editor/multiply_grid_step", TTR("Multiply grid step by 2"), KEY_KP_MULTIPLY); divide_grid_step_shortcut = ED_SHORTCUT("canvas_item_editor/divide_grid_step", TTR("Divide grid step by 2"), KEY_KP_DIVIDE); pan_view_shortcut = ED_SHORTCUT("canvas_item_editor/pan_view", TTR("Pan View"), KEY_SPACE); diff --git a/editor/plugins/canvas_item_editor_plugin.h b/editor/plugins/canvas_item_editor_plugin.h index 24149a57b0..62a9b1e162 100644 --- a/editor/plugins/canvas_item_editor_plugin.h +++ b/editor/plugins/canvas_item_editor_plugin.h @@ -79,6 +79,11 @@ public: TOOL_MAX }; + enum AddNodeOption { + ADD_NODE, + ADD_INSTANCE, + }; + private: EditorNode *editor; @@ -284,6 +289,7 @@ private: bool ruler_tool_active; Point2 ruler_tool_origin; + Point2 node_create_position; MenuOption last_option; @@ -376,6 +382,7 @@ private: Button *key_auto_insert_button; PopupMenu *selection_menu; + PopupMenu *add_node_menu; Control *top_ruler; Control *left_ruler; @@ -436,6 +443,9 @@ private: void _snap_changed(); void _selection_result_pressed(int); void _selection_menu_hide(); + void _add_node_pressed(int p_result); + void _node_created(Node *p_node); + void _reset_create_position(); UndoRedo *undo_redo; bool _build_bones_list(Node *p_node); diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index bb6cc50a31..9643881f96 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -4713,7 +4713,7 @@ Dictionary Node3DEditor::get_state() const { continue; } int state = gizmos_menu->get_item_state(gizmos_menu->get_item_index(i)); - String name = gizmo_plugins_by_name[i]->get_name(); + String name = gizmo_plugins_by_name[i]->get_gizmo_name(); gizmos_status[name] = state; } @@ -4839,7 +4839,7 @@ void Node3DEditor::set_state(const Dictionary &p_state) { } int state = EditorNode3DGizmoPlugin::VISIBLE; for (int i = 0; i < keys.size(); i++) { - if (gizmo_plugins_by_name.write[j]->get_name() == String(keys[i])) { + if (gizmo_plugins_by_name.write[j]->get_gizmo_name() == String(keys[i])) { state = gizmos_status[keys[i]]; break; } @@ -5750,7 +5750,7 @@ void Node3DEditor::_update_gizmos_menu() { if (!gizmo_plugins_by_name[i]->can_be_hidden()) { continue; } - String plugin_name = gizmo_plugins_by_name[i]->get_name(); + String plugin_name = gizmo_plugins_by_name[i]->get_gizmo_name(); const int plugin_state = gizmo_plugins_by_name[i]->get_state(); gizmos_menu->add_multistate_item(plugin_name, 3, plugin_state, i); const int idx = gizmos_menu->get_item_index(i); @@ -7252,7 +7252,7 @@ void Node3DEditorPlugin::snap_cursor_to_plane(const Plane &p_plane) { struct _GizmoPluginPriorityComparator { bool operator()(const Ref<EditorNode3DGizmoPlugin> &p_a, const Ref<EditorNode3DGizmoPlugin> &p_b) const { if (p_a->get_priority() == p_b->get_priority()) { - return p_a->get_name() < p_b->get_name(); + return p_a->get_gizmo_name() < p_b->get_gizmo_name(); } return p_a->get_priority() > p_b->get_priority(); } @@ -7260,7 +7260,7 @@ struct _GizmoPluginPriorityComparator { struct _GizmoPluginNameComparator { bool operator()(const Ref<EditorNode3DGizmoPlugin> &p_a, const Ref<EditorNode3DGizmoPlugin> &p_b) const { - return p_a->get_name() < p_b->get_name(); + return p_a->get_gizmo_name() < p_b->get_gizmo_name(); } }; @@ -7471,7 +7471,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_gizmo_name")); 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/tile_map_editor_plugin.cpp b/editor/plugins/tile_map_editor_plugin.cpp index 6a16aa28a9..74b01b3c36 100644 --- a/editor/plugins/tile_map_editor_plugin.cpp +++ b/editor/plugins/tile_map_editor_plugin.cpp @@ -40,9 +40,12 @@ void TileMapEditor::_node_removed(Node *p_node) { if (p_node == node && node) { - // Fixes #44824, which describes a situation where you can reselect a TileMap node without first de-selecting it when switching scenes. - node->disconnect("settings_changed", callable_mp(this, &TileMapEditor::_tileset_settings_changed)); + Callable callable_tileset_settings_changed = callable_mp(this, &TileMapEditor::_tileset_settings_changed); + if (node->is_connected("settings_changed", callable_tileset_settings_changed)) { + // Fixes #44824, which describes a situation where you can reselect a TileMap node without first de-selecting it when switching scenes. + node->disconnect("settings_changed", callable_tileset_settings_changed); + } node = nullptr; } } @@ -1870,7 +1873,11 @@ void TileMapEditor::edit(Node *p_tile_map) { } if (node) { - node->disconnect("settings_changed", callable_mp(this, &TileMapEditor::_tileset_settings_changed)); + Callable callable_tileset_settings_changed = callable_mp(this, &TileMapEditor::_tileset_settings_changed); + + if (node->is_connected("settings_changed", callable_tileset_settings_changed)) { + node->disconnect("settings_changed", callable_tileset_settings_changed); + } } if (p_tile_map) { node = Object::cast_to<TileMap>(p_tile_map); @@ -1897,7 +1904,11 @@ void TileMapEditor::edit(Node *p_tile_map) { } if (node) { - node->connect("settings_changed", callable_mp(this, &TileMapEditor::_tileset_settings_changed)); + Callable callable_tileset_settings_changed = callable_mp(this, &TileMapEditor::_tileset_settings_changed); + + if (!node->is_connected("settings_changed", callable_tileset_settings_changed)) { + node->connect("settings_changed", callable_tileset_settings_changed); + } } _clear_bucket_cache(); diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp index 58589467a8..16a0576af4 100644 --- a/editor/scene_tree_dock.cpp +++ b/editor/scene_tree_dock.cpp @@ -219,6 +219,9 @@ void SceneTreeDock::_perform_instance_scenes(const Vector<String> &p_files, Node editor_data->get_undo_redo().commit_action(); editor->push_item(instances[instances.size() - 1]); + for (int i = 0; i < instances.size(); i++) { + emit_signal("node_created", instances[i]); + } } void SceneTreeDock::_replace_with_branch_scene(const String &p_file, Node *base) { @@ -347,6 +350,11 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { break; } + if (reset_create_dialog) { + create_dialog->set_base_type("Node"); + reset_create_dialog = false; + } + // Prefer nodes that inherit from the current scene root. Node *current_edited_scene_root = EditorNode::get_singleton()->get_edited_scene(); if (current_edited_scene_root) { @@ -367,6 +375,9 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { } create_dialog->popup_create(true); + if (!p_confirm_override) { + emit_signal("add_node_used"); + } } break; case TOOL_INSTANCE: { if (!profile_allow_editing) { @@ -381,7 +392,9 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { quick_open->popup_dialog("PackedScene", true); quick_open->set_title(TTR("Instance Child Scene")); - + if (!p_confirm_override) { + emit_signal("add_node_used"); + } } break; case TOOL_EXPAND_COLLAPSE: { if (!scene_tree->get_selected()) { @@ -2101,6 +2114,8 @@ void SceneTreeDock::_do_create(Node *p_parent) { } ct->set_size(ms); } + + emit_signal("node_created", c); } void SceneTreeDock::_create() { @@ -2321,10 +2336,14 @@ void SceneTreeDock::_new_scene_from(String p_file) { Node *base = selection.front()->get(); - Map<Node *, Node *> reown; - reown[editor_data->get_edited_scene_root()] = base; - Node *copy = base->duplicate_and_reown(reown); + Map<const Node *, Node *> duplimap; + Node *copy = base->duplicate_from_editor(duplimap); + if (copy) { + for (int i = 0; i < copy->get_child_count(); i++) { + _set_node_owner_recursive(copy->get_child(i), copy); + } + Ref<PackedScene> sdata = memnew(PackedScene); Error err = sdata->pack(copy); memdelete(copy); @@ -2354,6 +2373,16 @@ void SceneTreeDock::_new_scene_from(String p_file) { } } +void SceneTreeDock::_set_node_owner_recursive(Node *p_node, Node *p_owner) { + if (!p_node->get_owner()) { + p_node->set_owner(p_owner); + } + + for (int i = 0; i < p_node->get_child_count(); i++) { + _set_node_owner_recursive(p_node->get_child(i), p_owner); + } +} + static bool _is_node_visible(Node *p_node) { if (!p_node->get_owner()) { return false; @@ -2776,6 +2805,16 @@ void SceneTreeDock::open_script_dialog(Node *p_for_node, bool p_extend) { } } +void SceneTreeDock::open_add_child_dialog() { + create_dialog->set_base_type("CanvasItem"); + _tool_selected(TOOL_NEW, true); + reset_create_dialog = true; +} + +void SceneTreeDock::open_instance_child_dialog() { + _tool_selected(TOOL_INSTANCE, true); +} + void SceneTreeDock::add_remote_tree_editor(Control *p_remote) { ERR_FAIL_COND(remote_tree != nullptr); add_child(p_remote); @@ -2975,6 +3014,8 @@ void SceneTreeDock::_bind_methods() { ClassDB::bind_method(D_METHOD("replace_node"), &SceneTreeDock::replace_node); ADD_SIGNAL(MethodInfo("remote_tree_selected")); + ADD_SIGNAL(MethodInfo("add_node_used")); + ADD_SIGNAL(MethodInfo("node_created", PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_RESOURCE_TYPE, "Node"))); } SceneTreeDock::SceneTreeDock(EditorNode *p_editor, Node *p_scene_root, EditorSelection *p_editor_selection, EditorData &p_editor_data) { diff --git a/editor/scene_tree_dock.h b/editor/scene_tree_dock.h index 3779b61c60..aa62c93cb5 100644 --- a/editor/scene_tree_dock.h +++ b/editor/scene_tree_dock.h @@ -100,6 +100,7 @@ class SceneTreeDock : public VBoxContainer { Vector<ObjectID> subresources; bool restore_script_editor_on_drag; + bool reset_create_dialog = false; int current_option; CreateDialog *create_dialog; @@ -203,6 +204,7 @@ class SceneTreeDock : public VBoxContainer { void _import_subscene(); void _new_scene_from(String p_file); + void _set_node_owner_recursive(Node *p_node, Node *p_owner); bool _validate_no_foreign(); bool _validate_no_instance(); @@ -273,6 +275,9 @@ public: void attach_script_to_selected(bool p_extend); void open_script_dialog(Node *p_for_node, bool p_extend); + void open_add_child_dialog(); + void open_instance_child_dialog(); + ScriptCreateDialog *get_script_create_dialog() { return script_create_dialog; } SceneTreeDock(EditorNode *p_editor, Node *p_scene_root, EditorSelection *p_editor_selection, EditorData &p_editor_data); |