1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-26 15:46:23 +00:00

Better deselection handling in AnimationTree editors

This commit is contained in:
vaner-org
2025-08-30 17:56:36 +05:30
parent 825ef2387f
commit f6a6aad6eb
5 changed files with 77 additions and 0 deletions

View File

@@ -127,6 +127,15 @@ void AnimationNodeBlendTreeEditor::update_graph() {
visible_properties.clear();
// Store selected nodes before clearing the graph.
List<StringName> selected_nodes;
for (int i = 0; i < graph->get_child_count(); i++) {
GraphNode *gn = Object::cast_to<GraphNode>(graph->get_child(i));
if (gn && gn->is_selected()) {
selected_nodes.push_back(gn->get_name());
}
}
graph->set_scroll_offset(blend_tree->get_graph_offset() * EDSCALE);
graph->clear_connections();
@@ -304,6 +313,17 @@ void AnimationNodeBlendTreeEditor::update_graph() {
graph->set_minimap_opacity(graph_minimap_opacity);
float graph_lines_curvature = EDITOR_GET("editors/visual_editors/lines_curvature");
graph->set_connection_lines_curvature(graph_lines_curvature);
// Restore selected nodes after graph reconstruction.
for (const StringName &name : selected_nodes) {
for (int i = 0; i < graph->get_child_count(); i++) {
GraphNode *gn = Object::cast_to<GraphNode>(graph->get_child(i));
if (gn && gn->get_name() == name) {
gn->set_selected(true);
break;
}
}
}
}
void AnimationNodeBlendTreeEditor::_file_opened(const String &p_file) {
@@ -539,6 +559,9 @@ void AnimationNodeBlendTreeEditor::_delete_node_request(const String &p_which) {
undo_redo->add_do_method(this, "update_graph");
undo_redo->add_undo_method(this, "update_graph");
undo_redo->commit_action();
// Return selection to host BlendTree node.
EditorNode::get_singleton()->push_item(blend_tree.ptr(), "", true);
}
void AnimationNodeBlendTreeEditor::_delete_nodes_request(const TypedArray<StringName> &p_nodes) {
@@ -597,6 +620,22 @@ void AnimationNodeBlendTreeEditor::_node_selected(Object *p_node) {
EditorNode::get_singleton()->push_item(anode.ptr(), "", true);
}
void AnimationNodeBlendTreeEditor::_node_deselected(Object *p_node) {
// Check if no nodes are selected, return selection to host BlendTree node.
bool any_selected = false;
for (int i = 0; i < graph->get_child_count(); i++) {
GraphNode *gn = Object::cast_to<GraphNode>(graph->get_child(i));
if (gn && gn->is_selected()) {
any_selected = true;
break;
}
}
if (!any_selected) {
EditorNode::get_singleton()->push_item(blend_tree.ptr(), "", true);
}
}
void AnimationNodeBlendTreeEditor::_open_in_editor(const String &p_which) {
Ref<AnimationNode> an = blend_tree->get_node(p_which);
ERR_FAIL_COND(an.is_null());
@@ -1192,6 +1231,7 @@ AnimationNodeBlendTreeEditor::AnimationNodeBlendTreeEditor() {
graph->connect("connection_request", callable_mp(this, &AnimationNodeBlendTreeEditor::_connection_request), CONNECT_DEFERRED);
graph->connect("disconnection_request", callable_mp(this, &AnimationNodeBlendTreeEditor::_disconnection_request), CONNECT_DEFERRED);
graph->connect("node_selected", callable_mp(this, &AnimationNodeBlendTreeEditor::_node_selected));
graph->connect("node_deselected", callable_mp(this, &AnimationNodeBlendTreeEditor::_node_deselected));
graph->connect("scroll_offset_changed", callable_mp(this, &AnimationNodeBlendTreeEditor::_scroll_changed));
graph->connect("delete_nodes_request", callable_mp(this, &AnimationNodeBlendTreeEditor::_delete_nodes_request));
graph->connect("popup_request", callable_mp(this, &AnimationNodeBlendTreeEditor::_popup_request));