diff options
-rw-r--r-- | gtk2_ardour/stripable_treemodel.cc | 264 | ||||
-rw-r--r-- | gtk2_ardour/stripable_treemodel.h | 133 |
2 files changed, 397 insertions, 0 deletions
diff --git a/gtk2_ardour/stripable_treemodel.cc b/gtk2_ardour/stripable_treemodel.cc new file mode 100644 index 0000000000..197683577c --- /dev/null +++ b/gtk2_ardour/stripable_treemodel.cc @@ -0,0 +1,264 @@ +/* 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::PresentationOrderSorter()); + + 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::PresentationOrderSorter()); + + 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); +} diff --git a/gtk2_ardour/stripable_treemodel.h b/gtk2_ardour/stripable_treemodel.h new file mode 100644 index 0000000000..a91ddc026d --- /dev/null +++ b/gtk2_ardour/stripable_treemodel.h @@ -0,0 +1,133 @@ +/* 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 + */ + +#ifndef __gtk2_ardour_stripable_treemodel_h__ +#define __gtk2_ardour_stripable_treemodel_h__ + +#include <set> + +#include <boost/shared_ptr.hpp> +#include <boost/weak_ptr.hpp> +#include <stdint.h> + +#include <gtkmm.h> + +namespace ARDOUR { + class Session; + class Stripable; +} + +class AxisView; +class AxisViewProvider; +class StripableSorter; + +class StripableTreeModel : public Gtk::TreeModel, public Glib::Object +{ + protected: + StripableTreeModel (AxisViewProvider&); + virtual ~StripableTreeModel(); + + public: + static Glib::RefPtr<StripableTreeModel> create (AxisViewProvider&); + void set_session (ARDOUR::Session&); + + protected: + Gtk::TreeModelFlags get_flags_vfunc() const; + int get_n_columns_vfunc() const; + GType get_column_type_vfunc(int index) const; + void get_value_vfunc(const TreeModel::iterator& iter, int column, Glib::ValueBase& value) const; + bool iter_next_vfunc(const iterator& iter, iterator& iter_next) const; + bool iter_children_vfunc(const iterator& parent, iterator& iter) const; + bool iter_has_child_vfunc(const iterator& iter) const; + int iter_n_children_vfunc(const iterator& iter) const; + int iter_n_root_children_vfunc() const; + bool iter_nth_child_vfunc(const iterator& parent, int n, iterator& iter) const; + bool iter_nth_root_child_vfunc(int n, iterator& iter) const; + bool iter_parent_vfunc(const iterator& child, iterator& iter) const; + Path get_path_vfunc(const iterator& iter) const; + bool get_iter_vfunc(const Path& path, iterator& iter) const; + bool iter_is_valid(const iterator& iter) const; + + public: + typedef Gtk::TreeModelColumn<std::string> StringColumn; + typedef Gtk::TreeModelColumn<bool> BoolColumn; + typedef Gtk::TreeModelColumn<uint32_t> UnsignedColumn; + typedef Gtk::TreeModelColumn<AxisView*> AVColumn; + typedef Gtk::TreeModelColumn<boost::shared_ptr<ARDOUR::Stripable> > StripableColumn; + + struct Columns : public Gtk::TreeModel::ColumnRecord { + + Columns () { + add (text); + add (visible); + add (rec_state); + add (rec_safe); + add (mute_state); + add (solo_state); + add (solo_visible); + add (solo_isolate_state); + add (solo_safe_state); + add (is_track); + add (av); + add (stripable); + add (name_editable); + add (is_input_active); + add (is_midi); + add (active); + } + + StringColumn text; + BoolColumn visible; + UnsignedColumn rec_state; + UnsignedColumn rec_safe; + UnsignedColumn mute_state; + UnsignedColumn solo_state; + /** true if the solo buttons are visible for this route, otherwise false */ + BoolColumn solo_visible; + UnsignedColumn solo_isolate_state; + UnsignedColumn solo_safe_state; + BoolColumn is_track; + AVColumn av; + StripableColumn stripable; + BoolColumn name_editable; + BoolColumn is_input_active; + BoolColumn is_midi; + BoolColumn active; + }; + + Columns columns; + + private: + ARDOUR::Session* _session; + AxisViewProvider& axis_view_provider; + + int n_columns; + + void text_value (boost::shared_ptr<ARDOUR::Stripable> stripable, Glib::ValueBase& value) const; + + struct Glue { + Glue (boost::shared_ptr<ARDOUR::Stripable>); + + boost::weak_ptr<ARDOUR::Stripable> stripable; + }; + + typedef std::set<Glue*> GlueList; + mutable GlueList glue_list; + void remember_glue_item (Glue*) const; +}; + +#endif /* __gtk2_ardour_stripable_treemodel_h__ */ |