From 864e4e3a6d75d374358a2dc1f6f4c05621baaa1a Mon Sep 17 00:00:00 2001 From: Kasper Arnklit Frandsen Date: Tue, 4 Mar 2025 13:20:52 +0000 Subject: [PATCH] Add alphabetical sorting to Animation Player --- editor/animation_track_editor.cpp | 67 +++++++++++++++++++++++++++++-- editor/animation_track_editor.h | 4 ++ 2 files changed, 67 insertions(+), 4 deletions(-) diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp index 7df40cfec6..7de934dd37 100644 --- a/editor/animation_track_editor.cpp +++ b/editor/animation_track_editor.cpp @@ -3354,7 +3354,7 @@ bool AnimationTrackEdit::_try_select_at_ui_pos(const Point2 &p_pos, bool p_aggre } Variant AnimationTrackEdit::get_drag_data(const Point2 &p_point) { - if (!clicking_on_name) { + if (!clicking_on_name || (get_editor()->is_sorting_alphabetically() && !get_editor()->is_grouping_tracks())) { return Variant(); } @@ -3774,6 +3774,10 @@ Size2 AnimationTrackEditGroup::get_minimum_size() const { return Vector2(0, MAX(font->get_height(font_size), icon_size.y) + separation + content_margin); } +String AnimationTrackEditGroup::get_node_name() const { + return node_name; +} + void AnimationTrackEditGroup::set_timeline(AnimationTimelineEdit *p_timeline) { timeline = p_timeline; timeline->connect("zoom_changed", callable_mp(this, &AnimationTrackEditGroup::_zoom_changed)); @@ -4901,9 +4905,13 @@ void AnimationTrackEditor::_update_tracks() { } RBMap group_sort; + LocalVector group_containers; bool use_grouping = !view_group->is_pressed(); bool use_filter = selected_filter->is_pressed(); + bool use_alphabetic_sorting = alphabetic_sorting->is_pressed(); + + AnimationTrackEdit *selected_track_edit = nullptr; for (int i = 0; i < animation->get_track_count(); i++) { AnimationTrackEdit *track_edit = nullptr; @@ -5014,8 +5022,8 @@ void AnimationTrackEditor::_update_tracks() { VBoxContainer *vb = memnew(VBoxContainer); vb->add_theme_constant_override("separation", 0); vb->add_child(g); - track_vbox->add_child(vb); group_sort[base_path] = vb; + group_containers.push_back(vb); } track_edit->set_in_group(true); @@ -5023,7 +5031,6 @@ void AnimationTrackEditor::_update_tracks() { } else { track_edit->set_in_group(false); - track_vbox->add_child(track_edit); } track_edit->set_timeline(timeline); @@ -5033,7 +5040,7 @@ void AnimationTrackEditor::_update_tracks() { track_edit->set_editor(this); if (selected == i) { - track_edit->grab_focus(); + selected_track_edit = track_edit; } track_edit->connect("timeline_changed", callable_mp(this, &AnimationTrackEditor::_timeline_changed)); @@ -5054,6 +5061,45 @@ void AnimationTrackEditor::_update_tracks() { track_edit->connect("create_reset_request", callable_mp(this, &AnimationTrackEditor::_edit_menu_pressed).bind(EDIT_ADD_RESET_KEY), CONNECT_DEFERRED); track_edit->connect("delete_request", callable_mp(this, &AnimationTrackEditor::_edit_menu_pressed).bind(EDIT_DELETE_SELECTION), CONNECT_DEFERRED); } + + if (use_grouping) { + if (use_alphabetic_sorting) { + struct GroupAlphaCompare { + bool operator()(const VBoxContainer *p_lhs, const VBoxContainer *p_rhs) const { + String lhs_node_name = Object::cast_to(p_lhs->get_child(0))->get_node_name(); + String rhs_node_name = Object::cast_to(p_rhs->get_child(0))->get_node_name(); + return lhs_node_name < rhs_node_name; + } + }; + + group_containers.sort_custom(); + } + + for (VBoxContainer *vb : group_containers) { + track_vbox->add_child(vb); + } + + } else { + if (use_alphabetic_sorting) { + struct TrackAlphaCompare { + bool operator()(const AnimationTrackEdit *p_lhs, const AnimationTrackEdit *p_rhs) const { + String lhs_leaf = (String)p_lhs->get_path().slice(-p_lhs->get_path().get_subname_count() - 1); + String rhs_leaf = (String)p_rhs->get_path().slice(-p_rhs->get_path().get_subname_count() - 1); + return lhs_leaf < rhs_leaf; + } + }; + + track_edits.sort_custom(); + } + + for (AnimationTrackEdit *track_edit : track_edits) { + track_vbox->add_child(track_edit); + } + } + + if (selected_track_edit != nullptr) { + selected_track_edit->grab_focus(); + } } void AnimationTrackEditor::_redraw_tracks() { @@ -5210,6 +5256,7 @@ void AnimationTrackEditor::_notification(int p_what) { view_group->set_button_icon(get_editor_theme_icon(view_group->is_pressed() ? SNAME("AnimationTrackList") : SNAME("AnimationTrackGroup"))); function_name_toggler->set_button_icon(get_editor_theme_icon(SNAME("MemberMethod"))); selected_filter->set_button_icon(get_editor_theme_icon(SNAME("AnimationFilter"))); + alphabetic_sorting->set_button_icon(get_editor_theme_icon(SNAME("Sort"))); imported_anim_warning->set_button_icon(get_editor_theme_icon(SNAME("NodeWarning"))); dummy_player_warning->set_button_icon(get_editor_theme_icon(SNAME("NodeWarning"))); inactive_player_warning->set_button_icon(get_editor_theme_icon(SNAME("NodeWarning"))); @@ -7412,6 +7459,10 @@ bool AnimationTrackEditor::is_grouping_tracks() { return !view_group->is_pressed(); } +bool AnimationTrackEditor::is_sorting_alphabetically() { + return alphabetic_sorting->is_pressed(); +} + bool AnimationTrackEditor::is_function_name_pressed() { return function_name_toggler->is_pressed(); } @@ -7729,6 +7780,14 @@ AnimationTrackEditor::AnimationTrackEditor() { bottom_hf->add_child(selected_filter); + alphabetic_sorting = memnew(Button); + alphabetic_sorting->set_flat(true); + alphabetic_sorting->connect(SceneStringName(pressed), callable_mp(this, &AnimationTrackEditor::_update_tracks)); + alphabetic_sorting->set_toggle_mode(true); + alphabetic_sorting->set_tooltip_text(TTR("Sort tracks/groups alphabetically.\nIf disabled, tracks are shown in the order they are added and can be reordered using drag-and-drop.")); + + bottom_hf->add_child(alphabetic_sorting); + view_group = memnew(Button); view_group->set_flat(true); view_group->connect(SceneStringName(pressed), callable_mp(this, &AnimationTrackEditor::_view_group_toggle)); diff --git a/editor/animation_track_editor.h b/editor/animation_track_editor.h index fa6a143f5a..127e89eeac 100644 --- a/editor/animation_track_editor.h +++ b/editor/animation_track_editor.h @@ -569,6 +569,7 @@ public: void set_timeline(AnimationTimelineEdit *p_timeline); void set_root(Node *p_root); void set_editor(AnimationTrackEditor *p_editor); + String get_node_name() const; AnimationTrackEditGroup(); }; @@ -805,8 +806,10 @@ class AnimationTrackEditor : public VBoxContainer { Button *function_name_toggler = nullptr; void _view_group_toggle(); + Button *view_group = nullptr; Button *selected_filter = nullptr; + Button *alphabetic_sorting = nullptr; void _auto_fit(); void _auto_fit_bezier(); @@ -945,6 +948,7 @@ public: float snap_time(float p_value, bool p_relative = false); float get_snap_unit(); bool is_grouping_tracks(); + bool is_sorting_alphabetically(); PackedStringArray get_selected_section() const; bool is_marker_selected(const StringName &p_marker) const; bool is_marker_moving_selection() const;