@@ -3354,7 +3354,7 @@ bool AnimationTrackEdit::_try_select_at_ui_pos(const Point2 &p_pos, bool p_aggre
33543354}
33553355
33563356Variant AnimationTrackEdit::get_drag_data (const Point2 &p_point) {
3357- if (!clicking_on_name) {
3357+ if (!clicking_on_name || ( get_editor ()-> is_sorting_alphabetically () && ! get_editor ()-> is_grouping_tracks ()) ) {
33583358 return Variant ();
33593359 }
33603360
@@ -3774,6 +3774,10 @@ Size2 AnimationTrackEditGroup::get_minimum_size() const {
37743774 return Vector2 (0 , MAX (font->get_height (font_size), icon_size.y ) + separation + content_margin);
37753775}
37763776
3777+ String AnimationTrackEditGroup::get_node_name () const {
3778+ return node_name;
3779+ }
3780+
37773781void AnimationTrackEditGroup::set_timeline (AnimationTimelineEdit *p_timeline) {
37783782 timeline = p_timeline;
37793783 timeline->connect (" zoom_changed" , callable_mp (this , &AnimationTrackEditGroup::_zoom_changed));
@@ -4901,9 +4905,13 @@ void AnimationTrackEditor::_update_tracks() {
49014905 }
49024906
49034907 RBMap<String, VBoxContainer *> group_sort;
4908+ LocalVector<VBoxContainer *> group_containers;
49044909
49054910 bool use_grouping = !view_group->is_pressed ();
49064911 bool use_filter = selected_filter->is_pressed ();
4912+ bool use_alphabetic_sorting = alphabetic_sorting->is_pressed ();
4913+
4914+ AnimationTrackEdit *selected_track_edit = nullptr ;
49074915
49084916 for (int i = 0 ; i < animation->get_track_count (); i++) {
49094917 AnimationTrackEdit *track_edit = nullptr ;
@@ -5014,16 +5022,15 @@ void AnimationTrackEditor::_update_tracks() {
50145022 VBoxContainer *vb = memnew (VBoxContainer);
50155023 vb->add_theme_constant_override (" separation" , 0 );
50165024 vb->add_child (g);
5017- track_vbox->add_child (vb);
50185025 group_sort[base_path] = vb;
5026+ group_containers.push_back (vb);
50195027 }
50205028
50215029 track_edit->set_in_group (true );
50225030 group_sort[base_path]->add_child (track_edit);
50235031
50245032 } else {
50255033 track_edit->set_in_group (false );
5026- track_vbox->add_child (track_edit);
50275034 }
50285035
50295036 track_edit->set_timeline (timeline);
@@ -5033,7 +5040,7 @@ void AnimationTrackEditor::_update_tracks() {
50335040 track_edit->set_editor (this );
50345041
50355042 if (selected == i) {
5036- track_edit-> grab_focus () ;
5043+ selected_track_edit = track_edit;
50375044 }
50385045
50395046 track_edit->connect (" timeline_changed" , callable_mp (this , &AnimationTrackEditor::_timeline_changed));
@@ -5054,6 +5061,45 @@ void AnimationTrackEditor::_update_tracks() {
50545061 track_edit->connect (" create_reset_request" , callable_mp (this , &AnimationTrackEditor::_edit_menu_pressed).bind (EDIT_ADD_RESET_KEY), CONNECT_DEFERRED);
50555062 track_edit->connect (" delete_request" , callable_mp (this , &AnimationTrackEditor::_edit_menu_pressed).bind (EDIT_DELETE_SELECTION), CONNECT_DEFERRED);
50565063 }
5064+
5065+ if (use_grouping) {
5066+ if (use_alphabetic_sorting) {
5067+ struct GroupAlphaCompare {
5068+ bool operator ()(const VBoxContainer *p_lhs, const VBoxContainer *p_rhs) const {
5069+ String lhs_node_name = Object::cast_to<AnimationTrackEditGroup>(p_lhs->get_child (0 ))->get_node_name ();
5070+ String rhs_node_name = Object::cast_to<AnimationTrackEditGroup>(p_rhs->get_child (0 ))->get_node_name ();
5071+ return lhs_node_name < rhs_node_name;
5072+ }
5073+ };
5074+
5075+ group_containers.sort_custom <GroupAlphaCompare>();
5076+ }
5077+
5078+ for (VBoxContainer *vb : group_containers) {
5079+ track_vbox->add_child (vb);
5080+ }
5081+
5082+ } else {
5083+ if (use_alphabetic_sorting) {
5084+ struct TrackAlphaCompare {
5085+ bool operator ()(const AnimationTrackEdit *p_lhs, const AnimationTrackEdit *p_rhs) const {
5086+ String lhs_leaf = (String)p_lhs->get_path ().slice (-p_lhs->get_path ().get_subname_count () - 1 );
5087+ String rhs_leaf = (String)p_rhs->get_path ().slice (-p_rhs->get_path ().get_subname_count () - 1 );
5088+ return lhs_leaf < rhs_leaf;
5089+ }
5090+ };
5091+
5092+ track_edits.sort_custom <TrackAlphaCompare>();
5093+ }
5094+
5095+ for (AnimationTrackEdit *track_edit : track_edits) {
5096+ track_vbox->add_child (track_edit);
5097+ }
5098+ }
5099+
5100+ if (selected_track_edit != nullptr ) {
5101+ selected_track_edit->grab_focus ();
5102+ }
50575103}
50585104
50595105void AnimationTrackEditor::_redraw_tracks () {
@@ -5210,6 +5256,7 @@ void AnimationTrackEditor::_notification(int p_what) {
52105256 view_group->set_button_icon (get_editor_theme_icon (view_group->is_pressed () ? SNAME (" AnimationTrackList" ) : SNAME (" AnimationTrackGroup" )));
52115257 function_name_toggler->set_button_icon (get_editor_theme_icon (SNAME (" MemberMethod" )));
52125258 selected_filter->set_button_icon (get_editor_theme_icon (SNAME (" AnimationFilter" )));
5259+ alphabetic_sorting->set_button_icon (get_editor_theme_icon (SNAME (" Sort" )));
52135260 imported_anim_warning->set_button_icon (get_editor_theme_icon (SNAME (" NodeWarning" )));
52145261 dummy_player_warning->set_button_icon (get_editor_theme_icon (SNAME (" NodeWarning" )));
52155262 inactive_player_warning->set_button_icon (get_editor_theme_icon (SNAME (" NodeWarning" )));
@@ -7412,6 +7459,10 @@ bool AnimationTrackEditor::is_grouping_tracks() {
74127459 return !view_group->is_pressed ();
74137460}
74147461
7462+ bool AnimationTrackEditor::is_sorting_alphabetically () {
7463+ return alphabetic_sorting->is_pressed ();
7464+ }
7465+
74157466bool AnimationTrackEditor::is_function_name_pressed () {
74167467 return function_name_toggler->is_pressed ();
74177468}
@@ -7730,6 +7781,14 @@ AnimationTrackEditor::AnimationTrackEditor() {
77307781
77317782 bottom_hf->add_child (selected_filter);
77327783
7784+ alphabetic_sorting = memnew (Button);
7785+ alphabetic_sorting->set_flat (true );
7786+ alphabetic_sorting->connect (SceneStringName (pressed), callable_mp (this , &AnimationTrackEditor::_update_tracks));
7787+ alphabetic_sorting->set_toggle_mode (true );
7788+ alphabetic_sorting->set_tooltip_text (TTR (" Sort tracks/groups alphabetically.\n If disabled, tracks are shown in the order they are added and can be reordered using drag-and-drop." ));
7789+
7790+ bottom_hf->add_child (alphabetic_sorting);
7791+
77337792 view_group = memnew (Button);
77347793 view_group->set_flat (true );
77357794 view_group->connect (SceneStringName (pressed), callable_mp (this , &AnimationTrackEditor::_view_group_toggle));
0 commit comments