Everything for a custom Gtk::TreeModel
I implemented an entire Gtk::TreeModel in this commit, plus some minor supporting code in the library to look up playlist entries by index. Signed-off-by: Anna Schumaker <schumaker.anna@gmail.com>
This commit is contained in:
parent
6c58f9bc2f
commit
2ecb37f6dc
253
gui/model.cpp
Normal file
253
gui/model.cpp
Normal file
|
@ -0,0 +1,253 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2014 (c) Anna Schumaker.
|
||||||
|
*
|
||||||
|
* See the example at:
|
||||||
|
* https://git.gnome.org/browse/gtkmm-documentation/tree/examples/others/treemodelcustom
|
||||||
|
*/
|
||||||
|
#include <ocarina.h>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
PlayqueueModel::PlayqueueModel(Playqueue *q)
|
||||||
|
: Glib::ObjectBase( typeid(PlayqueueModel) ),
|
||||||
|
Glib::Object(),
|
||||||
|
stamp(1), queue(q)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlayqueueModel::on_row_inserted(unsigned int row)
|
||||||
|
{
|
||||||
|
Gtk::TreePath path;
|
||||||
|
Gtk::TreeIter iter;
|
||||||
|
|
||||||
|
path.push_back(row);
|
||||||
|
stamp++;
|
||||||
|
row_inserted(path, iter);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlayqueueModel::on_row_deleted(unsigned int row)
|
||||||
|
{
|
||||||
|
Gtk::TreePath path;
|
||||||
|
|
||||||
|
path.push_back(row);
|
||||||
|
stamp++;
|
||||||
|
row_deleted(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Function overrides begin here
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
Gtk::TreeModelFlags PlayqueueModel::get_flags_vfunc() const
|
||||||
|
{
|
||||||
|
return Gtk::TREE_MODEL_LIST_ONLY;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PlayqueueModel::get_n_columns_vfunc() const
|
||||||
|
{
|
||||||
|
return 9;
|
||||||
|
}
|
||||||
|
|
||||||
|
GType PlayqueueModel::get_column_type_vfunc(int index) const
|
||||||
|
{
|
||||||
|
switch (index) {
|
||||||
|
case 0:
|
||||||
|
case 5:
|
||||||
|
case 7:
|
||||||
|
return G_TYPE_UINT;
|
||||||
|
case 1:
|
||||||
|
case 2:
|
||||||
|
case 3:
|
||||||
|
case 4:
|
||||||
|
case 6:
|
||||||
|
case 8:
|
||||||
|
return G_TYPE_STRING;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlayqueueModel::get_value_uint(struct library::Song &song, int column,
|
||||||
|
Glib::ValueBase &value) const
|
||||||
|
{
|
||||||
|
Glib::Value<unsigned int> specific;
|
||||||
|
specific.init(Glib::Value<unsigned int>::value_type());
|
||||||
|
|
||||||
|
switch (column) {
|
||||||
|
case 0:
|
||||||
|
specific.set(song.track->track);
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
specific.set(song.album->year);
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
specific.set(song.track->play_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
value.init(Glib::Value<unsigned int>::value_type());
|
||||||
|
value = specific;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlayqueueModel::get_value_str(struct library::Song &song, int column,
|
||||||
|
Glib::ValueBase &value) const
|
||||||
|
{
|
||||||
|
Glib::Value<std::string> specific;
|
||||||
|
specific.init(Glib::Value<std::string>::value_type());
|
||||||
|
|
||||||
|
switch (column) {
|
||||||
|
case 1:
|
||||||
|
specific.set(song.track->title);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
specific.set(song.track->length_str);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
specific.set(song.artist->primary_key);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
specific.set(song.album->name);
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
specific.set(song.genre->primary_key);
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
std::stringstream ss;
|
||||||
|
if (song.track->play_count == 0)
|
||||||
|
specific.set("Never");
|
||||||
|
else {
|
||||||
|
ss << song.track->last_month << " / ";
|
||||||
|
ss << song.track->last_day << " / ";
|
||||||
|
ss << song.track->last_year;
|
||||||
|
specific.set(ss.str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
value.init(Glib::Value<std::string>::value_type());
|
||||||
|
value = specific;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlayqueueModel::get_value_vfunc(const Gtk::TreeIter &iter, int column,
|
||||||
|
Glib::ValueBase &value) const
|
||||||
|
{
|
||||||
|
unsigned int row;
|
||||||
|
struct library::Song song;
|
||||||
|
|
||||||
|
if (!check_iter_validity(iter))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (column > get_n_columns_vfunc())
|
||||||
|
return;
|
||||||
|
|
||||||
|
row = GPOINTER_TO_UINT(iter.gobj()->user_data);
|
||||||
|
library :: lookup((*queue)[row], &song);
|
||||||
|
|
||||||
|
switch (column) {
|
||||||
|
case 0:
|
||||||
|
case 5:
|
||||||
|
case 7:
|
||||||
|
get_value_uint(song, column, value);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
get_value_str(song, column, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PlayqueueModel::iter_next_vfunc(const Gtk::TreeIter &iter,
|
||||||
|
Gtk::TreeIter &iter_next) const
|
||||||
|
{
|
||||||
|
unsigned int index;
|
||||||
|
iter_next = Gtk::TreeIter();
|
||||||
|
|
||||||
|
if (!check_iter_validity(iter))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
iter_next.set_stamp(stamp);
|
||||||
|
index = GPOINTER_TO_UINT(iter.gobj()->user_data);
|
||||||
|
index++;
|
||||||
|
if (index < queue->size()) {
|
||||||
|
iter_next.gobj()->user_data = GUINT_TO_POINTER(index);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PlayqueueModel::iter_children_vfunc(const Gtk::TreeIter &parent,
|
||||||
|
Gtk::TreeIter &iter) const
|
||||||
|
{
|
||||||
|
return iter_nth_child_vfunc(parent, 0, iter);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PlayqueueModel::iter_has_child_vfunc(const Gtk::TreeIter &iter) const
|
||||||
|
{
|
||||||
|
return (iter_n_children_vfunc(iter) > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int PlayqueueModel::iter_n_children_vfunc(const Gtk::TreeIter &iter) const
|
||||||
|
{
|
||||||
|
if (!check_iter_validity(iter))
|
||||||
|
return 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PlayqueueModel::iter_n_root_children_vfunc(const Gtk::TreeIter &iter) const
|
||||||
|
{
|
||||||
|
return queue->size();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PlayqueueModel::iter_nth_child_vfunc(const Gtk::TreeIter &parent,
|
||||||
|
int n, Gtk::TreeIter &iter) const
|
||||||
|
{
|
||||||
|
iter = Gtk::TreeIter();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PlayqueueModel::iter_nth_root_child_vfunc(int n, Gtk::TreeIter &iter) const
|
||||||
|
{
|
||||||
|
iter = Gtk::TreeIter();
|
||||||
|
if ((unsigned int)n < queue->size()) {
|
||||||
|
iter.gobj()->user_data = GUINT_TO_POINTER(n);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PlayqueueModel::iter_parent_vfunc(const Gtk::TreeIter &child,
|
||||||
|
Gtk::TreeIter &iter) const
|
||||||
|
{
|
||||||
|
iter = Gtk::TreeIter();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Gtk::TreeModel::Path PlayqueueModel::get_path_vfunc(const Gtk::TreeIter &iter) const
|
||||||
|
{
|
||||||
|
Gtk::TreeModel::Path path;
|
||||||
|
|
||||||
|
if (check_iter_validity(iter))
|
||||||
|
path.push_back(GPOINTER_TO_UINT(iter.gobj()->user_data));
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PlayqueueModel::get_iter_vfunc(const Gtk::TreePath &path,
|
||||||
|
Gtk::TreeIter &iter_next) const
|
||||||
|
{
|
||||||
|
iter_next = Gtk::TreeIter();
|
||||||
|
|
||||||
|
if (path.size() != 1)
|
||||||
|
return false;
|
||||||
|
if ((unsigned int)path[0] >= queue->size())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
iter_next.set_stamp(stamp);
|
||||||
|
iter_next.gobj()->user_data = GUINT_TO_POINTER(path[0]);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PlayqueueModel::check_iter_validity(const Gtk::TreeIter &iter) const
|
||||||
|
{
|
||||||
|
return stamp == iter.get_stamp();
|
||||||
|
}
|
50
gui/tabs.cpp
50
gui/tabs.cpp
|
@ -38,7 +38,7 @@ static unsigned int q_col_width[] = { 20, 300, 1, 125, 125, 1, 125, 1, 1 };
|
||||||
*/
|
*/
|
||||||
class OcarinaTab {
|
class OcarinaTab {
|
||||||
private:
|
private:
|
||||||
Playqueue *queue;
|
Glib::RefPtr<PlayqueueModel> model;
|
||||||
|
|
||||||
/* Tab widgets */
|
/* Tab widgets */
|
||||||
Gtk::VBox tab_box;
|
Gtk::VBox tab_box;
|
||||||
|
@ -55,21 +55,24 @@ private:
|
||||||
Gtk::TreeView page_view;
|
Gtk::TreeView page_view;
|
||||||
|
|
||||||
void setup_columns();
|
void setup_columns();
|
||||||
|
void set_tab_size();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
OcarinaTab(const std::string &, Playqueue *);
|
OcarinaTab(const std::string &, Playqueue *);
|
||||||
~OcarinaTab();
|
~OcarinaTab();
|
||||||
void set_tab_size();
|
|
||||||
|
void on_row_inserted(unsigned int);
|
||||||
|
void on_row_deleted(unsigned int);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
OcarinaTab::OcarinaTab(const std::string &text, Playqueue *pq)
|
OcarinaTab::OcarinaTab(const std::string &text, Playqueue *pq)
|
||||||
: queue(pq),
|
: tab_name("<big>" + text + "</big>", 1, 0.5),
|
||||||
tab_name("<big>" + text + "</big>", 1, 0.5),
|
|
||||||
tab_size("0", 1, 0.5)
|
tab_size("0", 1, 0.5)
|
||||||
{
|
{
|
||||||
Gtk::Notebook *notebook;
|
Gtk::Notebook *notebook;
|
||||||
get_builder()->get_widget("o_notebook", notebook);
|
get_builder()->get_widget("o_notebook", notebook);
|
||||||
|
model = Glib::RefPtr<PlayqueueModel>(new PlayqueueModel(pq));
|
||||||
|
|
||||||
|
|
||||||
/* Make tab label */
|
/* Make tab label */
|
||||||
|
@ -95,6 +98,8 @@ OcarinaTab::OcarinaTab(const std::string &text, Playqueue *pq)
|
||||||
page_view.append_column("Genre", queue_cols.q_col_genre);
|
page_view.append_column("Genre", queue_cols.q_col_genre);
|
||||||
page_view.append_column("Count", queue_cols.q_col_count);
|
page_view.append_column("Count", queue_cols.q_col_count);
|
||||||
page_view.append_column("Played", queue_cols.q_col_played);
|
page_view.append_column("Played", queue_cols.q_col_played);
|
||||||
|
|
||||||
|
page_view.set_model(model);
|
||||||
page_scroll.add(page_view);
|
page_scroll.add(page_view);
|
||||||
setup_columns();
|
setup_columns();
|
||||||
|
|
||||||
|
@ -117,14 +122,7 @@ OcarinaTab::~OcarinaTab()
|
||||||
get_builder()->get_widget("o_notebook", notebook);
|
get_builder()->get_widget("o_notebook", notebook);
|
||||||
notebook->remove_page(page_box);
|
notebook->remove_page(page_box);
|
||||||
|
|
||||||
tab_map.erase(queue);
|
tab_map.erase(model->queue);
|
||||||
}
|
|
||||||
|
|
||||||
void OcarinaTab::set_tab_size()
|
|
||||||
{
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << queue->size();
|
|
||||||
tab_size.set_text(ss.str());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OcarinaTab::setup_columns()
|
void OcarinaTab::setup_columns()
|
||||||
|
@ -136,19 +134,39 @@ void OcarinaTab::setup_columns()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OcarinaTab::set_tab_size()
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << model->queue->size();
|
||||||
|
tab_size.set_text(ss.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
void OcarinaTab::on_row_inserted(unsigned int row)
|
||||||
|
{
|
||||||
|
model->on_row_inserted(row);
|
||||||
|
set_tab_size();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OcarinaTab::on_row_deleted(unsigned int row)
|
||||||
|
{
|
||||||
|
model->on_row_deleted(row);
|
||||||
|
set_tab_size();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Do stuff with tabs
|
* Do stuff with tabs
|
||||||
*/
|
*/
|
||||||
static void on_track_added(Playqueue *pq)
|
static void on_track_added(Playqueue *pq, unsigned int row)
|
||||||
{
|
{
|
||||||
tab_map[pq]->set_tab_size();
|
tab_map[pq]->on_row_inserted(row);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void on_track_deleted(Playqueue *pq)
|
static void on_track_deleted(Playqueue *pq, unsigned int row)
|
||||||
{
|
{
|
||||||
tab_map[pq]->set_tab_size();
|
tab_map[pq]->on_row_deleted(row);
|
||||||
}
|
}
|
||||||
|
|
||||||
void init_tabs()
|
void init_tabs()
|
||||||
|
|
|
@ -16,8 +16,8 @@ struct Callbacks {
|
||||||
void (*on_library_track_del)(unsigned int);
|
void (*on_library_track_del)(unsigned int);
|
||||||
|
|
||||||
/* Playqueue callbacks */
|
/* Playqueue callbacks */
|
||||||
void (*on_queue_track_add)(Playqueue *);
|
void (*on_queue_track_add)(Playqueue *, unsigned int);
|
||||||
void (*on_queue_track_del)(Playqueue *);
|
void (*on_queue_track_del)(Playqueue *, unsigned int);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,40 @@
|
||||||
#ifndef OCARINA_H
|
#ifndef OCARINA_H
|
||||||
#define OCARINA_H
|
#define OCARINA_H
|
||||||
|
|
||||||
|
#include <playqueue.h>
|
||||||
#include <gtkmm.h>
|
#include <gtkmm.h>
|
||||||
|
/* model.cpp */
|
||||||
|
class PlayqueueModel : public Gtk::TreeModel, public Glib::Object {
|
||||||
|
private:
|
||||||
|
void get_value_uint(struct library::Song &, int, Glib::ValueBase &) const;
|
||||||
|
void get_value_str(struct library::Song &, int, Glib::ValueBase &) const;
|
||||||
|
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;
|
||||||
|
bool iter_children_vfunc(const Gtk::TreeIter &, Gtk::TreeIter &) const;
|
||||||
|
bool iter_has_child_vfunc(const Gtk::TreeIter &) const;
|
||||||
|
int iter_n_children_vfunc(const Gtk::TreeIter &) const;
|
||||||
|
int iter_n_root_children_vfunc(const Gtk::TreeIter &) const;
|
||||||
|
bool iter_nth_child_vfunc(const Gtk::TreeIter &, int, Gtk::TreeIter &) const;
|
||||||
|
bool iter_nth_root_child_vfunc(int, Gtk::TreeIter &) const;
|
||||||
|
bool iter_parent_vfunc(const Gtk::TreeIter &, Gtk::TreeIter &) const;
|
||||||
|
Gtk::TreeModel::Path get_path_vfunc(const Gtk::TreeIter &) const;
|
||||||
|
bool get_iter_vfunc(const Gtk::TreePath &, Gtk::TreeIter &) const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
int stamp;
|
||||||
|
Playqueue *queue;
|
||||||
|
PlayqueueModel(Playqueue *);
|
||||||
|
|
||||||
|
void on_row_inserted(unsigned int);
|
||||||
|
void on_row_deleted(unsigned int);
|
||||||
|
};
|
||||||
|
|
||||||
/* tabs.cpp */
|
/* tabs.cpp */
|
||||||
void init_tabs();
|
void init_tabs();
|
||||||
|
|
|
@ -38,6 +38,7 @@ public:
|
||||||
void del(unsigned int);
|
void del(unsigned int);
|
||||||
void del_track(unsigned int);
|
void del_track(unsigned int);
|
||||||
unsigned int size();
|
unsigned int size();
|
||||||
|
unsigned int operator[](unsigned int);
|
||||||
|
|
||||||
unsigned int next();
|
unsigned int next();
|
||||||
void reset_cur();
|
void reset_cur();
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
static void no_op(unsigned int) {}
|
static void no_op(unsigned int) {}
|
||||||
static void no_op(unsigned int id, library :: Library *path) {}
|
static void no_op(unsigned int id, library :: Library *path) {}
|
||||||
static void no_op(Playqueue *) {}
|
static void no_op(Playqueue *, unsigned int) {}
|
||||||
|
|
||||||
|
|
||||||
static struct Callbacks callbacks = {
|
static struct Callbacks callbacks = {
|
||||||
|
|
|
@ -58,13 +58,14 @@ unsigned int Playqueue :: get_length()
|
||||||
|
|
||||||
unsigned int Playqueue :: add(unsigned int track_id)
|
unsigned int Playqueue :: add(unsigned int track_id)
|
||||||
{
|
{
|
||||||
|
unsigned int id = tracks.size();
|
||||||
library :: Song song;
|
library :: Song song;
|
||||||
tracks.push_back(track_id);
|
tracks.push_back(track_id);
|
||||||
|
|
||||||
library :: lookup(track_id, &song);
|
library :: lookup(track_id, &song);
|
||||||
length += song.track->length;
|
length += song.track->length;
|
||||||
get_callbacks()->on_queue_track_add(this);
|
get_callbacks()->on_queue_track_add(this, id);
|
||||||
return tracks.size() - 1;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int Playqueue :: add_front(unsigned int track_id)
|
unsigned int Playqueue :: add_front(unsigned int track_id)
|
||||||
|
@ -74,7 +75,7 @@ unsigned int Playqueue :: add_front(unsigned int track_id)
|
||||||
|
|
||||||
library :: lookup(track_id, &song);
|
library :: lookup(track_id, &song);
|
||||||
length += song.track->length;
|
length += song.track->length;
|
||||||
get_callbacks()->on_queue_track_add(this);
|
get_callbacks()->on_queue_track_add(this, 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,7 +87,7 @@ void Playqueue :: del(unsigned int plist_id)
|
||||||
tracks.erase(tracks.begin() + plist_id);
|
tracks.erase(tracks.begin() + plist_id);
|
||||||
library :: lookup(track_id, &song);
|
library :: lookup(track_id, &song);
|
||||||
length -= song.track->length;
|
length -= song.track->length;
|
||||||
get_callbacks()->on_queue_track_del(this);
|
get_callbacks()->on_queue_track_del(this, plist_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Playqueue :: del_track(unsigned int track_id)
|
void Playqueue :: del_track(unsigned int track_id)
|
||||||
|
@ -98,7 +99,6 @@ void Playqueue :: del_track(unsigned int track_id)
|
||||||
else
|
else
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
get_callbacks()->on_queue_track_del(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int Playqueue :: size()
|
unsigned int Playqueue :: size()
|
||||||
|
@ -106,6 +106,11 @@ unsigned int Playqueue :: size()
|
||||||
return tracks.size();
|
return tracks.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned int Playqueue :: operator[](unsigned int i)
|
||||||
|
{
|
||||||
|
return tracks[i];
|
||||||
|
}
|
||||||
|
|
||||||
unsigned int Playqueue :: next()
|
unsigned int Playqueue :: next()
|
||||||
{
|
{
|
||||||
unsigned int res;
|
unsigned int res;
|
||||||
|
|
|
@ -103,6 +103,22 @@ bool test_0()
|
||||||
click_button("o_collection_import");
|
click_button("o_collection_import");
|
||||||
break;
|
break;
|
||||||
case 19:
|
case 19:
|
||||||
|
case 23:
|
||||||
|
on_collection_toggled("0");
|
||||||
|
break;
|
||||||
|
case 20:
|
||||||
|
case 24:
|
||||||
|
on_collection_toggled("1");
|
||||||
|
break;
|
||||||
|
case 25:
|
||||||
|
case 21:
|
||||||
|
on_collection_toggled("2");
|
||||||
|
break;
|
||||||
|
case 26:
|
||||||
|
case 22:
|
||||||
|
on_collection_toggled("3");
|
||||||
|
break;
|
||||||
|
case 27:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
end_test();
|
end_test();
|
||||||
|
|
Loading…
Reference in New Issue
Block a user