diff --git a/src/app/tracklist.cpp b/src/app/tracklist.cpp index c5d7211..1a297ba 100644 --- a/src/app/tracklist.cpp +++ b/src/app/tracklist.cpp @@ -201,27 +201,6 @@ static Metadata_Type get_sorting_alternate_metadata_type(Metadata_Type type) { return METADATA_TITLE; } -static int compare_strings_case_insensitive(const char *a, const char *b) { - for (; *a && *b; ++a, ++b) { - if (isalpha(*a) && isalpha(*b)) { - int ca = tolower(*a); - int cb = tolower(*b); - if (ca < cb) - return -1; - else if (ca > cb) - return 1; - } - else if (isalpha(*a)) - return -1; - else if (isalpha(*b)) - return 1; - } - - if (*a) return 1; - if (*b) return -1; - return 0; -} - static bool track_sorts_before_track(const Track& a, const Track& b, Metadata_Type aspect) { const char *A = get_metadata_string(a.metadata, aspect); const char *B = get_metadata_string(b.metadata, aspect); diff --git a/src/app/tracklist.h b/src/app/tracklist.h index 4f85b28..73d311c 100644 --- a/src/app/tracklist.h +++ b/src/app/tracklist.h @@ -46,6 +46,27 @@ static bool string_contains(const char *haystack, const char *needle) { return false; } +static int compare_strings_case_insensitive(const char *a, const char *b) { + for (; *a && *b; ++a, ++b) { + if (isalpha(*a) && isalpha(*b)) { + int ca = tolower(*a); + int cb = tolower(*b); + if (ca < cb) + return -1; + else if (ca > cb) + return 1; + } + else if (isalpha(*a)) + return -1; + else if (isalpha(*b)) + return 1; + } + + if (*a) return 1; + if (*b) return -1; + return 0; +} + struct Track_Filter { uint32 enabled; const char *filter; diff --git a/src/app/ui.cpp b/src/app/ui.cpp index e90d90d..d3f50c5 100644 --- a/src/app/ui.cpp +++ b/src/app/ui.cpp @@ -120,6 +120,7 @@ static struct { Stream_State state; int32 queue_position; Auto_Array playlists; + Auto_Array playlist_order; // Order of user playlists int32 renaming_playlist; int32 selected_playlist; int32 queued_playlist; @@ -215,6 +216,37 @@ static void goto_previous_track() { } } +static void quick_sort_playlists(Auto_Array& order, int low, int high) { + int pivot; + if (low < high) { + pivot = high; + { + int i = low-1; + for (int j = low; j <= high-1; ++j) { + bool j_before_pivot = compare_strings_case_insensitive(G.playlists[order[j]].name, + G.playlists[order[pivot]].name) == -1; + if (j_before_pivot) { + i++; + SWAP(G.playlists[order[i]], G.playlists[order[j]]); + } + } + SWAP(G.playlists[order[i+1]], G.playlists[order[high]]); + pivot = i + 1; + } + + quick_sort_playlists(order, low, pivot-1); + quick_sort_playlists(order, pivot+1, high); + } +} + +static void sort_playlists() { + uint32 count = G.playlists.m_count; + G.playlist_order.reset(); + for (uint32 i = PLAYLIST_USER; i < G.playlists.m_count; ++i) + G.playlist_order.append(i); + quick_sort_playlists(G.playlist_order, 0, G.playlist_order.m_count-1); +} + static int32 show_playlist_dropdown_selector() { uint32 playlist_count = G.playlists.length(); char name_id[128]; @@ -511,7 +543,9 @@ void init_ui() { if (!file_exists("playlists")) { create_directory("playlists"); } + sort_playlists(); STOP_TIMER(load_playlists); + G.renaming_playlist = -1; G.selected_playlist = PLAYLIST_LIBRARY; G.queued_playlist = -1; @@ -538,6 +572,7 @@ static void queue_playlist(int32 index) { static void create_playlist() { Tracklist list = {}; G.renaming_playlist = G.playlists.append(list); + G.playlist_order.append(G.renaming_playlist); } static bool add_from_file_select_dialog_callback(const char *path) { @@ -757,6 +792,7 @@ bool show_ui() { G.playlists.remove_range(deleting_playlist, deleting_playlist); if (deleting_playlist == G.selected_playlist) G.selected_playlist = -1; if (deleting_playlist == G.queued_playlist) G.queued_playlist = -1; + sort_playlists(); ImGui::CloseCurrentPopup(); } ImGui::SameLine(); @@ -767,7 +803,9 @@ bool show_ui() { } // Show list of user playlists - for (uint32 iplaylist = PLAYLIST_USER; iplaylist < playlist_count; ++iplaylist) { + for (uint32 order = 0; order < G.playlist_order.m_count; ++order) { + uint32 iplaylist = G.playlist_order[order]; + if (iplaylist < PLAYLIST_USER || iplaylist >= G.playlists.m_count) continue; Tracklist &playlist = G.playlists[iplaylist]; ImGui::TableNextRow(); ImGui::TableSetColumnIndex(0); @@ -776,12 +814,26 @@ bool show_ui() { bool commit = false; ImGui::SetWindowFocus(); ImGui::SetKeyboardFocusHere(); + commit |= ImGui::InputText("##playlist_name", playlist.name, sizeof(playlist.name), ImGuiInputTextFlags_EnterReturnsTrue); if (commit) { + // Store the name of the playlist so we can find its new index in the playlist array + char name[sizeof(playlist.name)+1]; + name[sizeof(playlist.name)] = 0; + strncpy(name, playlist.name, sizeof(playlist.name)); + G.renaming_playlist = -1; - G.selected_playlist = iplaylist; playlist.save_to_file(); + sort_playlists(); + + // Find new index of playlist and select it + for (uint32 i = PLAYLIST_USER; i < G.playlists.m_count; ++i) { + if (!strcmp(G.playlists[i].name, name)) { + G.selected_playlist = i; + break; + } + } } } else {