ocarina/gui/queue/model.cpp

195 lines
4.1 KiB
C++

/*
* Copyright 2014 (c) Anna Schumaker.
*
* See the example at:
* https://git.gnome.org/browse/gtkmm-documentation/tree/examples/others/treemodelcustom
*/
#include <core/audio.h>
extern "C" {
#include <core/string.h>
}
#include <gui/queue/model.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;
}