diff options
-rw-r--r-- | deadbeef.h | 9 | ||||
-rw-r--r-- | playlist.c | 58 | ||||
-rw-r--r-- | playlist.h | 5 | ||||
-rw-r--r-- | plugins.c | 2 | ||||
-rw-r--r-- | plugins/gtkui/callbacks.c | 27 | ||||
-rw-r--r-- | plugins/gtkui/callbacks.h | 4 | ||||
-rw-r--r-- | plugins/gtkui/deadbeef.glade | 9 | ||||
-rw-r--r-- | plugins/gtkui/interface.c | 9 |
8 files changed, 113 insertions, 10 deletions
@@ -295,6 +295,13 @@ enum { DDB_REPLAYGAIN_TRACKPEAK, }; +// sort order constants +enum ddb_sort_order_t { + DDB_SORT_DESCENDING, + DDB_SORT_ASCENDING, + DDB_SORT_RANDOM, // available since API 1.3 +}; + // typecasting macros #define DB_PLUGIN(x) ((DB_plugin_t *)(x)) #define DB_CALLBACK(x) ((DB_callback_t)(x)) @@ -476,7 +483,7 @@ typedef struct { void (*plt_copy_items) (ddb_playlist_t *to, int iter, ddb_playlist_t * from, DB_playItem_t *before, uint32_t *indices, int cnt); void (*plt_search_reset) (ddb_playlist_t *plt); void (*plt_search_process) (ddb_playlist_t *plt, const char *text); - void (*plt_sort) (ddb_playlist_t *plt, int iter, int id, const char *format, int ascending); + void (*plt_sort) (ddb_playlist_t *plt, int iter, int id, const char *format, int order); // add files and folders to current playlist int (*plt_add_file) (ddb_playlist_t *plt, const char *fname, int (*cb)(DB_playItem_t *it, void *data), void *user_data); @@ -3174,7 +3174,13 @@ qsort_cmp_func (const void *a, const void *b) { } void -plt_sort (playlist_t *playlist, int iter, int id, const char *format, int ascending) { +plt_sort (playlist_t *playlist, int iter, int id, const char *format, int order) { + if (order == DDB_SORT_RANDOM) { + plt_sort_random (playlist, iter); + return; + } + int ascending = order == DDB_SORT_DESCENDING ? 0 : 1; + if (id == DB_COLUMN_FILENUMBER || !playlist->head[iter] || !playlist->head[iter]->next[iter]) { return; } @@ -3234,6 +3240,56 @@ plt_sort (playlist_t *playlist, int iter, int id, const char *format, int ascend } void +plt_sort_random (playlist_t *playlist, int iter) { + if (!playlist->head[iter] || !playlist->head[iter]->next[iter]) { + return; + } + + LOCK; + + const int playlist_count = playlist->count[iter]; + playItem_t **array = malloc (playlist_count * sizeof (playItem_t *)); + int idx = 0; + for (playItem_t *it = playlist->head[iter]; it; it = it->next[iter], idx++) { + array[idx] = it; + } + + //randomize array + for (int swap_a = 0; swap_a < playlist_count - 1; swap_a++) { + //select random item above swap_a-1 + const int swap_b = swap_a + (rand() / (float)RAND_MAX * (playlist_count - swap_a)); + + //swap a with b + playItem_t* const swap_temp = array[swap_a]; + array[swap_a] = array[swap_b]; + array[swap_b] = swap_temp; + + } + + playItem_t *prev = NULL; + playlist->head[iter] = 0; + for (idx = 0; idx < playlist->count[iter]; idx++) { + playItem_t *it = array[idx]; + it->prev[iter] = prev; + it->next[iter] = NULL; + if (!prev) { + playlist->head[iter] = it; + } + else { + prev->next[iter] = it; + } + prev = it; + } + playlist->tail[iter] = array[playlist->count[iter]-1]; + + free (array); + + plt_modified (playlist); + + UNLOCK; +} + +void plt_reset_cursor (playlist_t *playlist) { int i; LOCK; @@ -400,7 +400,10 @@ void plt_search_process (playlist_t *plt, const char *text); void -plt_sort (playlist_t *plt, int iter, int id, const char *format, int ascending); +plt_sort (playlist_t *plt, int iter, int id, const char *format, int order); + +void +plt_sort_random (playlist_t *plt, int iter); // playqueue support functions int @@ -172,7 +172,7 @@ static DB_functions_t deadbeef_api = { .pl_get_item_duration = (float (*) (DB_playItem_t *it))pl_get_item_duration, .pl_get_item_flags = (uint32_t (*) (DB_playItem_t *it))pl_get_item_flags, .pl_set_item_flags = (void (*) (DB_playItem_t *it, uint32_t flags))pl_set_item_flags, - .plt_sort = (void (*) (ddb_playlist_t *plt, int iter, int id, const char *format, int ascending))plt_sort, + .plt_sort = (void (*) (ddb_playlist_t *plt, int iter, int id, const char *format, int order))plt_sort, .pl_items_copy_junk = (void (*)(DB_playItem_t *from, DB_playItem_t *first, DB_playItem_t *last))pl_items_copy_junk, .pl_set_item_replaygain = (void (*)(DB_playItem_t *it, int idx, float value))pl_set_item_replaygain, .pl_get_item_replaygain = (float (*)(DB_playItem_t *it, int idx))pl_get_item_replaygain, diff --git a/plugins/gtkui/callbacks.c b/plugins/gtkui/callbacks.c index 3005bc27..be18328c 100644 --- a/plugins/gtkui/callbacks.c +++ b/plugins/gtkui/callbacks.c @@ -1154,7 +1154,7 @@ on_sort_by_title_activate (GtkMenuItem *menuitem, gpointer user_data) { ddb_playlist_t *plt = deadbeef->plt_get_curr (); - deadbeef->plt_sort (plt, PL_MAIN, -1, "%t", 1); + deadbeef->plt_sort (plt, PL_MAIN, -1, "%t", DDB_SORT_ASCENDING); deadbeef->plt_unref (plt); DdbListview *pl = DDB_LISTVIEW (lookup_widget (mainwin, "playlist")); @@ -1168,7 +1168,7 @@ on_sort_by_track_nr_activate (GtkMenuItem *menuitem, gpointer user_data) { ddb_playlist_t *plt = deadbeef->plt_get_curr (); - deadbeef->plt_sort (plt, PL_MAIN, -1, "%n", 1); + deadbeef->plt_sort (plt, PL_MAIN, -1, "%n", DDB_SORT_ASCENDING); deadbeef->plt_unref (plt); DdbListview *pl = DDB_LISTVIEW (lookup_widget (mainwin, "playlist")); @@ -1182,7 +1182,7 @@ on_sort_by_album_activate (GtkMenuItem *menuitem, gpointer user_data) { ddb_playlist_t *plt = deadbeef->plt_get_curr (); - deadbeef->plt_sort (plt, PL_MAIN, -1, "%b", 1); + deadbeef->plt_sort (plt, PL_MAIN, -1, "%b", DDB_SORT_ASCENDING); deadbeef->plt_unref (plt); DdbListview *pl = DDB_LISTVIEW (lookup_widget (mainwin, "playlist")); @@ -1196,7 +1196,7 @@ on_sort_by_artist_activate (GtkMenuItem *menuitem, gpointer user_data) { ddb_playlist_t *plt = deadbeef->plt_get_curr (); - deadbeef->plt_sort (plt, PL_MAIN, -1, "%a", 1); + deadbeef->plt_sort (plt, PL_MAIN, -1, "%a", DDB_SORT_ASCENDING); deadbeef->plt_unref (plt); DdbListview *pl = DDB_LISTVIEW (lookup_widget (mainwin, "playlist")); @@ -1210,7 +1210,22 @@ on_sort_by_date_activate (GtkMenuItem *menuitem, gpointer user_data) { ddb_playlist_t *plt = deadbeef->plt_get_curr (); - deadbeef->plt_sort (plt, PL_MAIN, -1, "%y", 1); + deadbeef->plt_sort (plt, PL_MAIN, -1, "%y", DDB_SORT_ASCENDING); + deadbeef->plt_unref (plt); + + DdbListview *pl = DDB_LISTVIEW (lookup_widget (mainwin, "playlist")); + ddb_listview_clear_sort (pl); + ddb_listview_refresh (pl, DDB_REFRESH_LIST | DDB_LIST_CHANGED); +} + + +void +on_sort_by_random_activate (GtkMenuItem *menuitem, + gpointer user_data) +{ + ddb_playlist_t *plt = deadbeef->plt_get_curr (); + deadbeef->plt_sort (plt, PL_MAIN, -1, NULL, DDB_SORT_RANDOM); + deadbeef->plt_unref (plt); DdbListview *pl = DDB_LISTVIEW (lookup_widget (mainwin, "playlist")); @@ -1246,7 +1261,7 @@ on_sort_by_custom_activate (GtkMenuItem *menuitem, deadbeef->conf_set_str ("gtkui.sortby_fmt", fmt); ddb_playlist_t *plt = deadbeef->plt_get_curr (); - deadbeef->plt_sort (plt, PL_MAIN, -1, fmt, order == 0 ? 1 : 0); + deadbeef->plt_sort (plt, PL_MAIN, -1, fmt, order == 0 ? DDB_SORT_ASCENDING : DDB_SORT_DESCENDING); deadbeef->plt_unref (plt); DdbListview *pl = DDB_LISTVIEW (lookup_widget (mainwin, "playlist")); diff --git a/plugins/gtkui/callbacks.h b/plugins/gtkui/callbacks.h index e463394d..a354baca 100644 --- a/plugins/gtkui/callbacks.h +++ b/plugins/gtkui/callbacks.h @@ -1149,6 +1149,10 @@ on_sort_by_date_activate (GtkMenuItem *menuitem, gpointer user_data); void +on_sort_by_random_activate (GtkMenuItem *menuitem, + gpointer user_data); + +void on_sort_by_custom_activate (GtkMenuItem *menuitem, gpointer user_data); diff --git a/plugins/gtkui/deadbeef.glade b/plugins/gtkui/deadbeef.glade index cffda5b5..184b66fd 100644 --- a/plugins/gtkui/deadbeef.glade +++ b/plugins/gtkui/deadbeef.glade @@ -365,6 +365,15 @@ </child> <child> + <widget class="GtkMenuItem" id="random1"> + <property name="visible">True</property> + <property name="label" translatable="yes">Random</property> + <property name="use_underline">True</property> + <signal name="activate" handler="on_sort_by_random_activate" last_modification_time="Sun, 26 Feb 2012 19:22:44 GMT"/> + </widget> + </child> + + <child> <widget class="GtkMenuItem" id="custom2"> <property name="visible">True</property> <property name="label" translatable="yes">Custom</property> diff --git a/plugins/gtkui/interface.c b/plugins/gtkui/interface.c index 57db14db..84649092 100644 --- a/plugins/gtkui/interface.c +++ b/plugins/gtkui/interface.c @@ -69,6 +69,7 @@ create_mainwin (void) GtkWidget *album1; GtkWidget *artist1; GtkWidget *date1; + GtkWidget *random1; GtkWidget *custom2; GtkWidget *separator5; GtkWidget *preferences; @@ -312,6 +313,10 @@ create_mainwin (void) gtk_widget_show (date1); gtk_container_add (GTK_CONTAINER (sort_by1_menu), date1); + random1 = gtk_menu_item_new_with_mnemonic (_("Random")); + gtk_widget_show (random1); + gtk_container_add (GTK_CONTAINER (sort_by1_menu), random1); + custom2 = gtk_menu_item_new_with_mnemonic (_("Custom")); gtk_widget_show (custom2); gtk_container_add (GTK_CONTAINER (sort_by1_menu), custom2); @@ -693,6 +698,9 @@ create_mainwin (void) g_signal_connect ((gpointer) date1, "activate", G_CALLBACK (on_sort_by_date_activate), NULL); + g_signal_connect ((gpointer) random1, "activate", + G_CALLBACK (on_sort_by_random_activate), + NULL); g_signal_connect ((gpointer) custom2, "activate", G_CALLBACK (on_sort_by_custom_activate), NULL); @@ -819,6 +827,7 @@ create_mainwin (void) GLADE_HOOKUP_OBJECT (mainwin, album1, "album1"); GLADE_HOOKUP_OBJECT (mainwin, artist1, "artist1"); GLADE_HOOKUP_OBJECT (mainwin, date1, "date1"); + GLADE_HOOKUP_OBJECT (mainwin, random1, "random1"); GLADE_HOOKUP_OBJECT (mainwin, custom2, "custom2"); GLADE_HOOKUP_OBJECT (mainwin, separator5, "separator5"); GLADE_HOOKUP_OBJECT (mainwin, preferences, "preferences"); |