From 48cc1f992ae1b2efd08c4ebc442eb0f450f9d417 Mon Sep 17 00:00:00 2001 From: Anna Schumaker Date: Sun, 2 Feb 2014 14:06:27 -0500 Subject: [PATCH] gui: Add a playlist manager tab Signed-off-by: Anna Schumaker --- gui/main.cpp | 2 + gui/ocarina6.glade | 2 +- gui/tabs.cpp | 108 ++++++++++++++++++++++++++++++++++++++++++--- gui/wires.cpp | 53 ++++++++++++++++++++++ 4 files changed, 159 insertions(+), 6 deletions(-) diff --git a/gui/main.cpp b/gui/main.cpp index 12e53640..448d4214 100644 --- a/gui/main.cpp +++ b/gui/main.cpp @@ -4,6 +4,7 @@ #include #include #include +#include Gtk::Window *ocarina_init(int *argc, char ***argv) { @@ -11,6 +12,7 @@ Gtk::Window *ocarina_init(int *argc, char ***argv) audio::init(argc, argv); deck::init(); library::init(); + playlist::init(); init_tabs2(); return window; diff --git a/gui/ocarina6.glade b/gui/ocarina6.glade index f2aa1a76..e4c3d087 100644 --- a/gui/ocarina6.glade +++ b/gui/ocarina6.glade @@ -541,7 +541,7 @@ Manager True False - edit-delete + face-sad diff --git a/gui/tabs.cpp b/gui/tabs.cpp index 7dc96d06..e99ec091 100644 --- a/gui/tabs.cpp +++ b/gui/tabs.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -17,6 +18,14 @@ class OcarinaPage; static std::map tab_map; static unsigned int sort_timeout_count = 0; +static class SidebarColumns : public Gtk::TreeModelColumnRecord { +public: + SidebarColumns() + { add(sb_col_name); } + + Gtk::TreeModelColumn sb_col_name; +} sb_cols; + static class QueueColumns : public Gtk::TreeModelColumnRecord { public: QueueColumns() @@ -160,6 +169,36 @@ void PQTab::set_number(unsigned int num) +class ManagerTab : public OcarinaTab { +public: + Gtk::Label name_label; + Gtk::Image tab_icon; + + ManagerTab(const std::string &, const std::string &); + ~ManagerTab(); + void set_size(unsigned int); + void set_number(unsigned int); +}; + +ManagerTab::ManagerTab(const std::string &name, const std::string &icon) + : name_label(name, 0.5, 0.5) +{ + name_label.set_justify(Gtk::JUSTIFY_CENTER); + tab_icon.set_from_icon_name(icon, Gtk::ICON_SIZE_MENU); + tab_icon.set_alignment(0, 0.5); + + set_spacing(5); + pack_start(tab_icon); + pack_start(name_label); + show_all(); +} + +ManagerTab::~ManagerTab() {} +void ManagerTab::set_size(unsigned int) {} +void ManagerTab::set_number(unsigned int) {} + + + /* * Ocarina class definition @@ -178,10 +217,17 @@ private: Gtk::SearchEntry page_entry; Gtk::ToggleButton page_repeat; Gtk::ScrolledWindow page_scroll; + Gtk::HBox page_viewbox; Gtk::TreeView page_view; - void setup_common(Playqueue *, unsigned int); + /* Sidebar widgets */ + Glib::RefPtr sb_store; + Gtk::TreeView sb_view; + Gtk::ScrolledWindow sb_scroll; + + void setup_common(Playqueue *, unsigned int, bool); void setup_toolbar(); + void setup_sidebar(); void setup_treeview(); void setup_columns(); void set_tab_size(); @@ -194,6 +240,7 @@ public: OcarinaPage(const std::string &, const std::string &, Playqueue *, unsigned int); OcarinaPage(Playqueue *, unsigned int, unsigned int); + OcarinaPage(const std::string &, const std::string &, Playqueue *); ~OcarinaPage(); bool is_current_tab(); void check_pq_flags(); @@ -213,6 +260,7 @@ public: bool on_filter_visible(const Gtk::TreeIter &); void on_page_renumbered(); bool on_view_key_pressed(GdkEventKey *); + void on_sidebar_cursor_changed(); }; @@ -221,7 +269,7 @@ OcarinaPage::OcarinaPage(const std::string &name, const std::string &icon, : init_flags(flags) { tab = new PresetTab(name, icon); - setup_common(pq, 0); + setup_common(pq, 0, false); } OcarinaPage::OcarinaPage(Playqueue *pq, unsigned int flags, unsigned int pg) @@ -232,17 +280,26 @@ OcarinaPage::OcarinaPage(Playqueue *pq, unsigned int flags, unsigned int pg) pqt->close_button.signal_clicked().connect(sigc::mem_fun(*this, &OcarinaPage::on_close_clicked)); - setup_common(pq, pg); + setup_common(pq, pg, false); notebook->set_tab_reorderable(*this); } +OcarinaPage::OcarinaPage(const std::string &name, const std::string &icon, + Playqueue *pq) +{ + ManagerTab *man_tab = new ManagerTab(name, icon); + tab = man_tab; + + setup_common(pq, 0, true); +} + OcarinaPage::~OcarinaPage() { notebook->remove_page(*this); tab_map.erase(model->queue); } -void OcarinaPage::setup_common(Playqueue *pq, unsigned int pg) +void OcarinaPage::setup_common(Playqueue *pq, unsigned int pg, bool sidebar) { get_builder()->get_widget("o_notebook", notebook); model = Glib::RefPtr(new PlayqueueModel(pq)); @@ -252,9 +309,13 @@ void OcarinaPage::setup_common(Playqueue *pq, unsigned int pg) set_margin_left(1); set_margin_right(1); + set_spacing(1); setup_toolbar(); + if (sidebar == true) + setup_sidebar(); setup_treeview(); + pack_start(page_viewbox); show_all(); /* Add to notebook */ @@ -291,6 +352,32 @@ void OcarinaPage::setup_toolbar() pack_start(page_toolbar, false, false); } +void OcarinaPage::setup_sidebar() +{ + Gtk::TreeModel::Row row; + + sb_store = Gtk::ListStore::create(sb_cols); + sb_view.append_column("Playlists", sb_cols.sb_col_name); + sb_view.set_model(sb_store); + sb_view.get_selection()->set_mode(Gtk::SELECTION_BROWSE); + sb_view.signal_cursor_changed().connect(sigc::mem_fun(*this, + &OcarinaPage::on_sidebar_cursor_changed)); + + row = *(sb_store->append()); + row[sb_cols.sb_col_name] = "Favorites"; + + row = *(sb_store->append()); + row[sb_cols.sb_col_name] = "Banned"; + + sb_view.set_cursor(Gtk::TreePath("0")); + sb_scroll.set_shadow_type(Gtk::SHADOW_IN); + sb_scroll.set_margin_left(5); + sb_scroll.set_margin_bottom(5); + sb_scroll.add(sb_view); + + page_viewbox.pack_start(sb_scroll, false, false); +} + void OcarinaPage::setup_treeview() { /* Make page content */ @@ -323,7 +410,7 @@ void OcarinaPage::setup_treeview() page_scroll.add(page_view); setup_columns(); - pack_start(page_scroll); + page_viewbox.pack_start(page_scroll, true, true); }; void OcarinaPage::setup_columns() @@ -514,6 +601,16 @@ bool OcarinaPage::on_view_key_pressed(GdkEventKey *event) return false; } +void OcarinaPage::on_sidebar_cursor_changed() +{ + Gtk::TreePath path; + Gtk::TreeViewColumn *col; + + sb_view.get_cursor(path, col); + Gtk::TreeModel::Row row = *(sb_store->get_iter(path)); + playlist :: select(row[sb_cols.sb_col_name]); +} + /* @@ -619,6 +716,7 @@ void init_tabs() Gtk::Notebook *notebook; get_builder()->get_widget("o_notebook", notebook); + new OcarinaPage("Playlist\nManager", "emblem-documents", playlist::get_pq()); new OcarinaPage("History", "document-open-recent", audio::get_recent_pq(), 0); new OcarinaPage("Collection", "media-optical", deck::get_library_pq(), PQ_RANDOM); get_callbacks()->on_pq_created = on_pq_created; diff --git a/gui/wires.cpp b/gui/wires.cpp index 0a68e34b..6e09b062 100644 --- a/gui/wires.cpp +++ b/gui/wires.cpp @@ -5,12 +5,15 @@ #include #include #include +#include #include #include static bool audio_playing = false; static Glib::RefPtr builder; +static sigc::connection fav_connection; +static sigc::connection ban_connection; void enable_idle(); void enable_timeout(); @@ -69,16 +72,35 @@ static void set_label_text(Gtk::Label *label, const std::string &size, static void on_track_loaded(library :: Song &song) { + Gtk::ToggleButton *ban, *fav; Gtk::Label *title, *artist, *album, *duration; + builder->get_widget("o_title", title); builder->get_widget("o_artist", artist); builder->get_widget("o_album", album); builder->get_widget("o_total_time", duration); + builder->get_widget("o_ban", ban); + builder->get_widget("o_favorite", fav); set_label_text(title, "xx-large", song.track->title); set_label_text(artist, "x-large", "By: " + song.artist->primary_key); set_label_text(album, "x-large", "From: " + song.album->name); duration->set_text(song.track->length_str); + + std::set ids = playlist :: get_tracks("Banned"); + bool banned = ids.find(song.track_id) != ids.end(); + + ids = playlist :: get_tracks("Favorites"); + bool favorite = ids.find(song.track_id) != ids.end(); + + ban_connection.block(); + fav_connection.block(); + if (ban->get_active() != banned) + ban->set_active(banned); + if (fav->get_active() != favorite) + fav->set_active(favorite); + ban_connection.unblock(); + fav_connection.unblock(); } static void on_pause_count_changed(bool enabled, unsigned int count) @@ -94,6 +116,28 @@ static void on_pause_count_changed(bool enabled, unsigned int count) p_count->set_value(count); } +static void on_ban_toggled() +{ + Gtk::ToggleButton *ban; + builder->get_widget("o_ban", ban); + + if (ban->get_active() == true) + playlist :: add("Banned", audio::current_trackid()); + else + playlist :: del("Banned", audio::current_trackid()); +} + +static void on_fav_toggled() +{ + Gtk::ToggleButton *fav; + builder->get_widget("o_favorite", fav); + + if (fav->get_active() == true) + playlist :: add("Favorites", audio::current_trackid()); + else + playlist :: del("Favorites", audio::current_trackid()); +} + /* @@ -344,6 +388,8 @@ Gtk::Window *connect_wires() Gtk::SpinButton *count; Gtk::CheckButton *enabled; Gtk::Scale *position; + Gtk::ToggleButton *ban; + Gtk::ToggleButton *fav; builder = Gtk::Builder::create(); builder->add_from_file("gui/ocarina6.glade"); @@ -393,6 +439,13 @@ Gtk::Window *connect_wires() connect_button("o_collection_import", on_collection_import); + /* Favorite and ban buttons */ + builder->get_widget("o_ban", ban); + builder->get_widget("o_favorite", fav); + ban_connection = ban->signal_toggled().connect(sigc::ptr_fun(on_ban_toggled)); + fav_connection = fav->signal_toggled().connect(sigc::ptr_fun(on_fav_toggled)); + + /* Set up other tabs */ init_tabs();