ocarina/ocarina/tabs.cpp

284 lines
8.1 KiB
C++

// Copyright (c) 2011 Bryan Schumaker
#include <libsaria.h>
#include <library.h>
#include <print.h>
#include <deck.h>
#include <ban.h>
#include "ocarina.h"
#include <sstream>
using namespace std;
static GtkNotebook *tabs;
static PlaylistWidgets library_widgets;
static PlaylistWidgets recent_widgets;
static PlaylistWidgets banned_widgets;
static list<struct PlaylistWidgets *> dynamic_widgets;
struct PlaylistWidgets *find_page_widgets(GtkWidget *page)
{
list<struct PlaylistWidgets *>::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<struct PlaylistWidgets *>::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 << "<span size='x-large'>" << playlist->get_number() << " </span>";
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);
}