// Copyright (c) 2011 Bryan Schumaker #include #include #include #include #include #include "ocarina.h" #include using namespace std; static GtkNotebook *tabs; static PlaylistWidgets library_widgets; static PlaylistWidgets recent_widgets; static PlaylistWidgets banned_widgets; static list dynamic_widgets; struct PlaylistWidgets *find_page_widgets(GtkWidget *page) { list::iterator it; for (it = dynamic_widgets.begin(); it != dynamic_widgets.end(); it++) { if (GTK_WIDGET((*it)->page_box) == page) return *it; } return NULL; } struct PlaylistWidgets *find_playlist_widgets(libsaria::Playlist *plist) { list::iterator it; if (plist == library_widgets.playlist) return &library_widgets; else if (plist == recent_widgets.playlist) return &recent_widgets; else if (plist == banned_widgets.playlist) return &banned_widgets; for (it = dynamic_widgets.begin(); it != dynamic_widgets.end(); it++) { if ((*it)->playlist == plist) return *it; } return NULL; } static struct PlaylistWidgets *find_nth_widgets(unsigned int n) { unsigned int size = dynamic_widgets.size(); /* Dynamic playlists */ if (n < size) return find_playlist_widgets(libsaria::deck::get_playlist(n)); switch (n - size) { case 0: return &library_widgets; case 1: return &recent_widgets; case 2: return &banned_widgets; } return NULL; } struct PlaylistWidgets *current_widgets() { return find_nth_widgets(gtk_notebook_get_current_page(tabs)); } libsaria::Playlist *current_playlist() { return current_widgets()->playlist; } void playlist_switch_to(string &key) { unsigned int size = dynamic_widgets.size(); if (key == "l") gtk_notebook_set_current_page(tabs, size); else if (key == "r") gtk_notebook_set_current_page(tabs, size + 1); else if (key == "b") gtk_notebook_set_current_page(tabs, size + 2); } void playlist_switch_to_n(unsigned int n) { unsigned int size = dynamic_widgets.size(); if (size <= n) return; gtk_notebook_set_current_page(tabs, n); } bool playlist_entry_focused() { return gtk_widget_is_focus(GTK_WIDGET(current_widgets()->entry)); } void playlist_focus_entry() { gtk_widget_grab_focus(GTK_WIDGET(current_widgets()->entry)); } bool playlist_key_press(string &key) { GtkTreeView *treeview = current_widgets()->treeview; if (gtk_widget_is_focus(GTK_WIDGET(treeview))) return playlist_key_pressed(treeview, key); return false; } void playlist_focus_treeview() { GtkTreePath *path; GtkTreeView *treeview = current_widgets()->treeview; gtk_widget_grab_focus(GTK_WIDGET(treeview)); gtk_tree_view_get_cursor(treeview, &path, NULL); if (path == NULL) return; gtk_tree_view_set_cursor(treeview, path, NULL, FALSE); gtk_tree_path_free(path); } static void on_switch_page(GtkNotebook *tabs, gpointer page, unsigned int page_num, gpointer data) { struct PlaylistWidgets *widgets = find_nth_widgets(page_num); update_length_label(widgets->playlist); } static void on_page_reordered(GtkWidget *notebook, GtkWidget *page, guint num, gpointer d) { struct PlaylistWidgets *widgets = find_page_widgets(page); unsigned int n = libsaria::deck::move_playlist(widgets->playlist, num); if (n != num) gtk_notebook_reorder_child(tabs, page, n); } static void on_click_open(GtkWidget *b, gpointer d) { string file = run_chooser("FileChooser"); if (file != "") { println("Playing file: " + file); libsaria::play_outside_song(file); } } static void init_tab_action() { GtkWidget *box = gtk_vbox_new(FALSE, 0); GtkWidget *img = gtk_image_new_from_stock(GTK_STOCK_OPEN, GTK_ICON_SIZE_BUTTON); GtkWidget *open = gtk_button_new(); gtk_button_set_image(GTK_BUTTON(open), img); g_signal_connect(open, "clicked", G_CALLBACK(on_click_open), NULL); gtk_box_pack_start(GTK_BOX(box), open, false, false, 0); gtk_box_pack_start(GTK_BOX(box), get_widget("BanButton"), false, false, 0); gtk_widget_show_all(box); gtk_notebook_set_action_widget(tabs, box, GTK_PACK_END); } static void add_page(GtkWidget *page, GtkWidget *tab_label, int page_num) { gtk_notebook_insert_page(tabs, page, tab_label, page_num); } static void make_tab_label(const string &name, struct PlaylistWidgets *widgets) { GtkWidget *box = gtk_vbox_new(FALSE, 0); GtkWidget *label = gtk_label_new(name.c_str()); widgets->tab_box = GTK_BOX(gtk_hbox_new(FALSE, 0)); gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.0); gtk_misc_set_alignment(GTK_MISC(widgets->size_label), 1.0, 0.0); gtk_box_pack_start(widgets->tab_box, GTK_WIDGET(widgets->page_label), FALSE, FALSE, 0); gtk_box_pack_start(widgets->tab_box, box, TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(box), GTK_WIDGET(widgets->size_label), FALSE, FALSE, 0); gtk_widget_show_all(GTK_WIDGET(widgets->tab_box)); } static void init_page(const string &name, struct PlaylistWidgets *widgets, libsaria::Playlist *playlist, int page_num, unsigned int flags) { setup_widgets(widgets, playlist); setup_playlist_page(widgets, flags); make_tab_label(name, widgets); add_page(GTK_WIDGET(widgets->page_box), GTK_WIDGET(widgets->tab_box), page_num); } void init_tabs() { tabs = GTK_NOTEBOOK(get_widget("PlaylistTabs")); init_tab_action(); init_page("Library", &library_widgets, libsaria::library::get_playlist(), -1, RANDOM_BUTTON); init_page("Recent", &recent_widgets, libsaria::deck::get_recent_plist(), -1, NO_EXTRA_WIDGETS); init_page("Banned", &banned_widgets, libsaria::ban::get_banned_plist(), -1, NO_EXTRA_WIDGETS); connect_signal("PlaylistTabs", "switch-page", G_CALLBACK(on_switch_page), NULL); connect_signal("PlaylistTabs", "page-reordered", G_CALLBACK(on_page_reordered), NULL); } static void new_playlist(libsaria::Playlist *playlist) { struct PlaylistWidgets *widgets = new struct PlaylistWidgets; dynamic_widgets.push_back(widgets); init_page("Playlist", widgets, playlist, libsaria::deck::get_playlist_index(playlist), CLOSE_BUTTON | DISABLE_BUTTON | RANDOM_BUTTON | SORT_BUTTON); gtk_notebook_set_tab_reorderable(tabs, GTK_WIDGET(widgets->page_box), true); } static void delete_playlist(libsaria::Playlist *playlist) { struct PlaylistWidgets *widgets = find_playlist_widgets(playlist); int page_num = gtk_notebook_page_num(tabs, GTK_WIDGET(widgets->page_box)); int cur_page = gtk_notebook_get_current_page(tabs); if (cur_page == page_num) gtk_notebook_set_current_page(tabs, cur_page + 1); dynamic_widgets.remove(widgets); delete widgets; gtk_notebook_remove_page(tabs, page_num); } static void renumber_playlist(libsaria::Playlist *playlist) { stringstream s; struct PlaylistWidgets *widgets = find_playlist_widgets(playlist); s << "" << playlist->get_number() << " "; gtk_label_set_markup(widgets->page_label, s.str().c_str()); gtk_notebook_reorder_child(tabs, GTK_WIDGET(widgets->page_box), playlist->get_number()); } static void disable_playlist(libsaria::Playlist *playlist) { bool enabled = !playlist->check_flag(PL_DISABLED); struct PlaylistWidgets *widgets = find_playlist_widgets(playlist); if (widgets) { gtk_toggle_button_set_active(widgets->disable, !enabled); gtk_widget_set_sensitive(GTK_WIDGET(widgets->treeview), enabled); gtk_widget_set_sensitive(GTK_WIDGET(widgets->tab_box), enabled); } } static void random_playlist(libsaria::Playlist *playlist) { struct PlaylistWidgets *widgets = find_playlist_widgets(playlist); if (widgets) gtk_toggle_button_set_active(widgets->random, playlist->check_flag(PL_RANDOM)); } static void sort_playlist(libsaria::Playlist *playlist) { struct PlaylistWidgets *widgets = find_playlist_widgets(playlist); if (widgets) gtk_toggle_button_set_active(widgets->sort, playlist->check_flag(PL_SORTED)); } void update_tabs(notify_t event, libsaria::Playlist *playlist) { if (event == PLAYLIST_NEW) new_playlist(playlist); else if (event == PLAYLIST_DELETE) delete_playlist(playlist); else if (event == PLAYLIST_CHANGED) { disable_playlist(playlist); random_playlist(playlist); sort_playlist(playlist); } else if (event == PLAYLIST_RENUMBER) renumber_playlist(playlist); }