gui: Switch over to using a GuiQueueModel
Signed-off-by: Anna Schumaker <Anna@OcarinaProject.net>
This commit is contained in:
parent
ea149d57df
commit
ada392550a
|
@ -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;
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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--)
|
||||
|
|
14
gui/tabs.cpp
14
gui/tabs.cpp
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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 */
|
|
@ -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();
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Reference in New Issue