summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--deadbeef.h4
-rw-r--r--playlist.c39
-rw-r--r--playlist.h7
-rw-r--r--plugins.c1
-rw-r--r--plugins/gtkui/gtkui.c85
5 files changed, 129 insertions, 7 deletions
diff --git a/deadbeef.h b/deadbeef.h
index 396e1c9b..ba05f5cf 100644
--- a/deadbeef.h
+++ b/deadbeef.h
@@ -82,13 +82,12 @@ extern "C" {
// these are "public" fields, available to plugins
typedef struct DB_playItem_s {
char *fname; // full pathname
-// struct DB_decoder_s *decoder; // codec to use with this file
const char *decoder_id;
int tracknum; // used for stuff like sid, nsf, cue (will be ignored by most codecs)
int startsample; // start sample of track, or -1 for auto
int endsample; // end sample of track, or -1 for auto
int shufflerating; // sort order for shuffle mode
- float playtime; // total playtime
+ float playtime; // actual playback time of this track in seconds
time_t started_timestamp; // result of calling time(NULL)
const char *filetype; // e.g. MP3 or OGG
float replaygain_album_gain;
@@ -311,6 +310,7 @@ typedef struct {
int (*pl_get_cursor) (int iter);
void (*pl_set_selected) (DB_playItem_t *it, int sel);
int (*pl_is_selected) (DB_playItem_t *it);
+ int (*pl_is_group_title) (DB_playItem_t *it);
void (*pl_clear) (void);
int (*pl_load) (const char *name);
int (*pl_save) (const char *name);
diff --git a/playlist.c b/playlist.c
index 22e33a23..95530b00 100644
--- a/playlist.c
+++ b/playlist.c
@@ -2562,3 +2562,42 @@ pl_items_copy_junk (playItem_t *from, playItem_t *first, playItem_t *last) {
}
UNLOCK;
}
+
+void
+pl_group_by (const char *fmt) {
+ // remove all groupings
+ playItem_t *it;
+ it = playlist->head[PL_MAIN];
+ while (it) {
+ playItem_t *next = it->next[PL_MAIN];
+ if (it->is_group_title) {
+ pl_remove (it);
+ }
+ it = next;
+ }
+
+ // insert new
+ if (fmt) {
+ it = playlist->head[PL_MAIN];
+ char str[1024] = "--";
+ char curr[1024];
+ int idx = 0;
+ while (it) {
+ pl_format_title (it, -1, curr, sizeof (curr), -1, fmt);
+ if (strcmp (str, curr)) {
+ strcpy (str, curr);
+ playItem_t *grp = pl_item_alloc ();
+ grp->fname = strdup (str);
+ grp->is_group_title = 1;
+ it = pl_insert_item (it->prev[PL_MAIN], grp);
+ pl_item_unref (it);
+ }
+ it = it->next[PL_MAIN];
+ }
+ }
+}
+
+int
+pl_is_group_title (playItem_t *it) {
+ return it->is_group_title;
+}
diff --git a/playlist.h b/playlist.h
index df695662..c3a99107 100644
--- a/playlist.h
+++ b/playlist.h
@@ -53,6 +53,7 @@ typedef struct playItem_s {
unsigned selected : 1;
unsigned played : 1; // mark as played in shuffle mode
unsigned in_playlist : 1; // 1 if item is in playlist
+ unsigned is_group_title : 1; // 1 if this is a group title
} playItem_t;
typedef struct playlist_s {
@@ -245,6 +246,12 @@ pl_set_selected (playItem_t *it, int sel);
int
pl_is_selected (playItem_t *it);
+int
+pl_is_group_title (playItem_t *it);
+
+void
+pl_group_by (const char *fmt);
+
playItem_t *
pl_get_first (int iter);
diff --git a/plugins.c b/plugins.c
index 6ac46182..4c933479 100644
--- a/plugins.c
+++ b/plugins.c
@@ -137,6 +137,7 @@ static DB_functions_t deadbeef_api = {
.pl_get_cursor = pl_get_cursor,
.pl_set_selected = (void (*) (DB_playItem_t *, int))pl_set_selected,
.pl_is_selected = (int (*) (DB_playItem_t *))pl_is_selected,
+ .pl_is_group_title = (int (*) (DB_playItem_t *))pl_is_group_title,
.pl_clear = pl_clear,
.pl_load = pl_load,
.pl_save = pl_save,
diff --git a/plugins/gtkui/gtkui.c b/plugins/gtkui/gtkui.c
index e5beccb0..b34bb36e 100644
--- a/plugins/gtkui/gtkui.c
+++ b/plugins/gtkui/gtkui.c
@@ -1003,6 +1003,14 @@ void main_selection_changed (DdbListviewIter it, int idx) {
void main_draw_column_data (GdkDrawable *drawable, DdbListviewIter it, int idx, DdbListviewColIter column, int x, int y, int width, int height) {
gtkpl_column_t *c = (gtkpl_column_t *)column;
+ if (deadbeef->pl_is_group_title ((DB_playItem_t *)it)) {
+ if (c == main_columns) {
+ float clr[] = {0, 0.1, 0.5};
+ draw_set_fg_color (clr);
+ draw_text (x + 5, y + height/2 - draw_get_font_size ()/2 - 2, 1000, 0, ((DB_playItem_t *)it)->fname);
+ }
+ return;
+ }
if (it == deadbeef->streamer_get_playing_track () && c->id == DB_COLUMN_PLAYING) {
int paused = deadbeef->get_output ()->state () == OUTPUT_STATE_PAUSED;
int buffering = !deadbeef->streamer_ok_to_read (-1);
@@ -1031,6 +1039,32 @@ void main_draw_column_data (GdkDrawable *drawable, DdbListviewIter it, int idx,
}
}
+#if 0
+void
+on_group_by_none_activate (GtkMenuItem *menuitem,
+ gpointer user_data)
+{
+ deadbeef->plt_group_by (NULL);
+ main_refresh ();
+}
+
+void
+on_group_by_artist_date_album_activate (GtkMenuItem *menuitem,
+ gpointer user_data)
+{
+ deadbeef->plt_group_by ("%a - [%y] %b");
+ main_refresh ();
+}
+
+void
+on_group_by_artist_activate (GtkMenuItem *menuitem,
+ gpointer user_data)
+{
+ deadbeef->plt_group_by ("%a");
+ main_refresh ();
+}
+#endif
+
GtkWidget*
create_headermenu (void)
{
@@ -1038,6 +1072,12 @@ create_headermenu (void)
GtkWidget *add_column;
GtkWidget *edit_column;
GtkWidget *remove_column;
+ GtkWidget *separator;
+ GtkWidget *group_by;
+ GtkWidget *group_by_menu;
+ GtkWidget *none;
+ GtkWidget *artist_date_album;
+ GtkWidget *artist;
headermenu = gtk_menu_new ();
@@ -1053,6 +1093,32 @@ create_headermenu (void)
gtk_widget_show (remove_column);
gtk_container_add (GTK_CONTAINER (headermenu), remove_column);
+#if 0
+ separator = gtk_separator_menu_item_new ();
+ gtk_widget_show (separator);
+ gtk_container_add (GTK_CONTAINER (headermenu), separator);
+ gtk_widget_set_sensitive (separator, FALSE);
+
+ group_by = gtk_menu_item_new_with_mnemonic ("Group by");
+ gtk_widget_show (group_by);
+ gtk_container_add (GTK_CONTAINER (headermenu), group_by);
+
+ group_by_menu = gtk_menu_new ();
+ gtk_menu_item_set_submenu (GTK_MENU_ITEM (group_by), group_by_menu);
+
+ none = gtk_menu_item_new_with_mnemonic ("None");
+ gtk_widget_show (none);
+ gtk_container_add (GTK_CONTAINER (group_by_menu), none);
+
+ artist_date_album = gtk_menu_item_new_with_mnemonic ("Artist/Date/Album");
+ gtk_widget_show (artist_date_album);
+ gtk_container_add (GTK_CONTAINER (group_by_menu), artist_date_album);
+
+ artist = gtk_menu_item_new_with_mnemonic ("Artist");
+ gtk_widget_show (artist);
+ gtk_container_add (GTK_CONTAINER (group_by_menu), artist);
+#endif
+
g_signal_connect ((gpointer) add_column, "activate",
G_CALLBACK (on_add_column_activate),
NULL);
@@ -1063,14 +1129,23 @@ create_headermenu (void)
G_CALLBACK (on_remove_column_activate),
NULL);
- /* Store pointers to all widgets, for use by lookup_widget(). */
-// GLADE_HOOKUP_OBJECT_NO_REF (headermenu, headermenu, "headermenu");
-// GLADE_HOOKUP_OBJECT (headermenu, add_column, "add_column");
-// GLADE_HOOKUP_OBJECT (headermenu, edit_column, "edit_column");
-// GLADE_HOOKUP_OBJECT (headermenu, remove_column, "remove_column");
+#if 0
+ g_signal_connect ((gpointer) remove_column, "activate",
+ G_CALLBACK (on_group_by_none_activate),
+ NULL);
+
+ g_signal_connect ((gpointer) remove_column, "activate",
+ G_CALLBACK (on_group_by_artist_date_album_activate),
+ NULL);
+
+ g_signal_connect ((gpointer) remove_column, "activate",
+ G_CALLBACK (on_group_by_artist_activate),
+ NULL);
+#endif
return headermenu;
}
+
void
main_header_context_menu (DdbListview *ps, DdbListviewColIter c) {
GtkWidget *menu = create_headermenu ();