Add ability to rename groups in the GroupsEditor
This commit is contained in:
parent
34e0e7de58
commit
8075adc650
2 changed files with 117 additions and 40 deletions
|
@ -39,6 +39,24 @@
|
||||||
#include "scene/gui/label.h"
|
#include "scene/gui/label.h"
|
||||||
#include "scene/resources/packed_scene.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() {
|
void GroupDialog::_group_selected() {
|
||||||
nodes_to_add->clear();
|
nodes_to_add->clear();
|
||||||
add_node_root = nodes_to_add->create_item();
|
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");
|
Ref<Texture2D> icon = EditorNode::get_singleton()->get_object_icon(p_current, "Node");
|
||||||
node->set_icon(0, icon);
|
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_selectable(0, false);
|
||||||
node->set_custom_color(0, groups->get_theme_color(SNAME("disabled_font_color"), SNAME("Editor")));
|
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() {
|
void GroupDialog::_add_pressed() {
|
||||||
TreeItem *selected = nodes_to_add->get_next_selected(nullptr);
|
TreeItem *selected = nodes_to_add->get_next_selected(nullptr);
|
||||||
|
|
||||||
|
@ -218,19 +218,14 @@ void GroupDialog::_add_group_text_changed(const String &p_new_text) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void GroupDialog::_group_renamed() {
|
void GroupDialog::_group_renamed() {
|
||||||
TreeItem *renamed_group = groups->get_edited();
|
TreeItem *renamed_group = groups->get_selected();
|
||||||
if (!renamed_group) {
|
if (!renamed_group) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const String name = renamed_group->get_text(0).strip_edges();
|
const String name = renamed_group->get_text(0).strip_edges();
|
||||||
for (TreeItem *E = groups_root->get_first_child(); E; E = E->get_next()) {
|
if (name == selected_group) {
|
||||||
if (E != renamed_group && E->get_text(0) == name) {
|
return;
|
||||||
renamed_group->set_text(0, selected_group);
|
|
||||||
error->set_text(TTR("Group name already exists."));
|
|
||||||
error->popup_centered();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (name.is_empty()) {
|
if (name.is_empty()) {
|
||||||
|
@ -240,6 +235,15 @@ void GroupDialog::_group_renamed() {
|
||||||
return;
|
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.
|
renamed_group->set_text(0, name); // Spaces trimmed.
|
||||||
|
|
||||||
undo_redo->create_action(TTR("Rename Group"));
|
undo_redo->create_action(TTR("Rename Group"));
|
||||||
|
@ -248,7 +252,7 @@ void GroupDialog::_group_renamed() {
|
||||||
scene_tree->get_nodes_in_group(selected_group, &nodes);
|
scene_tree->get_nodes_in_group(selected_group, &nodes);
|
||||||
bool removed_all = true;
|
bool removed_all = true;
|
||||||
for (Node *node : nodes) {
|
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_do_method(node, "remove_from_group", selected_group);
|
||||||
undo_redo->add_undo_method(node, "remove_from_group", name);
|
undo_redo->add_undo_method(node, "remove_from_group", name);
|
||||||
undo_redo->add_do_method(node, "add_to_group", name, true);
|
undo_redo->add_do_method(node, "add_to_group", name, true);
|
||||||
|
@ -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);
|
scene_tree->get_nodes_in_group(name, &nodes);
|
||||||
bool removed_all = true;
|
bool removed_all = true;
|
||||||
for (Node *E : nodes) {
|
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_do_method(E, "remove_from_group", name);
|
||||||
undo_redo->add_undo_method(E, "add_to_group", name, true);
|
undo_redo->add_undo_method(E, "add_to_group", name, true);
|
||||||
} else {
|
} else {
|
||||||
|
@ -571,7 +575,7 @@ GroupDialog::GroupDialog() {
|
||||||
|
|
||||||
set_title(TTR("Group Editor"));
|
set_title(TTR("Group Editor"));
|
||||||
|
|
||||||
error = memnew(ConfirmationDialog);
|
error = memnew(AcceptDialog);
|
||||||
add_child(error);
|
add_child(error);
|
||||||
error->set_ok_button_text(TTR("Close"));
|
error->set_ok_button_text(TTR("Close"));
|
||||||
|
|
||||||
|
@ -584,14 +588,12 @@ void GroupsEditor::_add_group(const String &p_group) {
|
||||||
if (!node) {
|
if (!node) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const String name = group_name->get_text().strip_edges();
|
const String name = group_name->get_text().strip_edges();
|
||||||
if (name.is_empty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
group_name->clear();
|
group_name->clear();
|
||||||
if (node->is_in_group(name)) {
|
if (node->is_in_group(name)) {
|
||||||
|
error->set_text(TTR("Group name already exists."));
|
||||||
|
error->popup_centered();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -609,6 +611,65 @@ void GroupsEditor::_add_group(const String &p_group) {
|
||||||
undo_redo->commit_action();
|
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) {
|
void GroupsEditor::_modify_group(Object *p_item, int p_column, int p_id, MouseButton p_button) {
|
||||||
if (p_button != MouseButton::LEFT) {
|
if (p_button != MouseButton::LEFT) {
|
||||||
return;
|
return;
|
||||||
|
@ -624,7 +685,7 @@ void GroupsEditor::_modify_group(Object *p_item, int p_column, int p_id, MouseBu
|
||||||
}
|
}
|
||||||
switch (p_id) {
|
switch (p_id) {
|
||||||
case DELETE_GROUP: {
|
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->create_action(TTR("Remove from Group"));
|
||||||
|
|
||||||
undo_redo->add_do_method(node, "remove_from_group", name);
|
undo_redo->add_do_method(node, "remove_from_group", name);
|
||||||
|
@ -666,6 +727,7 @@ void GroupsEditor::update_tree() {
|
||||||
groups.sort_custom<_GroupInfoComparator>();
|
groups.sort_custom<_GroupInfoComparator>();
|
||||||
|
|
||||||
TreeItem *root = tree->create_item();
|
TreeItem *root = tree->create_item();
|
||||||
|
groups_root = root;
|
||||||
|
|
||||||
for (const GroupInfo &gi : groups) {
|
for (const GroupInfo &gi : groups) {
|
||||||
if (!gi.persistent) {
|
if (!gi.persistent) {
|
||||||
|
@ -692,6 +754,7 @@ void GroupsEditor::update_tree() {
|
||||||
|
|
||||||
TreeItem *item = tree->create_item(root);
|
TreeItem *item = tree->create_item(root);
|
||||||
item->set_text(0, gi.name);
|
item->set_text(0, gi.name);
|
||||||
|
item->set_editable(0, true);
|
||||||
if (can_be_deleted) {
|
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("Remove"), SNAME("EditorIcons")), DELETE_GROUP);
|
||||||
item->add_button(0, get_theme_icon(SNAME("ActionCopy"), SNAME("EditorIcons")), COPY_GROUP);
|
item->add_button(0, get_theme_icon(SNAME("ActionCopy"), SNAME("EditorIcons")), COPY_GROUP);
|
||||||
|
@ -717,6 +780,7 @@ void GroupsEditor::_show_group_dialog() {
|
||||||
|
|
||||||
void GroupsEditor::_bind_methods() {
|
void GroupsEditor::_bind_methods() {
|
||||||
ClassDB::bind_method("update_tree", &GroupsEditor::update_tree);
|
ClassDB::bind_method("update_tree", &GroupsEditor::update_tree);
|
||||||
|
ClassDB::bind_method("_group_selected", &GroupsEditor::_group_selected);
|
||||||
}
|
}
|
||||||
|
|
||||||
GroupsEditor::GroupsEditor() {
|
GroupsEditor::GroupsEditor() {
|
||||||
|
@ -749,13 +813,21 @@ GroupsEditor::GroupsEditor() {
|
||||||
add->connect("pressed", callable_mp(this, &GroupsEditor::_add_group).bind(String()));
|
add->connect("pressed", callable_mp(this, &GroupsEditor::_add_group).bind(String()));
|
||||||
|
|
||||||
tree = memnew(Tree);
|
tree = memnew(Tree);
|
||||||
tree->set_hide_root(true);
|
|
||||||
tree->set_v_size_flags(Control::SIZE_EXPAND_FILL);
|
|
||||||
vbc->add_child(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);
|
||||||
|
tree->connect("item_selected", callable_mp(this, &GroupsEditor::_group_selected));
|
||||||
tree->connect("button_clicked", callable_mp(this, &GroupsEditor::_modify_group));
|
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);
|
tree->add_theme_constant_override("draw_guides", 1);
|
||||||
add_theme_constant_override("separation", 3 * EDSCALE);
|
add_theme_constant_override("separation", 3 * EDSCALE);
|
||||||
|
|
||||||
|
error = memnew(AcceptDialog);
|
||||||
|
add_child(error);
|
||||||
|
error->get_ok_button()->set_text(TTR("Close"));
|
||||||
|
|
||||||
_group_name_changed("");
|
_group_name_changed("");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,7 @@ class EditorUndoRedoManager;
|
||||||
class GroupDialog : public AcceptDialog {
|
class GroupDialog : public AcceptDialog {
|
||||||
GDCLASS(GroupDialog, AcceptDialog);
|
GDCLASS(GroupDialog, AcceptDialog);
|
||||||
|
|
||||||
ConfirmationDialog *error = nullptr;
|
AcceptDialog *error = nullptr;
|
||||||
|
|
||||||
SceneTree *scene_tree = nullptr;
|
SceneTree *scene_tree = nullptr;
|
||||||
TreeItem *groups_root = nullptr;
|
TreeItem *groups_root = nullptr;
|
||||||
|
@ -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 _modify_group_pressed(Object *p_item, int p_column, int p_id, MouseButton p_button);
|
||||||
void _delete_group_item(const String &p_name);
|
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_groups(Node *p_current);
|
||||||
void _load_nodes(Node *p_current);
|
void _load_nodes(Node *p_current);
|
||||||
|
|
||||||
|
@ -113,8 +111,10 @@ class GroupsEditor : public VBoxContainer {
|
||||||
GDCLASS(GroupsEditor, VBoxContainer);
|
GDCLASS(GroupsEditor, VBoxContainer);
|
||||||
|
|
||||||
Node *node = nullptr;
|
Node *node = nullptr;
|
||||||
|
TreeItem *groups_root = nullptr;
|
||||||
|
|
||||||
GroupDialog *group_dialog = nullptr;
|
GroupDialog *group_dialog = nullptr;
|
||||||
|
AcceptDialog *error = nullptr;
|
||||||
|
|
||||||
LineEdit *group_name = nullptr;
|
LineEdit *group_name = nullptr;
|
||||||
Button *add = nullptr;
|
Button *add = nullptr;
|
||||||
|
@ -122,11 +122,16 @@ class GroupsEditor : public VBoxContainer {
|
||||||
|
|
||||||
Ref<EditorUndoRedoManager> undo_redo;
|
Ref<EditorUndoRedoManager> undo_redo;
|
||||||
|
|
||||||
|
String selected_group;
|
||||||
|
|
||||||
void update_tree();
|
void update_tree();
|
||||||
void _add_group(const String &p_group = "");
|
void _add_group(const String &p_group = "");
|
||||||
void _modify_group(Object *p_item, int p_column, int p_id, MouseButton p_button);
|
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_name_changed(const String &p_new_text);
|
||||||
|
|
||||||
|
void _group_selected();
|
||||||
|
void _group_renamed();
|
||||||
|
|
||||||
void _show_group_dialog();
|
void _show_group_dialog();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
Loading…
Add table
Reference in a new issue