gui: Create generic filtering functions

I need to create a FilterDesc struct with needed widgets and then
filtering can happen generically on all tabs!

Signed-off-by: Anna Schumaker <schumaker.anna@gmail.com>
This commit is contained in:
Anna Schumaker 2014-02-17 19:15:02 -05:00 committed by Anna Schumaker
parent 5d365afae1
commit f68f03c057
7 changed files with 115 additions and 64 deletions

View File

@ -3,6 +3,7 @@
*/ */
#include <deck.h> #include <deck.h>
#include <ocarina.h> #include <ocarina.h>
#include <tabs.h>
static Glib::RefPtr<PlayqueueModel> model; static Glib::RefPtr<PlayqueueModel> model;
@ -72,7 +73,7 @@ static void collection_track_deleted(Playqueue *pq, unsigned int row)
} }
static struct TabFuncs collection_funcs = { static struct TabType collection_funcs = {
.init_late = collection_init_late, .init_late = collection_init_late,
.cleanup = collection_cleanup, .cleanup = collection_cleanup,
@ -81,16 +82,23 @@ static struct TabFuncs collection_funcs = {
.track_deleted = collection_track_deleted, .track_deleted = collection_track_deleted,
}; };
static struct FilterDesc filter_desc;
/* /*
* Basic tab setup * Basic tab setup
*/ */
struct TabFuncs *init_collection_tab() struct TabType *init_collection_tab()
{ {
model = Glib::RefPtr<PlayqueueModel>(new PlayqueueModel(library_pq())); model = Glib::RefPtr<PlayqueueModel>(new PlayqueueModel(library_pq()));
get_widget<Gtk::TreeView>("o_collection_pq_treeview")->set_model(model);
filter_desc.model = model;
filter_desc.entry = get_widget<Gtk::SearchEntry>("o_collection_entry");
init_filter(&filter_desc);
get_widget<Gtk::TreeView>("o_collection_pq_treeview")->set_model(filter_desc.filter);
get_random_button()->signal_toggled().connect(sigc::ptr_fun(on_random_toggled)); get_random_button()->signal_toggled().connect(sigc::ptr_fun(on_random_toggled));

View File

@ -4,6 +4,7 @@
#include <audio.h> #include <audio.h>
#include <filter.h> #include <filter.h>
#include <ocarina.h> #include <ocarina.h>
#include <tabs.h>
#include <set> #include <set>
@ -20,11 +21,6 @@ static inline Playqueue *history_pq()
return audio::get_recent_pq(); return audio::get_recent_pq();
} }
static Gtk::SearchEntry *get_entry()
{
return get_widget<Gtk::SearchEntry>("o_history_entry");
}
static void set_queue_size() static void set_queue_size()
{ {
Gtk::Label *label = get_widget<Gtk::Label>("o_history_size"); Gtk::Label *label = get_widget<Gtk::Label>("o_history_size");
@ -37,31 +33,6 @@ static void set_queue_size()
* Gtk signal functions * Gtk signal functions
*/ */
static void on_history_entry_changed()
{
filter :: search(get_entry()->get_text(), visible_ids);
history_filter->refilter();
}
static bool on_history_entry_key_released(GdkEventKey *event)
{
std::string key = gdk_keyval_name(event->keyval);
return key == "space";
}
bool on_history_filter_visible(const Gtk::TreeIter &iter)
{
unsigned int pq_id;
std::set<unsigned int>::iterator it;
if (get_entry()->get_text().size() == 0)
return true;
pq_id = model->iter_to_id(iter);
return visible_ids.find(history_pq()->operator[](pq_id)) != visible_ids.end();
}
/* /*
@ -93,7 +64,7 @@ static void history_track_deleted(Playqueue *pq, unsigned int row)
} }
static struct TabFuncs history_funcs = { static struct TabType history_funcs = {
.init_late = history_init_late, .init_late = history_init_late,
.cleanup = history_cleanup, .cleanup = history_cleanup,
@ -102,23 +73,23 @@ static struct TabFuncs history_funcs = {
.track_deleted = history_track_deleted, .track_deleted = history_track_deleted,
}; };
static struct FilterDesc filter_desc;
/* /*
* Basic tab setup * Basic tab setup
*/ */
struct TabFuncs *init_history_tab() struct TabType *init_history_tab()
{ {
model = Glib::RefPtr<PlayqueueModel>(new PlayqueueModel(history_pq())); model = Glib::RefPtr<PlayqueueModel>(new PlayqueueModel(history_pq()));
history_filter = Gtk::TreeModelFilter::create(model);
get_widget<Gtk::TreeView>("o_history_treeview")->set_model(history_filter);
Gtk::SearchEntry *entry = get_entry(); filter_desc.model = model;
entry->signal_changed().connect(sigc::ptr_fun(on_history_entry_changed)); filter_desc.entry = get_widget<Gtk::SearchEntry>("o_history_entry");
entry->signal_key_release_event().connect(sigc::ptr_fun(on_history_entry_key_released)); init_filter(&filter_desc);
history_filter->set_visible_func(sigc::ptr_fun(on_history_filter_visible)); get_widget<Gtk::TreeView>("o_history_treeview")->set_model(filter_desc.filter);
return &history_funcs; return &history_funcs;
} }

View File

@ -192,7 +192,7 @@
<property name="margin_right">5</property> <property name="margin_right">5</property>
<property name="spacing">5</property> <property name="spacing">5</property>
<child> <child>
<object class="GtkSearchEntry" id="searchentry1"> <object class="GtkSearchEntry" id="o_collection_entry">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="primary_icon_name">edit-find-symbolic</property> <property name="primary_icon_name">edit-find-symbolic</property>

View File

@ -3,6 +3,7 @@
*/ */
#include <playlist.h> #include <playlist.h>
#include <ocarina.h> #include <ocarina.h>
#include <tabs.h>
static Glib::RefPtr<PlayqueueModel> model; static Glib::RefPtr<PlayqueueModel> model;
@ -84,7 +85,7 @@ static void playlist_track_deleted(Playqueue *pq, unsigned int row)
} }
static struct TabFuncs playlist_funcs = { static struct TabType playlist_funcs = {
.init_late = playlist_init_late, .init_late = playlist_init_late,
.cleanup = playlist_cleanup, .cleanup = playlist_cleanup,
@ -99,7 +100,7 @@ static struct TabFuncs playlist_funcs = {
* Basic tab setup * Basic tab setup
*/ */
struct TabFuncs *init_playlist_tab() struct TabType *init_playlist_tab()
{ {
Gtk::TreeView *playlist = get_playlist_treeview(); Gtk::TreeView *playlist = get_playlist_treeview();

View File

@ -8,6 +8,7 @@
#include <ocarina.h> #include <ocarina.h>
#include <playlist.h> #include <playlist.h>
#include <playqueue.h> #include <playqueue.h>
#include <tabs.h>
#include <list> #include <list>
#include <map> #include <map>
@ -15,9 +16,58 @@
#include <sstream> #include <sstream>
#include <string> #include <string>
/*
* Generic tab functions for filtering
*/
static bool on_entry_key_released(GdkEventKey *event)
{
std::string key = gdk_keyval_name(event->keyval);
return key == "space";
}
static void on_entry_changed(struct FilterDesc *f)
{
filter :: search(f->entry->get_text(), f->visible_ids);
f->filter->refilter();
}
static bool on_filter_visible(const Gtk::TreeIter &iter, struct FilterDesc *f)
{
unsigned int pq_id;
std::set<unsigned int>::iterator it;
if (f->entry->get_text().size() == 0)
return true;
pq_id = f->model->iter_to_id(iter);
it = f->visible_ids.find(f->model->queue->operator[](pq_id));
return it != f->visible_ids.end();
}
void init_filter(struct FilterDesc *filter)
{
filter->filter = Gtk::TreeModelFilter::create(filter->model);
filter->entry->signal_key_release_event().connect(sigc::ptr_fun(on_entry_key_released));
filter->entry->signal_changed().connect(sigc::bind<struct FilterDesc *>(
sigc::ptr_fun(on_entry_changed),
filter));
filter->filter->set_visible_func(sigc::bind<struct FilterDesc *>(
sigc::ptr_fun(on_filter_visible),
filter));
}
/*
* Mostly legacy code ....
*/
class OcarinaPage; class OcarinaPage;
static std::map<Playqueue *, OcarinaPage *> tab_map; static std::map<Playqueue *, OcarinaPage *> tab_map;
static std::list<TabFuncs *> tab_types; static std::list<TabType *> tab_types;
static unsigned int sort_timeout_count = 0; static unsigned int sort_timeout_count = 0;
@ -603,9 +653,9 @@ void OcarinaPage::on_focus_search()
/* /*
* Do stuff with tabs * Do stuff with tabs
*/ */
static TabFuncs *find_tab_funcs(Playqueue *pq) static TabType *find_tab_funcs(Playqueue *pq)
{ {
std::list<TabFuncs *>::iterator tab_it; std::list<TabType *>::iterator tab_it;
for (tab_it = tab_types.begin(); tab_it != tab_types.end(); tab_it++) { for (tab_it = tab_types.begin(); tab_it != tab_types.end(); tab_it++) {
if ((*tab_it)->has_queue(pq)) if ((*tab_it)->has_queue(pq))
return *tab_it; return *tab_it;
@ -621,7 +671,7 @@ static void on_track_added(Playqueue *pq, unsigned int row)
if (it != tab_map.end()) if (it != tab_map.end())
it->second->on_row_inserted(row); it->second->on_row_inserted(row);
struct TabFuncs *tab; struct TabType *tab;
tab = find_tab_funcs(pq); tab = find_tab_funcs(pq);
if (tab) if (tab)
tab->track_added(pq, row); tab->track_added(pq, row);
@ -634,7 +684,7 @@ static void on_track_deleted(Playqueue *pq, unsigned int row)
if (it != tab_map.end()) if (it != tab_map.end())
it->second->on_row_deleted(row); it->second->on_row_deleted(row);
struct TabFuncs *tab; struct TabType *tab;
tab = find_tab_funcs(pq); tab = find_tab_funcs(pq);
if (tab) if (tab)
tab->track_deleted(pq, row); tab->track_deleted(pq, row);
@ -794,7 +844,7 @@ void init_tabs2()
for (it = tab_map.begin(); it != tab_map.end(); it++) for (it = tab_map.begin(); it != tab_map.end(); it++)
it->second->check_pq_flags(); it->second->check_pq_flags();
std::list<TabFuncs *>::iterator tab_it; std::list<TabType *>::iterator tab_it;
for (tab_it = tab_types.begin(); tab_it != tab_types.end(); tab_it++) for (tab_it = tab_types.begin(); tab_it != tab_types.end(); tab_it++)
(*tab_it)->init_late(); (*tab_it)->init_late();
} }
@ -804,7 +854,7 @@ void cleanup_tabs()
while (tab_map.size() > 0) while (tab_map.size() > 0)
delete tab_map.begin()->second; delete tab_map.begin()->second;
std::list<TabFuncs *>::iterator it; std::list<TabType *>::iterator it;
for (it = tab_types.begin(); it != tab_types.end(); it++) for (it = tab_types.begin(); it != tab_types.end(); it++)
(*it)->cleanup(); (*it)->cleanup();
} }

View File

@ -5,22 +5,13 @@
#define OCARINA_H #define OCARINA_H
#include <playqueue.h> #include <playqueue.h>
#include <tabs.h>
#include <gtkmm.h> #include <gtkmm.h>
/* collection.cpp */
struct TabFuncs *init_collection_tab();
/* collection_mgr.cpp */ /* collection_mgr.cpp */
void collection_mgr_init(); void collection_mgr_init();
/* history.cpp */
struct TabFuncs *init_history_tab();
/* main.cpp */ /* main.cpp */
Gtk::Window *ocarina_init(int *, char ***); Gtk::Window *ocarina_init(int *, char ***);
@ -63,9 +54,6 @@ public:
unsigned int path_to_id(const Gtk::TreePath &); unsigned int path_to_id(const Gtk::TreePath &);
}; };
/* playlist.cpp */
struct TabFuncs *init_playlist_tab();
/* tabs.cpp */ /* tabs.cpp */
void queue_selected(bool); void queue_selected(bool);

View File

@ -4,9 +4,25 @@
#ifndef OCARINA_TABS_H #ifndef OCARINA_TABS_H
#define OCARINA_TABS_H #define OCARINA_TABS_H
#include <gtkmm.h>
#include <sstream> #include <sstream>
struct TabFuncs { struct FilterDesc {
/*
* Set these variables
*/
Glib::RefPtr<PlayqueueModel> model;
Gtk::SearchEntry *entry;
/*
* These are configured automatically
*/
Glib::RefPtr<Gtk::TreeModelFilter> filter;
std::set<unsigned int> visible_ids;
};
struct TabType {
void (*init_late)(); void (*init_late)();
void (*cleanup)(); void (*cleanup)();
@ -15,6 +31,7 @@ struct TabFuncs {
void (*track_deleted)(Playqueue *, unsigned int); void (*track_deleted)(Playqueue *, unsigned int);
}; };
static inline std::string itoa(unsigned int i) static inline std::string itoa(unsigned int i)
{ {
std::stringstream ss; std::stringstream ss;
@ -22,4 +39,20 @@ static inline std::string itoa(unsigned int i)
return ss.str(); return ss.str();
} }
/* collection.cpp */
struct TabType *init_collection_tab();
/* history.cpp */
struct TabType *init_history_tab();
/* playlist.cpp */
struct TabType *init_playlist_tab();
/* tabs.cpp */
void init_filter(struct FilterDesc *);
#endif /* OCARINA_TABS_H */ #endif /* OCARINA_TABS_H */