summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMikael Hermansson <mikael@hermansson.io>2024-06-06 17:47:15 +0200
committerMikael Hermansson <mikael@hermansson.io>2024-08-19 14:05:33 +0200
commit351f454a9492fc8cf64b4b83a6895649c587a528 (patch)
treefdda47e2e894f34ada30b15a8c0dd642c23b2b1f
parent7a4a6fbc039fefbccbb23a66285722ad20bf418a (diff)
downloadredot-engine-351f454a9492fc8cf64b4b83a6895649c587a528.tar.gz
Allow keying properties with multiple nodes selected
-rw-r--r--editor/animation_track_editor.cpp132
-rw-r--r--editor/animation_track_editor.h4
-rw-r--r--editor/plugins/animation_player_editor_plugin.cpp2
-rw-r--r--editor/plugins/canvas_item_editor_plugin.cpp18
4 files changed, 47 insertions, 109 deletions
diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp
index c59c937905..7874b2febd 100644
--- a/editor/animation_track_editor.cpp
+++ b/editor/animation_track_editor.cpp
@@ -41,6 +41,7 @@
#include "editor/gui/editor_spin_slider.h"
#include "editor/gui/scene_tree_editor.h"
#include "editor/inspector_dock.h"
+#include "editor/multi_node_edit.h"
#include "editor/plugins/animation_player_editor_plugin.h"
#include "editor/themes/editor_scale.h"
#include "scene/3d/mesh_instance_3d.h"
@@ -3627,7 +3628,7 @@ void AnimationTrackEditor::update_keying() {
EditorSelectionHistory *editor_history = EditorNode::get_singleton()->get_editor_selection_history();
if (is_visible_in_tree() && animation.is_valid() && editor_history->get_path_size() > 0) {
Object *obj = ObjectDB::get_instance(editor_history->get_path_object(0));
- keying_enabled = Object::cast_to<Node>(obj) != nullptr;
+ keying_enabled = Object::cast_to<Node>(obj) != nullptr || Object::cast_to<MultiNodeEdit>(obj) != nullptr;
}
if (keying_enabled == keying) {
@@ -4044,19 +4045,20 @@ void AnimationTrackEditor::_insert_animation_key(NodePath p_path, const Variant
_query_insert(id);
}
-void AnimationTrackEditor::insert_node_value_key(Node *p_node, const String &p_property, const Variant &p_value, bool p_only_if_exists) {
+void AnimationTrackEditor::insert_node_value_key(Node *p_node, const String &p_property, bool p_only_if_exists, bool p_advance) {
ERR_FAIL_NULL(root);
// Let's build a node path.
- Node *node = p_node;
- String path = root->get_path_to(node, true);
+ String path = root->get_path_to(p_node, true);
+
+ Variant value = p_node->get(p_property);
- if (Object::cast_to<AnimationPlayer>(node) && p_property == "current_animation") {
- if (node == AnimationPlayerEditor::get_singleton()->get_player()) {
+ if (Object::cast_to<AnimationPlayer>(p_node) && p_property == "current_animation") {
+ if (p_node == AnimationPlayerEditor::get_singleton()->get_player()) {
EditorNode::get_singleton()->show_warning(TTR("AnimationPlayer can't animate itself, only other players."));
return;
}
- _insert_animation_key(path, p_value);
+ _insert_animation_key(path, value);
return;
}
@@ -4084,26 +4086,26 @@ void AnimationTrackEditor::insert_node_value_key(Node *p_node, const String &p_p
InsertData id;
id.path = np;
id.track_idx = i;
- id.value = p_value;
+ id.value = value;
id.type = Animation::TYPE_VALUE;
// TRANSLATORS: This describes the target of new animation track, will be inserted into another string.
id.query = vformat(TTR("property '%s'"), p_property);
- id.advance = false;
+ id.advance = p_advance;
// Dialog insert.
_query_insert(id);
inserted = true;
} else if (animation->track_get_type(i) == Animation::TYPE_BEZIER) {
- Variant value;
+ Variant actual_value;
String track_path = animation->track_get_path(i);
if (track_path == np) {
- value = p_value; // All good.
+ actual_value = value; // All good.
} else {
int sep = track_path.rfind(":");
if (sep != -1) {
String base_path = track_path.substr(0, sep);
if (base_path == np) {
String value_name = track_path.substr(sep + 1);
- value = p_value.get(value_name);
+ actual_value = value.get(value_name);
} else {
continue;
}
@@ -4115,10 +4117,10 @@ void AnimationTrackEditor::insert_node_value_key(Node *p_node, const String &p_p
InsertData id;
id.path = animation->track_get_path(i);
id.track_idx = i;
- id.value = value;
+ id.value = actual_value;
id.type = Animation::TYPE_BEZIER;
id.query = vformat(TTR("property '%s'"), p_property);
- id.advance = false;
+ id.advance = p_advance;
// Dialog insert.
_query_insert(id);
inserted = true;
@@ -4131,105 +4133,41 @@ void AnimationTrackEditor::insert_node_value_key(Node *p_node, const String &p_p
InsertData id;
id.path = np;
id.track_idx = -1;
- id.value = p_value;
+ id.value = value;
id.type = Animation::TYPE_VALUE;
id.query = vformat(TTR("property '%s'"), p_property);
- id.advance = false;
+ id.advance = p_advance;
// Dialog insert.
_query_insert(id);
}
-void AnimationTrackEditor::insert_value_key(const String &p_property, const Variant &p_value, bool p_advance) {
+void AnimationTrackEditor::insert_value_key(const String &p_property, bool p_advance) {
EditorSelectionHistory *history = EditorNode::get_singleton()->get_editor_selection_history();
ERR_FAIL_NULL(root);
ERR_FAIL_COND(history->get_path_size() == 0);
Object *obj = ObjectDB::get_instance(history->get_path_object(0));
- ERR_FAIL_NULL(Object::cast_to<Node>(obj));
-
- // Let's build a node path.
- Node *node = Object::cast_to<Node>(obj);
- String path = root->get_path_to(node, true);
-
- if (Object::cast_to<AnimationPlayer>(node) && p_property == "current_animation") {
- if (node == AnimationPlayerEditor::get_singleton()->get_player()) {
- EditorNode::get_singleton()->show_warning(TTR("AnimationPlayer can't animate itself, only other players."));
- return;
- }
- _insert_animation_key(path, p_value);
- return;
- }
-
- for (int i = 1; i < history->get_path_size(); i++) {
- String prop = history->get_path_property(i);
- ERR_FAIL_COND(prop.is_empty());
- path += ":" + prop;
- }
-
- path += ":" + p_property;
- NodePath np = path;
+ Ref<MultiNodeEdit> multi_node_edit(obj);
+ if (multi_node_edit.is_valid()) {
+ Node *edited_scene = EditorNode::get_singleton()->get_edited_scene();
+ ERR_FAIL_NULL(edited_scene);
- // Locate track.
-
- bool inserted = false;
+ make_insert_queue();
- make_insert_queue();
- for (int i = 0; i < animation->get_track_count(); i++) {
- if (animation->track_get_type(i) == Animation::TYPE_VALUE) {
- if (animation->track_get_path(i) != np) {
- continue;
- }
-
- InsertData id;
- id.path = np;
- id.track_idx = i;
- id.value = p_value;
- id.type = Animation::TYPE_VALUE;
- id.query = vformat(TTR("property '%s'"), p_property);
- id.advance = p_advance;
- // Dialog insert.
- _query_insert(id);
- inserted = true;
- } else if (animation->track_get_type(i) == Animation::TYPE_BEZIER) {
- Variant value;
- if (animation->track_get_path(i) == np) {
- value = p_value; // All good.
- } else {
- String tpath = animation->track_get_path(i);
- int index = tpath.rfind(":");
- if (NodePath(tpath.substr(0, index + 1)) == np) {
- String subindex = tpath.substr(index + 1, tpath.length() - index);
- value = p_value.get(subindex);
- } else {
- continue;
- }
- }
-
- InsertData id;
- id.path = animation->track_get_path(i);
- id.track_idx = i;
- id.value = value;
- id.type = Animation::TYPE_BEZIER;
- id.query = vformat(TTR("property '%s'"), p_property);
- id.advance = p_advance;
- // Dialog insert.
- _query_insert(id);
- inserted = true;
+ for (int i = 0; i < multi_node_edit->get_node_count(); ++i) {
+ Node *node = edited_scene->get_node(multi_node_edit->get_node(i));
+ insert_node_value_key(node, p_property, false, p_advance);
}
- }
- commit_insert_queue();
- if (!inserted) {
- InsertData id;
- id.path = np;
- id.track_idx = -1;
- id.value = p_value;
- id.type = Animation::TYPE_VALUE;
- id.query = vformat(TTR("property '%s'"), p_property);
- id.advance = p_advance;
- // Dialog insert.
- _query_insert(id);
+ commit_insert_queue();
+ } else {
+ Node *node = Object::cast_to<Node>(obj);
+ ERR_FAIL_NULL(node);
+
+ make_insert_queue();
+ insert_node_value_key(node, p_property, false, p_advance);
+ commit_insert_queue();
}
}
diff --git a/editor/animation_track_editor.h b/editor/animation_track_editor.h
index 4c7c1a58f8..7d1c8e7572 100644
--- a/editor/animation_track_editor.h
+++ b/editor/animation_track_editor.h
@@ -712,8 +712,8 @@ public:
void cleanup();
void set_anim_pos(float p_pos);
- void insert_node_value_key(Node *p_node, const String &p_property, const Variant &p_value, bool p_only_if_exists = false);
- void insert_value_key(const String &p_property, const Variant &p_value, bool p_advance);
+ void insert_node_value_key(Node *p_node, const String &p_property, bool p_only_if_exists = false, bool p_advance = false);
+ void insert_value_key(const String &p_property, bool p_advance);
void insert_transform_key(Node3D *p_node, const String &p_sub, const Animation::TrackType p_type, const Variant &p_value);
bool has_track(Node3D *p_node, const String &p_sub, const Animation::TrackType p_type);
void make_insert_queue();
diff --git a/editor/plugins/animation_player_editor_plugin.cpp b/editor/plugins/animation_player_editor_plugin.cpp
index 660e4647a1..bed9983461 100644
--- a/editor/plugins/animation_player_editor_plugin.cpp
+++ b/editor/plugins/animation_player_editor_plugin.cpp
@@ -2165,7 +2165,7 @@ void AnimationPlayerEditorPlugin::_property_keyed(const String &p_keyed, const V
return;
}
te->_clear_selection();
- te->insert_value_key(p_keyed, p_value, p_advance);
+ te->insert_value_key(p_keyed, p_advance);
}
void AnimationPlayerEditorPlugin::_transform_key_request(Object *sp, const String &p_sub, const Transform3D &p_key) {
diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp
index 1afe2ddda7..3108c2f41a 100644
--- a/editor/plugins/canvas_item_editor_plugin.cpp
+++ b/editor/plugins/canvas_item_editor_plugin.cpp
@@ -4319,13 +4319,13 @@ void CanvasItemEditor::_insert_animation_keys(bool p_location, bool p_rotation,
Node2D *n2d = Object::cast_to<Node2D>(ci);
if (key_pos && p_location) {
- te->insert_node_value_key(n2d, "position", n2d->get_position(), p_on_existing);
+ te->insert_node_value_key(n2d, "position", p_on_existing);
}
if (key_rot && p_rotation) {
- te->insert_node_value_key(n2d, "rotation", n2d->get_rotation(), p_on_existing);
+ te->insert_node_value_key(n2d, "rotation", p_on_existing);
}
if (key_scale && p_scale) {
- te->insert_node_value_key(n2d, "scale", n2d->get_scale(), p_on_existing);
+ te->insert_node_value_key(n2d, "scale", p_on_existing);
}
if (n2d->has_meta("_edit_bone_") && n2d->get_parent_item()) {
@@ -4351,13 +4351,13 @@ void CanvasItemEditor::_insert_animation_keys(bool p_location, bool p_rotation,
if (has_chain && ik_chain.size()) {
for (Node2D *&F : ik_chain) {
if (key_pos) {
- te->insert_node_value_key(F, "position", F->get_position(), p_on_existing);
+ te->insert_node_value_key(F, "position", p_on_existing);
}
if (key_rot) {
- te->insert_node_value_key(F, "rotation", F->get_rotation(), p_on_existing);
+ te->insert_node_value_key(F, "rotation", p_on_existing);
}
if (key_scale) {
- te->insert_node_value_key(F, "scale", F->get_scale(), p_on_existing);
+ te->insert_node_value_key(F, "scale", p_on_existing);
}
}
}
@@ -4367,13 +4367,13 @@ void CanvasItemEditor::_insert_animation_keys(bool p_location, bool p_rotation,
Control *ctrl = Object::cast_to<Control>(ci);
if (key_pos) {
- te->insert_node_value_key(ctrl, "position", ctrl->get_position(), p_on_existing);
+ te->insert_node_value_key(ctrl, "position", p_on_existing);
}
if (key_rot) {
- te->insert_node_value_key(ctrl, "rotation", ctrl->get_rotation(), p_on_existing);
+ te->insert_node_value_key(ctrl, "rotation", p_on_existing);
}
if (key_scale) {
- te->insert_node_value_key(ctrl, "size", ctrl->get_size(), p_on_existing);
+ te->insert_node_value_key(ctrl, "size", p_on_existing);
}
}
}