diff --git a/editor/animation/animation_player_editor_plugin.cpp b/editor/animation/animation_player_editor_plugin.cpp index 18bcf9f833a..2509674ab3c 100644 --- a/editor/animation/animation_player_editor_plugin.cpp +++ b/editor/animation/animation_player_editor_plugin.cpp @@ -56,6 +56,24 @@ /////////////////////////////////// +void AnimationPlayerEditor::_find_player() { + if (!is_visible() || player) { + return; + } + + Node *edited_scene = EditorNode::get_singleton()->get_edited_scene(); + + if (!edited_scene) { + return; + } + + TypedArray players = edited_scene->find_children("", "AnimationPlayer"); + + if (players.size() == 1) { + plugin->edit(players.front()); + } +} + void AnimationPlayerEditor::_node_removed(Node *p_node) { if (player && original_node == p_node) { if (is_dummy) { @@ -130,6 +148,8 @@ void AnimationPlayerEditor::_notification(int p_what) { get_tree()->connect(SNAME("node_removed"), callable_mp(this, &AnimationPlayerEditor::_node_removed)); + EditorNode::get_singleton()->connect("scene_changed", callable_mp(this, &AnimationPlayerEditor::_find_player)); + add_theme_style_override(SceneStringName(panel), EditorNode::get_singleton()->get_editor_theme()->get_stylebox(SceneStringName(panel), SNAME("Panel"))); } break; @@ -190,6 +210,7 @@ void AnimationPlayerEditor::_notification(int p_what) { } break; case NOTIFICATION_VISIBILITY_CHANGED: { + _find_player(); _ensure_dummy_player(); } break; } diff --git a/editor/animation/animation_player_editor_plugin.h b/editor/animation/animation_player_editor_plugin.h index cbf8ee9deb8..7ebc3f276aa 100644 --- a/editor/animation/animation_player_editor_plugin.h +++ b/editor/animation/animation_player_editor_plugin.h @@ -249,6 +249,7 @@ class AnimationPlayerEditor : public VBoxContainer { protected: void _notification(int p_what); void _node_removed(Node *p_node); + void _find_player(); static void _bind_methods(); public: diff --git a/editor/animation/animation_track_editor.cpp b/editor/animation/animation_track_editor.cpp index c26f65dc3fe..3fe0270e5f0 100644 --- a/editor/animation/animation_track_editor.cpp +++ b/editor/animation/animation_track_editor.cpp @@ -31,6 +31,7 @@ #include "animation_track_editor.h" #include "animation_track_editor_plugins.h" +#include "core/config/project_settings.h" #include "core/error/error_macros.h" #include "core/input/input.h" #include "editor/animation/animation_bezier_editor.h" @@ -4897,7 +4898,7 @@ AnimationTrackEditor::TrackIndices AnimationTrackEditor::_confirm_insert(InsertD } void AnimationTrackEditor::show_select_node_warning(bool p_show) { - info_message->set_visible(p_show); + info_message_vbox->set_visible(p_show); } void AnimationTrackEditor::show_dummy_player_warning(bool p_show) { @@ -5350,6 +5351,7 @@ void AnimationTrackEditor::_notification(int p_what) { panner->setup_warped_panning(get_viewport(), EDITOR_GET("editors/panning/warped_mouse_panning")); } break; case NOTIFICATION_THEME_CHANGED: { + add_animation_player->set_button_icon(get_editor_theme_icon(SNAME("Add"))); zoom_icon->set_texture(get_editor_theme_icon(SNAME("Zoom"))); bezier_edit_icon->set_button_icon(get_editor_theme_icon(SNAME("EditBezier"))); snap_timeline->set_button_icon(get_editor_theme_icon(SNAME("SnapTimeline"))); @@ -5378,6 +5380,11 @@ void AnimationTrackEditor::_notification(int p_what) { } break; case NOTIFICATION_READY: { + Node *scene_root = EditorNode::get_singleton()->get_scene_root(); + scene_root->connect("child_entered_tree", callable_mp(this, &AnimationTrackEditor::_root_node_changed).bind(false)); + scene_root->connect("child_exiting_tree", callable_mp(this, &AnimationTrackEditor::_root_node_changed).bind(true)); + + EditorNode::get_singleton()->connect("scene_changed", callable_mp(this, &AnimationTrackEditor::_scene_changed)); EditorNode::get_singleton()->get_editor_selection()->connect("selection_changed", callable_mp(this, &AnimationTrackEditor::_selection_changed)); } break; @@ -7592,6 +7599,14 @@ void AnimationTrackEditor::_auto_fit_bezier() { } } +void AnimationTrackEditor::_root_node_changed(Node *p_node, bool p_removed) { + add_animation_player->set_disabled(p_removed); +} + +void AnimationTrackEditor::_scene_changed() { + add_animation_player->set_disabled(EditorNode::get_singleton()->get_edited_scene() == nullptr); +} + void AnimationTrackEditor::_selection_changed() { if (selected_filter->is_pressed()) { _update_tracks(); // Needs updating. @@ -7650,6 +7665,36 @@ float AnimationTrackEditor::get_snap_unit() { return snap_unit; } +void AnimationTrackEditor::_add_animation_player() { + EditorData &editor_data = EditorNode::get_editor_data(); + Node *scene = editor_data.get_edited_scene_root(); + + ERR_FAIL_NULL_EDMSG(scene, "Cannot add AnimationPlayer without root node in scene"); + + AnimationPlayer *animation_player = memnew(AnimationPlayer); + editor_data.instantiate_object_properties(animation_player); + + String new_name = scene->validate_child_name(animation_player); + if (GLOBAL_GET("editor/naming/node_name_casing").operator int() != NAME_CASING_PASCAL_CASE) { + new_name = adjust_name_casing(new_name); + } + animation_player->set_name(new_name); + + EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton(); + undo_redo->create_action_for_history(TTR("Create Node"), editor_data.get_current_edited_scene_history_id()); + + undo_redo->add_do_method(scene, "add_child", animation_player, true); + undo_redo->add_do_method(animation_player, "set_owner", scene); + undo_redo->add_do_reference(animation_player); + undo_redo->add_undo_method(scene, "remove_child", animation_player); + + undo_redo->commit_action(); + + EditorSelection *editor_selection = EditorNode::get_singleton()->get_editor_selection(); + editor_selection->clear(); + editor_selection->add_node(animation_player); +} + void AnimationTrackEditor::_show_imported_anim_warning() { // It looks terrible on a single line but the TTR extractor doesn't support line breaks yet. EditorNode::get_singleton()->show_warning( @@ -7766,7 +7811,14 @@ AnimationTrackEditor::AnimationTrackEditor() { timeline_vbox->set_v_size_flags(SIZE_EXPAND_FILL); timeline_vbox->set_h_size_flags(SIZE_EXPAND_FILL); + info_message_vbox = memnew(VBoxContainer); + main_panel->add_child(info_message_vbox); + info_message_vbox->set_alignment(AlignmentMode::ALIGNMENT_CENTER); + info_message_vbox->set_v_size_flags(SIZE_EXPAND_FILL); + info_message_vbox->set_h_size_flags(SIZE_EXPAND_FILL); + info_message = memnew(Label); + info_message_vbox->add_child(info_message); info_message->set_focus_mode(FOCUS_ACCESSIBILITY); info_message->set_text(TTR("Select an AnimationPlayer node to create and edit animations.")); info_message->set_vertical_alignment(VERTICAL_ALIGNMENT_CENTER); @@ -7774,7 +7826,13 @@ AnimationTrackEditor::AnimationTrackEditor() { info_message->set_autowrap_mode(TextServer::AUTOWRAP_WORD_SMART); info_message->set_custom_minimum_size(Size2(100 * EDSCALE, 0)); info_message->set_anchors_and_offsets_preset(PRESET_FULL_RECT, PRESET_MODE_KEEP_SIZE, 8 * EDSCALE); - main_panel->add_child(info_message); + + add_animation_player = memnew(Button); + info_message_vbox->add_child(add_animation_player); + add_animation_player->set_text(TTR("Add AnimationPlayer")); + add_animation_player->set_tooltip_text(TTR("Add a new AnimationPlayer node to the scene.")); + add_animation_player->set_h_size_flags(SIZE_SHRINK_CENTER); + add_animation_player->connect(SceneStringName(pressed), callable_mp(this, &AnimationTrackEditor::_add_animation_player)); timeline = memnew(AnimationTimelineEdit); timeline_vbox->add_child(timeline); diff --git a/editor/animation/animation_track_editor.h b/editor/animation/animation_track_editor.h index c6458f9df71..8e80a5bc35d 100644 --- a/editor/animation/animation_track_editor.h +++ b/editor/animation/animation_track_editor.h @@ -603,7 +603,10 @@ class AnimationTrackEditor : public VBoxContainer { AnimationBezierTrackEdit *bezier_edit = nullptr; VBoxContainer *timeline_vbox = nullptr; + VBoxContainer *info_message_vbox = nullptr; Label *info_message = nullptr; + Button *add_animation_player = nullptr; + void _add_animation_player(); AnimationTimelineEdit *timeline = nullptr; AnimationMarkerEdit *marker_edit = nullptr; @@ -827,6 +830,8 @@ class AnimationTrackEditor : public VBoxContainer { void _auto_fit(); void _auto_fit_bezier(); + void _root_node_changed(Node *p_node, bool p_removed); + void _scene_changed(); void _selection_changed(); ConfirmationDialog *track_copy_dialog = nullptr;