ocarina/gui/queue.c
Anna Schumaker 3d31349cca gui/playlist: Random state isn't saved when random button is clicked
We were calling the queue function directly, rather than passing through
the playlist layer.  This means random state isn't saved when the button
is clicked and Ocarina is closed.

Fixes #78: Call playlist_set_random() when clicking random button
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
2016-08-28 09:06:33 -04:00

210 lines
5.8 KiB
C

/*
* Copyright 2016 (c) Anna Schumaker.
*/
#include <core/filter.h>
#include <core/playlist.h>
#include <core/string.h>
#include <gui/builder.h>
#include <gui/model.h>
#include <gui/queue.h>
#include <gui/view.h>
static struct gui_queue *gq_queue = NULL;
static void __queue_set_runtime(struct gui_queue *queue)
{
gchar *len;
if (queue != gq_queue)
return;
len = string_sec2str_long(queue->gq_queue->q_length);
gtk_label_set_text(GTK_LABEL(gui_builder_widget("o_runtime")), len);
g_free(len);
}
static void __queue_toggle_flag(bool active, GtkWidget *widget,
enum queue_flags flag)
{
if (gq_queue == NULL)
return;
/*
* Some GTK themes have trouble with toggle buttons,
* so let's help users by changing image sensitivity.
*/
if (active)
queue_set_flag(gq_queue->gq_queue, flag);
else
queue_unset_flag(gq_queue->gq_queue, flag);
gtk_widget_set_sensitive(widget, active);
}
void __queue_random(GtkToggleButton *button, gpointer data)
{
__queue_toggle_flag(gtk_toggle_button_get_active(button),
gtk_button_get_image(GTK_BUTTON(button)),
Q_RANDOM);
if (gq_queue->gq_playlist) {
playlist_set_random(gq_queue->gq_playlist->pl_type,
gq_queue->gq_playlist->pl_name,
gtk_toggle_button_get_active(button));
}
}
void __queue_repeat(GtkToggleButton *button, gpointer data)
{
__queue_toggle_flag(gtk_toggle_button_get_active(button),
gtk_button_get_image(GTK_BUTTON(button)),
Q_REPEAT);
}
void __queue_disabled(GtkSwitch *enabled, GParamSpec *pspec, gpointer data)
{
__queue_toggle_flag(gtk_switch_get_active(enabled),
gui_builder_widget("o_treeview"),
Q_ENABLED);
}
static gboolean __queue_visible_func(GtkTreeModel *model, GtkTreeIter *iter,
gpointer data)
{
struct track *track;
if (!gq_queue || (strlen(gtk_entry_get_text(GTK_ENTRY(data))) == 0))
return TRUE;
if (!gq_queue->gq_visible)
return FALSE;
track = gui_queue_model_iter_get_track(gq_queue->gq_model, iter);
return g_hash_table_contains(gq_queue->gq_visible, track);
}
void __queue_filter(GtkSearchEntry *entry, gpointer data)
{
const gchar *text = gtk_entry_get_text(GTK_ENTRY(entry));
if (!gq_queue)
return;
if (gq_queue->gq_search) {
g_free(gq_queue->gq_search);
gq_queue->gq_search = NULL;
}
if (strlen(text) > 0) {
gq_queue->gq_visible = filter_search(text);
gq_queue->gq_search = g_strdup(text);
}
gtk_tree_model_filter_refilter(GTK_TREE_MODEL_FILTER(gq_queue->gq_filter));
gui_view_scroll();
if (gq_queue->gq_visible) {
g_hash_table_destroy(gq_queue->gq_visible);
gq_queue->gq_visible = NULL;
}
}
struct gui_queue *gui_queue_alloc(struct playlist *playlist, struct queue *queue,
const gchar *text, unsigned int flags)
{
struct gui_queue *gq = g_malloc(sizeof(struct gui_queue));
gq->gq_flags = flags;
gq->gq_text = g_strdup(text);
gq->gq_search = NULL;
gq->gq_model = gui_queue_model_new(queue);
gq->gq_filter = gtk_tree_model_filter_new(
GTK_TREE_MODEL(gq->gq_model), NULL);
gq->gq_playlist = playlist;
gq->gq_queue = queue;
gq->gq_visible = NULL;
gtk_tree_model_filter_set_visible_func(
GTK_TREE_MODEL_FILTER(gq->gq_filter),
__queue_visible_func,
gui_builder_object("o_search"), NULL);
return gq;
}
void gui_queue_free(struct queue *queue)
{
struct gui_queue *gq = gui_queue(queue);
queue->q_private = NULL;
if (gq_queue == gq)
gui_view_set_model(NULL);
if (gq->gq_search)
g_free(gq->gq_search);
g_object_unref(gq->gq_model);
g_free(gq->gq_text);
g_free(gq);
}
void gui_queue_show(struct gui_queue *queue)
{
GtkTreeView *view = GTK_TREE_VIEW(gui_builder_widget("o_treeview"));
GtkButton *random = GTK_BUTTON(gui_builder_widget("o_random"));
GtkButton *repeat = GTK_BUTTON(gui_builder_widget("o_repeat"));
GtkSwitch *enabled = GTK_SWITCH(gui_builder_widget("o_enable"));
GtkEntry *search = GTK_ENTRY(gui_builder_widget("o_search"));
GtkLabel *runtime = GTK_LABEL(gui_builder_widget("o_runtime"));
bool has_random = false, has_repeat = false, is_enabled = false;;
gq_queue = queue;
gtk_widget_set_sensitive(GTK_WIDGET(random), gui_queue_can_random(queue));
gtk_widget_set_sensitive(GTK_WIDGET(repeat), gui_queue_can_repeat(queue));
gtk_widget_set_sensitive(GTK_WIDGET(enabled), gui_queue_can_disable(queue));
if (queue) {
has_random = queue_has_flag(queue->gq_queue, Q_RANDOM);
has_repeat = queue_has_flag(queue->gq_queue, Q_REPEAT);
is_enabled = queue_has_flag(queue->gq_queue, Q_ENABLED);
gui_view_set_model(GTK_TREE_MODEL_FILTER(queue->gq_filter));
__queue_set_runtime(queue);
} else
gtk_label_set_text(runtime, "");
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(random), has_random);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(repeat), has_repeat);
gtk_switch_set_active(GTK_SWITCH(enabled), is_enabled);
/*
* Some GTK themes have trouble with toggle buttons,
* so let's help users know what the current state is.
*/
gtk_widget_set_sensitive(gtk_button_get_image(random), has_random);
gtk_widget_set_sensitive(gtk_button_get_image(repeat), has_repeat);
gtk_widget_set_sensitive(GTK_WIDGET(view), is_enabled);
gtk_widget_set_sensitive(GTK_WIDGET(search), queue != NULL);
gtk_entry_set_text(search, (queue && queue->gq_search) ? queue->gq_search : "");
}
void gui_queue_added(struct queue *queue, unsigned int row)
{
gui_queue_model_add(gui_queue(queue)->gq_model, row);
__queue_set_runtime(gui_queue(queue));
}
void gui_queue_removed(struct queue *queue, unsigned int row)
{
gui_queue_model_remove(gui_queue(queue)->gq_model, row);
__queue_set_runtime(gui_queue(queue));
}
void gui_queue_cleared(struct queue *queue, unsigned int n)
{
gui_queue_model_clear(gui_queue(queue)->gq_model, n);
__queue_set_runtime(gui_queue(queue));
}
void gui_queue_updated(struct queue *queue, unsigned int row)
{
gui_queue_model_update(gui_queue(queue)->gq_model, row);
__queue_set_runtime(gui_queue(queue));
}