From 3562e164b0548763d94dd6fcc2ff722f34effce2 Mon Sep 17 00:00:00 2001 From: Anna Schumaker Date: Fri, 26 Aug 2016 09:25:17 -0400 Subject: [PATCH] gui/sidebar: Implement selection-changed handlers Signed-off-by: Anna Schumaker --- gui/playlist.c | 41 ++++----------------------------- gui/sidebar.c | 46 ++++++++++++++++++++++++++++++++++++- include/gui/model.h | 1 + include/gui/playlist.h | 2 +- share/ocarina/ocarina.ui | 2 +- tests/gui/playlist.c | 4 ++++ tests/gui/sidebar.c | 49 ++++++++++++++++++++++++++++++++++++++++ 7 files changed, 105 insertions(+), 40 deletions(-) diff --git a/gui/playlist.c b/gui/playlist.c index af24df7e..3f354088 100644 --- a/gui/playlist.c +++ b/gui/playlist.c @@ -16,7 +16,6 @@ enum playlist_sidebar_columns { P_SB_TYPE, }; -static gchar *p_name = NULL; static bool p_filter_enable = true; static bool p_init_done = false; @@ -44,33 +43,6 @@ static void __playlist_set_size(GtkTreeIter *iter, const gchar *name) g_free(text); } -void __playlist_selection_changed(GtkTreeSelection *selection, gpointer data) -{ - GtkTreeModel *model = gui_sidebar_model(); - GtkTreeIter iter, child; - struct queue *queue; - - if (gtk_tree_selection_get_selected(selection, &model, &iter)) { - __playlist_filter_get_iter(&iter, &child); - if (p_name) - g_free(p_name); - - p_name = gui_sidebar_iter_name(&child); - queue = playlist_get_queue(gui_sidebar_iter_type(&child), p_name); - gui_queue_show(gui_queue(queue)); - } -} - -gboolean __playlist_on_select(GtkTreeSelection *selection, GtkTreeModel *model, - GtkTreePath *path, gboolean selected, gpointer data) -{ - GtkTreeIter iter, child; - - gtk_tree_model_get_iter(model, &iter, path); - __playlist_filter_get_iter(&iter, &child); - return gui_sidebar_iter_type(&child) != PL_MAX_TYPE; -} - bool __playlist_keypress(GtkTreeView *treeview, GdkEventKey *event, gpointer data) { @@ -267,11 +239,8 @@ bool __gui_playlist_init_idle() void gui_playlist_init() { - GtkTreeView *treeview; GtkTreeIter parent; - treeview = gui_sidebar_treeview(); - gui_sidebar_iter_first(&parent); gui_sidebar_iter_add(&parent, playlist_get(PL_SYSTEM, "Queued Tracks"), "audio-x-generic"); @@ -296,16 +265,14 @@ void gui_playlist_init() gui_sidebar_iter_append_child(&parent, playlist_get(PL_SYSTEM, "Unplayed"), "audio-x-generic"); - gtk_tree_selection_set_select_function( - gtk_tree_view_get_selection(treeview), - __playlist_on_select, NULL, NULL); - idle_schedule(IDLE_SYNC, __gui_playlist_init_idle, NULL); } -gchar *gui_playlist_cur() +const gchar *gui_playlist_cur() { - return p_name; + if (gui_model_get_playlist()) + return gui_model_get_playlist()->pl_name; + return NULL; } void gui_playlist_add_library(struct playlist *playlist) diff --git a/gui/sidebar.c b/gui/sidebar.c index d66e1023..31653117 100644 --- a/gui/sidebar.c +++ b/gui/sidebar.c @@ -4,6 +4,7 @@ #include #include #include +#include enum sidebar_columns { SB_IMAGE, @@ -74,6 +75,13 @@ static int __gui_sidebar_compare(GtkTreeIter *iter, const gchar *name, return ret; } +static inline void __gui_sidebar_filter_iter_convert(GtkTreeIter *iter, + GtkTreeIter *child) +{ + gtk_tree_model_filter_convert_iter_to_child_iter(gui_sidebar_filter(), + child, iter); +} + static gboolean __gui_sidebar_visible_func(GtkTreeModel *model, GtkTreeIter *iter, gpointer data) @@ -90,7 +98,38 @@ static gboolean __gui_sidebar_visible_func(GtkTreeModel *model, } } - return ret;; + return ret; +} + +static gboolean __gui_sidebar_can_select(GtkTreeSelection *selection, + GtkTreeModel *model, GtkTreePath *path, + gboolean selected, gpointer data) +{ + GtkTreeIter iter, child; + + gtk_tree_model_get_iter(model, &iter, path); + __gui_sidebar_filter_iter_convert(&iter, &child); + return gui_sidebar_iter_type(&child) != PL_MAX_TYPE; +} + +void __gui_sidebar_selection_changed(GtkTreeSelection *selection, gpointer data) +{ + GtkTreeModel *model = GTK_TREE_MODEL(gui_sidebar_filter()); + struct playlist *playlist = NULL; + enum playlist_type_t type; + GtkTreeIter iter, child; + gchar *name; + + if (gtk_tree_selection_get_selected(selection, &model, &iter)) { + __gui_sidebar_filter_iter_convert(&iter, &child); + + name = gui_sidebar_iter_name(&child); + type = gui_sidebar_iter_type(&child); + playlist = playlist_get(type, name); + g_free(name); + } + + gui_treeview_set_playlist(playlist); } void __gui_sidebar_resized(GtkPaned *pane, GParamSpec *pspec, gpointer data) @@ -101,6 +140,7 @@ void __gui_sidebar_resized(GtkPaned *pane, GParamSpec *pspec, gpointer data) void gui_sidebar_init() { int pos = settings_get(SIDEBAR_SETTING); + GtkTreeSelection *selection; GtkTreeIter iter; if (!gui_sidebar_iter_first(&iter)) { @@ -108,6 +148,10 @@ void gui_sidebar_init() __gui_sidebar_add_header(&iter, "Dynamic", "emblem-generic"); __gui_sidebar_add_header(&iter, "Library", "emblem-system"); + selection = gtk_tree_view_get_selection(gui_sidebar_treeview()); + gtk_tree_selection_set_select_function(selection, + __gui_sidebar_can_select, + NULL, NULL); gtk_tree_model_filter_set_visible_func(gui_sidebar_filter(), __gui_sidebar_visible_func, NULL, NULL); diff --git a/include/gui/model.h b/include/gui/model.h index 51c1b26c..9a8e7857 100644 --- a/include/gui/model.h +++ b/include/gui/model.h @@ -4,6 +4,7 @@ #ifndef OCARINA_GUI_MODEL_H #define OCARINA_GUI_MODEL_H #include +#include #include #define GUI_MODEL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), \ diff --git a/include/gui/playlist.h b/include/gui/playlist.h index 487974e9..5a8a0d47 100644 --- a/include/gui/playlist.h +++ b/include/gui/playlist.h @@ -10,7 +10,7 @@ void gui_playlist_init(); /* Called to get the currently selected playlist. */ -gchar *gui_playlist_cur(); +const gchar *gui_playlist_cur(); /* Called to add a library playlist. */ void gui_playlist_add_library(struct playlist *); diff --git a/share/ocarina/ocarina.ui b/share/ocarina/ocarina.ui index 0d0b1f86..67d87010 100644 --- a/share/ocarina/ocarina.ui +++ b/share/ocarina/ocarina.ui @@ -751,7 +751,7 @@ audio-volume-medium - + diff --git a/tests/gui/playlist.c b/tests/gui/playlist.c index d86bb42a..6ae87c0c 100644 --- a/tests/gui/playlist.c +++ b/tests/gui/playlist.c @@ -62,10 +62,12 @@ static void test_playlist_sidebar() gtk_tree_selection_unselect_all(selection); gtk_tree_selection_select_path(selection, path); g_assert_cmpuint(gtk_tree_selection_count_selected_rows(selection), ==, 0); + g_assert_null(gui_playlist_cur()); gtk_tree_path_next(path); gtk_tree_selection_select_path(selection, path); g_assert_cmpuint(gtk_tree_selection_count_selected_rows(selection), ==, 0); + g_assert_null(gui_playlist_cur()); gtk_tree_path_down(path); gtk_tree_selection_select_path(selection, path); @@ -87,10 +89,12 @@ static void test_playlist_sidebar() gtk_tree_selection_unselect_all(selection); gtk_tree_selection_select_path(selection, path); g_assert_cmpuint(gtk_tree_selection_count_selected_rows(selection), ==, 0); + g_assert_null(gui_playlist_cur()); gtk_tree_path_next(path); gtk_tree_selection_select_path(selection, path); g_assert_cmpuint(gtk_tree_selection_count_selected_rows(selection), ==, 0); + g_assert_null(gui_playlist_cur()); /* Most played and least played are both filtered out */ gtk_tree_path_down(path); diff --git a/tests/gui/sidebar.c b/tests/gui/sidebar.c index 9e299e89..ff516915 100644 --- a/tests/gui/sidebar.c +++ b/tests/gui/sidebar.c @@ -2,8 +2,12 @@ * Copyright 2015 (c) Anna Schumaker. */ #include +#include #include +#include +#include #include +#include #include const gchar *test_pl_names[8] = { "Collection", @@ -91,6 +95,44 @@ static void test_sidebar() } } +static void test_sidebar_selection() +{ + GtkTreeSelection *selection; + GtkTreeModel *filter; + GtkTreePath *path; + GtkTreeIter iter; + unsigned int i, n; + + selection = gtk_tree_view_get_selection(gui_sidebar_treeview()); + filter = GTK_TREE_MODEL(gui_sidebar_filter()); + + g_assert_cmpuint(gtk_tree_model_iter_n_children(filter, NULL), ==, 6); + playlist_new(PL_LIBRARY, "tests/Music/Hyrule Symphony"); + while (idle_run_task()) {} + playlist_add(PL_SYSTEM, "History", track_get(0)); + gtk_tree_model_filter_refilter(gui_sidebar_filter()); + g_assert_cmpuint(gtk_tree_model_iter_n_children(filter, NULL), ==, 8); + + g_assert_true(gui_sidebar_iter_first(&iter)); + path = gtk_tree_model_get_path(gui_sidebar_model(), &iter); + for (i = 0; i < 8; i++) { + gtk_tree_selection_select_path(selection, path); + n = gtk_tree_selection_count_selected_rows(selection); + g_assert_cmpuint(n, ==, (i < 2) ? 1 : 0); + if (i == 0) + g_assert(gui_model_get_playlist() == + playlist_get(PL_SYSTEM, "Collection")); + else if (i == 1) + g_assert(gui_model_get_playlist() == + playlist_get(PL_SYSTEM, "History")); + else + g_assert_null(gui_model_get_playlist()); + gtk_tree_selection_unselect_all(selection); + gtk_tree_path_next(path); + } + gtk_tree_path_free(path); +} + static void test_sidebar_pos() { g_assert_false(settings_has("gui.sidebar.pos")); @@ -112,14 +154,21 @@ int main(int argc, char **argv) gtk_init(&argc, NULL); core_init(&argc, &argv, &init_data); gui_builder_init("share/ocarina/ocarina.ui"); + gui_model_init(); + gui_filter_init(); + gui_treeview_init(); gui_sidebar_init(); g_test_init(&argc, &argv, NULL); g_test_add_func("/Gui/Sidebar", test_sidebar); + g_test_add_func("/Gui/Sidebar/Selection", test_sidebar_selection); g_test_add_func("/Gui/Sidebar/Pos", test_sidebar_pos); ret = g_test_run(); core_deinit(); + gui_treeview_deinit(); + gui_filter_deinit(); + gui_model_deinit(); gui_builder_deinit(); return ret; }