ardour/gtk2_ardour/stripable_treemodel.cc

265 lines
5.6 KiB
C++

/* Copyright (C) 2017 Paul Davis
* based on gtkmm example Copyright (C) 2002 gtkmm development team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <iostream>
#include "ardour/session.h"
#include "ardour/types.h"
#include "axis_provider.h"
#include "stripable_treemodel.h"
using namespace ARDOUR;
StripableTreeModel::Glue::Glue (boost::shared_ptr<Stripable> s)
: stripable (s)
{
}
StripableTreeModel::StripableTreeModel (AxisViewProvider& avp)
: Glib::ObjectBase( typeid(StripableTreeModel) ) //register a custom GType.
, Glib::Object() //The custom GType is actually registered here.
, axis_view_provider (avp)
{
n_columns = columns.size();
}
void
StripableTreeModel::set_session (Session& s)
{
_session = &s;
}
StripableTreeModel::~StripableTreeModel()
{
}
Glib::RefPtr<StripableTreeModel>
StripableTreeModel::create (AxisViewProvider& avp)
{
return Glib::RefPtr<StripableTreeModel> (new StripableTreeModel (avp));
}
Gtk::TreeModelFlags
StripableTreeModel::get_flags_vfunc() const
{
return Gtk::TREE_MODEL_LIST_ONLY;
}
int
StripableTreeModel::get_n_columns_vfunc() const
{
return n_columns;
}
GType
StripableTreeModel::get_column_type_vfunc (int index) const
{
if (index <= n_columns) {
return columns.types()[index];
}
return 0;
}
void
StripableTreeModel::get_value_vfunc (const TreeModel::iterator& iter, int column, Glib::ValueBase& value) const
{
if (!_session) {
return;
}
if (column > n_columns) {
return;
}
const Glue* glue = (const Glue*)iter.gobj()->user_data;
boost::shared_ptr<Stripable> iter_stripable = glue->stripable.lock();
if (!iter_stripable) {
return;
}
switch (column) {
case 0:
return text_value (iter_stripable, value);
}
}
void
StripableTreeModel::text_value (boost::shared_ptr<Stripable> stripable, Glib::ValueBase& value) const
{
StringColumn::ValueType val;
val.set (stripable->name());
value = val;
}
bool
StripableTreeModel::iter_next_vfunc (const iterator& iter, iterator& iter_next) const
{
if (!_session) {
return false;
}
const Glue* glue = (const Glue*)iter.gobj()->user_data;
boost::shared_ptr<Stripable> iter_stripable = glue->stripable.lock();
if (!iter_stripable) {
return false;
}
//initialize the next iterator:
iter_next = iterator();
StripableList sl;
_session->get_stripables (sl);
if (sl.empty()) {
return false;
}
sl.sort (Stripable::Sorter());
for (StripableList::const_iterator s = sl.begin(); s != sl.end(); ++s) {
if (*s == iter_stripable) {
++s;
if (s != sl.end()) {
Glue* new_glue = new Glue (iter_stripable);
iter_next.gobj()->user_data = (void*)new_glue;
remember_glue_item (new_glue);
return true; //success
}
break;
}
}
return false; //There is no next row.
}
bool
StripableTreeModel::iter_children_vfunc(const iterator& parent, iterator& iter) const
{
return false;
}
bool
StripableTreeModel::iter_has_child_vfunc(const iterator& iter) const
{
return false;
}
int
StripableTreeModel::iter_n_children_vfunc(const iterator& iter) const
{
return 0;
}
int
StripableTreeModel::iter_n_root_children_vfunc() const
{
if (_session) {
StripableList sl;
_session->get_stripables (sl);
return sl.size();
}
return 0;
}
bool
StripableTreeModel::iter_nth_child_vfunc(const iterator& parent, int /* n */, iterator& iter) const
{
iter = iterator(); //Set is as invalid, as the TreeModel documentation says that it should be.
return false; //There are no children.
}
bool
StripableTreeModel::iter_nth_root_child_vfunc(int n, iterator& iter) const
{
iter = iterator(); //clear the input parameter.
if (!_session) {
return false;
}
StripableList sl;
_session->get_stripables (sl);
if (sl.empty()) {
return false;
}
sl.sort (Stripable::Sorter());
StripableList::const_iterator s;
for (s = sl.begin(); s != sl.end() && n > 0; ++s, --n);
if (s != sl.end()) {
Glue* new_glue = new Glue (*s);
iter.gobj()->user_data = new_glue;
remember_glue_item (new_glue);
return true;
}
return false; //There are no children.
}
bool
StripableTreeModel::iter_parent_vfunc(const iterator& child, iterator& iter) const
{
iter = iterator(); //Set is as invalid, as the TreeModel documentation says that it should be.
return false; //There are no children, so no parents.
}
Gtk::TreeModel::Path
StripableTreeModel::get_path_vfunc(const iterator& /* iter */) const
{
//TODO:
return Path();
}
bool
StripableTreeModel::get_iter_vfunc (const Path& path, iterator& iter) const
{
unsigned sz = path.size();
if (!sz || sz > 1) {
/* path must refer to something, but not children since we
don't do children.
*/
iter = iterator(); //Set is as invalid, as the TreeModel documentation says that it should be.
return false;
}
return iter_nth_root_child_vfunc (path[0], iter);
}
bool
StripableTreeModel::iter_is_valid(const iterator& iter) const
{
const Glue* glue = (const Glue*)iter.gobj()->user_data;
if (!glue->stripable.lock()) {
return false;
}
return Gtk::TreeModel::iter_is_valid(iter);
}
void
StripableTreeModel::remember_glue_item (Glue* item) const
{
glue_list.insert (item);
}