gui: Switch over to using a GuiQueueModel

Signed-off-by: Anna Schumaker <Anna@OcarinaProject.net>
This commit is contained in:
Anna Schumaker 2016-01-18 10:14:46 -05:00
parent ea149d57df
commit ada392550a
7 changed files with 54 additions and 272 deletions

View File

@ -1,195 +0,0 @@
/*
* Copyright 2014 (c) Anna Schumaker.
*
* See the example at:
* https://git.gnome.org/browse/gtkmm-documentation/tree/examples/others/treemodelcustom
*/
extern "C" {
#include <core/audio.h>
#include <core/string.h>
}
#include <gui/queue/model.h>
#include <gui/ocarina.h>
#include <stdlib.h>
QueueModel::QueueModel(queue *q)
: Glib::ObjectBase( typeid(QueueModel) ),
Glib::Object(), _stamp(1), _queue(q)
{
}
void QueueModel::increment_stamp()
{
if (++_stamp == 0)
++_stamp;
}
bool QueueModel::check_iter_validity(const Gtk::TreeIter &iter) const
{
return _stamp == iter.get_stamp();
}
void QueueModel::on_row_inserted(unsigned int row)
{
increment_stamp();
row_inserted(Gtk::TreePath(1, row), Gtk::TreeIter());
}
void QueueModel::on_row_deleted(unsigned int row)
{
increment_stamp();
row_deleted(Gtk::TreePath(1, row));
}
void QueueModel::on_cleared(unsigned int n)
{
increment_stamp();
for (unsigned int i = 1; i <= n; i++)
row_deleted(Gtk::TreePath(1, n - i));
}
void QueueModel::on_row_changed(unsigned int row)
{
increment_stamp();
row_changed(Gtk::TreePath(1, row), Gtk::TreeIter());
}
void QueueModel::on_path_selected(const Gtk::TreePath &path)
{
audio_load(track_get(path_to_id(path)));
queue_selected(_queue, path[0]);
audio_play();
}
unsigned int QueueModel :: iter_to_id(const Gtk::TreeIter &iter) const
{
return GPOINTER_TO_UINT(iter.gobj()->user_data);
}
unsigned int QueueModel::path_to_id(const Gtk::TreePath &path) const
{
return queue_at(_queue, path[0])->tr_dbe.dbe_index;
}
Gtk::TreeModelFlags QueueModel::get_flags_vfunc() const
{
return Gtk::TREE_MODEL_LIST_ONLY;
}
int QueueModel::get_n_columns_vfunc() const
{
return 10;
}
GType QueueModel::get_column_type_vfunc(int index) const
{
if (index > 9)
return 0;
if (index == 0 || index == 5 || index == 7)
return G_TYPE_UINT;
return G_TYPE_STRING;
}
template <class T>
static void set_val(const T &t, Glib::ValueBase &value)
{
Glib::Value<T> specific;
specific.init(Glib::Value<T>::value_type());
specific.set(t);
value.init(specific.gobj());
}
void QueueModel::get_value_vfunc(const Gtk::TreeIter &iter, int column,
Glib::ValueBase &value) const
{
struct track *track;
std::string field;
gchar *str;
if (!check_iter_validity(iter) ||
column > get_n_columns_vfunc())
return;
track = queue_at(_queue, iter_to_id(iter));
switch (column) {
case 0:
return set_val(track->tr_track, value);
case 1:
field = track->tr_title;
return set_val(field, value);
case 2:
str = string_sec2str(track->tr_length);
set_val(Glib::ustring(str), value);
g_free(str);
return;
case 3:
field = track->tr_artist->ar_name;
return set_val(field, value);
case 4:
field = track->tr_album->al_name;
return set_val(field, value);
case 5:
return set_val(track->tr_album->al_year, value);
case 6:
field = track->tr_genre->ge_name;
return set_val(field, value);
case 7:
return set_val(track->tr_count, value);
case 8:
str = track_last_play(track);
set_val(Glib::Markup::escape_text(str), value);
g_free(str);
return;
case 9:
str = track_path(track);
set_val(Glib::Markup::escape_text(str), value);
g_free(str);
return;
}
}
bool QueueModel::iter_next_vfunc(const Gtk::TreeIter &iter,
Gtk::TreeIter &next) const
{
next = Gtk::TreeIter();
if (check_iter_validity(iter))
return iter_nth_root_child_vfunc(iter_to_id(iter) + 1, next);
return false;
}
int QueueModel::iter_n_root_children_vfunc() const
{
return queue_size(_queue);
}
bool QueueModel::iter_nth_root_child_vfunc(int n, Gtk::TreeIter &iter) const
{
iter = Gtk::TreeIter();
if (n >= (int)queue_size(_queue))
return false;
iter.set_stamp(_stamp);
iter.gobj()->user_data = GUINT_TO_POINTER(n);
return true;
}
Gtk::TreeModel::Path QueueModel::get_path_vfunc(const Gtk::TreeIter &iter) const
{
Gtk::TreeModel::Path path;
if (check_iter_validity(iter))
path.push_back(iter_to_id(iter));
return path;
}
bool QueueModel::get_iter_vfunc(const Gtk::TreePath &path,
Gtk::TreeIter &iter) const
{
iter = Gtk::TreeIter();
if (path.size() == 1)
return iter_nth_root_child_vfunc(path[0], iter);
return false;
}

