/* * Copyright 2014 (c) Anna Schumaker. */ #include #include #include #include #include #include #include class OcarinaPage; static std::map tab_map; static class QueueColumns : public Gtk::TreeModelColumnRecord { public: QueueColumns() { add(q_col_track); add(q_col_title); add(q_col_length); add(q_col_artist); add(q_col_album); add(q_col_year); add(q_col_genre); add(q_col_count); add(q_col_played); } Gtk::TreeModelColumn q_col_track; Gtk::TreeModelColumn q_col_title; Gtk::TreeModelColumn q_col_length; Gtk::TreeModelColumn q_col_artist; Gtk::TreeModelColumn q_col_album; Gtk::TreeModelColumn q_col_year; Gtk::TreeModelColumn q_col_genre; Gtk::TreeModelColumn q_col_count; Gtk::TreeModelColumn q_col_played; } queue_cols; static unsigned int q_col_width[] = { 20, 300, 60, 100, 100, 45, 100, 60, 1 }; /* * Tab class definition */ class OcarinaTab { public: Gtk::Label name_label; Gtk::Label size_label; Gtk::Image tab_icon; Gtk::HBox box; Gtk::VBox inner_box; OcarinaTab(const std::string &, const std::string &); ~OcarinaTab(); void set_size(unsigned int); }; OcarinaTab::OcarinaTab(const std::string &name, const std::string &icon) : name_label("" + name + "", 1, 0.5), size_label("0", 0.5, 0.5) { tab_icon.set_from_icon_name(icon, Gtk::ICON_SIZE_MENU); name_label.set_use_markup(); name_label.set_margin_right(1); box.set_spacing(5); inner_box.pack_start(name_label); inner_box.pack_start(size_label); box.pack_start(tab_icon); box.pack_start(inner_box); box.show_all(); } OcarinaTab::~OcarinaTab() {} void OcarinaTab::set_size(unsigned int size) { std::stringstream ss; ss << size; size_label.set_text(ss.str()); } /* * Ocarina class definition */ class OcarinaPage { private: Glib::RefPtr model; Gtk::Notebook *notebook; OcarinaTab tab; /* Page widgets */ Gtk::VBox page_box; Gtk::HBox page_toolbar; Gtk::SearchEntry page_entry; Gtk::ToggleButton page_random; //Gtk::ToggleButton page_repeat; Gtk::ScrolledWindow page_scroll; Gtk::TreeView page_view; void setup_columns(); void set_tab_size(); public: OcarinaPage(const std::string &, const std::string &, Playqueue *); ~OcarinaPage(); bool is_current_tab(); bool is_current_tab(unsigned int); void on_row_inserted(unsigned int); void on_row_deleted(unsigned int); void on_runtime_changed(); }; OcarinaPage::OcarinaPage(const std::string &name, const std::string &icon, Playqueue *pq) : tab(name, icon) { get_builder()->get_widget("o_notebook", notebook); model = Glib::RefPtr(new PlayqueueModel(pq)); /* Make page content */ page_random.set_image_from_icon_name("media-playlist-shuffle"); page_random.set_active(pq->get_flags() & PQ_RANDOM); //page_repeat.set_image_from_icon_name("media-playlist-repeat"); page_toolbar.set_spacing(5); page_view.append_column("#", queue_cols.q_col_track); page_view.append_column("Title", queue_cols.q_col_title); page_view.append_column("Length", queue_cols.q_col_length); page_view.append_column("Artist", queue_cols.q_col_artist); page_view.append_column("Album", queue_cols.q_col_album); page_view.append_column("Year", queue_cols.q_col_year); page_view.append_column("Genre", queue_cols.q_col_genre); page_view.append_column("Count", queue_cols.q_col_count); page_view.append_column("Played", queue_cols.q_col_played); page_view.set_model(model); page_scroll.add(page_view); setup_columns(); page_toolbar.pack_start(page_entry); page_toolbar.pack_start(page_random, false, false); //page_toolbar.pack_start(page_repeat, false, false); page_box.pack_start(page_toolbar, false, false); page_box.pack_start(page_scroll); page_box.show_all(); /* Add to notebook */ notebook->prepend_page(page_box, tab.box); tab_map[pq] = this; }; OcarinaPage::~OcarinaPage() { notebook->remove_page(page_box); tab_map.erase(model->queue); } void OcarinaPage::setup_columns() { std::vector columns = page_view.get_columns(); for (unsigned int i = 0; i < columns.size(); i++) { columns[i]->set_resizable(); columns[i]->set_fixed_width(q_col_width[i]); columns[i]->set_sizing(Gtk::TREE_VIEW_COLUMN_FIXED); } } bool OcarinaPage::is_current_tab() { return notebook->page_num(page_box) == notebook->get_current_page(); } bool OcarinaPage::is_current_tab(unsigned int tab) { return notebook->page_num(page_box) == (int)tab; } void OcarinaPage::set_tab_size() { tab.set_size(model->queue->size()); } void OcarinaPage::on_row_inserted(unsigned int row) { model->on_row_inserted(row); set_tab_size(); if (is_current_tab()) on_runtime_changed(); } void OcarinaPage::on_row_deleted(unsigned int row) { model->on_row_deleted(row); set_tab_size(); if (is_current_tab()) on_runtime_changed(); } void OcarinaPage::on_runtime_changed() { Gtk::Label *label; get_builder()->get_widget("o_queue_time", label); label->set_text(model->queue->get_length_str()); } /* * Do stuff with tabs */ static void on_track_added(Playqueue *pq, unsigned int row) { std::map::iterator it; it = tab_map.find(pq); if (it != tab_map.end()) it->second->on_row_inserted(row); } static void on_track_deleted(Playqueue *pq, unsigned int row) { std::map::iterator it; it = tab_map.find(pq); if (it != tab_map.end()) it->second->on_row_deleted(row); } static void on_switch_page(Gtk::Widget *page, unsigned int num) { Gtk::Label *label; std::map::iterator it; get_builder()->get_widget("o_queue_time", label); for (it = tab_map.begin(); it != tab_map.end(); it++) { if (it->second->is_current_tab(num)) { it->second->on_runtime_changed(); label->show(); return; } } label->hide(); } void init_tabs() { Gtk::Notebook *notebook; get_builder()->get_widget("o_notebook", notebook); new OcarinaPage("Collection", "media-optical", deck::get_library_pq()); get_callbacks()->on_queue_track_add = on_track_added; get_callbacks()->on_queue_track_del = on_track_deleted; notebook->signal_switch_page().connect(sigc::ptr_fun(on_switch_page)); } void cleanup_tabs() { std::map::iterator it; for (it = tab_map.begin(); it != tab_map.end(); it++) delete it->second; }