234 lines
5.6 KiB
C
234 lines
5.6 KiB
C
/*
|
|
* Copyright 2016 (c) Anna Schumaker.
|
|
*/
|
|
#include <core/idle.h>
|
|
#include <core/string.h>
|
|
#include <gui/filter.h>
|
|
#include <gui/model.h>
|
|
#include <gui/playlist.h>
|
|
#include <gui/treeview.h>
|
|
#include <gui/sidebar.h>
|
|
|
|
static void (*update_size[PL_MAX_TYPE])(struct playlist *) = {
|
|
[PL_SYSTEM] = gui_pl_system_update,
|
|
[PL_ARTIST] = gui_pl_artist_update,
|
|
[PL_LIBRARY] = gui_pl_library_update,
|
|
[PL_USER] = gui_pl_user_update,
|
|
};
|
|
|
|
static void (*select_playlist[PL_MAX_TYPE])(struct playlist *) = {
|
|
[PL_SYSTEM] = gui_pl_system_select,
|
|
[PL_ARTIST] = gui_pl_artist_select,
|
|
[PL_LIBRARY] = gui_pl_library_select,
|
|
[PL_USER] = gui_pl_user_select,
|
|
};
|
|
|
|
static inline void __gui_playlist_update_size(struct playlist *playlist)
|
|
{
|
|
update_size[playlist->pl_type](playlist);
|
|
}
|
|
|
|
static void __gui_playlist_alloc(struct playlist *playlist)
|
|
{
|
|
if (playlist->pl_type == PL_ARTIST)
|
|
gui_pl_artist_add(playlist);
|
|
}
|
|
|
|
static void __gui_playlist_added(struct playlist *playlist, struct track *track)
|
|
{
|
|
gui_model_add(playlist, track);
|
|
__gui_playlist_update_size(playlist);
|
|
}
|
|
|
|
static void __gui_playlist_removed(struct playlist *playlist, struct track *track,
|
|
unsigned int n)
|
|
{
|
|
gui_model_remove(playlist, track, n);
|
|
__gui_playlist_update_size(playlist);
|
|
}
|
|
|
|
|
|
struct playlist_callbacks playlist_cb = {
|
|
.pl_cb_alloc = __gui_playlist_alloc,
|
|
.pl_cb_added = __gui_playlist_added,
|
|
.pl_cb_removed = __gui_playlist_removed,
|
|
.pl_cb_updated = gui_model_update,
|
|
};
|
|
|
|
|
|
static void __gui_playlist_add_selected_to(struct playlist *playlist)
|
|
{
|
|
GList *cur, *list = NULL;
|
|
struct track *track;
|
|
|
|
if (!playlist)
|
|
return;
|
|
|
|
list = gui_treeview_list_selected_tracks();
|
|
cur = g_list_first(list);
|
|
while (cur) {
|
|
track = (struct track *)cur->data;
|
|
playlist_add(playlist, track);
|
|
cur = g_list_next(cur);
|
|
}
|
|
g_list_free(list);
|
|
}
|
|
|
|
void __gui_playlist_add_favorites(GtkMenuItem *item, gpointer data)
|
|
{
|
|
__gui_playlist_add_selected_to(playlist_lookup(PL_SYSTEM, "Favorites"));
|
|
}
|
|
|
|
void __gui_playlist_add_hidden(GtkMenuItem *item, gpointer data)
|
|
{
|
|
__gui_playlist_add_selected_to(playlist_lookup(PL_SYSTEM, "Hidden"));
|
|
}
|
|
|
|
void __gui_playlist_add_user(GtkMenuItem *item, gpointer data)
|
|
{
|
|
__gui_playlist_add_selected_to(gui_pl_user_add_dialog());
|
|
}
|
|
|
|
void __gui_playlist_add_other(GtkMenuItem *item, gpointer data)
|
|
{
|
|
__gui_playlist_add_selected_to(data);
|
|
}
|
|
|
|
void __gui_playlist_add_queued(GtkMenuItem *item, gpointer data)
|
|
{
|
|
__gui_playlist_add_selected_to(playlist_lookup(PL_SYSTEM, "Queued Tracks"));
|
|
}
|
|
|
|
void __gui_playlist_delete(GtkMenuItem *item, gpointer data)
|
|
{
|
|
struct playlist *playlist = gui_model_get_playlist();
|
|
GList *cur, *list = NULL;
|
|
struct track *track;
|
|
|
|
if (!playlist)
|
|
return;
|
|
|
|
list = gui_treeview_list_selected_tracks();
|
|
cur = g_list_first(list);
|
|
while (cur) {
|
|
track = (struct track *)cur->data;
|
|
playlist_remove(playlist, track);
|
|
cur = g_list_next(cur);
|
|
}
|
|
g_list_free(list);
|
|
}
|
|
|
|
void __gui_playlist_keypress(GtkTreeView *treeview, GdkEventKey *event,
|
|
gpointer data)
|
|
{
|
|
switch (event->keyval) {
|
|
case GDK_KEY_f:
|
|
__gui_playlist_add_favorites(NULL, NULL);
|
|
break;
|
|
case GDK_KEY_h:
|
|
__gui_playlist_add_hidden(NULL, NULL);
|
|
break;
|
|
case GDK_KEY_p:
|
|
__gui_playlist_add_user(NULL, NULL);
|
|
break;
|
|
case GDK_KEY_q:
|
|
__gui_playlist_add_queued(NULL, NULL);
|
|
break;
|
|
case GDK_KEY_Delete:
|
|
__gui_playlist_delete(NULL, NULL);
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
static GtkWidget *__gui_playlist_build_submenu(void)
|
|
{
|
|
struct playlist *playlist;
|
|
GList *list = gui_pl_user_list();
|
|
GList *cur = g_list_first(list);
|
|
GtkWidget *submenu, *item;
|
|
|
|
if (!list)
|
|
return NULL;
|
|
|
|
submenu = gtk_menu_new();
|
|
while (cur) {
|
|
playlist = (struct playlist *)cur->data;
|
|
item = gtk_menu_item_new_with_label(playlist->pl_name);
|
|
gtk_menu_shell_append(GTK_MENU_SHELL(submenu), item);
|
|
g_signal_connect(item, "activate",
|
|
G_CALLBACK(__gui_playlist_add_other),
|
|
playlist);
|
|
cur = g_list_next(cur);
|
|
}
|
|
|
|
gtk_widget_show_all(submenu);
|
|
g_list_free(list);
|
|
return submenu;
|
|
}
|
|
|
|
bool __gui_playlist_button_press(GtkTreeView *treeview, GdkEventButton *event,
|
|
gpointer data)
|
|
{
|
|
GtkWidget *submenu;
|
|
|
|
if (event->button != GDK_BUTTON_SECONDARY)
|
|
return false;
|
|
|
|
submenu = __gui_playlist_build_submenu();
|
|
gtk_menu_item_set_submenu(gui_rc_add_to_other(), submenu);
|
|
gtk_widget_set_visible(GTK_WIDGET(gui_rc_add_to_other()),
|
|
submenu != NULL);
|
|
|
|
gui_treeview_select_path_at_pos(event->x, event->y);
|
|
gtk_menu_popup_at_pointer(gui_rc_menu(), (GdkEvent *)event);
|
|
return true;
|
|
}
|
|
|
|
void __gui_playlist_row_activated(GtkTreeView *treeview, GtkTreePath *path,
|
|
GtkTreeViewColumn *col, gpointer data)
|
|
{
|
|
struct playlist *prev = playlist_current();
|
|
|
|
gui_sidebar_filter_path_select(path);
|
|
__gui_playlist_update_size(prev);
|
|
__gui_playlist_update_size(playlist_current());
|
|
}
|
|
|
|
void __gui_playlist_row_collapsed(GtkTreeView *treeview, GtkTreeIter *iter,
|
|
GtkTreePath *path, gpointer data)
|
|
{
|
|
gui_sidebar_filter_row_expanded(iter, false);
|
|
}
|
|
|
|
void __gui_playlist_row_expanded(GtkTreeView *treeview, GtkTreeIter *iter,
|
|
GtkTreePath *path, gpointer data)
|
|
{
|
|
gui_sidebar_filter_row_expanded(iter, true);
|
|
}
|
|
|
|
bool __gui_playlist_init_idle()
|
|
{
|
|
struct playlist *playlist = playlist_current();
|
|
GtkTreeModel *filter = GTK_TREE_MODEL(gui_sidebar_filter());
|
|
GtkTreeIter iter;
|
|
|
|
gtk_tree_model_get_iter_first(filter, &iter);
|
|
do {
|
|
gui_sidebar_filter_set_expand(&iter);
|
|
} while (gtk_tree_model_iter_next(filter, &iter));
|
|
|
|
select_playlist[playlist->pl_type](playlist);
|
|
return true;
|
|
}
|
|
|
|
void gui_playlist_init()
|
|
{
|
|
gui_pl_system_init();
|
|
gui_pl_artist_init();
|
|
gui_pl_user_init();
|
|
gui_pl_library_init();
|
|
|
|
idle_schedule(IDLE_SYNC, __gui_playlist_init_idle, NULL);
|
|
}
|