View File

@ -2,7 +2,10 @@
* Copyright 2015 (c) Anna Schumaker.
*/
extern "C" {
#include <core/audio.h>
#include <core/filter.h>
#include <gui/model.h>
#include <gui/queue.h>
}
#include <gui/queue/window.h>
@ -19,19 +22,35 @@ QueueWindow :: ~QueueWindow()
set_deinit(&_q_search_res);
}
int queue_window_filter_ids(GtkTreeModel *model, GtkTreeIter *iter,
gpointer data)
{
QueueWindow *window = (QueueWindow *)data;
struct queue *queue = window->_queue;
struct track *track;
if (window->_q_search_empty)
return true;
track = gui_queue_model_iter_get_track(gui_queue(queue)->gq_model, iter);
return set_has(&window->_q_search_res, track->tr_dbe.dbe_index);
}
void QueueWindow :: init(queue *queue)
{
_queue = queue;
q_model = Glib::RefPtr<QueueModel>(new QueueModel(queue));
q_filter = Gtk::TreeModelFilter::create(q_model);
GtkTreeModel *model = GTK_TREE_MODEL(gui_queue(queue)->gq_model);
q_filter = gtk_tree_model_filter_new(model, NULL);
q_filter->set_visible_func(sigc::mem_fun(*this, &QueueWindow::filter_ids));
gtk_tree_model_filter_set_visible_func(GTK_TREE_MODEL_FILTER(q_filter),
queue_window_filter_ids,
this, NULL);
q_treeview->signal_row_activated().connect(sigc::mem_fun(*this,
&QueueWindow :: on_row_activated));
q_treeview->signal_key_press_event().connect(sigc::mem_fun(*this,
&QueueWindow :: on_key_press), false);
q_treeview->set_model(q_filter);
gtk_tree_view_set_model(q_treeview->gobj(), q_filter);
}
void QueueWindow :: filter(std::string &text)
@ -39,18 +58,7 @@ void QueueWindow :: filter(std::string &text)
_q_search_empty = (text.find_first_not_of(" \t") == std::string::npos);
if (!_q_search_empty)
filter_search(text.c_str(), &_q_search_res);
q_filter->refilter();
}
bool QueueWindow :: filter_ids(const Gtk::TreeIter &iter)
{
unsigned int id;
if (_q_search_empty)
return true;
id = q_model->iter_to_id(iter);
return set_has(&_q_search_res, queue_at(_queue, id)->tr_dbe.dbe_index);
gtk_tree_model_filter_refilter(GTK_TREE_MODEL_FILTER(q_filter));
}
bool QueueWindow :: on_key_press(GdkEventKey *event)
@ -64,6 +72,16 @@ bool QueueWindow :: on_key_press(GdkEventKey *event)
void QueueWindow :: on_row_activated(const Gtk::TreePath &path,
Gtk::TreeViewColumn *col)
{
Gtk::TreePath real_path = q_filter->convert_path_to_child_path(path);
q_model->on_path_selected(real_path);
GtkTreePath *orig = path.gobj_copy();
GtkTreePath *real = gtk_tree_model_filter_convert_path_to_child_path(
GTK_TREE_MODEL_FILTER(q_filter), orig);
struct track *track = gui_queue_model_path_get_track(
gui_queue(_queue)->gq_model, real);
audio_load(track);
queue_selected(_queue, gtk_tree_path_get_indices(real)[0]);
audio_play();
gtk_tree_path_free(orig);
gtk_tree_path_free(real);
}

View File

