summaryrefslogtreecommitdiff
path: root/editor/scene_tree_dock.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'editor/scene_tree_dock.cpp')
-rw-r--r--editor/scene_tree_dock.cpp172
1 files changed, 57 insertions, 115 deletions
diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp
index 3e98c854c5..d1dc188be9 100644
--- a/editor/scene_tree_dock.cpp
+++ b/editor/scene_tree_dock.cpp
@@ -135,6 +135,8 @@ void SceneTreeDock::shortcut_input(const Ref<InputEvent> &p_event) {
_tool_selected(TOOL_ERASE, true);
} else if (ED_IS_SHORTCUT("scene_tree/copy_node_path", p_event)) {
_tool_selected(TOOL_COPY_NODE_PATH);
+ } else if (ED_IS_SHORTCUT("scene_tree/toggle_unique_name", p_event)) {
+ _tool_selected(TOOL_TOGGLE_SCENE_UNIQUE_NAME);
} else if (ED_IS_SHORTCUT("scene_tree/delete", p_event)) {
_tool_selected(TOOL_ERASE);
} else {
@@ -439,8 +441,8 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
}
}
- bool collapsed = _is_collapsed_recursive(selected_item);
- _set_collapsed_recursive(selected_item, !collapsed);
+ bool collapsed = selected_item->is_any_collapsed();
+ selected_item->set_collapsed_recursive(!collapsed);
tree->ensure_cursor_is_visible();
@@ -916,6 +918,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
String existing;
if (extensions.size()) {
String root_name(tocopy->get_name());
+ root_name = EditorNode::adjust_scene_name_casing(root_name);
existing = root_name + "." + extensions.front()->get().to_lower();
}
new_scene_from_dialog->set_current_path(existing);
@@ -1073,6 +1076,14 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
if (first_selected == nullptr) {
return;
}
+ if (first_selected->get() == EditorNode::get_singleton()->get_edited_scene()) {
+ // Exclude Root Node. It should never be unique name in its own scene!
+ editor_selection->remove_node(first_selected->get());
+ first_selected = editor_selection->get_selected_node_list().front();
+ if (first_selected == nullptr) {
+ return;
+ }
+ }
bool enabling = !first_selected->get()->is_unique_name_in_owner();
List<Node *> full_selection = editor_selection->get_full_selected_node_list();
@@ -1212,17 +1223,6 @@ void SceneTreeDock::add_root_node(Node *p_node) {
editor_data->get_undo_redo()->commit_action();
}
-void SceneTreeDock::_node_collapsed(Object *p_obj) {
- TreeItem *ti = Object::cast_to<TreeItem>(p_obj);
- if (!ti) {
- return;
- }
-
- if (Input::get_singleton()->is_key_pressed(Key::SHIFT)) {
- _set_collapsed_recursive(ti, ti->is_collapsed());
- }
-}
-
void SceneTreeDock::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_READY: {
@@ -1235,14 +1235,14 @@ void SceneTreeDock::_notification(int p_what) {
CanvasItemEditorPlugin *canvas_item_plugin = Object::cast_to<CanvasItemEditorPlugin>(editor_data->get_editor("2D"));
if (canvas_item_plugin) {
- canvas_item_plugin->get_canvas_item_editor()->connect("item_lock_status_changed", Callable(scene_tree, "_update_tree"));
- canvas_item_plugin->get_canvas_item_editor()->connect("item_group_status_changed", Callable(scene_tree, "_update_tree"));
- scene_tree->connect("node_changed", callable_mp((CanvasItem *)canvas_item_plugin->get_canvas_item_editor()->get_viewport_control(), &CanvasItem::update));
+ canvas_item_plugin->get_canvas_item_editor()->connect("item_lock_status_changed", callable_mp(scene_tree, &SceneTreeEditor::_update_tree));
+ canvas_item_plugin->get_canvas_item_editor()->connect("item_group_status_changed", callable_mp(scene_tree, &SceneTreeEditor::_update_tree));
+ scene_tree->connect("node_changed", callable_mp((CanvasItem *)canvas_item_plugin->get_canvas_item_editor()->get_viewport_control(), &CanvasItem::queue_redraw));
}
Node3DEditorPlugin *spatial_editor_plugin = Object::cast_to<Node3DEditorPlugin>(editor_data->get_editor("3D"));
- spatial_editor_plugin->get_spatial_editor()->connect("item_lock_status_changed", Callable(scene_tree, "_update_tree"));
- spatial_editor_plugin->get_spatial_editor()->connect("item_group_status_changed", Callable(scene_tree, "_update_tree"));
+ spatial_editor_plugin->get_spatial_editor()->connect("item_lock_status_changed", callable_mp(scene_tree, &SceneTreeEditor::_update_tree));
+ spatial_editor_plugin->get_spatial_editor()->connect("item_group_status_changed", callable_mp(scene_tree, &SceneTreeEditor::_update_tree));
button_add->set_icon(get_theme_icon(SNAME("Add"), SNAME("EditorIcons")));
button_instance->set_icon(get_theme_icon(SNAME("Instance"), SNAME("EditorIcons")));
@@ -1255,16 +1255,14 @@ void SceneTreeDock::_notification(int p_what) {
// create_root_dialog
HBoxContainer *top_row = memnew(HBoxContainer);
- top_row->set_name("NodeShortcutsTopRow");
top_row->set_h_size_flags(SIZE_EXPAND_FILL);
Label *l = memnew(Label(TTR("Create Root Node:")));
l->set_theme_type_variation("HeaderSmall");
top_row->add_child(l);
top_row->add_spacer();
- Button *node_shortcuts_toggle = memnew(Button);
+ node_shortcuts_toggle = memnew(Button);
node_shortcuts_toggle->set_flat(true);
- node_shortcuts_toggle->set_name("NodeShortcutsToggle");
node_shortcuts_toggle->set_icon(get_theme_icon(SNAME("Favorites"), SNAME("EditorIcons")));
node_shortcuts_toggle->set_toggle_mode(true);
node_shortcuts_toggle->set_tooltip_text(TTR("Switch to Favorite Nodes"));
@@ -1276,18 +1274,15 @@ void SceneTreeDock::_notification(int p_what) {
create_root_dialog->add_child(top_row);
ScrollContainer *scroll_container = memnew(ScrollContainer);
- scroll_container->set_name("NodeShortcutsScrollContainer");
create_root_dialog->add_child(scroll_container);
scroll_container->set_v_size_flags(SIZE_EXPAND_FILL);
scroll_container->set_horizontal_scroll_mode(ScrollContainer::SCROLL_MODE_DISABLED);
VBoxContainer *node_shortcuts = memnew(VBoxContainer);
- node_shortcuts->set_name("NodeShortcuts");
scroll_container->add_child(node_shortcuts);
node_shortcuts->set_h_size_flags(SIZE_EXPAND_FILL);
- VBoxContainer *beginner_node_shortcuts = memnew(VBoxContainer);
- beginner_node_shortcuts->set_name("BeginnerNodeShortcuts");
+ beginner_node_shortcuts = memnew(VBoxContainer);
node_shortcuts->add_child(beginner_node_shortcuts);
button_2d = memnew(Button);
@@ -1308,8 +1303,7 @@ void SceneTreeDock::_notification(int p_what) {
button_ui->set_icon(get_theme_icon(SNAME("Control"), SNAME("EditorIcons")));
button_ui->connect("pressed", callable_mp(this, &SceneTreeDock::_tool_selected).bind(TOOL_CREATE_USER_INTERFACE, false));
- VBoxContainer *favorite_node_shortcuts = memnew(VBoxContainer);
- favorite_node_shortcuts->set_name("FavoriteNodeShortcuts");
+ favorite_node_shortcuts = memnew(VBoxContainer);
node_shortcuts->add_child(favorite_node_shortcuts);
button_custom = memnew(Button);
@@ -1940,48 +1934,6 @@ void SceneTreeDock::_do_reparent(Node *p_new_parent, int p_position_in_parent, V
editor_data->get_undo_redo()->commit_action();
}
-bool SceneTreeDock::_is_collapsed_recursive(TreeItem *p_item) const {
- bool is_branch_collapsed = false;
-
- List<TreeItem *> needs_check;
- needs_check.push_back(p_item);
-
- while (!needs_check.is_empty()) {
- TreeItem *item = needs_check.back()->get();
- needs_check.pop_back();
-
- TreeItem *child = item->get_first_child();
- is_branch_collapsed = item->is_collapsed() && child;
-
- if (is_branch_collapsed) {
- break;
- }
- while (child) {
- needs_check.push_back(child);
- child = child->get_next();
- }
- }
- return is_branch_collapsed;
-}
-
-void SceneTreeDock::_set_collapsed_recursive(TreeItem *p_item, bool p_collapsed) {
- List<TreeItem *> to_collapse;
- to_collapse.push_back(p_item);
-
- while (!to_collapse.is_empty()) {
- TreeItem *item = to_collapse.back()->get();
- to_collapse.pop_back();
-
- item->set_collapsed(p_collapsed);
-
- TreeItem *child = item->get_first_child();
- while (child) {
- to_collapse.push_back(child);
- child = child->get_next();
- }
- }
-}
-
void SceneTreeDock::_script_created(Ref<Script> p_script) {
List<Node *> selected = editor_selection->get_selected_node_list();
@@ -1993,7 +1945,7 @@ void SceneTreeDock::_script_created(Ref<Script> p_script) {
Node *node = selected.front()->get();
Ref<Script> existing = node->get_script();
- editor_data->get_undo_redo()->create_action(TTR("Attach Script"));
+ editor_data->get_undo_redo()->create_action(TTR("Attach Script"), UndoRedo::MERGE_DISABLE, node);
editor_data->get_undo_redo()->add_do_method(InspectorDock::get_singleton(), "store_script_properties", node);
editor_data->get_undo_redo()->add_undo_method(InspectorDock::get_singleton(), "store_script_properties", node);
editor_data->get_undo_redo()->add_do_method(node, "set_script", p_script);
@@ -2004,7 +1956,7 @@ void SceneTreeDock::_script_created(Ref<Script> p_script) {
editor_data->get_undo_redo()->add_undo_method(this, "_update_script_button");
editor_data->get_undo_redo()->commit_action();
} else {
- editor_data->get_undo_redo()->create_action(TTR("Attach Script"));
+ editor_data->get_undo_redo()->create_action(TTR("Attach Script"), UndoRedo::MERGE_DISABLE, selected.front()->get());
for (Node *E : selected) {
Ref<Script> existing = E->get_script();
editor_data->get_undo_redo()->add_do_method(InspectorDock::get_singleton(), "store_script_properties", E);
@@ -2099,9 +2051,9 @@ void SceneTreeDock::_delete_confirm(bool p_cut) {
EditorNode::get_singleton()->get_editor_plugins_over()->make_visible(false);
if (p_cut) {
- editor_data->get_undo_redo()->create_action(TTR("Cut Node(s)"));
+ editor_data->get_undo_redo()->create_action(TTR("Cut Node(s)"), UndoRedo::MERGE_DISABLE, remove_list.front()->get());
} else {
- editor_data->get_undo_redo()->create_action(TTR("Remove Node(s)"));
+ editor_data->get_undo_redo()->create_action(TTR("Remove Node(s)"), UndoRedo::MERGE_DISABLE, remove_list.front()->get());
}
bool entire_scene = false;
@@ -2109,6 +2061,7 @@ void SceneTreeDock::_delete_confirm(bool p_cut) {
for (const Node *E : remove_list) {
if (E == edited_scene) {
entire_scene = true;
+ break;
}
}
@@ -2164,7 +2117,7 @@ void SceneTreeDock::_delete_confirm(bool p_cut) {
// hack, force 2d editor viewport to refresh after deletion
if (CanvasItemEditor *editor = CanvasItemEditor::get_singleton()) {
- editor->get_viewport_control()->update();
+ editor->get_viewport_control()->queue_redraw();
}
_push_item(nullptr);
@@ -2226,7 +2179,7 @@ void SceneTreeDock::_do_create(Node *p_parent) {
Node *child = Object::cast_to<Node>(c);
ERR_FAIL_COND(!child);
- editor_data->get_undo_redo()->create_action(TTR("Create Node"));
+ editor_data->get_undo_redo()->create_action_for_history(TTR("Create Node"), editor_data->get_current_edited_scene_history_id());
if (edited_scene) {
editor_data->get_undo_redo()->add_do_method(p_parent, "add_child", child, true);
@@ -2643,7 +2596,7 @@ void SceneTreeDock::_script_dropped(String p_file, NodePath p_to) {
Ref<Script> scr = ResourceLoader::load(p_file);
ERR_FAIL_COND(!scr.is_valid());
if (Node *n = get_node(p_to)) {
- editor_data->get_undo_redo()->create_action(TTR("Attach Script"));
+ editor_data->get_undo_redo()->create_action(TTR("Attach Script"), UndoRedo::MERGE_DISABLE, n);
editor_data->get_undo_redo()->add_do_method(InspectorDock::get_singleton(), "store_script_properties", n);
editor_data->get_undo_redo()->add_undo_method(InspectorDock::get_singleton(), "store_script_properties", n);
editor_data->get_undo_redo()->add_do_method(n, "set_script", scr);
@@ -2870,10 +2823,13 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) {
}
}
if (all_owned) {
- menu->add_separator();
- menu->add_icon_check_item(get_theme_icon(SNAME("SceneUniqueName"), SNAME("EditorIcons")), TTR("Access as Scene Unique Name"), TOOL_TOGGLE_SCENE_UNIQUE_NAME);
- // Checked based on `selection[0]` because `full_selection` has undesired ordering.
- menu->set_item_checked(menu->get_item_index(TOOL_TOGGLE_SCENE_UNIQUE_NAME), selection[0]->is_unique_name_in_owner());
+ // Group "toggle_unique_name" with "copy_node_path", if it is available.
+ if (menu->get_item_index(TOOL_COPY_NODE_PATH) == -1) {
+ menu->add_separator();
+ }
+ Node *node = full_selection[0];
+ menu->add_icon_shortcut(get_theme_icon(SNAME("SceneUniqueName"), SNAME("EditorIcons")), ED_GET_SHORTCUT("scene_tree/toggle_unique_name"), TOOL_TOGGLE_SCENE_UNIQUE_NAME);
+ menu->set_item_text(menu->get_item_index(TOOL_TOGGLE_SCENE_UNIQUE_NAME), node->is_unique_name_in_owner() ? TTR("Revoke Unique Name") : TTR("Access as Unique Name"));
}
}
@@ -3227,25 +3183,11 @@ void SceneTreeDock::_local_tree_selected() {
}
void SceneTreeDock::_update_create_root_dialog() {
- BaseButton *toggle = Object::cast_to<BaseButton>(create_root_dialog->get_node(String("NodeShortcutsTopRow/NodeShortcutsToggle")));
- Node *node_shortcuts = create_root_dialog->get_node(String("NodeShortcutsScrollContainer/NodeShortcuts"));
-
- if (!toggle || !node_shortcuts) {
- return;
- }
-
- Control *beginner_nodes = Object::cast_to<Control>(node_shortcuts->get_node(String("BeginnerNodeShortcuts")));
- Control *favorite_nodes = Object::cast_to<Control>(node_shortcuts->get_node(String("FavoriteNodeShortcuts")));
-
- if (!beginner_nodes || !favorite_nodes) {
- return;
- }
-
- EditorSettings::get_singleton()->set_setting("_use_favorites_root_selection", toggle->is_pressed());
+ EditorSettings::get_singleton()->set_setting("_use_favorites_root_selection", node_shortcuts_toggle->is_pressed());
EditorSettings::get_singleton()->save();
- if (toggle->is_pressed()) {
- for (int i = 0; i < favorite_nodes->get_child_count(); i++) {
- favorite_nodes->get_child(i)->queue_delete();
+ if (node_shortcuts_toggle->is_pressed()) {
+ for (int i = 0; i < favorite_node_shortcuts->get_child_count(); i++) {
+ favorite_node_shortcuts->get_child(i)->queue_delete();
}
Ref<FileAccess> f = FileAccess::open(EditorPaths::get_singleton()->get_project_settings_dir().path_join("favorites.Node"), FileAccess::READ);
@@ -3255,7 +3197,7 @@ void SceneTreeDock::_update_create_root_dialog() {
if (!l.is_empty()) {
Button *button = memnew(Button);
- favorite_nodes->add_child(button);
+ favorite_node_shortcuts->add_child(button);
button->set_text(l);
button->set_clip_text(true);
String name = l.get_slicec(' ', 0);
@@ -3268,14 +3210,14 @@ void SceneTreeDock::_update_create_root_dialog() {
}
}
- if (!favorite_nodes->is_visible_in_tree()) {
- favorite_nodes->show();
- beginner_nodes->hide();
+ if (!favorite_node_shortcuts->is_visible_in_tree()) {
+ favorite_node_shortcuts->show();
+ beginner_node_shortcuts->hide();
}
} else {
- if (!beginner_nodes->is_visible_in_tree()) {
- beginner_nodes->show();
- favorite_nodes->hide();
+ if (!beginner_node_shortcuts->is_visible_in_tree()) {
+ beginner_node_shortcuts->show();
+ favorite_node_shortcuts->hide();
}
button_clipboard->set_visible(!node_clipboard.is_empty());
}
@@ -3422,24 +3364,25 @@ SceneTreeDock::SceneTreeDock(Node *p_scene_root, EditorSelection *p_editor_selec
ED_SHORTCUT("scene_tree/batch_rename", TTR("Batch Rename"), KeyModifierMask::SHIFT | Key::F2);
ED_SHORTCUT_OVERRIDE("scene_tree/batch_rename", "macos", KeyModifierMask::SHIFT | Key::ENTER);
- ED_SHORTCUT("scene_tree/add_child_node", TTR("Add Child Node"), KeyModifierMask::CMD | Key::A);
- ED_SHORTCUT("scene_tree/instance_scene", TTR("Instantiate Child Scene"), KeyModifierMask::CMD | KeyModifierMask::SHIFT | Key::A);
+ ED_SHORTCUT("scene_tree/add_child_node", TTR("Add Child Node"), KeyModifierMask::CMD_OR_CTRL | Key::A);
+ ED_SHORTCUT("scene_tree/instance_scene", TTR("Instantiate Child Scene"), KeyModifierMask::CMD_OR_CTRL | KeyModifierMask::SHIFT | Key::A);
ED_SHORTCUT("scene_tree/expand_collapse_all", TTR("Expand/Collapse Branch"));
- ED_SHORTCUT("scene_tree/cut_node", TTR("Cut"), KeyModifierMask::CMD | Key::X);
- ED_SHORTCUT("scene_tree/copy_node", TTR("Copy"), KeyModifierMask::CMD | Key::C);
- ED_SHORTCUT("scene_tree/paste_node", TTR("Paste"), KeyModifierMask::CMD | Key::V);
+ ED_SHORTCUT("scene_tree/cut_node", TTR("Cut"), KeyModifierMask::CMD_OR_CTRL | Key::X);
+ ED_SHORTCUT("scene_tree/copy_node", TTR("Copy"), KeyModifierMask::CMD_OR_CTRL | Key::C);
+ ED_SHORTCUT("scene_tree/paste_node", TTR("Paste"), KeyModifierMask::CMD_OR_CTRL | Key::V);
ED_SHORTCUT("scene_tree/change_node_type", TTR("Change Type"));
ED_SHORTCUT("scene_tree/attach_script", TTR("Attach Script"));
ED_SHORTCUT("scene_tree/extend_script", TTR("Extend Script"));
ED_SHORTCUT("scene_tree/detach_script", TTR("Detach Script"));
- ED_SHORTCUT("scene_tree/move_up", TTR("Move Up"), KeyModifierMask::CMD | Key::UP);
- ED_SHORTCUT("scene_tree/move_down", TTR("Move Down"), KeyModifierMask::CMD | Key::DOWN);
- ED_SHORTCUT("scene_tree/duplicate", TTR("Duplicate"), KeyModifierMask::CMD | Key::D);
+ ED_SHORTCUT("scene_tree/move_up", TTR("Move Up"), KeyModifierMask::CMD_OR_CTRL | Key::UP);
+ ED_SHORTCUT("scene_tree/move_down", TTR("Move Down"), KeyModifierMask::CMD_OR_CTRL | Key::DOWN);
+ ED_SHORTCUT("scene_tree/duplicate", TTR("Duplicate"), KeyModifierMask::CMD_OR_CTRL | Key::D);
ED_SHORTCUT("scene_tree/reparent", TTR("Reparent"));
ED_SHORTCUT("scene_tree/reparent_to_new_node", TTR("Reparent to New Node"));
ED_SHORTCUT("scene_tree/make_root", TTR("Make Scene Root"));
ED_SHORTCUT("scene_tree/save_branch_as_scene", TTR("Save Branch as Scene"));
- ED_SHORTCUT("scene_tree/copy_node_path", TTR("Copy Node Path"), KeyModifierMask::CMD | KeyModifierMask::SHIFT | Key::C);
+ ED_SHORTCUT("scene_tree/copy_node_path", TTR("Copy Node Path"), KeyModifierMask::CMD_OR_CTRL | KeyModifierMask::SHIFT | Key::C);
+ ED_SHORTCUT("scene_tree/toggle_unique_name", TTR("Toggle Access as Unique Name"));
ED_SHORTCUT("scene_tree/delete_no_confirm", TTR("Delete (No Confirm)"), KeyModifierMask::SHIFT | Key::KEY_DELETE);
ED_SHORTCUT("scene_tree/delete", TTR("Delete"), Key::KEY_DELETE);
@@ -3536,7 +3479,6 @@ SceneTreeDock::SceneTreeDock(Node *p_scene_root, EditorSelection *p_editor_selec
scene_tree->connect("nodes_dragged", callable_mp(this, &SceneTreeDock::_nodes_drag_begin));
scene_tree->get_scene_tree()->connect("item_double_clicked", callable_mp(this, &SceneTreeDock::_focus_node));
- scene_tree->get_scene_tree()->connect("item_collapsed", callable_mp(this, &SceneTreeDock::_node_collapsed));
editor_selection->connect("selection_changed", callable_mp(this, &SceneTreeDock::_selection_changed));