Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ability to rename groups in the GroupsEditor #62659

Merged
merged 1 commit into from
Oct 11, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
144 changes: 108 additions & 36 deletions editor/groups_editor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -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")));
}
Expand All @@ -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);

Expand Down Expand Up @@ -218,19 +218,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();
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was changed to prevent bug:
group_renaming_bug

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()) {
Expand All @@ -240,6 +235,15 @@ 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.

undo_redo->create_action(TTR("Rename Group"));
Expand All @@ -248,7 +252,7 @@ void GroupDialog::_group_renamed() {
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);
Expand Down Expand Up @@ -324,7 +328,7 @@ void GroupDialog::_modify_group_pressed(Object *p_item, int p_column, int p_id,
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 {
Expand Down Expand Up @@ -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"));

Expand All @@ -584,14 +588,12 @@ 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;
}

Expand All @@ -609,6 +611,65 @@ 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.

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;
Expand All @@ -624,7 +685,7 @@ 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);
undo_redo->create_action(TTR("Remove from Group"));

undo_redo->add_do_method(node, "remove_from_group", name);
Expand Down Expand Up @@ -666,6 +727,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) {
Expand All @@ -692,6 +754,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);
Expand All @@ -717,6 +780,7 @@ void GroupsEditor::_show_group_dialog() {

void GroupsEditor::_bind_methods() {
ClassDB::bind_method("update_tree", &GroupsEditor::update_tree);
ClassDB::bind_method("_group_selected", &GroupsEditor::_group_selected);
}

GroupsEditor::GroupsEditor() {
Expand Down Expand Up @@ -749,13 +813,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("");
}

Expand Down
11 changes: 8 additions & 3 deletions editor/groups_editor.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class EditorUndoRedoManager;
class GroupDialog : public AcceptDialog {
GDCLASS(GroupDialog, AcceptDialog);

ConfirmationDialog *error = nullptr;
AcceptDialog *error = nullptr;

SceneTree *scene_tree = nullptr;
TreeItem *groups_root = nullptr;
Expand Down Expand Up @@ -88,8 +88,6 @@ class GroupDialog : public AcceptDialog {
void _modify_group_pressed(Object *p_item, int p_column, int p_id, MouseButton p_button);
void _delete_group_item(const String &p_name);

bool _can_edit(Node *p_node, String p_group);

void _load_groups(Node *p_current);
void _load_nodes(Node *p_current);

Expand All @@ -113,20 +111,27 @@ class GroupsEditor : public VBoxContainer {
GDCLASS(GroupsEditor, VBoxContainer);

Node *node = nullptr;
TreeItem *groups_root = nullptr;

GroupDialog *group_dialog = nullptr;
AcceptDialog *error = nullptr;

LineEdit *group_name = nullptr;
Button *add = nullptr;
Tree *tree = nullptr;

Ref<EditorUndoRedoManager> undo_redo;

String selected_group;

void update_tree();
void _add_group(const String &p_group = "");
void _modify_group(Object *p_item, int p_column, int p_id, MouseButton p_button);
void _group_name_changed(const String &p_new_text);

void _group_selected();
void _group_renamed();

void _show_group_dialog();

protected:
Expand Down