@ -100,6 +100,7 @@ QueueTab :: QueueTab(queue *pq, unsigned int num)
QueueTab :: ~QueueTab()
{
tab_window->q_treeview->unset_model();
queue_mapping.erase(&tab_vbox);
tab_unmap();
gui_sidebar_remove(gui_queue(tab_pq));
@ -135,11 +136,14 @@ bool QueueTab :: on_key_press_event(const std::string &key)
*/
Glib::RefPtr<Gtk::TreeSelection> sel = tab_window->q_treeview->get_selection();
std::vector<Gtk::TreeModel::Path> rows = sel->get_selected_rows();
Gtk::TreeModel::Path path;
GtkTreePath *path;
for (unsigned int i = 0; i < rows.size(); i++) {
path = tab_window->q_filter->convert_path_to_child_path(rows[i]);
ids.push_back(path[0]);
path = gtk_tree_model_filter_convert_path_to_child_path(
GTK_TREE_MODEL_FILTER(tab_window->q_filter),
rows[i].gobj());
ids.push_back(gtk_tree_path_get_indices(path)[0]);
gtk_tree_path_free(path);
}
for (unsigned int i = ids.size(); i > 0; i--)

View File

@ -115,14 +115,12 @@ Tab :: ~Tab() {}
void Tab :: on_track_added(unsigned int row)
{
tab_window->q_model->on_row_inserted(row);
tab_label->set_size();
tab_runtime_changed();
}
void Tab :: on_track_removed(unsigned int row)
{
tab_window->q_model->on_row_deleted(row);
tab_label->set_size();
tab_runtime_changed();
}
@ -137,7 +135,6 @@ void Tab :: on_tracks_cleared(unsigned int n)
void Tab :: on_track_updated(unsigned int row)
{
tab_window->q_model->on_row_changed(row);
tab_runtime_changed();
}
@ -191,11 +188,16 @@ void Tab :: tab_selected_ids(std::vector<unsigned int> &ids)
{
Glib::RefPtr<Gtk::TreeSelection> sel = tab_window->q_treeview->get_selection();
std::vector<Gtk::TreeModel::Path> rows = sel->get_selected_rows();
Gtk::TreeModel::Path path;
GtkTreePath *path;
struct track *track;
for (unsigned int i = 0; i < rows.size(); i++) {
path = tab_window->q_filter->convert_path_to_child_path(rows[i]);
ids.push_back(tab_window->q_model->path_to_id(path));
path = gtk_tree_model_filter_convert_path_to_child_path(
GTK_TREE_MODEL_FILTER(tab_window->q_filter),
rows[i].gobj());
track = gui_queue_model_path_get_track(gui_queue(tab_pq)->gq_model,
path);
ids.push_back(track->tr_dbe.dbe_index);
}
sel->unselect_all();
}

View File

@ -1,44 +0,0 @@
/*
* Copyright 2014 (c) Anna Schumaker.
*/
#ifndef OCARINA_GUI_QUEUE_MODEL_H
#define OCARINA_GUI_QUEUE_MODEL_H
extern "C" {
#include <core/queue.h>
}
#include <gtkmm.h>
class QueueModel : public Gtk::TreeModel, public Glib::Object {
private:
int _stamp;
queue *_queue;
void increment_stamp();
bool check_iter_validity(const Gtk::TreeIter &) const;
protected:
/* Inherited from Gtk::TreeModel */
Gtk::TreeModelFlags get_flags_vfunc() const;
int get_n_columns_vfunc() const;
GType get_column_type_vfunc(int) const;
void get_value_vfunc(const Gtk::TreeIter &, int, Glib::ValueBase &) const;
bool iter_next_vfunc(const Gtk::TreeIter &, Gtk::TreeIter &) const;
int iter_n_root_children_vfunc() const;
bool iter_nth_root_child_vfunc(int, Gtk::TreeIter &) const;
Gtk::TreeModel::Path get_path_vfunc(const Gtk::TreeIter &) const;
bool get_iter_vfunc(const Gtk::TreePath &, Gtk::TreeIter &) const;
public:
QueueModel(queue *);
void on_row_inserted(unsigned int);
void on_row_deleted(unsigned int);
void on_row_changed(unsigned int);
void on_cleared(unsigned int);
void on_path_selected(const Gtk::TreePath &);
unsigned int iter_to_id(const Gtk::TreeIter &) const;
unsigned int path_to_id(const Gtk::TreePath &) const;
};
#endif /* OCARINA_GUI_QUEUE_MODEL_H */

View File

@ -6,22 +6,20 @@
extern "C" {
#include <core/containers/set.h>
#include <gui/queue.h>
}
#include <gui/queue/model.h>
#include <gtkmm.h>
class QueueWindow : public Gtk::ScrolledWindow {
private:
public:
Glib::RefPtr<Gtk::Builder> _builder;
queue *_queue;
struct set _q_search_res;
bool _q_search_empty;
public:
Gtk::TreeView *q_treeview;
Glib::RefPtr<QueueModel> q_model;
Glib::RefPtr<Gtk::TreeModelFilter> q_filter;
GtkTreeModel *q_filter;
QueueWindow(BaseObjectType *, const Glib::RefPtr<Gtk::Builder>);
~QueueWindow();

View File

@ -6,7 +6,6 @@
#include <gui/ocarina.h>
#include <gui/queue/label.h>
#include <gui/queue/model.h>
#include <gui/queue/window.h>
#include <core/playlist.h>
#include <core/queue.h>