summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarl Hetherington <carl@carlh.net>2009-01-25 06:47:11 +0000
committerCarl Hetherington <carl@carlh.net>2009-01-25 06:47:11 +0000
commit49510ba1d7fc1c85e767c05f10f9481998ef94b0 (patch)
treee04210728fb9b5e52864eb8cdc0774e4d0b9d7f2
parenta9d67a2cc97b28795a9112a176ba1f2c1ab470d3 (diff)
Some refactoring. Add port group headers to the port matrix.
git-svn-id: svn://localhost/ardour2/branches/3.0@4443 d708f5d6-7413-0410-9779-e7cbd77b26cf
-rw-r--r--gtk2_ardour/bundle_manager.cc23
-rw-r--r--gtk2_ardour/bundle_manager.h4
-rw-r--r--gtk2_ardour/global_port_matrix.cc19
-rw-r--r--gtk2_ardour/io_selector.cc33
-rw-r--r--gtk2_ardour/io_selector.h2
-rw-r--r--gtk2_ardour/mixer_strip.cc26
-rw-r--r--gtk2_ardour/mixer_strip.h4
-rw-r--r--gtk2_ardour/port_group.cc85
-rw-r--r--gtk2_ardour/port_group.h21
-rw-r--r--gtk2_ardour/port_matrix.cc47
-rw-r--r--gtk2_ardour/port_matrix.h20
-rw-r--r--gtk2_ardour/port_matrix_body.cc20
-rw-r--r--gtk2_ardour/port_matrix_body.h22
-rw-r--r--gtk2_ardour/port_matrix_column_labels.cc130
-rw-r--r--gtk2_ardour/port_matrix_column_labels.h1
-rw-r--r--gtk2_ardour/port_matrix_component.cc32
-rw-r--r--gtk2_ardour/port_matrix_component.h10
-rw-r--r--gtk2_ardour/port_matrix_grid.cc35
-rw-r--r--gtk2_ardour/port_matrix_grid.h3
-rw-r--r--gtk2_ardour/port_matrix_row_labels.cc110
-rw-r--r--gtk2_ardour/port_matrix_row_labels.h5
-rw-r--r--libs/ardour/ardour/io.h7
-rw-r--r--libs/ardour/ardour/session.h9
-rw-r--r--libs/ardour/ardour/types.h3
-rw-r--r--libs/ardour/io.cc99
-rw-r--r--libs/ardour/session.cc30
-rw-r--r--libs/ardour/session_state.cc4
27 files changed, 481 insertions, 323 deletions
diff --git a/gtk2_ardour/bundle_manager.cc b/gtk2_ardour/bundle_manager.cc
index 42fbabbbe9..04bf240f7c 100644
--- a/gtk2_ardour/bundle_manager.cc
+++ b/gtk2_ardour/bundle_manager.cc
@@ -33,12 +33,16 @@
BundleEditorMatrix::BundleEditorMatrix (
ARDOUR::Session& session, boost::shared_ptr<ARDOUR::Bundle> bundle
)
- : PortMatrix (
- session, bundle->type(), bundle->ports_are_inputs(),
- PortGroupList::Mask (PortGroupList::SYSTEM | PortGroupList::OTHER)
- )
+ : PortMatrix (session, bundle->type(), bundle->ports_are_inputs())
{
- _our_bundles.push_back (bundle);
+ _port_group = new PortGroup ("", true);
+ _port_group->bundles.push_back (bundle);
+ _row_ports.push_back (_port_group);
+}
+
+BundleEditorMatrix::~BundleEditorMatrix ()
+{
+ delete _port_group;
}
void
@@ -89,14 +93,14 @@ BundleEditorMatrix::add_channel (boost::shared_ptr<ARDOUR::Bundle> b)
return;
}
- _our_bundles.front()->add_channel (d.get_name());
+ _port_group->bundles.front()->add_channel (d.get_name());
setup ();
}
void
BundleEditorMatrix::remove_channel (boost::shared_ptr<ARDOUR::Bundle> b, uint32_t c)
{
- _our_bundles.front()->remove_channel (c);
+ _port_group->bundles.front()->remove_channel (c);
setup ();
}
@@ -232,7 +236,10 @@ BundleManager::BundleManager (ARDOUR::Session& session)
_tree_view.append_column (_("Name"), _list_model_columns.name);
_tree_view.set_headers_visible (false);
- _session.foreach_bundle (sigc::mem_fun (*this, &BundleManager::add_bundle));
+ boost::shared_ptr<ARDOUR::BundleList> bundles = _session.bundles ();
+ for (ARDOUR::BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
+ add_bundle (*i);
+ }
/* New / Edit / Delete buttons */
Gtk::VBox* buttons = new Gtk::VBox;
diff --git a/gtk2_ardour/bundle_manager.h b/gtk2_ardour/bundle_manager.h
index 1aeb196e67..8ab4279117 100644
--- a/gtk2_ardour/bundle_manager.h
+++ b/gtk2_ardour/bundle_manager.h
@@ -35,6 +35,7 @@ class BundleEditorMatrix : public PortMatrix
{
public:
BundleEditorMatrix (ARDOUR::Session &, boost::shared_ptr<ARDOUR::Bundle>);
+ ~BundleEditorMatrix ();
void set_state (
boost::shared_ptr<ARDOUR::Bundle> ab,
@@ -58,6 +59,9 @@ class BundleEditorMatrix : public PortMatrix
return true;
}
void rename_channel (boost::shared_ptr<ARDOUR::Bundle>, uint32_t);
+
+ private:
+ PortGroup* _port_group;
};
class BundleEditor : public ArdourDialog
diff --git a/gtk2_ardour/global_port_matrix.cc b/gtk2_ardour/global_port_matrix.cc
index 51b1f47b3f..80ddecc813 100644
--- a/gtk2_ardour/global_port_matrix.cc
+++ b/gtk2_ardour/global_port_matrix.cc
@@ -25,25 +25,19 @@
#include "ardour/port.h"
GlobalPortMatrix::GlobalPortMatrix (ARDOUR::Session& s, ARDOUR::DataType t)
- : PortMatrix (s, t, true, PortGroupList::Mask (PortGroupList::BUSS |
- PortGroupList::TRACK |
- PortGroupList::SYSTEM |
- PortGroupList::OTHER)),
+ : PortMatrix (s, t, true),
_session (s),
- _our_port_group_list (s, t, false, PortGroupList::Mask (PortGroupList::BUSS |
- PortGroupList::TRACK |
- PortGroupList::SYSTEM |
- PortGroupList::OTHER))
+ _our_port_group_list (t, false)
{
setup ();
- _port_group_list.VisibilityChanged.connect (sigc::mem_fun (*this, &GlobalPortMatrix::group_visibility_changed));
+ _column_ports.VisibilityChanged.connect (sigc::mem_fun (*this, &GlobalPortMatrix::group_visibility_changed));
}
void
GlobalPortMatrix::group_visibility_changed ()
{
- _our_port_group_list.take_visibility_from (_port_group_list);
+ _row_ports.take_visibility_from (_column_ports);
setup ();
}
@@ -51,11 +45,8 @@ GlobalPortMatrix::group_visibility_changed ()
void
GlobalPortMatrix::setup ()
{
- _our_port_group_list.refresh ();
- _our_bundles = _our_port_group_list.bundles ();
-
+ _row_ports.gather (_session);
PortMatrix::setup ();
-
}
void
diff --git a/gtk2_ardour/io_selector.cc b/gtk2_ardour/io_selector.cc
index d61a37d655..cb1a07ce14 100644
--- a/gtk2_ardour/io_selector.cc
+++ b/gtk2_ardour/io_selector.cc
@@ -42,25 +42,30 @@ using namespace ARDOUR;
using namespace Gtk;
IOSelector::IOSelector (ARDOUR::Session& session, boost::shared_ptr<ARDOUR::IO> io, bool offer_inputs)
- : PortMatrix (session, io->default_type(), offer_inputs,
- PortGroupList::Mask (PortGroupList::BUSS |
- PortGroupList::SYSTEM |
- PortGroupList::OTHER))
+ : PortMatrix (session, io->default_type(), offer_inputs)
, _session (session)
, _io (io)
{
/* Listen for ports changing on the IO */
_io->PortCountChanged.connect (sigc::hide (mem_fun (*this, &IOSelector::ports_changed)));
+
+ _port_group = new PortGroup ("", true);
+ _row_ports.push_back (_port_group);
setup ();
}
+IOSelector::~IOSelector ()
+{
+ delete _port_group;
+}
+
void
IOSelector::setup ()
{
- _our_bundles.clear ();
- _our_bundles.push_back (boost::shared_ptr<ARDOUR::Bundle> (new ARDOUR::Bundle));
- _our_bundles.front()->set_name (_io->name());
+ _port_group->bundles.clear ();
+ _port_group->bundles.push_back (boost::shared_ptr<ARDOUR::Bundle> (new ARDOUR::Bundle));
+ _port_group->bundles.front()->set_name (_io->name());
if (offering_input ()) {
const PortSet& ps (_io->outputs());
@@ -69,8 +74,8 @@ IOSelector::setup ()
for (PortSet::const_iterator i = ps.begin(); i != ps.end(); ++i) {
char buf[32];
snprintf (buf, sizeof(buf), _("out %d"), j + 1);
- _our_bundles.front()->add_channel (buf);
- _our_bundles.front()->add_port_to_channel (j, _session.engine().make_port_name_non_relative (i->name()));
+ _port_group->bundles.front()->add_channel (buf);
+ _port_group->bundles.front()->add_port_to_channel (j, _session.engine().make_port_name_non_relative (i->name()));
++j;
}
@@ -82,8 +87,8 @@ IOSelector::setup ()
for (PortSet::const_iterator i = ps.begin(); i != ps.end(); ++i) {
char buf[32];
snprintf (buf, sizeof(buf), _("in %d"), j + 1);
- _our_bundles.front()->add_channel (buf);
- _our_bundles.front()->add_port_to_channel (j, _session.engine().make_port_name_non_relative (i->name()));
+ _port_group->bundles.front()->add_channel (buf);
+ _port_group->bundles.front()->add_port_to_channel (j, _session.engine().make_port_name_non_relative (i->name()));
++j;
}
@@ -303,11 +308,7 @@ IOSelectorWindow::IOSelectorWindow (ARDOUR::Session& session, boost::shared_ptr<
get_vbox()->set_spacing (8);
- /* XXX: do we still need the ScrolledWindow? */
- Gtk::ScrolledWindow* sel_scroll = Gtk::manage (new Gtk::ScrolledWindow);
- sel_scroll->set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_NEVER);
- sel_scroll->add (_selector);
- get_vbox()->pack_start (*sel_scroll, true, true);
+ get_vbox()->pack_start (_selector, true, true);
set_position (Gtk::WIN_POS_MOUSE);
diff --git a/gtk2_ardour/io_selector.h b/gtk2_ardour/io_selector.h
index 8b49e5e2de..20bcb2ff27 100644
--- a/gtk2_ardour/io_selector.h
+++ b/gtk2_ardour/io_selector.h
@@ -30,6 +30,7 @@ namespace ARDOUR {
class IOSelector : public PortMatrix {
public:
IOSelector (ARDOUR::Session&, boost::shared_ptr<ARDOUR::IO>, bool);
+ ~IOSelector ();
void set_state (
boost::shared_ptr<ARDOUR::Bundle>,
@@ -62,6 +63,7 @@ class IOSelector : public PortMatrix {
private:
ARDOUR::Session& _session;
boost::shared_ptr<ARDOUR::IO> _io;
+ PortGroup* _port_group;
void ports_changed ();
};
diff --git a/gtk2_ardour/mixer_strip.cc b/gtk2_ardour/mixer_strip.cc
index 6f591bc6c0..05f2bb3615 100644
--- a/gtk2_ardour/mixer_strip.cc
+++ b/gtk2_ardour/mixer_strip.cc
@@ -629,11 +629,12 @@ MixerStrip::output_press (GdkEventButton *ev)
citems.push_back (MenuElem (_("Disconnect"), mem_fun (*(static_cast<RouteUI*>(this)), &RouteUI::disconnect_output)));
citems.push_back (SeparatorElem());
- std::vector<boost::shared_ptr<Bundle> > current = _route->bundles_connected_to_outputs ();
+ ARDOUR::BundleList current = _route->bundles_connected_to_outputs ();
- _session.foreach_bundle (
- bind (mem_fun (*this, &MixerStrip::add_bundle_to_output_menu), current)
- );
+ boost::shared_ptr<ARDOUR::BundleList> b = _session.bundles ();
+ for (ARDOUR::BundleList::iterator i = b->begin(); i != b->end(); ++i) {
+ add_bundle_to_output_menu (*i, current);
+ }
output_menu.popup (1, ev->time);
break;
@@ -697,11 +698,12 @@ MixerStrip::input_press (GdkEventButton *ev)
citems.push_back (MenuElem (_("Disconnect"), mem_fun (*(static_cast<RouteUI*>(this)), &RouteUI::disconnect_input)));
citems.push_back (SeparatorElem());
- std::vector<boost::shared_ptr<Bundle> > current = _route->bundles_connected_to_inputs ();
+ ARDOUR::BundleList current = _route->bundles_connected_to_inputs ();
- _session.foreach_bundle (
- bind (mem_fun (*this, &MixerStrip::add_bundle_to_input_menu), current)
- );
+ boost::shared_ptr<ARDOUR::BundleList> b = _session.bundles ();
+ for (ARDOUR::BundleList::iterator i = b->begin(); i != b->end(); ++i) {
+ add_bundle_to_input_menu (*i, current);
+ }
input_menu.popup (1, ev->time);
break;
@@ -745,7 +747,7 @@ MixerStrip::bundle_output_chosen (boost::shared_ptr<ARDOUR::Bundle> c)
}
void
-MixerStrip::add_bundle_to_input_menu (boost::shared_ptr<Bundle> b, std::vector<boost::shared_ptr<Bundle> > const & current)
+MixerStrip::add_bundle_to_input_menu (boost::shared_ptr<Bundle> b, ARDOUR::BundleList const & current)
{
using namespace Menu_Helpers;
@@ -770,7 +772,7 @@ MixerStrip::add_bundle_to_input_menu (boost::shared_ptr<Bundle> b, std::vector<b
}
void
-MixerStrip::add_bundle_to_output_menu (boost::shared_ptr<Bundle> b, std::vector<boost::shared_ptr<Bundle> > const & current)
+MixerStrip::add_bundle_to_output_menu (boost::shared_ptr<Bundle> b, ARDOUR::BundleList const & current)
{
using namespace Menu_Helpers;
@@ -833,7 +835,7 @@ MixerStrip::connect_to_pan ()
void
MixerStrip::update_input_display ()
{
- std::vector<boost::shared_ptr<ARDOUR::Bundle> > c = _route->bundles_connected_to_inputs ();
+ ARDOUR::BundleList c = _route->bundles_connected_to_inputs ();
/* XXX: how do we represent >1 connected bundle? */
if (c.empty() == false) {
@@ -854,7 +856,7 @@ MixerStrip::update_input_display ()
void
MixerStrip::update_output_display ()
{
- std::vector<boost::shared_ptr<ARDOUR::Bundle> > c = _route->bundles_connected_to_outputs ();
+ ARDOUR::BundleList c = _route->bundles_connected_to_outputs ();
/* XXX: how do we represent >1 connected bundle? */
if (c.empty() == false) {
diff --git a/gtk2_ardour/mixer_strip.h b/gtk2_ardour/mixer_strip.h
index 393a38569e..a831a54117 100644
--- a/gtk2_ardour/mixer_strip.h
+++ b/gtk2_ardour/mixer_strip.h
@@ -180,10 +180,10 @@ class MixerStrip : public RouteUI, public Gtk::EventBox
gint output_press (GdkEventButton *);
Gtk::Menu input_menu;
- void add_bundle_to_input_menu (boost::shared_ptr<ARDOUR::Bundle>, std::vector<boost::shared_ptr<ARDOUR::Bundle> > const &);
+ void add_bundle_to_input_menu (boost::shared_ptr<ARDOUR::Bundle>, ARDOUR::BundleList const &);
Gtk::Menu output_menu;
- void add_bundle_to_output_menu (boost::shared_ptr<ARDOUR::Bundle>, std::vector<boost::shared_ptr<ARDOUR::Bundle> > const &);
+ void add_bundle_to_output_menu (boost::shared_ptr<ARDOUR::Bundle>, ARDOUR::BundleList const &);
void bundle_input_chosen (boost::shared_ptr<ARDOUR::Bundle>);
void bundle_output_chosen (boost::shared_ptr<ARDOUR::Bundle>);
diff --git a/gtk2_ardour/port_group.cc b/gtk2_ardour/port_group.cc
index accab1d183..616f674ddb 100644
--- a/gtk2_ardour/port_group.cc
+++ b/gtk2_ardour/port_group.cc
@@ -60,7 +60,7 @@ PortGroup::clear ()
bool
PortGroup::has_port (std::string const& p) const
{
- for (vector<boost::shared_ptr<ARDOUR::Bundle> >::const_iterator i = bundles.begin(); i != bundles.end(); ++i) {
+ for (ARDOUR::BundleList::const_iterator i = bundles.begin(); i != bundles.end(); ++i) {
if ((*i)->offers_port_alone (p)) {
return true;
}
@@ -111,40 +111,29 @@ PortGroupUI::setup_visibility_checkbutton ()
}
/** PortGroupList constructor.
- * @param session Session to get bundles from.
* @param type Type of bundles to offer (audio or MIDI)
* @param offer_inputs true to offer output bundles, otherwise false.
- * @param mask Mask of groups to make visible by default.
*/
-PortGroupList::PortGroupList (ARDOUR::Session & session, ARDOUR::DataType type, bool offer_inputs, Mask mask)
- : _session (session), _type (type), _offer_inputs (offer_inputs),
- _buss (_("Bus"), mask & BUSS),
- _track (_("Track"), mask & TRACK),
- _system (_("System"), mask & SYSTEM),
- _other (_("Other"), mask & OTHER)
+PortGroupList::PortGroupList (ARDOUR::DataType type, bool offer_inputs)
+ : _type (type), _offer_inputs (offer_inputs),
+ _buss (_("Bus"), true),
+ _track (_("Track"), true),
+ _system (_("System"), true),
+ _other (_("Other"), true)
{
- refresh ();
-
- for (iterator i = begin(); i != end(); ++i) {
- (*i)->VisibilityChanged.connect (sigc::mem_fun (*this, &PortGroupList::visibility_changed));
- }
+
}
-/** Find or re-find all our bundles and set up our lists */
+/** Gather bundles from around the system and put them in this PortGroupList */
void
-PortGroupList::refresh ()
+PortGroupList::gather (ARDOUR::Session& session)
{
- clear ();
-
- _buss.clear ();
- _track.clear ();
- _system.clear ();
- _other.clear ();
+ clear_list ();
/* Find the bundles for routes */
- boost::shared_ptr<ARDOUR::Session::RouteList> routes = _session.get_routes ();
+ boost::shared_ptr<ARDOUR::Session::RouteList> routes = session.get_routes ();
for (ARDOUR::Session::RouteList::const_iterator i = routes->begin(); i != routes->end(); ++i) {
@@ -174,20 +163,25 @@ PortGroupList::refresh ()
}
/* Bundles created by the session */
- _session.foreach_bundle (sigc::mem_fun (*this, &PortGroupList::maybe_add_session_bundle));
+ boost::shared_ptr<ARDOUR::BundleList> b = session.bundles ();
+ for (ARDOUR::BundleList::iterator i = b->begin(); i != b->end(); ++i) {
+ if ((*i)->ports_are_inputs() == _offer_inputs && (*i)->type() == _type) {
+ _system.bundles.push_back (*i);
+ }
+ }
/* XXX: inserts, sends, plugin inserts? */
/* Now find all other ports that we haven't thought of yet */
- const char **ports = _session.engine().get_ports ("", _type.to_jack_type(), _offer_inputs ?
+ const char **ports = session.engine().get_ports ("", _type.to_jack_type(), _offer_inputs ?
JackPortIsInput : JackPortIsOutput);
if (ports) {
int n = 0;
string client_matching_string;
- client_matching_string = _session.engine().client_name();
+ client_matching_string = session.engine().client_name();
client_matching_string += ':';
while (ports[n]) {
@@ -215,6 +209,12 @@ PortGroupList::refresh ()
push_back (&_buss);
push_back (&_track);
push_back (&_other);
+
+ for (iterator i = begin(); i != end(); ++i) {
+ _visibility_connections.push_back (
+ (*i)->VisibilityChanged.connect (sigc::mem_fun (*this, &PortGroupList::visibility_changed))
+ );
+ }
}
bool
@@ -236,20 +236,12 @@ PortGroupList::set_offer_inputs (bool i)
_offer_inputs = i;
}
-void
-PortGroupList::maybe_add_session_bundle (boost::shared_ptr<ARDOUR::Bundle> b)
+ARDOUR::BundleList
+PortGroupList::bundles () const
{
- if (b->ports_are_inputs () == _offer_inputs && b->type () == _type) {
- _system.bundles.push_back (b);
- }
-}
-
-std::vector<boost::shared_ptr<ARDOUR::Bundle> >
-PortGroupList::bundles ()
-{
- std::vector<boost::shared_ptr<ARDOUR::Bundle> > bundles;
+ ARDOUR::BundleList bundles;
- for (iterator i = begin (); i != end (); ++i) {
+ for (const_iterator i = begin (); i != end (); ++i) {
if ((*i)->visible()) {
std::copy ((*i)->bundles.begin(), (*i)->bundles.end(), std::back_inserter (bundles));
@@ -334,3 +326,20 @@ PortGroupList::take_visibility_from (PortGroupList const & o)
++j;
}
}
+
+void
+PortGroupList::clear_list ()
+{
+ clear ();
+
+ _buss.clear ();
+ _track.clear ();
+ _system.clear ();
+ _other.clear ();
+
+ for (std::vector<sigc::connection>::iterator i = _visibility_connections.begin(); i != _visibility_connections.end(); ++i) {
+ i->disconnect ();
+ }
+
+ _visibility_connections.clear ();
+}
diff --git a/gtk2_ardour/port_group.h b/gtk2_ardour/port_group.h
index a5b5b109c4..17e9842f93 100644
--- a/gtk2_ardour/port_group.h
+++ b/gtk2_ardour/port_group.h
@@ -26,6 +26,7 @@
#include <gtkmm/checkbutton.h>
#include <boost/shared_ptr.hpp>
#include <ardour/data_type.h>
+#include <ardour/types.h>
namespace ARDOUR {
class Session;
@@ -53,7 +54,7 @@ public:
void clear ();
std::string name; ///< name for the group
- std::vector<boost::shared_ptr<ARDOUR::Bundle> > bundles;
+ ARDOUR::BundleList bundles;
std::vector<std::string> ports;
bool visible () const {
return _visible;
@@ -95,30 +96,22 @@ class PortGroupUI
class PortGroupList : public std::list<PortGroup*>, public sigc::trackable
{
public:
- enum Mask {
- BUSS = 0x1,
- TRACK = 0x2,
- SYSTEM = 0x4,
- OTHER = 0x8
- };
+ PortGroupList (ARDOUR::DataType, bool);
- PortGroupList (ARDOUR::Session &, ARDOUR::DataType, bool, Mask);
-
- void refresh ();
+ void gather (ARDOUR::Session &);
void set_type (ARDOUR::DataType);
void set_offer_inputs (bool);
- std::vector<boost::shared_ptr<ARDOUR::Bundle> > bundles ();
+ ARDOUR::BundleList bundles () const;
void take_visibility_from (PortGroupList const &);
+ void clear_list ();
sigc::signal<void> VisibilityChanged;
private:
- void maybe_add_session_bundle (boost::shared_ptr<ARDOUR::Bundle>);
bool port_has_prefix (std::string const &, std::string const &) const;
std::string common_prefix (std::vector<std::string> const &) const;
void visibility_changed ();
- ARDOUR::Session& _session;
ARDOUR::DataType _type;
bool _offer_inputs;
@@ -126,6 +119,8 @@ class PortGroupList : public std::list<PortGroup*>, public sigc::trackable
PortGroup _track;
PortGroup _system;
PortGroup _other;
+
+ std::vector<sigc::connection> _visibility_connections;
};
#endif /* __gtk_ardour_port_group_h__ */
diff --git a/gtk2_ardour/port_matrix.cc b/gtk2_ardour/port_matrix.cc
index 5d6ea37408..fccc707694 100644
--- a/gtk2_ardour/port_matrix.cc
+++ b/gtk2_ardour/port_matrix.cc
@@ -22,6 +22,7 @@
#include <gtkmm/adjustment.h>
#include <gtkmm/label.h>
#include "ardour/bundle.h"
+#include "ardour/types.h"
#include "port_matrix.h"
#include "i18n.h"
@@ -29,20 +30,23 @@
* @param session Our session.
* @param type Port type that we are handling.
* @param offer_inputs true to offer inputs, otherwise false.
- * @param mask Mask of port groups to offer.
*/
-PortMatrix::PortMatrix (ARDOUR::Session& session, ARDOUR::DataType type, bool offer_inputs, PortGroupList::Mask mask)
- : _port_group_list (session, type, offer_inputs, mask),
+PortMatrix::PortMatrix (ARDOUR::Session& session, ARDOUR::DataType type, bool offer_inputs)
+ : _row_ports (type, !offer_inputs),
+ _column_ports (type, offer_inputs),
+ _session (session),
_offer_inputs (offer_inputs),
_type (type),
_body (this, offer_inputs ? PortMatrixBody::BOTTOM_AND_LEFT : PortMatrixBody::TOP_AND_RIGHT)
{
+ setup ();
+
/* checkbuttons for visibility of groups */
Gtk::HBox* visibility_buttons = Gtk::manage (new Gtk::HBox);
visibility_buttons->pack_start (*Gtk::manage (new Gtk::Label (_("Show:"))), Gtk::PACK_SHRINK);
-
- for (std::list<PortGroup*>::iterator i = _port_group_list.begin(); i != _port_group_list.end(); ++i) {
+
+ for (std::list<PortGroup*>::iterator i = _column_ports.begin(); i != _column_ports.end(); ++i) {
_port_group_uis.push_back (new PortGroupUI (this, *i));
}
@@ -76,8 +80,8 @@ PortMatrix::~PortMatrix ()
void
PortMatrix::setup ()
{
- _port_group_list.refresh ();
- _body.setup (_our_bundles, _port_group_list.bundles ());
+ _column_ports.gather (_session);
+ _body.setup (_row_ports, _column_ports);
setup_scrollbars ();
queue_draw ();
}
@@ -86,7 +90,8 @@ void
PortMatrix::set_offer_inputs (bool s)
{
_offer_inputs = s;
- _port_group_list.set_offer_inputs (s);
+ _column_ports.set_offer_inputs (s);
+ _row_ports.set_offer_inputs (!s);
setup ();
}
@@ -94,7 +99,8 @@ void
PortMatrix::set_type (ARDOUR::DataType t)
{
_type = t;
- _port_group_list.set_type (t);
+ _column_ports.set_type (t);
+ _row_ports.set_type (t);
setup ();
}
@@ -131,18 +137,17 @@ PortMatrix::setup_scrollbars ()
void
PortMatrix::disassociate_all ()
{
- for (PortGroupList::iterator i = _port_group_list.begin(); i != _port_group_list.end(); ++i) {
-
- for (std::vector<boost::shared_ptr<ARDOUR::Bundle> >::iterator j = (*i)->bundles.begin(); j != (*i)->bundles.end(); ++j) {
-
- for (uint32_t k = 0; k < (*j)->nchannels(); ++k) {
-
- for (uint32_t l = 0; l < _our_bundles.front()->nchannels(); ++l) {
-
- set_state (
- _our_bundles.front(), l, *j, k, false, 0
- );
- }
+ ARDOUR::BundleList c = _column_ports.bundles ();
+ ARDOUR::BundleList r = _row_ports.bundles ();
+
+ for (ARDOUR::BundleList::iterator i = c.begin(); i != c.end(); ++i) {
+ for (uint32_t j = 0; j < (*i)->nchannels(); ++j) {
+ for (uint32_t k = 0; k < r.front()->nchannels(); ++k) {
+
+ set_state (
+ r.front(), k, *i, j, false, 0
+ );
+
}
}
}
diff --git a/gtk2_ardour/port_matrix.h b/gtk2_ardour/port_matrix.h
index ad6730976d..85a273265e 100644
--- a/gtk2_ardour/port_matrix.h
+++ b/gtk2_ardour/port_matrix.h
@@ -46,13 +46,21 @@ namespace ARDOUR {
class PortMatrix : public Gtk::VBox
{
public:
- PortMatrix (ARDOUR::Session&, ARDOUR::DataType, bool, PortGroupList::Mask);
+ PortMatrix (ARDOUR::Session&, ARDOUR::DataType, bool);
~PortMatrix ();
virtual void setup ();
void set_offer_inputs (bool);
void set_type (ARDOUR::DataType);
- bool offering_input () const { return _offer_inputs; }
+
+ ARDOUR::DataType type () const {
+ return _type;
+ }
+
+ bool offering_input () const {
+ return _offer_inputs;
+ }
+
void disassociate_all ();
enum Result {
@@ -106,15 +114,15 @@ public:
protected:
- std::vector<boost::shared_ptr<ARDOUR::Bundle> > _our_bundles;
- /// list of port groups
- PortGroupList _port_group_list;
+ PortGroupList _row_ports;
+ PortGroupList _column_ports;
private:
void hscroll_changed ();
void vscroll_changed ();
-
+
+ ARDOUR::Session& _session;
/// true to offer inputs, otherwise false
bool _offer_inputs;
/// port type that we are working with
diff --git a/gtk2_ardour/port_matrix_body.cc b/gtk2_ardour/port_matrix_body.cc
index d9d8013578..3531712a56 100644
--- a/gtk2_ardour/port_matrix_body.cc
+++ b/gtk2_ardour/port_matrix_body.cc
@@ -19,6 +19,7 @@
#include <iostream>
#include "ardour/bundle.h"
+#include "ardour/types.h"
#include "port_matrix_body.h"
#include "port_matrix.h"
@@ -29,7 +30,9 @@ PortMatrixBody::PortMatrixBody (PortMatrix* p, Arrangement a)
_grid (p, this),
_arrangement (a),
_xoffset (0),
- _yoffset (0)
+ _yoffset (0),
+ _column_ports (_port_matrix->type(), _port_matrix->offering_input()),
+ _row_ports (_port_matrix->type(), !_port_matrix->offering_input())
{
modify_bg (Gtk::STATE_NORMAL, Gdk::Color ("#00000"));
}
@@ -215,10 +218,7 @@ PortMatrixBody::compute_rectangles ()
}
void
-PortMatrixBody::setup (
- std::vector<boost::shared_ptr<ARDOUR::Bundle> > const & row,
- std::vector<boost::shared_ptr<ARDOUR::Bundle> > const & column
- )
+PortMatrixBody::setup (PortGroupList const& row, PortGroupList const& column)
{
for (std::list<sigc::connection>::iterator i = _bundle_connections.begin(); i != _bundle_connections.end(); ++i) {
i->disconnect ();
@@ -226,10 +226,11 @@ PortMatrixBody::setup (
_bundle_connections.clear ();
- _row_bundles = row;
- _column_bundles = column;
+ _row_ports = row;
+ _column_ports = column;
- for (std::vector<boost::shared_ptr<ARDOUR::Bundle> >::iterator i = _row_bundles.begin(); i != _row_bundles.end(); ++i) {
+ ARDOUR::BundleList r = _row_ports.bundles ();
+ for (ARDOUR::BundleList::iterator i = r.begin(); i != r.end(); ++i) {
_bundle_connections.push_back (
(*i)->NameChanged.connect (sigc::mem_fun (*this, &PortMatrixBody::rebuild_and_draw_row_labels))
@@ -237,7 +238,8 @@ PortMatrixBody::setup (
}
- for (std::vector<boost::shared_ptr<ARDOUR::Bundle> >::iterator i = _column_bundles.begin(); i != _column_bundles.end(); ++i) {
+ ARDOUR::BundleList c = _column_ports.bundles ();
+ for (ARDOUR::BundleList::iterator i = c.begin(); i != c.end(); ++i) {
_bundle_connections.push_back (
(*i)->NameChanged.connect (sigc::mem_fun (*this, &PortMatrixBody::rebuild_and_draw_column_labels))
);
diff --git a/gtk2_ardour/port_matrix_body.h b/gtk2_ardour/port_matrix_body.h
index 753f4f7096..c9fd8bdb65 100644
--- a/gtk2_ardour/port_matrix_body.h
+++ b/gtk2_ardour/port_matrix_body.h
@@ -23,6 +23,7 @@
#include "port_matrix_column_labels.h"
#include "port_matrix_row_labels.h"
#include "port_matrix_grid.h"
+#include "port_group.h"
class PortMatrix;
@@ -40,20 +41,17 @@ public:
PortMatrixBody (PortMatrix *, Arrangement);
- /** @return bundles to offer for columns */
- std::vector<boost::shared_ptr<ARDOUR::Bundle> > const & column_bundles () {
- return _column_bundles;
+ /** @return ports to offer for columns */
+ PortGroupList const & column_ports () {
+ return _column_ports;
}
- /** @return bundles to offer for rows */
- std::vector<boost::shared_ptr<ARDOUR::Bundle> > const & row_bundles () {
- return _row_bundles;
+ /** @return ports to offer for rows */
+ PortGroupList const & row_ports () {
+ return _row_ports;
}
- void setup (
- std::vector<boost::shared_ptr<ARDOUR::Bundle> > const &,
- std::vector<boost::shared_ptr<ARDOUR::Bundle> > const &
- );
+ void setup (PortGroupList const &, PortGroupList const &);
uint32_t full_scroll_width ();
uint32_t alloc_scroll_width ();
@@ -91,9 +89,9 @@ private:
uint32_t _yoffset;
/// bundles to offer for columns
- std::vector<boost::shared_ptr<ARDOUR::Bundle> > _column_bundles;
+ PortGroupList _column_ports;
/// bundles to offer for rows
- std::vector<boost::shared_ptr<ARDOUR::Bundle> > _row_bundles;
+ PortGroupList _row_ports;
std::list<sigc::connection> _bundle_connections;
};
diff --git a/gtk2_ardour/port_matrix_column_labels.cc b/gtk2_ardour/port_matrix_column_labels.cc
index 72954d1627..3ef501d89b 100644
--- a/gtk2_ardour/port_matrix_column_labels.cc
+++ b/gtk2_ardour/port_matrix_column_labels.cc
@@ -19,6 +19,7 @@
#include <iostream>
#include "ardour/bundle.h"
+#include "ardour/types.h"
#include "port_matrix_column_labels.h"
#include "port_matrix.h"
@@ -39,10 +40,13 @@ PortMatrixColumnLabels::compute_dimensions ()
_longest_bundle_name = 0;
/* width of the longest channel name */
_longest_channel_name = 0;
- /* height of highest bit of text */
+ /* height of highest bit of text (apart from group names) */
_highest_text = 0;
-
- for (std::vector<boost::shared_ptr<ARDOUR::Bundle> >::const_iterator i = _body->column_bundles().begin (); i != _body->column_bundles().end(); ++i) {
+ /* width of the whole thing */
+ _width = 0;
+
+ ARDOUR::BundleList const c = _body->column_ports().bundles();
+ for (ARDOUR::BundleList::const_iterator i = c.begin (); i != c.end(); ++i) {
cairo_text_extents_t ext;
cairo_text_extents (cr, (*i)->name().c_str(), &ext);
@@ -68,23 +72,33 @@ PortMatrixColumnLabels::compute_dimensions ()
_highest_text = ext.height;
}
}
+
+ _width += (*i)->nchannels() * column_width();
+ }
+
+ _highest_group_name = 0;
+ for (PortGroupList::const_iterator i = _body->column_ports().begin(); i != _body->column_ports().end(); ++i) {
+ if ((*i)->visible()) {
+ cairo_text_extents_t ext;
+ cairo_text_extents (cr, (*i)->name.c_str(), &ext);
+ if (ext.height > _highest_group_name) {
+ _highest_group_name = ext.height;
+ }
+ }
}
cairo_destroy (cr);
gdk_pixmap_unref (pm);
- /* width and height of the whole thing */
-
- _width = 0;
- for (std::vector<boost::shared_ptr<ARDOUR::Bundle> >::const_iterator i = _body->column_bundles().begin (); i != _body->column_bundles().end(); ++i) {
- _width += (*i)->nchannels() * column_width();
- }
+ /* height of the whole thing */
- _height =
+ double const parallelogram_height =
(_longest_bundle_name + _longest_channel_name + 4 * name_pad()) * sin (angle())
+ _highest_text * cos (angle());
- _width += _height / tan (angle ());
+ _height = parallelogram_height + _highest_group_name + 2 * name_pad();
+
+ _width += parallelogram_height / tan (angle ());
}
double
@@ -103,28 +117,84 @@ PortMatrixColumnLabels::render (cairo_t* cr)
cairo_rectangle (cr, 0, 0, _width, _height);
cairo_fill (cr);
+ /* PORT GROUP NAME */
+
+ double x = 0;
+ double y = 0;
+
+ if (_location == TOP) {
+ x = (_height - _highest_group_name - 2 * name_pad()) / tan (angle());
+ y = _highest_group_name + name_pad();
+ } else {
+ x = 0;
+ y = _height - name_pad();
+ }
+
+ int g = 0;
+ for (PortGroupList::const_iterator i = _body->column_ports().begin(); i != _body->column_ports().end(); ++i) {
+
+ if (!(*i)->visible() || ((*i)->bundles.empty() && (*i)->ports.empty()) ) {
+ continue;
+ }
+
+ /* compute width of this group */
+ uint32_t w = 0;
+ for (ARDOUR::BundleList::const_iterator j = (*i)->bundles.begin(); j != (*i)->bundles.end(); ++j) {
+ w += (*j)->nchannels() * column_width();
+ }
+ w += (*i)->ports.size() * column_width();
+
+ /* rectangle */
+ set_source_rgb (cr, get_a_group_colour (g));
+ double const rh = _highest_group_name + 2 * name_pad();
+ if (_location == TOP) {
+ cairo_rectangle (cr, x, 0, w, rh);
+ } else if (_location == BOTTOM) {
+ cairo_rectangle (cr, x, _height - rh, w, rh);
+ }
+ cairo_fill (cr);
+
+ std::pair<std::string, double> const display = display_port_name (cr, (*i)->name, w);
+
+ /* plot it */
+ set_source_rgb (cr, text_colour());
+ cairo_move_to (cr, x + (w - display.second) / 2, y);
+ cairo_show_text (cr, display.first.c_str());
+
+ x += w;
+ ++g;
+ }
+
/* BUNDLE PARALLELOGRAM-TYPE-THING AND NAME */
- double x = 0;
- for (std::vector<boost::shared_ptr<ARDOUR::Bundle> >::const_iterator i = _body->column_bundles().begin (); i != _body->column_bundles().end(); ++i) {
+ x = 0;
+ ARDOUR::BundleList const c = _body->column_ports().bundles();
+ for (ARDOUR::BundleList::const_iterator i = c.begin (); i != c.end(); ++i) {
- Gdk::Color colour = get_a_bundle_colour (i - _body->column_bundles().begin ());
+ Gdk::Color colour = get_a_bundle_colour (i - c.begin ());
set_source_rgb (cr, colour);
double const w = (*i)->nchannels() * column_width();
+ double const ph = _height - _highest_group_name - 2 * name_pad();
double x_ = x;
- double y_ = _height;
- cairo_move_to (cr, x_, y_);
- x_ += w;
- cairo_line_to (cr, x_, y_);
- x_ += _height / tan (angle ());
- y_ -= _height;
- cairo_line_to (cr, x_, y_);
- x_ -= w;
- cairo_line_to (cr, x_, y_);
- cairo_line_to (cr, x, _height);
+ if (_location == TOP) {
+ y = _height;
+ } else if (_location == BOTTOM) {
+ y = ph;
+ }
+
+ double y_ = y;
+ cairo_move_to (cr, x_, y_);
+ x_ += w;
+ cairo_line_to (cr, x_, y_);
+ x_ += ph / tan (angle ());
+ y_ -= ph;
+ cairo_line_to (cr, x_, y_);
+ x_ -= w;
+ cairo_line_to (cr, x_, y_);
+ cairo_line_to (cr, x, y);
cairo_fill_preserve (cr);
set_source_rgb (cr, background_colour());
cairo_set_line_width (cr, label_border_width());
@@ -132,7 +202,6 @@ PortMatrixColumnLabels::render (cairo_t* cr)
set_source_rgb (cr, text_colour());
-
if (_location == TOP) {
double const rl = 3 * name_pad() + _longest_channel_name;
@@ -147,7 +216,7 @@ PortMatrixColumnLabels::render (cairo_t* cr)
cairo_move_to (
cr,
x + basic_text_x_pos (0),
- _height - name_pad() * sin (angle())
+ ph - name_pad() * sin (angle())
);
}
@@ -163,16 +232,17 @@ PortMatrixColumnLabels::render (cairo_t* cr)
/* PORT NAMES */
x = 0;
- for (std::vector<boost::shared_ptr<ARDOUR::Bundle> >::const_iterator i = _body->column_bundles().begin(); i != _body->column_bundles().end(); ++i) {
+ for (ARDOUR::BundleList::const_iterator i = c.begin (); i != c.end(); ++i) {
for (uint32_t j = 0; j < (*i)->nchannels(); ++j) {
double const lc = _longest_channel_name + name_pad();
double const w = column_width();
+ double const ph = _height - _highest_group_name - 2 * name_pad();
if (_location == BOTTOM) {
- double x_ = x + _height / tan (angle()) + w;
+ double x_ = x + ph / tan (angle()) + w;
double const ix = x_;
double y_ = 0;
cairo_move_to (cr, x_, y_);
@@ -203,7 +273,7 @@ PortMatrixColumnLabels::render (cairo_t* cr)
}
- Gdk::Color colour = get_a_bundle_colour (i - _body->column_bundles().begin());
+ Gdk::Color colour = get_a_bundle_colour (i - c.begin());
set_source_rgb (cr, colour);
cairo_fill_preserve (cr);
set_source_rgb (cr, background_colour());
@@ -216,7 +286,7 @@ PortMatrixColumnLabels::render (cairo_t* cr)
cairo_move_to (cr, x + basic_text_x_pos(j), _height - name_pad() * sin (angle()));
} else if (_location == BOTTOM) {
double const rl = 3 * name_pad() + _longest_bundle_name;
- cairo_move_to (cr, x + basic_text_x_pos(j) + rl * cos (angle ()), _height - rl * sin (angle()));
+ cairo_move_to (cr, x + basic_text_x_pos(j) + rl * cos (angle ()), ph - rl * sin (angle()));
}
cairo_save (cr);
diff --git a/gtk2_ardour/port_matrix_column_labels.h b/gtk2_ardour/port_matrix_column_labels.h
index 76510073ec..5bdd7a2930 100644
--- a/gtk2_ardour/port_matrix_column_labels.h
+++ b/gtk2_ardour/port_matrix_column_labels.h
@@ -50,6 +50,7 @@ private:
double _longest_bundle_name;
double _longest_channel_name;
double _highest_text;
+ double _highest_group_name;
Location _location;
};
diff --git a/gtk2_ardour/port_matrix_component.cc b/gtk2_ardour/port_matrix_component.cc
index e2d1e07027..74f989934e 100644
--- a/gtk2_ardour/port_matrix_component.cc
+++ b/gtk2_ardour/port_matrix_component.cc
@@ -105,3 +105,35 @@ PortMatrixComponent::dimensions ()
return std::make_pair (_width, _height);
}
+
+std::pair<std::string, double>
+PortMatrixComponent::display_port_name (cairo_t* cr, std::string const &n, double avail) const
+{
+ /* XXX hopefully there exists a more efficient way of doing this */
+
+ Glib::ustring name = Glib::ustring (n).uppercase ();
+ bool abbreviated = false;
+ uint32_t width = 0;
+
+ while (1) {
+ if (name.length() <= 2) {
+ break;
+ }
+
+ cairo_text_extents_t ext;
+ cairo_text_extents (cr, name.c_str(), &ext);
+ if (ext.width < avail) {
+ width = ext.width;
+ break;
+ }
+
+ if (abbreviated) {
+ name = name.substr (0, name.length() - 2) + ".";
+ } else {
+ name = name.substr (0, name.length() - 1) + ".";
+ abbreviated = true;
+ }
+ }
+
+ return std::make_pair (name, width);
+}
diff --git a/gtk2_ardour/port_matrix_component.h b/gtk2_ardour/port_matrix_component.h
index 7c836ee96f..cc0f082695 100644
--- a/gtk2_ardour/port_matrix_component.h
+++ b/gtk2_ardour/port_matrix_component.h
@@ -124,8 +124,18 @@ protected:
}
}
+ /* XXX */
+ static Gdk::Color get_a_group_colour (int x) {
+ if ((x % 2) == 0) {
+ return Gdk::Color ("#222222");
+ } else {
+ return Gdk::Color ("#444444");
+ }
+ }
+
void set_source_rgb (cairo_t *, Gdk::Color const &);
void set_source_rgba (cairo_t *, Gdk::Color const &, double);
+ std::pair<std::string, double> display_port_name (cairo_t*, std::string const &, double) const;
/** Render the complete component to a cairo context. */
virtual void render (cairo_t *) = 0;
diff --git a/gtk2_ardour/port_matrix_grid.cc b/gtk2_ardour/port_matrix_grid.cc
index f63cd231d7..bab229efaf 100644
--- a/gtk2_ardour/port_matrix_grid.cc
+++ b/gtk2_ardour/port_matrix_grid.cc
@@ -20,6 +20,7 @@
#include <iostream>
#include <cairo/cairo.h>
#include "ardour/bundle.h"
+#include "ardour/types.h"
#include "port_matrix_grid.h"
#include "port_matrix.h"
@@ -34,13 +35,15 @@ void
PortMatrixGrid::compute_dimensions ()
{
_width = 0;
- for (uint32_t i = 0; i < _body->column_bundles().size(); ++i) {
- _width += _body->column_bundles()[i]->nchannels() * column_width();
+ ARDOUR::BundleList const c = _body->column_ports().bundles();
+ for (ARDOUR::BundleList::const_iterator i = c.begin(); i != c.end(); ++i) {
+ _width += (*i)->nchannels() * column_width();
}
_height = 0;
- for (uint32_t i = 0; i < _body->row_bundles().size(); ++i) {
- _height += _body->row_bundles()[i]->nchannels() * row_height();
+ ARDOUR::BundleList const r = _body->row_ports().bundles();
+ for (ARDOUR::BundleList::const_iterator i = r.begin(); i != r.end(); ++i) {
+ _height += (*i)->nchannels() * row_height();
}
}
@@ -58,17 +61,18 @@ PortMatrixGrid::render (cairo_t* cr)
set_source_rgb (cr, grid_colour());
uint32_t x = 0;
- for (std::vector<boost::shared_ptr<ARDOUR::Bundle> >::size_type i = 0; i < _body->column_bundles().size(); ++i) {
+ ARDOUR::BundleList const c = _body->column_ports().bundles();
+ for (ARDOUR::BundleList::size_type i = 0; i < c.size(); ++i) {
cairo_set_line_width (cr, thin_grid_line_width());
- for (uint32_t j = 1; j < _body->column_bundles()[i]->nchannels(); ++j) {
+ for (uint32_t j = 1; j < c[i]->nchannels(); ++j) {
x += column_width();
cairo_move_to (cr, x, 0);
cairo_line_to (cr, x, _height);
cairo_stroke (cr);
}
- if (i < (_body->column_bundles().size() - 1)) {
+ if (i < (c.size() - 1)) {
x += column_width();
cairo_set_line_width (cr, thick_grid_line_width());
cairo_move_to (cr, x, 0);
@@ -82,17 +86,18 @@ PortMatrixGrid::render (cairo_t* cr)
/* HORIZONTAL GRID LINES */
uint32_t y = 0;
- for (std::vector<boost::shared_ptr<ARDOUR::Bundle> >::size_type i = 0; i < _body->row_bundles().size(); ++i) {
+ ARDOUR::BundleList const r = _body->row_ports().bundles();
+ for (ARDOUR::BundleList::size_type i = 0; i < r.size(); ++i) {
cairo_set_line_width (cr, thin_grid_line_width());
- for (uint32_t j = 1; j < _body->row_bundles()[i]->nchannels(); ++j) {
+ for (uint32_t j = 1; j < r[i]->nchannels(); ++j) {
y += row_height();
cairo_move_to (cr, 0, y);
cairo_line_to (cr, grid_width, y);
cairo_stroke (cr);
}
- if (i < (_body->row_bundles().size() - 1)) {
+ if (i < (r.size() - 1)) {
y += row_height();
cairo_set_line_width (cr, thick_grid_line_width());
cairo_move_to (cr, 0, y);
@@ -106,10 +111,10 @@ PortMatrixGrid::render (cairo_t* cr)
uint32_t bx = 0;
uint32_t by = 0;
- for (std::vector<boost::shared_ptr<ARDOUR::Bundle> >::const_iterator i = _body->column_bundles().begin(); i < _body->column_bundles().end(); ++i) {
+ for (ARDOUR::BundleList::const_iterator i = c.begin(); i < c.end(); ++i) {
by = 0;
- for (std::vector<boost::shared_ptr<ARDOUR::Bundle> >::const_iterator j = _body->row_bundles().begin(); j < _body->row_bundles().end(); ++j) {
+ for (ARDOUR::BundleList::const_iterator j = r.begin(); j < r.end(); ++j) {
x = bx;
for (uint32_t k = 0; k < (*i)->nchannels (); k++) {
@@ -174,7 +179,8 @@ PortMatrixGrid::button_press (double x, double y, int b)
boost::shared_ptr<ARDOUR::Bundle> other_bundle;
uint32_t other_channel = 0;
- for (std::vector<boost::shared_ptr<ARDOUR::Bundle> >::const_iterator i = _body->row_bundles().begin(); i != _body->row_bundles().end(); ++i) {
+ ARDOUR::BundleList const r = _body->row_ports().bundles();
+ for (ARDOUR::BundleList::const_iterator i = r.begin(); i != r.end(); ++i) {
if (grid_row < (*i)->nchannels ()) {
our_bundle = *i;
our_channel = grid_row;
@@ -184,7 +190,8 @@ PortMatrixGrid::button_press (double x, double y, int b)
}
}
- for (std::vector<boost::shared_ptr<ARDOUR::Bundle> >::const_iterator i = _body->column_bundles().begin(); i != _body->column_bundles().end(); ++i) {
+ ARDOUR::BundleList const c = _body->column_ports().bundles();
+ for (ARDOUR::BundleList::const_iterator i = c.begin(); i != c.end(); ++i) {
if (grid_column < (*i)->nchannels ()) {
other_bundle = *i;
other_channel = grid_column;
diff --git a/gtk2_ardour/port_matrix_grid.h b/gtk2_ardour/port_matrix_grid.h
index 298d33c0b5..7441d3c79d 100644
--- a/gtk2_ardour/port_matrix_grid.h
+++ b/gtk2_ardour/port_matrix_grid.h
@@ -44,9 +44,6 @@ private:
void compute_dimensions ();
void render (cairo_t *);
- std::vector<boost::shared_ptr<ARDOUR::Bundle> > _column_bundles;
- std::vector<boost::shared_ptr<ARDOUR::Bundle> > _row_bundles;
-
PortMatrix* _port_matrix;
};
diff --git a/gtk2_ardour/port_matrix_row_labels.cc b/gtk2_ardour/port_matrix_row_labels.cc
index ab9480ac65..7740d9cf18 100644
--- a/gtk2_ardour/port_matrix_row_labels.cc
+++ b/gtk2_ardour/port_matrix_row_labels.cc
@@ -47,7 +47,10 @@ PortMatrixRowLabels::compute_dimensions ()
cairo_t* cr = gdk_cairo_create (pm);
_longest_port_name = 0;
- for (std::vector<boost::shared_ptr<ARDOUR::Bundle> >::const_iterator i = _body->row_bundles().begin(); i != _body->row_bundles().end(); ++i) {
+ _longest_bundle_name = 0;
+ _height = 0;
+ ARDOUR::BundleList const r = _body->row_ports().bundles();
+ for (ARDOUR::BundleList::const_iterator i = r.begin(); i != r.end(); ++i) {
for (uint32_t j = 0; j < (*i)->nchannels(); ++j) {
cairo_text_extents_t ext;
cairo_text_extents (cr, (*i)->channel_name(j).c_str(), &ext);
@@ -55,26 +58,34 @@ PortMatrixRowLabels::compute_dimensions ()
_longest_port_name = ext.width;
}
}
- }
- _longest_bundle_name = 0;
- for (std::vector<boost::shared_ptr<ARDOUR::Bundle> >::const_iterator i = _body->row_bundles().begin(); i != _body->row_bundles().end(); ++i) {
cairo_text_extents_t ext;
cairo_text_extents (cr, (*i)->name().c_str(), &ext);
if (ext.width > _longest_bundle_name) {
_longest_bundle_name = ext.width;
}
+
+ _height += (*i)->nchannels() * row_height();
}
+ _highest_group_name = 0;
+ for (PortGroupList::const_iterator i = _body->row_ports().begin(); i != _body->row_ports().end(); ++i) {
+ if ((*i)->visible()) {
+ cairo_text_extents_t ext;
+ cairo_text_extents (cr, (*i)->name.c_str(), &ext);
+ if (ext.height > _highest_group_name) {
+ _highest_group_name = ext.height;
+ }
+ }
+ }
+
cairo_destroy (cr);
gdk_pixmap_unref (pm);
- _height = 0;
- for (std::vector<boost::shared_ptr<ARDOUR::Bundle> >::const_iterator i = _body->row_bundles().begin(); i != _body->row_bundles().end(); ++i) {
- _height += (*i)->nchannels() * row_height();
- }
-
- _width = _longest_port_name + name_pad() * 4 + _longest_bundle_name;
+ _width = _highest_group_name +
+ _longest_port_name +
+ _longest_bundle_name +
+ name_pad() * 6;
}
@@ -87,27 +98,73 @@ PortMatrixRowLabels::render (cairo_t* cr)
cairo_rectangle (cr, 0, 0, _width, _height);
cairo_fill (cr);
+ /* PORT GROUP NAMES */
+
+ double x = 0;
+ if (_location == LEFT) {
+ x = 0;
+ } else if (_location == RIGHT) {
+ x = _width - _highest_group_name - 2 * name_pad();
+ }
+
+ double y = 0;
+ int g = 0;
+ for (PortGroupList::const_iterator i = _body->row_ports().begin(); i != _body->row_ports().end(); ++i) {
+
+ if (!(*i)->visible() || ((*i)->bundles.empty() && (*i)->ports.empty()) ) {
+ continue;
+ }
+
+ /* compute height of this group */
+ double h = 0;
+ for (ARDOUR::BundleList::const_iterator j = (*i)->bundles.begin(); j != (*i)->bundles.end(); ++j) {
+ h += (*j)->nchannels() * row_height();
+ }
+ h += (*i)->ports.size() * row_height();
+
+ /* rectangle */
+ set_source_rgb (cr, get_a_group_colour (g));
+ double const rw = _highest_group_name + 2 * name_pad();
+ cairo_rectangle (cr, x, y, rw, h);
+ cairo_fill (cr);
+
+ /* hence what abbreviation (or not) we need for the group name */
+ std::pair<std::string, double> display = display_port_name (cr, (*i)->name, h);
+
+ /* plot it */
+ set_source_rgb (cr, text_colour());
+ cairo_move_to (cr, x + rw - name_pad(), y + (h + display.second) / 2);
+ cairo_save (cr);
+ cairo_rotate (cr, - M_PI / 2);
+ cairo_show_text (cr, display.first.c_str());
+ cairo_restore (cr);
+
+ y += h;
+ ++g;
+ }
+
/* SIDE BUNDLE NAMES */
- uint32_t x = 0;
+ x = 0;
if (_location == LEFT) {
- x = name_pad();
+ x = _highest_group_name + 2 * name_pad();
} else if (_location == RIGHT) {
- x = _longest_port_name + name_pad() * 3;
+ x = _longest_port_name + name_pad() * 2;
}
- uint32_t y = 0;
- for (std::vector<boost::shared_ptr<ARDOUR::Bundle> >::const_iterator i = _body->row_bundles().begin(); i != _body->row_bundles().end(); ++i) {
+ y = 0;
+ ARDOUR::BundleList const r = _body->row_ports().bundles();
+ for (ARDOUR::BundleList::const_iterator i = r.begin(); i != r.end(); ++i) {
- Gdk::Color const colour = get_a_bundle_colour (i - _body->row_bundles().begin ());
+ Gdk::Color const colour = get_a_bundle_colour (i - r.begin ());
set_source_rgb (cr, colour);
- cairo_rectangle (cr, 0, y, _width, row_height() * (*i)->nchannels());
+ cairo_rectangle (cr, x, y, _longest_bundle_name + name_pad() * 2, row_height() * (*i)->nchannels());
cairo_fill_preserve (cr);
set_source_rgb (cr, background_colour());
cairo_set_line_width (cr, label_border_width ());
cairo_stroke (cr);
- uint32_t off = 0;
+ double off = 0;
if ((*i)->nchannels () > 0) {
/* use the extent of our first channel name so that the bundle name is vertically aligned with it */
cairo_text_extents_t ext;
@@ -118,7 +175,7 @@ PortMatrixRowLabels::render (cairo_t* cr)
}
set_source_rgb (cr, text_colour());
- cairo_move_to (cr, x, y + name_pad() + off);
+ cairo_move_to (cr, x + name_pad(), y + name_pad() + off);
cairo_show_text (cr, (*i)->name().c_str());
y += row_height() * (*i)->nchannels ();
@@ -128,17 +185,17 @@ PortMatrixRowLabels::render (cairo_t* cr)
/* SIDE PORT NAMES */
y = 0;
- for (std::vector<boost::shared_ptr<ARDOUR::Bundle> >::const_iterator i = _body->row_bundles().begin(); i != _body->row_bundles().end(); ++i) {
+ for (ARDOUR::BundleList::const_iterator i = r.begin(); i != r.end(); ++i) {
for (uint32_t j = 0; j < (*i)->nchannels(); ++j) {
- uint32_t x = 0;
+ double x = 0;
if (_location == LEFT) {
- x = _longest_bundle_name + name_pad() * 2;
+ x = _longest_bundle_name + _highest_group_name + name_pad() * 4;
} else if (_location == RIGHT) {
x = 0;
}
- Gdk::Color const colour = get_a_bundle_colour (i - _body->row_bundles().begin ());
+ Gdk::Color const colour = get_a_bundle_colour (i - r.begin ());
set_source_rgb (cr, colour);
cairo_rectangle (
cr,
@@ -154,7 +211,7 @@ PortMatrixRowLabels::render (cairo_t* cr)
cairo_text_extents_t ext;
cairo_text_extents (cr, (*i)->channel_name(j).c_str(), &ext);
- uint32_t const off = (row_height() - ext.height) / 2;
+ double const off = (row_height() - ext.height) / 2;
set_source_rgb (cr, text_colour());
cairo_move_to (cr, x + name_pad(), y + name_pad() + off);
@@ -187,8 +244,9 @@ PortMatrixRowLabels::button_press (double x, double y, int b, uint32_t t)
boost::shared_ptr<ARDOUR::Bundle> bundle;
uint32_t channel = 0;
-
- for (std::vector<boost::shared_ptr<ARDOUR::Bundle> >::const_iterator i = _body->row_bundles().begin(); i != _body->row_bundles().end(); ++i) {
+
+ ARDOUR::BundleList const r = _body->row_ports().bundles();
+ for (ARDOUR::BundleList::const_iterator i = r.begin(); i != r.end(); ++i) {
if (row < (*i)->nchannels ()) {
bundle = *i;
channel = row;
diff --git a/gtk2_ardour/port_matrix_row_labels.h b/gtk2_ardour/port_matrix_row_labels.h
index dd3d2a9348..dff6b71d26 100644
--- a/gtk2_ardour/port_matrix_row_labels.h
+++ b/gtk2_ardour/port_matrix_row_labels.h
@@ -54,8 +54,9 @@ private:
void rename_channel_proxy (boost::weak_ptr<ARDOUR::Bundle>, uint32_t);
PortMatrix* _port_matrix;
- uint32_t _longest_port_name;
- uint32_t _longest_bundle_name;
+ double _longest_port_name;
+ double _longest_bundle_name;
+ double _highest_group_name;
Gtk::Menu* _menu;
Location _location;
};
diff --git a/libs/ardour/ardour/io.h b/libs/ardour/ardour/io.h
index a738519d57..1918a9a41a 100644
--- a/libs/ardour/ardour/io.h
+++ b/libs/ardour/ardour/io.h
@@ -127,8 +127,8 @@ class IO : public SessionObject, public AutomatableControls, public Latent
int connect_input_ports_to_bundle (boost::shared_ptr<Bundle>, void *src);
int connect_output_ports_to_bundle (boost::shared_ptr<Bundle>, void *src);
- std::vector<boost::shared_ptr<Bundle> > bundles_connected_to_inputs ();
- std::vector<boost::shared_ptr<Bundle> > bundles_connected_to_outputs ();
+ BundleList bundles_connected_to_inputs ();
+ BundleList bundles_connected_to_outputs ();
boost::shared_ptr<Bundle> bundle_for_inputs () { return _bundle_for_inputs; }
boost::shared_ptr<Bundle> bundle_for_outputs () { return _bundle_for_outputs; }
@@ -380,9 +380,6 @@ class IO : public SessionObject, public AutomatableControls, public Latent
void create_bundles_for_inputs_and_outputs ();
void setup_bundles_for_inputs_and_outputs ();
-
- void maybe_add_input_bundle_to_list (boost::shared_ptr<Bundle>, std::vector<boost::shared_ptr<Bundle> >*);
- void maybe_add_output_bundle_to_list (boost::shared_ptr<Bundle>, std::vector<boost::shared_ptr<Bundle> >*);
};
} // namespace ARDOUR
diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h
index 2c173a9766..1a88882eb6 100644
--- a/libs/ardour/ardour/session.h
+++ b/libs/ardour/ardour/session.h
@@ -317,6 +317,10 @@ class Session : public PBD::StatefulDestructible
uint32_t ntracks () const;
uint32_t nbusses () const;
+ boost::shared_ptr<BundleList> bundles () {
+ return _bundles.reader ();
+ }
+
struct RoutePublicOrderSorter {
bool operator() (boost::shared_ptr<Route>, boost::shared_ptr<Route> b);
};
@@ -771,7 +775,6 @@ class Session : public PBD::StatefulDestructible
/* I/O bundles */
- void foreach_bundle (sigc::slot<void, boost::shared_ptr<Bundle> >);
void add_bundle (boost::shared_ptr<Bundle>);
void remove_bundle (boost::shared_ptr<Bundle>);
boost::shared_ptr<Bundle> bundle_by_name (string) const;
@@ -1616,9 +1619,7 @@ class Session : public PBD::StatefulDestructible
/* I/O bundles */
- typedef list<boost::shared_ptr<Bundle> > BundleList;
- mutable Glib::Mutex bundle_lock;
- BundleList _bundles;
+ SerializedRCUManager<BundleList> _bundles;
XMLNode* _bundle_xml_node;
int load_bundles (XMLNode const &);
diff --git a/libs/ardour/ardour/types.h b/libs/ardour/ardour/types.h
index 53077387ed..cb058254bf 100644
--- a/libs/ardour/ardour/types.h
+++ b/libs/ardour/ardour/types.h
@@ -419,6 +419,9 @@ namespace ARDOUR {
typedef std::list<nframes64_t> AnalysisFeatureList;
+ class Bundle;
+ typedef std::vector<boost::shared_ptr<Bundle> > BundleList;
+
} // namespace ARDOUR
std::istream& operator>>(std::istream& o, ARDOUR::SampleFormat& sf);
diff --git a/libs/ardour/io.cc b/libs/ardour/io.cc
index af4127c080..b86462472a 100644
--- a/libs/ardour/io.cc
+++ b/libs/ardour/io.cc
@@ -2629,42 +2629,11 @@ IO::create_bundles_for_inputs_and_outputs ()
setup_bundles_for_inputs_and_outputs ();
}
-/** Add a bundle to a list if is connected to our inputs.
- * @param b Bundle to check.
- * @param bundles List to add to.
- */
-void
-IO::maybe_add_input_bundle_to_list (boost::shared_ptr<Bundle> b, std::vector<boost::shared_ptr<Bundle> >* bundles)
-{
- if (b->ports_are_outputs() == false) {
- return;
- }
-
- if (b->nchannels() != n_inputs().n_total ()) {
- return;
- }
-
- for (uint32_t i = 0; i < n_inputs().n_total (); ++i) {
-
- Bundle::PortList const & pl = b->channel_ports (i);
-
- if (pl.empty()) {
- return;
- }
-
- if (!input(i)->connected_to (pl[0])) {
- return;
- }
- }
-
- bundles->push_back (b);
-}
-
/** @return Bundles connected to our inputs */
-std::vector<boost::shared_ptr<Bundle> >
+BundleList
IO::bundles_connected_to_inputs ()
{
- std::vector<boost::shared_ptr<Bundle> > bundles;
+ BundleList bundles;
/* User bundles */
for (std::vector<UserBundleInfo>::iterator i = _bundles_connected_to_inputs.begin(); i != _bundles_connected_to_inputs.end(); ++i) {
@@ -2672,51 +2641,31 @@ IO::bundles_connected_to_inputs ()
}
/* Normal bundles */
- _session.foreach_bundle (
- sigc::bind (sigc::mem_fun (*this, &IO::maybe_add_input_bundle_to_list), &bundles)
- );
-
- return bundles;
-}
-
-
-/** Add a bundle to a list if is connected to our outputs.
- * @param b Bundle to check.
- * @param bundles List to add to.
- */
-void
-IO::maybe_add_output_bundle_to_list (boost::shared_ptr<Bundle> b, std::vector<boost::shared_ptr<Bundle> >* bundles)
-{
- if (b->ports_are_inputs() == false) {
- return;
- }
-
- if (b->nchannels () != n_outputs().n_total ()) {
- return;
- }
-
- for (uint32_t i = 0; i < n_outputs().n_total (); ++i) {
+ boost::shared_ptr<ARDOUR::BundleList> b = _session.bundles ();
+ for (ARDOUR::BundleList::iterator i = b->begin(); i != b->end(); ++i) {
+ if ((*i)->ports_are_outputs() == false || (*i)->nchannels() != n_inputs().n_total()) {
+ continue;
+ }
- Bundle::PortList const & pl = b->channel_ports (i);
+ for (uint32_t j = 0; j < n_inputs().n_total(); ++j) {
- if (pl.empty()) {
- return;
- }
+ Bundle::PortList const& pl = (*i)->channel_ports (j);
+ if (!pl.empty() && input(j)->connected_to (pl[0])) {
+ bundles.push_back (*i);
+ }
- if (!output(i)->connected_to (pl[0])) {
- return;
}
}
- bundles->push_back (b);
+ return bundles;
}
/* @return Bundles connected to our outputs */
-std::vector<boost::shared_ptr<Bundle> >
+BundleList
IO::bundles_connected_to_outputs ()
{
- std::vector<boost::shared_ptr<Bundle> > bundles;
+ BundleList bundles;
/* User bundles */
for (std::vector<UserBundleInfo>::iterator i = _bundles_connected_to_outputs.begin(); i != _bundles_connected_to_outputs.end(); ++i) {
@@ -2724,9 +2673,21 @@ IO::bundles_connected_to_outputs ()
}
/* Auto bundles */
- _session.foreach_bundle (
- sigc::bind (sigc::mem_fun (*this, &IO::maybe_add_output_bundle_to_list), &bundles)
- );
+ boost::shared_ptr<ARDOUR::BundleList> b = _session.bundles ();
+ for (ARDOUR::BundleList::iterator i = b->begin(); i != b->end(); ++i) {
+ if ((*i)->ports_are_inputs() == false || (*i)->nchannels() != n_outputs().n_total()) {
+ continue;
+ }
+
+ for (uint32_t j = 0; j < n_outputs().n_total(); ++j) {
+
+ Bundle::PortList const& pl = (*i)->channel_ports (j);
+
+ if (!pl.empty() && output(j)->connected_to (pl[0])) {
+ bundles.push_back (*i);
+ }
+ }
+ }
return bundles;
}
diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc
index f870a677dc..59b873e87f 100644
--- a/libs/ardour/session.cc
+++ b/libs/ardour/session.cc
@@ -138,6 +138,7 @@ Session::Session (AudioEngine &eng,
routes (new RouteList),
auditioner ((Auditioner*) 0),
_total_free_4k_blocks (0),
+ _bundles (new BundleList),
_bundle_xml_node (0),
_click_io ((IO*) 0),
click_data (0),
@@ -219,6 +220,7 @@ Session::Session (AudioEngine &eng,
routes (new RouteList),
auditioner ((Auditioner *) 0),
_total_free_4k_blocks (0),
+ _bundles (new BundleList),
_bundle_xml_node (0),
_click_io ((IO *) 0),
click_data (0),
@@ -3761,8 +3763,9 @@ void
Session::add_bundle (shared_ptr<Bundle> bundle)
{
{
- Glib::Mutex::Lock guard (bundle_lock);
- _bundles.push_back (bundle);
+ RCUWriter<BundleList> writer (_bundles);
+ boost::shared_ptr<BundleList> b = writer.get_copy ();
+ b->push_back (bundle);
}
BundleAdded (bundle); /* EMIT SIGNAL */
@@ -3776,11 +3779,12 @@ Session::remove_bundle (shared_ptr<Bundle> bundle)
bool removed = false;
{
- Glib::Mutex::Lock guard (bundle_lock);
- BundleList::iterator i = find (_bundles.begin(), _bundles.end(), bundle);
+ RCUWriter<BundleList> writer (_bundles);
+ boost::shared_ptr<BundleList> b = writer.get_copy ();
+ BundleList::iterator i = find (b->begin(), b->end(), bundle);
- if (i != _bundles.end()) {
- _bundles.erase (i);
+ if (i != b->end()) {
+ b->erase (i);
removed = true;
}
}
@@ -3795,9 +3799,9 @@ Session::remove_bundle (shared_ptr<Bundle> bundle)
shared_ptr<Bundle>
Session::bundle_by_name (string name) const
{
- Glib::Mutex::Lock lm (bundle_lock);
-
- for (BundleList::const_iterator i = _bundles.begin(); i != _bundles.end(); ++i) {
+ boost::shared_ptr<BundleList> b = _bundles.reader ();
+
+ for (BundleList::const_iterator i = b->begin(); i != b->end(); ++i) {
if ((*i)->name() == name) {
return* i;
}
@@ -4290,12 +4294,4 @@ Session::sync_order_keys (const char* base)
Route::SyncOrderKeys (base); // EMIT SIGNAL
}
-void
-Session::foreach_bundle (sigc::slot<void, boost::shared_ptr<Bundle> > sl)
-{
- Glib::Mutex::Lock lm (bundle_lock);
- for (BundleList::iterator i = _bundles.begin(); i != _bundles.end(); ++i) {
- sl (*i);
- }
-}
diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc
index 6c6ce18c8b..42dae522df 100644
--- a/libs/ardour/session_state.cc
+++ b/libs/ardour/session_state.cc
@@ -1061,8 +1061,8 @@ Session::state(bool full_state)
child = node->add_child ("Bundles");
{
- Glib::Mutex::Lock lm (bundle_lock);
- for (BundleList::iterator i = _bundles.begin(); i != _bundles.end(); ++i) {
+ boost::shared_ptr<BundleList> bundles = _bundles.reader ();
+ for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
if (b) {
child->add_child_nocopy (b->get_state());