ocarina/gui/sidebar.c

182 lines
4.5 KiB
C

/*
* Copyright 2015 (c) Anna Schumaker.
*/
#include <core/collection.h>
#include <core/queue.h>
#include <core/tempq.h>
#include <gui/builder.h>
#include <gui/queue.h>
#include <gui/settings.h>
#include <gui/sidebar.h>
const gchar *SIDEBAR_SETTING = "gui.sidebar.pos";
const gchar *COLLECTION_FMT = "<big>Collection</big>\n%d track%s";
const gchar *HISTORY_FMT = "<big>History</big>\n%d track%s";
static GtkListStore *sb_store;
enum sidebar_columns {
SB_IMAGE,
SB_IMAGE_SZ,
SB_TEXT,
SB_QUEUE,
};
static void __sidebar_set_size(GtkTreeIter *iter, const gchar *name,
unsigned int size)
{
const gchar *fmt = "<big>%s</big>\n%d track%s";
gchar *text;
text = g_strdup_printf(fmt, name, size, (size == 1) ? "" : "s");
gtk_list_store_set(sb_store, iter, SB_TEXT, text, -1);
g_free(text);
}
static struct gui_queue *__sidebar_get_queue(GtkTreeIter *iter)
{
struct gui_queue *queue;
gtk_tree_model_get(GTK_TREE_MODEL(sb_store), iter, SB_QUEUE, &queue, -1);
return queue;
}
static bool __sidebar_find_queue(struct gui_queue *queue, GtkTreeIter *iter)
{
gtk_tree_model_get_iter_first(GTK_TREE_MODEL(sb_store), iter);
do {
if (__sidebar_get_queue(iter) == queue)
return true;
} while (gtk_tree_model_iter_next(GTK_TREE_MODEL(sb_store), iter));
return false;
}
void __sidebar_resize(GtkPaned *pane, GParamSpec *pspec, gpointer data)
{
gui_settings_set(SIDEBAR_SETTING, gtk_paned_get_position(pane));
}
bool __sidebar_keypress(GtkTreeView *treeview, GdkEventKey *event, gpointer data)
{
GtkTreeSelection *selection = gtk_tree_view_get_selection(treeview);
GtkTreeModel *model = GTK_TREE_MODEL(sb_store);
struct gui_queue *queue;
GtkTreePath *path;
GtkTreeIter iter;
GList *rows;
if (event->keyval != GDK_KEY_Delete)
return false;
rows = gtk_tree_selection_get_selected_rows(selection, &model);
path = rows->data;
if (gtk_tree_model_get_iter(model, &iter, path))
queue = __sidebar_get_queue(&iter);
if (tempq_index(queue->gq_queue) == -1)
goto out;
tempq_free(queue->gq_queue);
out:
g_list_free_full(rows, (GDestroyNotify)gtk_tree_path_free);
return true;
}
void __sidebar_selection_changed(GtkTreeSelection *selection, gpointer data)
{
GtkTreeModel *model = GTK_TREE_MODEL(sb_store);
GtkTreeIter iter;
if (gtk_tree_selection_get_selected(selection, &model, &iter)) {
GtkTreePath *path = gtk_tree_model_get_path(model, &iter);
gui_sidebar_selected(SB_SIDEBAR, __sidebar_get_queue(&iter));
gtk_tree_path_free(path);
}
}
void __sidebar_deselect(const gchar *widget)
{
GtkTreeView *treeview = GTK_TREE_VIEW(gui_builder_widget(widget));
GtkTreeSelection *selection = gtk_tree_view_get_selection(treeview);
gtk_tree_selection_unselect_all(selection);
}
void gui_sidebar_init()
{
GtkPaned *pane = GTK_PANED(gui_builder_widget("o_sidebar"));
int pos;
/* Set up entries in the liststore. */
sb_store = GTK_LIST_STORE(gui_builder_object("o_sidebar_store"));
/* Set sidebar width. */
pos = gui_settings_get(SIDEBAR_SETTING);
if (pos > 0)
gtk_paned_set_position(pane, pos);
}
gboolean gui_sidebar_on_select(GtkTreeSelection *selection,
GtkTreeModel *model, GtkTreePath *path,
gboolean selected, gpointer data)
{
return gtk_tree_path_get_depth(path) != 1;
}
void gui_sidebar_selected(enum sidebar_selection_t selected,
struct gui_queue *queue)
{
if (selected != SB_PLAYLIST)
__sidebar_deselect("o_playlist_view");
if (selected != SB_SIDEBAR)
__sidebar_deselect("o_sidebar_view");
gui_queue_show(queue);
}
void gui_sidebar_add(struct gui_queue *queue)
{
const gchar *text = "<big>Queued Tracks</big>\n0 tracks";
GtkTreeIter iter, sibling;
if (!GTK_IS_TREE_MODEL(sb_store))
return;
if (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(sb_store),
&sibling, NULL,
tempq_index(queue->gq_queue)))
gtk_list_store_insert_before(sb_store, &iter, &sibling);
else
gtk_list_store_insert(sb_store, &iter, -1);
gtk_list_store_set(sb_store, &iter, SB_IMAGE, "audio-x-generic",
SB_IMAGE_SZ, GTK_ICON_SIZE_BUTTON,
SB_TEXT, text,
SB_QUEUE, queue, -1);
__sidebar_set_size(&iter, queue->gq_text, queue_size(queue->gq_queue));
}
void gui_sidebar_remove(struct gui_queue *queue)
{
GtkTreeIter iter;
if (__sidebar_find_queue(queue, &iter))
gtk_list_store_remove(sb_store, &iter);
}
void gui_sidebar_set_size(struct gui_queue *queue)
{
GtkTreeIter iter;
if (!GTK_IS_TREE_MODEL(sb_store))
return;
if (__sidebar_find_queue(queue, &iter))
__sidebar_set_size(&iter, queue->gq_text,
queue_size(queue->gq_queue));
}