summaryrefslogtreecommitdiff
path: root/editor/groups_editor.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'editor/groups_editor.cpp')
-rw-r--r--editor/groups_editor.cpp160
1 files changed, 115 insertions, 45 deletions
diff --git a/editor/groups_editor.cpp b/editor/groups_editor.cpp
index dac86acae4..ab96caa88c 100644
--- a/editor/groups_editor.cpp
+++ b/editor/groups_editor.cpp
@@ -39,6 +39,24 @@
#include "scene/gui/label.h"
#include "scene/resources/packed_scene.h"
+static bool can_edit(Node *p_node, String p_group) {
+ Node *n = p_node;
+ bool can_edit = true;
+ while (n) {
+ Ref<SceneState> ss = (n == EditorNode::get_singleton()->get_edited_scene()) ? n->get_scene_inherited_state() : n->get_scene_instance_state();
+ if (ss.is_valid()) {
+ int path = ss->find_node_by_path(n->get_path_to(p_node));
+ if (path != -1) {
+ if (ss->is_node_in_group(path, p_group)) {
+ can_edit = false;
+ }
+ }
+ }
+ n = n->get_owner();
+ }
+ return can_edit;
+}
+
void GroupDialog::_group_selected() {
nodes_to_add->clear();
add_node_root = nodes_to_add->create_item();
@@ -94,7 +112,7 @@ void GroupDialog::_load_nodes(Node *p_current) {
Ref<Texture2D> icon = EditorNode::get_singleton()->get_object_icon(p_current, "Node");
node->set_icon(0, icon);
- if (!_can_edit(p_current, selected_group)) {
+ if (!can_edit(p_current, selected_group)) {
node->set_selectable(0, false);
node->set_custom_color(0, groups->get_theme_color(SNAME("disabled_font_color"), SNAME("Editor")));
}
@@ -105,24 +123,6 @@ void GroupDialog::_load_nodes(Node *p_current) {
}
}
-bool GroupDialog::_can_edit(Node *p_node, String p_group) {
- Node *n = p_node;
- bool can_edit = true;
- while (n) {
- Ref<SceneState> ss = (n == EditorNode::get_singleton()->get_edited_scene()) ? n->get_scene_inherited_state() : n->get_scene_instance_state();
- if (ss.is_valid()) {
- int path = ss->find_node_by_path(n->get_path_to(p_node));
- if (path != -1) {
- if (ss->is_node_in_group(path, p_group)) {
- can_edit = false;
- }
- }
- }
- n = n->get_owner();
- }
- return can_edit;
-}
-
void GroupDialog::_add_pressed() {
TreeItem *selected = nodes_to_add->get_next_selected(nullptr);
@@ -130,6 +130,7 @@ void GroupDialog::_add_pressed() {
return;
}
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Add to Group"));
while (selected) {
@@ -159,6 +160,7 @@ void GroupDialog::_removed_pressed() {
return;
}
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Remove from Group"));
while (selected) {
@@ -218,19 +220,14 @@ void GroupDialog::_add_group_text_changed(const String &p_new_text) {
}
void GroupDialog::_group_renamed() {
- TreeItem *renamed_group = groups->get_edited();
+ TreeItem *renamed_group = groups->get_selected();
if (!renamed_group) {
return;
}
const String name = renamed_group->get_text(0).strip_edges();
- for (TreeItem *E = groups_root->get_first_child(); E; E = E->get_next()) {
- if (E != renamed_group && E->get_text(0) == name) {
- renamed_group->set_text(0, selected_group);
- error->set_text(TTR("Group name already exists."));
- error->popup_centered();
- return;
- }
+ if (name == selected_group) {
+ return;
}
if (name.is_empty()) {
@@ -240,15 +237,25 @@ void GroupDialog::_group_renamed() {
return;
}
+ for (TreeItem *E = groups_root->get_first_child(); E; E = E->get_next()) {
+ if (E != renamed_group && E->get_text(0) == name) {
+ renamed_group->set_text(0, selected_group);
+ error->set_text(TTR("Group name already exists."));
+ error->popup_centered();
+ return;
+ }
+ }
+
renamed_group->set_text(0, name); // Spaces trimmed.
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Rename Group"));
List<Node *> nodes;
scene_tree->get_nodes_in_group(selected_group, &nodes);
bool removed_all = true;
for (Node *node : nodes) {
- if (_can_edit(node, selected_group)) {
+ if (can_edit(node, selected_group)) {
undo_redo->add_do_method(node, "remove_from_group", selected_group);
undo_redo->add_undo_method(node, "remove_from_group", name);
undo_redo->add_do_method(node, "add_to_group", name, true);
@@ -318,13 +325,14 @@ void GroupDialog::_modify_group_pressed(Object *p_item, int p_column, int p_id,
case DELETE_GROUP: {
String name = ti->get_text(0);
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Delete Group"));
List<Node *> nodes;
scene_tree->get_nodes_in_group(name, &nodes);
bool removed_all = true;
for (Node *E : nodes) {
- if (_can_edit(E, name)) {
+ if (can_edit(E, name)) {
undo_redo->add_do_method(E, "remove_from_group", name);
undo_redo->add_undo_method(E, "add_to_group", name, true);
} else {
@@ -398,10 +406,6 @@ void GroupDialog::_notification(int p_what) {
}
}
-void GroupDialog::set_undo_redo(Ref<EditorUndoRedoManager> p_undo_redo) {
- undo_redo = p_undo_redo;
-}
-
void GroupDialog::edit() {
popup_centered();
@@ -571,7 +575,7 @@ GroupDialog::GroupDialog() {
set_title(TTR("Group Editor"));
- error = memnew(ConfirmationDialog);
+ error = memnew(AcceptDialog);
add_child(error);
error->set_ok_button_text(TTR("Close"));
@@ -584,17 +588,16 @@ void GroupsEditor::_add_group(const String &p_group) {
if (!node) {
return;
}
-
const String name = group_name->get_text().strip_edges();
- if (name.is_empty()) {
- return;
- }
group_name->clear();
if (node->is_in_group(name)) {
+ error->set_text(TTR("Group name already exists."));
+ error->popup_centered();
return;
}
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Add to Group"));
undo_redo->add_do_method(node, "add_to_group", name, true);
@@ -609,6 +612,66 @@ void GroupsEditor::_add_group(const String &p_group) {
undo_redo->commit_action();
}
+void GroupsEditor::_group_selected() {
+ if (!tree->is_anything_selected()) {
+ return;
+ }
+ selected_group = tree->get_selected()->get_text(0);
+}
+
+void GroupsEditor::_group_renamed() {
+ if (!node || !can_edit(node, selected_group)) {
+ return;
+ }
+
+ TreeItem *ti = tree->get_selected();
+ if (!ti) {
+ return;
+ }
+
+ const String name = ti->get_text(0).strip_edges();
+ if (name == selected_group) {
+ return;
+ }
+
+ if (name.is_empty()) {
+ ti->set_text(0, selected_group);
+ error->set_text(TTR("Invalid group name."));
+ error->popup_centered();
+ return;
+ }
+
+ for (TreeItem *E = groups_root->get_first_child(); E; E = E->get_next()) {
+ if (E != ti && E->get_text(0) == name) {
+ ti->set_text(0, selected_group);
+ error->set_text(TTR("Group name already exists."));
+ error->popup_centered();
+ return;
+ }
+ }
+
+ ti->set_text(0, name); // Spaces trimmed.
+
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
+ undo_redo->create_action(TTR("Rename Group"));
+
+ undo_redo->add_do_method(node, "remove_from_group", selected_group);
+ undo_redo->add_undo_method(node, "remove_from_group", name);
+ undo_redo->add_do_method(node, "add_to_group", name, true);
+ undo_redo->add_undo_method(node, "add_to_group", selected_group, true);
+
+ undo_redo->add_do_method(this, "_group_selected");
+ undo_redo->add_undo_method(this, "_group_selected");
+ undo_redo->add_do_method(this, "update_tree");
+ undo_redo->add_undo_method(this, "update_tree");
+
+ // To force redraw of scene tree.
+ undo_redo->add_do_method(SceneTreeDock::get_singleton()->get_tree_editor(), "update_tree");
+ undo_redo->add_undo_method(SceneTreeDock::get_singleton()->get_tree_editor(), "update_tree");
+
+ undo_redo->commit_action();
+}
+
void GroupsEditor::_modify_group(Object *p_item, int p_column, int p_id, MouseButton p_button) {
if (p_button != MouseButton::LEFT) {
return;
@@ -624,7 +687,8 @@ void GroupsEditor::_modify_group(Object *p_item, int p_column, int p_id, MouseBu
}
switch (p_id) {
case DELETE_GROUP: {
- String name = ti->get_text(0);
+ const String name = ti->get_text(0);
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Remove from Group"));
undo_redo->add_do_method(node, "remove_from_group", name);
@@ -666,6 +730,7 @@ void GroupsEditor::update_tree() {
groups.sort_custom<_GroupInfoComparator>();
TreeItem *root = tree->create_item();
+ groups_root = root;
for (const GroupInfo &gi : groups) {
if (!gi.persistent) {
@@ -692,6 +757,7 @@ void GroupsEditor::update_tree() {
TreeItem *item = tree->create_item(root);
item->set_text(0, gi.name);
+ item->set_editable(0, true);
if (can_be_deleted) {
item->add_button(0, get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), DELETE_GROUP);
item->add_button(0, get_theme_icon(SNAME("ActionCopy"), SNAME("EditorIcons")), COPY_GROUP);
@@ -701,10 +767,6 @@ void GroupsEditor::update_tree() {
}
}
-void GroupsEditor::set_undo_redo(Ref<EditorUndoRedoManager> p_undo_redo) {
- undo_redo = p_undo_redo;
-}
-
void GroupsEditor::set_current(Node *p_node) {
node = p_node;
update_tree();
@@ -712,11 +774,11 @@ void GroupsEditor::set_current(Node *p_node) {
void GroupsEditor::_show_group_dialog() {
group_dialog->edit();
- group_dialog->set_undo_redo(undo_redo);
}
void GroupsEditor::_bind_methods() {
ClassDB::bind_method("update_tree", &GroupsEditor::update_tree);
+ ClassDB::bind_method("_group_selected", &GroupsEditor::_group_selected);
}
GroupsEditor::GroupsEditor() {
@@ -749,13 +811,21 @@ GroupsEditor::GroupsEditor() {
add->connect("pressed", callable_mp(this, &GroupsEditor::_add_group).bind(String()));
tree = memnew(Tree);
+ vbc->add_child(tree);
tree->set_hide_root(true);
+ tree->set_allow_reselect(true);
+ tree->set_allow_rmb_select(true);
tree->set_v_size_flags(Control::SIZE_EXPAND_FILL);
- vbc->add_child(tree);
+ tree->connect("item_selected", callable_mp(this, &GroupsEditor::_group_selected));
tree->connect("button_clicked", callable_mp(this, &GroupsEditor::_modify_group));
+ tree->connect("item_edited", callable_mp(this, &GroupsEditor::_group_renamed));
tree->add_theme_constant_override("draw_guides", 1);
add_theme_constant_override("separation", 3 * EDSCALE);
+ error = memnew(AcceptDialog);
+ add_child(error);
+ error->get_ok_button()->set_text(TTR("Close"));
+
_group_name_changed("");
}