Fixes to bundle manager to make it vaguely usable.
Rework signal handling for bundles so that all changes should now be noticed by port matrices. git-svn-id: svn://localhost/ardour2/branches/3.0@4501 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
91032b311e
commit
ee42a6dd97
|
@ -205,7 +205,6 @@ ARDOUR_UI::install_actions ()
|
|||
ActionManager::register_toggle_action (common_actions, X_("ToggleOptionsEditor"), _("Preferences"), mem_fun(*this, &ARDOUR_UI::toggle_options_window));
|
||||
act = ActionManager::register_toggle_action (common_actions, X_("ToggleInspector"), _("Track/Bus Inspector"), mem_fun(*this, &ARDOUR_UI::toggle_route_params_window));
|
||||
ActionManager::session_sensitive_actions.push_back (act);
|
||||
act = ActionManager::register_toggle_action (common_actions, X_("ToggleConnections"), _("Connections"), mem_fun(*this, &ARDOUR_UI::toggle_connection_editor));
|
||||
ActionManager::session_sensitive_actions.push_back (act);
|
||||
act = ActionManager::register_toggle_action (common_actions, X_("ToggleLocations"), _("Locations"), mem_fun(*this, &ARDOUR_UI::toggle_location_window));
|
||||
ActionManager::session_sensitive_actions.push_back (act);
|
||||
|
|
|
@ -37,15 +37,21 @@ BundleEditorMatrix::BundleEditorMatrix (
|
|||
_bundle (bundle)
|
||||
{
|
||||
_port_group = boost::shared_ptr<PortGroup> (new PortGroup (""));
|
||||
_port_group->add_bundle (bundle);
|
||||
_ports[OURS].add_group (_port_group);
|
||||
_port_group->add_bundle (_bundle);
|
||||
}
|
||||
|
||||
void
|
||||
BundleEditorMatrix::setup ()
|
||||
BundleEditorMatrix::setup_ports (int dim)
|
||||
{
|
||||
_ports[OTHER].gather (_session, _bundle->ports_are_inputs());
|
||||
PortMatrix::setup ();
|
||||
if (dim == OURS) {
|
||||
_ports[OURS].clear ();
|
||||
_ports[OURS].add_group (_port_group);
|
||||
} else {
|
||||
_ports[OTHER].suspend_signals ();
|
||||
_ports[OTHER].gather (_session, _bundle->ports_are_inputs());
|
||||
_ports[OTHER].remove_bundle (_bundle);
|
||||
_ports[OTHER].resume_signals ();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -85,14 +91,14 @@ BundleEditorMatrix::add_channel (boost::shared_ptr<ARDOUR::Bundle> b)
|
|||
}
|
||||
|
||||
_bundle->add_channel (d.get_name());
|
||||
setup ();
|
||||
setup_ports (OURS);
|
||||
}
|
||||
|
||||
void
|
||||
BundleEditorMatrix::remove_channel (ARDOUR::BundleChannel bc)
|
||||
{
|
||||
bc.bundle->remove_channel (bc.channel);
|
||||
setup ();
|
||||
setup_ports (OURS);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -108,6 +114,12 @@ BundleEditorMatrix::rename_channel (ARDOUR::BundleChannel bc)
|
|||
bc.bundle->set_channel_name (bc.channel, d.get_name ());
|
||||
}
|
||||
|
||||
bool
|
||||
BundleEditorMatrix::list_is_global (int dim) const
|
||||
{
|
||||
return (dim == OTHER);
|
||||
}
|
||||
|
||||
BundleEditor::BundleEditor (ARDOUR::Session& session, boost::shared_ptr<ARDOUR::UserBundle> bundle, bool add)
|
||||
: ArdourDialog (_("Edit Bundle")), _matrix (session, bundle), _bundle (bundle)
|
||||
{
|
||||
|
@ -133,9 +145,9 @@ BundleEditor::BundleEditor (ARDOUR::Session& session, boost::shared_ptr<ARDOUR::
|
|||
_input_or_output.append_text (_("Output"));
|
||||
|
||||
if (bundle->ports_are_inputs()) {
|
||||
_input_or_output.set_active_text (_("Output"));
|
||||
} else {
|
||||
_input_or_output.set_active_text (_("Input"));
|
||||
} else {
|
||||
_input_or_output.set_active_text (_("Output"));
|
||||
}
|
||||
|
||||
_input_or_output.signal_changed().connect (sigc::mem_fun (*this, &BundleEditor::input_or_output_changed));
|
||||
|
@ -174,10 +186,10 @@ BundleEditor::BundleEditor (ARDOUR::Session& session, boost::shared_ptr<ARDOUR::
|
|||
add_channel_button->signal_clicked().connect (sigc::bind (sigc::mem_fun (_matrix, &BundleEditorMatrix::add_channel), boost::shared_ptr<ARDOUR::Bundle> ()));
|
||||
|
||||
if (add) {
|
||||
add_button (Gtk::Stock::CANCEL, 1);
|
||||
add_button (Gtk::Stock::ADD, 0);
|
||||
add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
|
||||
add_button (Gtk::Stock::ADD, Gtk::RESPONSE_ACCEPT);
|
||||
} else {
|
||||
add_button (Gtk::Stock::CLOSE, 0);
|
||||
add_button (Gtk::Stock::CLOSE, Gtk::RESPONSE_ACCEPT);
|
||||
}
|
||||
|
||||
show_all ();
|
||||
|
@ -192,18 +204,22 @@ BundleEditor::name_changed ()
|
|||
void
|
||||
BundleEditor::input_or_output_changed ()
|
||||
{
|
||||
_bundle->remove_ports_from_channels ();
|
||||
|
||||
if (_input_or_output.get_active_text() == _("Output")) {
|
||||
_bundle->set_ports_are_inputs ();
|
||||
} else {
|
||||
_bundle->set_ports_are_outputs ();
|
||||
} else {
|
||||
_bundle->set_ports_are_inputs ();
|
||||
}
|
||||
|
||||
_matrix.setup ();
|
||||
_matrix.setup_all_ports ();
|
||||
}
|
||||
|
||||
void
|
||||
BundleEditor::type_changed ()
|
||||
{
|
||||
_bundle->remove_ports_from_channels ();
|
||||
|
||||
ARDOUR::DataType const t = _type.get_active_text() == _("Audio") ?
|
||||
ARDOUR::DataType::AUDIO : ARDOUR::DataType::MIDI;
|
||||
|
||||
|
@ -214,7 +230,7 @@ BundleEditor::type_changed ()
|
|||
void
|
||||
BundleEditor::on_map ()
|
||||
{
|
||||
_matrix.setup ();
|
||||
_matrix.setup_all_ports ();
|
||||
Window::on_map ();
|
||||
}
|
||||
|
||||
|
@ -284,7 +300,8 @@ BundleManager::new_clicked ()
|
|||
b->add_channel ("");
|
||||
|
||||
BundleEditor e (_session, b, true);
|
||||
if (e.run () == 0) {
|
||||
|
||||
if (e.run () == Gtk::RESPONSE_ACCEPT) {
|
||||
_session.add_bundle (b);
|
||||
add_bundle (b);
|
||||
}
|
||||
|
@ -297,9 +314,10 @@ BundleManager::edit_clicked ()
|
|||
if (i) {
|
||||
boost::shared_ptr<ARDOUR::UserBundle> b = (*i)[_list_model_columns.bundle];
|
||||
BundleEditor e (_session, b, false);
|
||||
e.run ();
|
||||
if (e.run () == Gtk::RESPONSE_ACCEPT) {
|
||||
_session.set_dirty ();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -325,12 +343,16 @@ BundleManager::add_bundle (boost::shared_ptr<ARDOUR::Bundle> b)
|
|||
(*i)[_list_model_columns.name] = u->name ();
|
||||
(*i)[_list_model_columns.bundle] = u;
|
||||
|
||||
u->NameChanged.connect (sigc::bind (sigc::mem_fun (*this, &BundleManager::bundle_name_changed), u));
|
||||
u->Changed.connect (sigc::bind (sigc::mem_fun (*this, &BundleManager::bundle_changed), u));
|
||||
}
|
||||
|
||||
void
|
||||
BundleManager::bundle_name_changed (boost::shared_ptr<ARDOUR::UserBundle> b)
|
||||
BundleManager::bundle_changed (ARDOUR::Bundle::Change c, boost::shared_ptr<ARDOUR::UserBundle> b)
|
||||
{
|
||||
if ((c & ARDOUR::Bundle::NameChanged) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
Gtk::TreeModel::iterator i = _list_model->children().begin ();
|
||||
while (i != _list_model->children().end()) {
|
||||
boost::shared_ptr<ARDOUR::UserBundle> t = (*i)[_list_model_columns.bundle];
|
||||
|
|
|
@ -47,7 +47,8 @@ class BundleEditorMatrix : public PortMatrix
|
|||
return d == OURS;
|
||||
}
|
||||
void rename_channel (ARDOUR::BundleChannel);
|
||||
void setup ();
|
||||
void setup_ports (int);
|
||||
bool list_is_global (int) const;
|
||||
|
||||
private:
|
||||
enum {
|
||||
|
@ -90,7 +91,7 @@ class BundleManager : public ArdourDialog
|
|||
void edit_clicked ();
|
||||
void delete_clicked ();
|
||||
void add_bundle (boost::shared_ptr<ARDOUR::Bundle>);
|
||||
void bundle_name_changed (boost::shared_ptr<ARDOUR::UserBundle>);
|
||||
void bundle_changed (ARDOUR::Bundle::Change, boost::shared_ptr<ARDOUR::UserBundle>);
|
||||
void set_button_sensitivity ();
|
||||
|
||||
class ModelColumns : public Gtk::TreeModelColumnRecord
|
||||
|
|
|
@ -27,16 +27,15 @@
|
|||
GlobalPortMatrix::GlobalPortMatrix (ARDOUR::Session& s, ARDOUR::DataType t)
|
||||
: PortMatrix (s, t)
|
||||
{
|
||||
setup ();
|
||||
setup_all_ports ();
|
||||
}
|
||||
|
||||
void
|
||||
GlobalPortMatrix::setup ()
|
||||
GlobalPortMatrix::setup_ports (int dim)
|
||||
{
|
||||
_ports[IN].gather (_session, true);
|
||||
_ports[OUT].gather (_session, false);
|
||||
|
||||
PortMatrix::setup ();
|
||||
_ports[dim].suspend_signals ();
|
||||
_ports[dim].gather (_session, dim == IN);
|
||||
_ports[dim].resume_signals ();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -70,12 +69,14 @@ GlobalPortMatrix::set_state (ARDOUR::BundleChannel c[2], bool s)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
PortMatrix::State
|
||||
GlobalPortMatrix::get_state (ARDOUR::BundleChannel c[2]) const
|
||||
{
|
||||
ARDOUR::Bundle::PortList const & in_ports = c[IN].bundle->channel_ports (c[IN].channel);
|
||||
ARDOUR::Bundle::PortList const & out_ports = c[OUT].bundle->channel_ports (c[OUT].channel);
|
||||
if (in_ports.empty() || out_ports.empty()) {
|
||||
return NOT_ASSOCIATED;
|
||||
}
|
||||
|
||||
for (ARDOUR::Bundle::PortList::const_iterator i = in_ports.begin(); i != in_ports.end(); ++i) {
|
||||
for (ARDOUR::Bundle::PortList::const_iterator j = out_ports.begin(); j != out_ports.end(); ++j) {
|
||||
|
|
|
@ -29,7 +29,7 @@ class GlobalPortMatrix : public PortMatrix
|
|||
public:
|
||||
GlobalPortMatrix (ARDOUR::Session&, ARDOUR::DataType);
|
||||
|
||||
void setup ();
|
||||
void setup_ports (int);
|
||||
|
||||
void set_state (ARDOUR::BundleChannel c[2], bool);
|
||||
State get_state (ARDOUR::BundleChannel c[2]) const;
|
||||
|
@ -43,6 +43,10 @@ public:
|
|||
return false;
|
||||
}
|
||||
|
||||
bool list_is_global (int) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
/* see PortMatrix: signal flow from 0 to 1 (out to in) */
|
||||
enum {
|
||||
|
|
|
@ -46,9 +46,6 @@ IOSelector::IOSelector (ARDOUR::Session& session, boost::shared_ptr<ARDOUR::IO>
|
|||
, _io (io)
|
||||
, _find_inputs_for_io_outputs (in)
|
||||
{
|
||||
/* Listen for ports changing on the IO */
|
||||
_io->PortCountChanged.connect (sigc::hide (mem_fun (*this, &IOSelector::ports_changed)));
|
||||
|
||||
/* signal flow from 0 to 1 */
|
||||
if (_find_inputs_for_io_outputs) {
|
||||
_other = 1;
|
||||
|
@ -61,54 +58,27 @@ IOSelector::IOSelector (ARDOUR::Session& session, boost::shared_ptr<ARDOUR::IO>
|
|||
_port_group = boost::shared_ptr<PortGroup> (new PortGroup (""));
|
||||
_ports[_ours].add_group (_port_group);
|
||||
|
||||
setup ();
|
||||
setup_all_ports ();
|
||||
}
|
||||
|
||||
void
|
||||
IOSelector::setup ()
|
||||
IOSelector::setup_ports (int dim)
|
||||
{
|
||||
_ports[_other].gather (_session, _find_inputs_for_io_outputs);
|
||||
|
||||
_port_group->clear ();
|
||||
_port_group->add_bundle (boost::shared_ptr<ARDOUR::Bundle> (new ARDOUR::Bundle));
|
||||
_port_group->only_bundle()->set_name (_io->name());
|
||||
_ports[dim].suspend_signals ();
|
||||
|
||||
if (_find_inputs_for_io_outputs) {
|
||||
const PortSet& ps (_io->outputs());
|
||||
if (dim == _other) {
|
||||
|
||||
int j = 0;
|
||||
for (PortSet::const_iterator i = ps.begin(); i != ps.end(); ++i) {
|
||||
char buf[32];
|
||||
snprintf (buf, sizeof(buf), _("out %d"), j + 1);
|
||||
_port_group->only_bundle()->add_channel (buf);
|
||||
_port_group->only_bundle()->add_port_to_channel (j, _session.engine().make_port_name_non_relative (i->name()));
|
||||
++j;
|
||||
}
|
||||
_ports[_other].gather (_session, _find_inputs_for_io_outputs);
|
||||
|
||||
} else {
|
||||
|
||||
const PortSet& ps (_io->inputs());
|
||||
|
||||
int j = 0;
|
||||
for (PortSet::const_iterator i = ps.begin(); i != ps.end(); ++i) {
|
||||
char buf[32];
|
||||
snprintf (buf, sizeof(buf), _("in %d"), j + 1);
|
||||
_port_group->only_bundle()->add_channel (buf);
|
||||
_port_group->only_bundle()->add_port_to_channel (j, _session.engine().make_port_name_non_relative (i->name()));
|
||||
++j;
|
||||
}
|
||||
|
||||
_port_group->clear ();
|
||||
_port_group->add_bundle (
|
||||
_find_inputs_for_io_outputs ? _io->bundle_for_outputs() : _io->bundle_for_inputs()
|
||||
);
|
||||
}
|
||||
|
||||
PortMatrix::setup ();
|
||||
}
|
||||
|
||||
void
|
||||
IOSelector::ports_changed ()
|
||||
{
|
||||
ENSURE_GUI_THREAD (mem_fun (*this, &IOSelector::ports_changed));
|
||||
|
||||
setup ();
|
||||
_ports[dim].resume_signals ();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -245,6 +215,12 @@ IOSelector::remove_channel (ARDOUR::BundleChannel bc)
|
|||
}
|
||||
}
|
||||
|
||||
bool
|
||||
IOSelector::list_is_global (int dim) const
|
||||
{
|
||||
return (dim == _other);
|
||||
}
|
||||
|
||||
IOSelectorWindow::IOSelectorWindow (ARDOUR::Session& session, boost::shared_ptr<ARDOUR::IO> io, bool for_input, bool can_cancel)
|
||||
: ArdourDialog ("I/O selector")
|
||||
, _selector (session, io, !for_input)
|
||||
|
@ -277,7 +253,7 @@ IOSelectorWindow::IOSelectorWindow (ARDOUR::Session& session, boost::shared_ptr<
|
|||
/* Rescan button */
|
||||
rescan_button.set_name ("IOSelectorButton");
|
||||
rescan_button.set_image (*Gtk::manage (new Gtk::Image (Gtk::Stock::REFRESH, Gtk::ICON_SIZE_BUTTON)));
|
||||
rescan_button.signal_clicked().connect (sigc::mem_fun (_selector, &IOSelector::setup));
|
||||
rescan_button.signal_clicked().connect (sigc::mem_fun (*this, &IOSelectorWindow::rescan));
|
||||
get_action_area()->pack_start (rescan_button, false, false);
|
||||
|
||||
io->PortCountChanged.connect (sigc::hide (mem_fun (*this, &IOSelectorWindow::ports_changed)));
|
||||
|
@ -324,6 +300,12 @@ IOSelectorWindow::ports_changed ()
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
IOSelectorWindow::rescan ()
|
||||
{
|
||||
_selector.setup_ports (_selector.other());
|
||||
}
|
||||
|
||||
void
|
||||
IOSelectorWindow::cancel ()
|
||||
{
|
||||
|
@ -341,7 +323,7 @@ IOSelectorWindow::accept ()
|
|||
void
|
||||
IOSelectorWindow::on_map ()
|
||||
{
|
||||
_selector.setup ();
|
||||
_selector.setup_all_ports ();
|
||||
Window::on_map ();
|
||||
}
|
||||
|
||||
|
@ -372,8 +354,8 @@ PortInsertUI::PortInsertUI (ARDOUR::Session& sess, boost::shared_ptr<ARDOUR::Por
|
|||
void
|
||||
PortInsertUI::redisplay ()
|
||||
{
|
||||
input_selector.setup ();
|
||||
output_selector.setup ();
|
||||
input_selector.setup_ports (input_selector.other());
|
||||
output_selector.setup_ports (output_selector.other());
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -454,3 +436,4 @@ PortInsertWindow::accept ()
|
|||
_portinsertui.finished (IOSelector::Accepted);
|
||||
hide ();
|
||||
}
|
||||
|
||||
|
|
|
@ -48,22 +48,29 @@ class IOSelector : public PortMatrix
|
|||
uint32_t maximum_io_ports () const;
|
||||
uint32_t minimum_io_ports () const;
|
||||
boost::shared_ptr<ARDOUR::IO> const io () { return _io; }
|
||||
void setup ();
|
||||
void setup_ports (int);
|
||||
bool list_is_global (int) const;
|
||||
|
||||
bool find_inputs_for_io_outputs () const {
|
||||
return _find_inputs_for_io_outputs;
|
||||
}
|
||||
|
||||
int ours () const {
|
||||
return _ours;
|
||||
}
|
||||
|
||||
int other () const {
|
||||
return _other;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
|
||||
int _other;
|
||||
int _ours;
|
||||
|
||||
boost::shared_ptr<ARDOUR::IO> _io;
|
||||
boost::shared_ptr<PortGroup> _port_group;
|
||||
bool _find_inputs_for_io_outputs;
|
||||
|
||||
void ports_changed ();
|
||||
};
|
||||
|
||||
class IOSelectorWindow : public ArdourDialog
|
||||
|
@ -89,7 +96,8 @@ class IOSelectorWindow : public ArdourDialog
|
|||
|
||||
void cancel ();
|
||||
void accept ();
|
||||
|
||||
void rescan ();
|
||||
|
||||
void ports_changed ();
|
||||
void io_name_changed (void *src);
|
||||
};
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "ardour/audio_track.h"
|
||||
#include "ardour/audioengine.h"
|
||||
#include "ardour/bundle.h"
|
||||
#include "ardour/user_bundle.h"
|
||||
#include "ardour/io_processor.h"
|
||||
#include "ardour/midi_track.h"
|
||||
#include "ardour/port.h"
|
||||
|
@ -36,6 +37,15 @@
|
|||
using namespace std;
|
||||
using namespace Gtk;
|
||||
|
||||
/** PortGroup constructor.
|
||||
* @param n Name.
|
||||
*/
|
||||
PortGroup::PortGroup (std::string const & n)
|
||||
: name (n), _visible (true)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/** Add a bundle to a group.
|
||||
* @param b Bundle.
|
||||
*/
|
||||
|
@ -45,25 +55,47 @@ PortGroup::add_bundle (boost::shared_ptr<ARDOUR::Bundle> b)
|
|||
assert (b.get());
|
||||
_bundles.push_back (b);
|
||||
|
||||
_bundle_changed_connections[b] =
|
||||
b->Changed.connect (sigc::mem_fun (*this, &PortGroup::bundle_changed));
|
||||
|
||||
Modified ();
|
||||
}
|
||||
|
||||
/** Add a port to a group.
|
||||
* @param p Port.
|
||||
*/
|
||||
void
|
||||
PortGroup::add_port (std::string const &p)
|
||||
PortGroup::remove_bundle (boost::shared_ptr<ARDOUR::Bundle> b)
|
||||
{
|
||||
ports.push_back (p);
|
||||
assert (b.get());
|
||||
|
||||
ARDOUR::BundleList::iterator i = std::find (_bundles.begin(), _bundles.end(), b);
|
||||
if (i == _bundles.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
_bundles.erase (i);
|
||||
_bundle_changed_connections[b].disconnect ();
|
||||
|
||||
Modified ();
|
||||
}
|
||||
|
||||
void
|
||||
PortGroup::bundle_changed (ARDOUR::Bundle::Change c)
|
||||
{
|
||||
BundleChanged (c);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PortGroup::clear ()
|
||||
{
|
||||
_bundles.clear ();
|
||||
ports.clear ();
|
||||
|
||||
for (ConnectionList::iterator i = _bundle_changed_connections.begin(); i != _bundle_changed_connections.end(); ++i) {
|
||||
|
||||
i->second.disconnect ();
|
||||
|
||||
}
|
||||
|
||||
_bundle_changed_connections.clear ();
|
||||
|
||||
Modified ();
|
||||
}
|
||||
|
@ -77,12 +109,6 @@ PortGroup::has_port (std::string const& p) const
|
|||
}
|
||||
}
|
||||
|
||||
for (vector<std::string>::const_iterator i = ports.begin(); i != ports.end(); ++i) {
|
||||
if (*i == p) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -95,15 +121,13 @@ PortGroup::only_bundle ()
|
|||
|
||||
|
||||
uint32_t
|
||||
PortGroup::total_ports () const
|
||||
PortGroup::total_channels () const
|
||||
{
|
||||
uint32_t n = 0;
|
||||
for (ARDOUR::BundleList::const_iterator i = _bundles.begin(); i != _bundles.end(); ++i) {
|
||||
n += (*i)->nchannels ();
|
||||
}
|
||||
|
||||
n += ports.size();
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
|
@ -111,7 +135,7 @@ PortGroup::total_ports () const
|
|||
/** PortGroupList constructor.
|
||||
*/
|
||||
PortGroupList::PortGroupList ()
|
||||
: _type (ARDOUR::DataType::AUDIO), _bundles_dirty (true)
|
||||
: _type (ARDOUR::DataType::AUDIO), _signals_suspended (false), _pending_change (false)
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -134,20 +158,20 @@ PortGroupList::gather (ARDOUR::Session& session, bool inputs)
|
|||
boost::shared_ptr<PortGroup> system (new PortGroup (_("System")));
|
||||
boost::shared_ptr<PortGroup> other (new PortGroup (_("Other")));
|
||||
|
||||
/* Find the bundles for routes. We take their bundles, copy them,
|
||||
and add ports from the route's processors */
|
||||
/* Find the bundles for routes. We use the RouteBundle class to join
|
||||
the route's IO bundles and processor bundles together so that they
|
||||
are presented as one bundle in the matrix. */
|
||||
|
||||
boost::shared_ptr<ARDOUR::RouteList> routes = session.get_routes ();
|
||||
|
||||
for (ARDOUR::RouteList::const_iterator i = routes->begin(); i != routes->end(); ++i) {
|
||||
/* Copy the appropriate bundle from the route */
|
||||
boost::shared_ptr<ARDOUR::Bundle> bundle (
|
||||
new ARDOUR::Bundle (
|
||||
inputs ? (*i)->bundle_for_inputs() : (*i)->bundle_for_outputs ()
|
||||
|
||||
boost::shared_ptr<RouteBundle> rb (
|
||||
new RouteBundle (
|
||||
inputs ? (*i)->bundle_for_inputs() : (*i)->bundle_for_outputs()
|
||||
)
|
||||
);
|
||||
|
||||
/* Add ports from the route's processors */
|
||||
uint32_t n = 0;
|
||||
while (1) {
|
||||
boost::shared_ptr<ARDOUR::Processor> p = (*i)->nth_processor (n);
|
||||
|
@ -158,9 +182,10 @@ PortGroupList::gather (ARDOUR::Session& session, bool inputs)
|
|||
boost::shared_ptr<ARDOUR::IOProcessor> iop = boost::dynamic_pointer_cast<ARDOUR::IOProcessor> (p);
|
||||
|
||||
if (iop) {
|
||||
boost::shared_ptr<ARDOUR::Bundle> pb = inputs ?
|
||||
iop->io()->bundle_for_inputs() : iop->io()->bundle_for_outputs();
|
||||
bundle->add_channels_from_bundle (pb);
|
||||
rb->add_processor_bundle (
|
||||
inputs ? iop->io()->bundle_for_inputs() : iop->io()->bundle_for_outputs()
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
++n;
|
||||
|
@ -187,22 +212,29 @@ PortGroupList::gather (ARDOUR::Session& session, bool inputs)
|
|||
}
|
||||
|
||||
if (g) {
|
||||
g->add_bundle (bundle);
|
||||
g->add_bundle (rb);
|
||||
}
|
||||
}
|
||||
|
||||
/* Bundles created by the session. We only add the mono ones,
|
||||
/* Bundles owned by the session. We only add the mono ones and the User ones
|
||||
otherwise there is duplication of the same ports within the matrix */
|
||||
|
||||
boost::shared_ptr<ARDOUR::BundleList> b = session.bundles ();
|
||||
for (ARDOUR::BundleList::iterator i = b->begin(); i != b->end(); ++i) {
|
||||
if ((*i)->nchannels() == 1 && (*i)->ports_are_inputs() == inputs && (*i)->type() == _type) {
|
||||
system->add_bundle (*i);
|
||||
if ((*i)->ports_are_inputs() == inputs && (*i)->type() == _type) {
|
||||
|
||||
if ((*i)->nchannels() == 1 || boost::dynamic_pointer_cast<ARDOUR::UserBundle> (*i)) {
|
||||
system->add_bundle (*i);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/* Now find all other ports that we haven't thought of yet */
|
||||
|
||||
std::vector<std::string> extra_system;
|
||||
std::vector<std::string> extra_other;
|
||||
|
||||
const char **ports = session.engine().get_ports ("", _type.to_jack_type(), inputs ?
|
||||
JackPortIsInput : JackPortIsOutput);
|
||||
if (ports) {
|
||||
|
@ -222,9 +254,9 @@ PortGroupList::gather (ARDOUR::Session& session, bool inputs)
|
|||
if (port_has_prefix (p, "system:") ||
|
||||
port_has_prefix (p, "alsa_pcm") ||
|
||||
port_has_prefix (p, "ardour:")) {
|
||||
system->add_port (p);
|
||||
extra_system.push_back (p);
|
||||
} else {
|
||||
other->add_port (p);
|
||||
extra_other.push_back (p);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -234,12 +266,38 @@ PortGroupList::gather (ARDOUR::Session& session, bool inputs)
|
|||
free (ports);
|
||||
}
|
||||
|
||||
if (!extra_system.empty()) {
|
||||
system->add_bundle (make_bundle_from_ports (extra_system, inputs));
|
||||
}
|
||||
|
||||
if (!extra_other.empty()) {
|
||||
other->add_bundle (make_bundle_from_ports (extra_other, inputs));
|
||||
}
|
||||
|
||||
add_group (system);
|
||||
add_group (bus);
|
||||
add_group (track);
|
||||
add_group (other);
|
||||
|
||||
_bundles_dirty = true;
|
||||
emit_changed ();
|
||||
}
|
||||
|
||||
boost::shared_ptr<ARDOUR::Bundle>
|
||||
PortGroupList::make_bundle_from_ports (std::vector<std::string> const & p, bool inputs) const
|
||||
{
|
||||
boost::shared_ptr<ARDOUR::Bundle> b (new ARDOUR::Bundle ("", _type, inputs));
|
||||
|
||||
std::string const pre = common_prefix (p);
|
||||
if (!pre.empty()) {
|
||||
b->set_name (pre.substr (0, pre.length() - 1));
|
||||
}
|
||||
|
||||
for (uint32_t j = 0; j < p.size(); ++j) {
|
||||
b->add_channel (p[j].substr (pre.length()));
|
||||
b->set_port (j, p[j]);
|
||||
}
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -247,75 +305,47 @@ PortGroupList::port_has_prefix (const std::string& n, const std::string& p) cons
|
|||
{
|
||||
return n.substr (0, p.length()) == p;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PortGroupList::update_bundles () const
|
||||
std::string
|
||||
PortGroupList::common_prefix_before (std::vector<std::string> const & p, std::string const & s) const
|
||||
{
|
||||
_bundles.clear ();
|
||||
|
||||
for (PortGroupList::List::const_iterator i = begin (); i != end (); ++i) {
|
||||
if ((*i)->visible()) {
|
||||
|
||||
std::copy ((*i)->bundles().begin(), (*i)->bundles().end(), std::back_inserter (_bundles));
|
||||
|
||||
/* make a bundle for the ports, if there are any */
|
||||
if (!(*i)->ports.empty()) {
|
||||
|
||||
boost::shared_ptr<ARDOUR::Bundle> b (new ARDOUR::Bundle ("", _type, !_offer_inputs));
|
||||
|
||||
std::string const pre = common_prefix ((*i)->ports);
|
||||
if (!pre.empty()) {
|
||||
b->set_name (pre.substr (0, pre.length() - 1));
|
||||
}
|
||||
|
||||
for (uint32_t j = 0; j < (*i)->ports.size(); ++j) {
|
||||
std::string const p = (*i)->ports[j];
|
||||
b->add_channel (p.substr (pre.length()));
|
||||
b->set_port (j, p);
|
||||
}
|
||||
|
||||
_bundles.push_back (b);
|
||||
}
|
||||
}
|
||||
/* we must have some strings and the first must contain the separator string */
|
||||
if (p.empty() || p[0].find_first_of (s) == std::string::npos) {
|
||||
return "";
|
||||
}
|
||||
|
||||
_bundles_dirty = false;
|
||||
/* prefix of the first string */
|
||||
std::string const fp = p[0].substr (0, p[0].find_first_of (s) + 1);
|
||||
|
||||
/* see if the other strings also start with fp */
|
||||
uint32_t j = 1;
|
||||
while (j < p.size()) {
|
||||
if (p[j].substr (0, fp.length()) != fp) {
|
||||
break;
|
||||
}
|
||||
++j;
|
||||
}
|
||||
|
||||
if (j != p.size()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return fp;
|
||||
}
|
||||
|
||||
|
||||
std::string
|
||||
PortGroupList::common_prefix (std::vector<std::string> const & p) const
|
||||
{
|
||||
/* common prefix before '/' ? */
|
||||
if (p[0].find_first_of ("/") != std::string::npos) {
|
||||
std::string const fp = p[0].substr (0, (p[0].find_first_of ("/") + 1));
|
||||
uint32_t j = 1;
|
||||
while (j < p.size()) {
|
||||
if (p[j].substr (0, fp.length()) != fp) {
|
||||
break;
|
||||
}
|
||||
++j;
|
||||
}
|
||||
|
||||
if (j == p.size()) {
|
||||
return fp;
|
||||
}
|
||||
std::string cp = common_prefix_before (p, "/");
|
||||
if (!cp.empty()) {
|
||||
return cp;
|
||||
}
|
||||
|
||||
/* or before ':' ? */
|
||||
if (p[0].find_first_of (":") != std::string::npos) {
|
||||
std::string const fp = p[0].substr (0, (p[0].find_first_of (":") + 1));
|
||||
uint32_t j = 1;
|
||||
while (j < p.size()) {
|
||||
if (p[j].substr (0, fp.length()) != fp) {
|
||||
break;
|
||||
}
|
||||
++j;
|
||||
}
|
||||
|
||||
if (j == p.size()) {
|
||||
return fp;
|
||||
}
|
||||
|
||||
cp = common_prefix_before (p, ":");
|
||||
if (!cp.empty()) {
|
||||
return cp;
|
||||
}
|
||||
|
||||
return "";
|
||||
|
@ -325,43 +355,134 @@ void
|
|||
PortGroupList::clear ()
|
||||
{
|
||||
_groups.clear ();
|
||||
_bundles_dirty = true;
|
||||
|
||||
for (std::vector<sigc::connection>::iterator i = _bundle_changed_connections.begin(); i != _bundle_changed_connections.end(); ++i) {
|
||||
i->disconnect ();
|
||||
}
|
||||
|
||||
_bundle_changed_connections.clear ();
|
||||
|
||||
emit_changed ();
|
||||
}
|
||||
|
||||
|
||||
ARDOUR::BundleList const &
|
||||
PortGroupList::bundles () const
|
||||
{
|
||||
if (_bundles_dirty) {
|
||||
update_bundles ();
|
||||
_bundles.clear ();
|
||||
|
||||
for (PortGroupList::List::const_iterator i = begin (); i != end (); ++i) {
|
||||
if ((*i)->visible()) {
|
||||
std::copy ((*i)->bundles().begin(), (*i)->bundles().end(), std::back_inserter (_bundles));
|
||||
}
|
||||
}
|
||||
|
||||
return _bundles;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
PortGroupList::total_visible_ports () const
|
||||
PortGroupList::total_visible_channels () const
|
||||
{
|
||||
uint32_t n = 0;
|
||||
|
||||
for (PortGroupList::List::const_iterator i = begin(); i != end(); ++i) {
|
||||
if ((*i)->visible()) {
|
||||
n += (*i)->total_ports ();
|
||||
n += (*i)->total_channels ();
|
||||
}
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
void
|
||||
PortGroupList::group_modified ()
|
||||
{
|
||||
_bundles_dirty = true;
|
||||
}
|
||||
|
||||
void
|
||||
PortGroupList::add_group (boost::shared_ptr<PortGroup> g)
|
||||
{
|
||||
_groups.push_back (g);
|
||||
g->Modified.connect (sigc::mem_fun (*this, &PortGroupList::group_modified));
|
||||
_bundles_dirty = true;
|
||||
|
||||
g->Modified.connect (sigc::mem_fun (*this, &PortGroupList::emit_changed));
|
||||
|
||||
_bundle_changed_connections.push_back (
|
||||
g->BundleChanged.connect (sigc::hide (sigc::mem_fun (*this, &PortGroupList::emit_changed)))
|
||||
);
|
||||
|
||||
emit_changed ();
|
||||
}
|
||||
|
||||
void
|
||||
PortGroupList::remove_bundle (boost::shared_ptr<ARDOUR::Bundle> b)
|
||||
{
|
||||
for (List::iterator i = _groups.begin(); i != _groups.end(); ++i) {
|
||||
(*i)->remove_bundle (b);
|
||||
}
|
||||
|
||||
emit_changed ();
|
||||
}
|
||||
|
||||
void
|
||||
PortGroupList::emit_changed ()
|
||||
{
|
||||
if (_signals_suspended) {
|
||||
_pending_change = true;
|
||||
} else {
|
||||
Changed ();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PortGroupList::suspend_signals ()
|
||||
{
|
||||
_signals_suspended = true;
|
||||
}
|
||||
|
||||
void
|
||||
PortGroupList::resume_signals ()
|
||||
{
|
||||
if (_pending_change) {
|
||||
Changed ();
|
||||
_pending_change = false;
|
||||
}
|
||||
|
||||
_signals_suspended = false;
|
||||
}
|
||||
|
||||
RouteBundle::RouteBundle (boost::shared_ptr<ARDOUR::Bundle> r)
|
||||
: _route (r)
|
||||
{
|
||||
_route->Changed.connect (sigc::hide (sigc::mem_fun (*this, &RouteBundle::reread_component_bundles)));
|
||||
reread_component_bundles ();
|
||||
}
|
||||
|
||||
void
|
||||
RouteBundle::reread_component_bundles ()
|
||||
{
|
||||
suspend_signals ();
|
||||
|
||||
remove_channels ();
|
||||
|
||||
set_name (_route->name());
|
||||
|
||||
for (uint32_t i = 0; i < _route->nchannels(); ++i) {
|
||||
add_channel (_route->channel_name (i));
|
||||
PortList const & pl = _route->channel_ports (i);
|
||||
for (uint32_t j = 0; j < pl.size(); ++j) {
|
||||
add_port_to_channel (i, pl[j]);
|
||||
}
|
||||
}
|
||||
|
||||
for (std::vector<boost::shared_ptr<ARDOUR::Bundle> >::iterator i = _processor.begin(); i != _processor.end(); ++i) {
|
||||
add_channels_from_bundle (*i);
|
||||
}
|
||||
|
||||
resume_signals ();
|
||||
}
|
||||
|
||||
void
|
||||
RouteBundle::add_processor_bundle (boost::shared_ptr<ARDOUR::Bundle> p)
|
||||
{
|
||||
p->Changed.connect (sigc::hide (sigc::mem_fun (*this, &RouteBundle::reread_component_bundles)));
|
||||
_processor.push_back (p);
|
||||
|
||||
reread_component_bundles ();
|
||||
}
|
||||
|
||||
|
|
|
@ -42,20 +42,15 @@ class PortMatrix;
|
|||
class PortGroup : public sigc::trackable
|
||||
{
|
||||
public:
|
||||
/** PortGroup constructor.
|
||||
* @param n Name.
|
||||
*/
|
||||
PortGroup (std::string const & n)
|
||||
: name (n), _visible (true) {}
|
||||
PortGroup (std::string const & n);
|
||||
|
||||
void add_bundle (boost::shared_ptr<ARDOUR::Bundle>);
|
||||
void remove_bundle (boost::shared_ptr<ARDOUR::Bundle>);
|
||||
boost::shared_ptr<ARDOUR::Bundle> only_bundle ();
|
||||
void add_port (std::string const &);
|
||||
void clear ();
|
||||
uint32_t total_ports () const;
|
||||
uint32_t total_channels () const;
|
||||
|
||||
std::string name; ///< name for the group
|
||||
std::vector<std::string> ports;
|
||||
|
||||
ARDOUR::BundleList const & bundles () const {
|
||||
return _bundles;
|
||||
|
@ -73,14 +68,21 @@ public:
|
|||
bool has_port (std::string const &) const;
|
||||
|
||||
sigc::signal<void> Modified;
|
||||
sigc::signal<void, ARDOUR::Bundle::Change> BundleChanged;
|
||||
|
||||
private:
|
||||
private:
|
||||
void bundle_changed (ARDOUR::Bundle::Change);
|
||||
|
||||
ARDOUR::BundleList _bundles;
|
||||
|
||||
typedef std::map<boost::shared_ptr<ARDOUR::Bundle>, sigc::connection> ConnectionList;
|
||||
ConnectionList _bundle_changed_connections;
|
||||
|
||||
bool _visible; ///< true if the group is visible in the UI
|
||||
};
|
||||
|
||||
/// A list of PortGroups
|
||||
class PortGroupList
|
||||
class PortGroupList : public sigc::trackable
|
||||
{
|
||||
public:
|
||||
PortGroupList ();
|
||||
|
@ -90,14 +92,17 @@ class PortGroupList
|
|||
void add_group (boost::shared_ptr<PortGroup>);
|
||||
void set_type (ARDOUR::DataType);
|
||||
void gather (ARDOUR::Session &, bool);
|
||||
void set_offer_inputs (bool);
|
||||
ARDOUR::BundleList const & bundles () const;
|
||||
void clear ();
|
||||
uint32_t total_visible_ports () const;
|
||||
void remove_bundle (boost::shared_ptr<ARDOUR::Bundle>);
|
||||
uint32_t total_visible_channels () const;
|
||||
uint32_t size () const {
|
||||
return _groups.size();
|
||||
}
|
||||
|
||||
void suspend_signals ();
|
||||
void resume_signals ();
|
||||
|
||||
List::const_iterator begin () const {
|
||||
return _groups.begin();
|
||||
}
|
||||
|
@ -105,18 +110,37 @@ class PortGroupList
|
|||
List::const_iterator end () const {
|
||||
return _groups.end();
|
||||
}
|
||||
|
||||
|
||||
sigc::signal<void> Changed;
|
||||
|
||||
private:
|
||||
bool port_has_prefix (std::string const &, std::string const &) const;
|
||||
std::string common_prefix (std::vector<std::string> const &) const;
|
||||
void update_bundles () const;
|
||||
void group_modified ();
|
||||
std::string common_prefix_before (std::vector<std::string> const &, std::string const &) const;
|
||||
void emit_changed ();
|
||||
boost::shared_ptr<ARDOUR::Bundle> make_bundle_from_ports (std::vector<std::string> const &, bool) const;
|
||||
|
||||
ARDOUR::DataType _type;
|
||||
bool _offer_inputs;
|
||||
mutable ARDOUR::BundleList _bundles;
|
||||
mutable bool _bundles_dirty;
|
||||
List _groups;
|
||||
std::vector<sigc::connection> _bundle_changed_connections;
|
||||
bool _signals_suspended;
|
||||
bool _pending_change;
|
||||
};
|
||||
|
||||
|
||||
class RouteBundle : public ARDOUR::Bundle
|
||||
{
|
||||
public:
|
||||
RouteBundle (boost::shared_ptr<ARDOUR::Bundle>);
|
||||
|
||||
void add_processor_bundle (boost::shared_ptr<ARDOUR::Bundle>);
|
||||
|
||||
private:
|
||||
void reread_component_bundles ();
|
||||
|
||||
boost::shared_ptr<ARDOUR::Bundle> _route;
|
||||
std::vector<boost::shared_ptr<ARDOUR::Bundle> > _processor;
|
||||
};
|
||||
|
||||
#endif /* __gtk_ardour_port_group_h__ */
|
||||
|
|
|
@ -48,9 +48,13 @@ PortMatrix::PortMatrix (ARDOUR::Session& session, ARDOUR::DataType type)
|
|||
_column_index (1)
|
||||
{
|
||||
_body = new PortMatrixBody (this);
|
||||
|
||||
_ports[0].set_type (type);
|
||||
_ports[1].set_type (type);
|
||||
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
_ports[i].set_type (type);
|
||||
|
||||
/* watch for the content of _ports[] changing */
|
||||
_ports[i].Changed.connect (sigc::mem_fun (*this, &PortMatrix::setup));
|
||||
}
|
||||
|
||||
_row_visibility_box.pack_start (_row_visibility_label, Gtk::PACK_SHRINK);
|
||||
_column_visibility_box.pack_start (_column_visibility_label, Gtk::PACK_SHRINK);
|
||||
|
@ -60,6 +64,9 @@ PortMatrix::PortMatrix (ARDOUR::Session& session, ARDOUR::DataType type)
|
|||
|
||||
/* watch for routes being added or removed */
|
||||
_session.RouteAdded.connect (sigc::hide (sigc::mem_fun (*this, &PortMatrix::routes_changed)));
|
||||
|
||||
/* and also bundles */
|
||||
_session.BundleAdded.connect (sigc::hide (sigc::mem_fun (*this, &PortMatrix::setup_global_ports)));
|
||||
|
||||
reconnect_to_routes ();
|
||||
|
||||
|
@ -93,7 +100,7 @@ PortMatrix::reconnect_to_routes ()
|
|||
boost::shared_ptr<ARDOUR::RouteList> routes = _session.get_routes ();
|
||||
for (ARDOUR::RouteList::iterator i = routes->begin(); i != routes->end(); ++i) {
|
||||
_route_connections.push_back (
|
||||
(*i)->processors_changed.connect (sigc::mem_fun (*this, &PortMatrix::setup))
|
||||
(*i)->processors_changed.connect (sigc::mem_fun (*this, &PortMatrix::setup_global_ports))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -103,10 +110,10 @@ void
|
|||
PortMatrix::routes_changed ()
|
||||
{
|
||||
reconnect_to_routes ();
|
||||
setup ();
|
||||
setup_global_ports ();
|
||||
}
|
||||
|
||||
/** Set up everything that changes about the matrix */
|
||||
/** Set up everything that depends on the content of _ports[] */
|
||||
void
|
||||
PortMatrix::setup ()
|
||||
{
|
||||
|
@ -235,7 +242,8 @@ PortMatrix::set_type (ARDOUR::DataType t)
|
|||
_type = t;
|
||||
_ports[0].set_type (_type);
|
||||
_ports[1].set_type (_type);
|
||||
setup ();
|
||||
|
||||
setup_all_ports ();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -300,11 +308,11 @@ void
|
|||
PortMatrix::select_arrangement ()
|
||||
{
|
||||
uint32_t const N[2] = {
|
||||
_ports[0].total_visible_ports (),
|
||||
_ports[1].total_visible_ports ()
|
||||
_ports[0].total_visible_channels (),
|
||||
_ports[1].total_visible_channels ()
|
||||
};
|
||||
|
||||
/* The list with the most ports goes on left or right, so that the most port
|
||||
/* The list with the most channels goes on left or right, so that the most channel
|
||||
names are printed horizontally and hence more readable. However we also
|
||||
maintain notional `signal flow' vaguely from left to right. Subclasses
|
||||
should choose where to put ports based on signal flowing from _ports[0]
|
||||
|
@ -380,6 +388,7 @@ PortMatrix::popup_channel_context_menu (int dim, uint32_t N, uint32_t t)
|
|||
|
||||
if (bc.bundle) {
|
||||
char buf [64];
|
||||
bool have_one = false;
|
||||
|
||||
if (can_rename_channels (dim)) {
|
||||
snprintf (buf, sizeof (buf), _("Rename '%s'..."), bc.bundle->channel_name (bc.channel).c_str());
|
||||
|
@ -390,6 +399,8 @@ PortMatrix::popup_channel_context_menu (int dim, uint32_t N, uint32_t t)
|
|||
sigc::bind (sigc::mem_fun (*this, &PortMatrix::rename_channel_proxy), w, bc.channel)
|
||||
)
|
||||
);
|
||||
|
||||
have_one = true;
|
||||
}
|
||||
|
||||
if (can_remove_channels (dim)) {
|
||||
|
@ -401,7 +412,20 @@ PortMatrix::popup_channel_context_menu (int dim, uint32_t N, uint32_t t)
|
|||
sigc::bind (sigc::mem_fun (*this, &PortMatrix::remove_channel_proxy), w, bc.channel)
|
||||
)
|
||||
);
|
||||
|
||||
have_one = true;
|
||||
}
|
||||
|
||||
if (have_one) {
|
||||
items.push_back (Gtk::Menu_Helpers::SeparatorElem ());
|
||||
}
|
||||
|
||||
boost::weak_ptr<ARDOUR::Bundle> w (bc.bundle);
|
||||
items.push_back (Gtk::Menu_Helpers::MenuElem (
|
||||
_("Disassociate all"),
|
||||
sigc::bind (sigc::mem_fun (*this, &PortMatrix::disassociate_all_on_channel), w, bc.channel, dim)
|
||||
)
|
||||
);
|
||||
|
||||
_menu->popup (1, t);
|
||||
}
|
||||
|
@ -431,3 +455,43 @@ PortMatrix::rename_channel_proxy (boost::weak_ptr<ARDOUR::Bundle> b, uint32_t c)
|
|||
|
||||
rename_channel (ARDOUR::BundleChannel (sb, c));
|
||||
}
|
||||
|
||||
void
|
||||
PortMatrix::disassociate_all_on_channel (boost::weak_ptr<ARDOUR::Bundle> bundle, uint32_t channel, int dim)
|
||||
{
|
||||
boost::shared_ptr<ARDOUR::Bundle> sb = bundle.lock ();
|
||||
if (!sb) {
|
||||
return;
|
||||
}
|
||||
|
||||
ARDOUR::BundleList a = _ports[1-dim].bundles ();
|
||||
|
||||
for (ARDOUR::BundleList::iterator i = a.begin(); i != a.end(); ++i) {
|
||||
for (uint32_t j = 0; j < (*i)->nchannels(); ++j) {
|
||||
|
||||
ARDOUR::BundleChannel c[2];
|
||||
c[dim] = ARDOUR::BundleChannel (sb, channel);
|
||||
c[1-dim] = ARDOUR::BundleChannel (*i, j);
|
||||
|
||||
set_state (c, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PortMatrix::setup_global_ports ()
|
||||
{
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
if (list_is_global (i)) {
|
||||
setup_ports (i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PortMatrix::setup_all_ports ()
|
||||
{
|
||||
setup_ports (0);
|
||||
setup_ports (1);
|
||||
}
|
||||
|
|
|
@ -89,7 +89,9 @@ public:
|
|||
return &_ports[d];
|
||||
}
|
||||
|
||||
virtual void setup ();
|
||||
void setup ();
|
||||
virtual void setup_ports (int) = 0;
|
||||
void setup_all_ports ();
|
||||
|
||||
/** @param c Channels; where c[0] is from _ports[0] and c[1] is from _ports[1].
|
||||
* @param s New state.
|
||||
|
@ -106,6 +108,7 @@ public:
|
|||
* @return state
|
||||
*/
|
||||
virtual State get_state (ARDOUR::BundleChannel c[2]) const = 0;
|
||||
virtual bool list_is_global (int) const = 0;
|
||||
|
||||
virtual void add_channel (boost::shared_ptr<ARDOUR::Bundle>) = 0;
|
||||
virtual bool can_remove_channels (int) const = 0;
|
||||
|
@ -141,6 +144,8 @@ private:
|
|||
void select_arrangement ();
|
||||
void remove_channel_proxy (boost::weak_ptr<ARDOUR::Bundle>, uint32_t);
|
||||
void rename_channel_proxy (boost::weak_ptr<ARDOUR::Bundle>, uint32_t);
|
||||
void disassociate_all_on_channel (boost::weak_ptr<ARDOUR::Bundle>, uint32_t, int);
|
||||
void setup_global_ports ();
|
||||
|
||||
/// port type that we are working with
|
||||
ARDOUR::DataType _type;
|
||||
|
|
|
@ -59,7 +59,7 @@ PortMatrixBody::on_expose_event (GdkEventExpose* event)
|
|||
|
||||
Gdk::Rectangle r = exposure;
|
||||
/* the get_pixmap call may cause things to be rerendered and sizes to change,
|
||||
so fetch the pixmaps before calculating where to put it */
|
||||
so fetch the pixmap before calculating where to put it */
|
||||
GdkPixmap* p = _column_labels->get_pixmap (get_window()->gobj());
|
||||
r.intersect (_column_labels->parent_rectangle(), intersects);
|
||||
|
||||
|
@ -278,7 +278,7 @@ PortMatrixBody::setup ()
|
|||
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))
|
||||
(*i)->Changed.connect (sigc::hide (sigc::mem_fun (*this, &PortMatrixBody::rebuild_and_draw_row_labels)))
|
||||
);
|
||||
|
||||
}
|
||||
|
@ -286,7 +286,7 @@ PortMatrixBody::setup ()
|
|||
ARDOUR::BundleList c = _matrix->columns()->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))
|
||||
(*i)->Changed.connect (sigc::hide (sigc::mem_fun (*this, &PortMatrixBody::rebuild_and_draw_column_labels)))
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -134,16 +134,12 @@ PortMatrixColumnLabels::render (cairo_t* cr)
|
|||
int g = 0;
|
||||
for (PortGroupList::List::const_iterator i = _matrix->columns()->begin(); i != _matrix->columns()->end(); ++i) {
|
||||
|
||||
if (!(*i)->visible() || ((*i)->bundles().empty() && (*i)->ports.empty()) ) {
|
||||
if (!(*i)->visible() || (*i)->bundles().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();
|
||||
uint32_t w = (*i)->total_channels() * column_width();
|
||||
|
||||
/* rectangle */
|
||||
set_source_rgb (cr, get_a_group_colour (g));
|
||||
|
@ -413,15 +409,14 @@ PortMatrixColumnLabels::queue_draw_for (ARDOUR::BundleChannel const & bc)
|
|||
);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PortMatrixColumnLabels::button_press (double x, double y, int b, uint32_t t)
|
||||
{
|
||||
uint32_t N = _matrix->columns()->total_visible_ports ();
|
||||
uint32_t N = _matrix->columns()->total_visible_channels ();
|
||||
uint32_t i = 0;
|
||||
for (; i < N; ++i) {
|
||||
|
||||
|
@ -453,19 +448,8 @@ PortMatrixColumnLabels::button_press (double x, double y, int b, uint32_t t)
|
|||
_body->highlight_associated_channels (_matrix->column_index(), i);
|
||||
break;
|
||||
case 3:
|
||||
maybe_popup_context_menu (i, t);
|
||||
_matrix->popup_channel_context_menu (_matrix->column_index(), i, t);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PortMatrixColumnLabels::maybe_popup_context_menu (int i, uint32_t t)
|
||||
{
|
||||
if (!_matrix->can_rename_channels (_matrix->column_index()) &&
|
||||
!_matrix->can_remove_channels (_matrix->column_index())) {
|
||||
return;
|
||||
}
|
||||
|
||||
_matrix->popup_channel_context_menu (_matrix->column_index(), i, t);
|
||||
}
|
||||
|
|
|
@ -49,7 +49,6 @@ private:
|
|||
double channel_x (ARDOUR::BundleChannel const &) const;
|
||||
double channel_y (ARDOUR::BundleChannel const &) const;
|
||||
void queue_draw_for (ARDOUR::BundleChannel const &);
|
||||
void maybe_popup_context_menu (int, uint32_t);
|
||||
|
||||
void render (cairo_t *);
|
||||
void compute_dimensions ();
|
||||
|
|
|
@ -104,16 +104,12 @@ PortMatrixRowLabels::render (cairo_t* cr)
|
|||
int g = 0;
|
||||
for (PortGroupList::List::const_iterator i = _matrix->rows()->begin(); i != _matrix->rows()->end(); ++i) {
|
||||
|
||||
if (!(*i)->visible() || ((*i)->bundles().empty() && (*i)->ports.empty()) ) {
|
||||
if (!(*i)->visible() || (*i)->bundles().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();
|
||||
double h = (*i)->total_channels () * row_height();
|
||||
|
||||
/* rectangle */
|
||||
set_source_rgb (cr, get_a_group_colour (g));
|
||||
|
@ -202,11 +198,6 @@ PortMatrixRowLabels::button_press (double x, double y, int b, uint32_t t)
|
|||
void
|
||||
PortMatrixRowLabels::maybe_popup_context_menu (double x, double y, uint32_t t)
|
||||
{
|
||||
if (!_matrix->can_rename_channels (_matrix->row_index()) &&
|
||||
!_matrix->can_remove_channels (_matrix->row_index())) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( (_matrix->arrangement() == PortMatrix::LEFT_TO_BOTTOM && x > (_longest_bundle_name + name_pad() * 2)) ||
|
||||
(_matrix->arrangement() == PortMatrix::TOP_TO_RIGHT && x < (_longest_port_name + name_pad() * 2))
|
||||
) {
|
||||
|
|
|
@ -57,24 +57,9 @@ class Bundle : public sigc::trackable
|
|||
PortList ports;
|
||||
};
|
||||
|
||||
/** Construct an audio bundle.
|
||||
* @param i true if ports are inputs, otherwise false.
|
||||
*/
|
||||
Bundle (bool i = true) : _type (DataType::AUDIO), _ports_are_inputs (i) {}
|
||||
|
||||
/** Construct an audio bundle.
|
||||
* @param n Name.
|
||||
* @param i true if ports are inputs, otherwise false.
|
||||
*/
|
||||
Bundle (std::string const & n, bool i = true) : _name (n), _type (DataType::AUDIO), _ports_are_inputs (i) {}
|
||||
|
||||
/** Construct a bundle.
|
||||
* @param n Name.
|
||||
* @param t Type.
|
||||
* @param i true if ports are inputs, otherwise false.
|
||||
*/
|
||||
Bundle (std::string const & n, DataType t, bool i = true) : _name (n), _type (t), _ports_are_inputs (i) {}
|
||||
|
||||
Bundle (bool i = true);
|
||||
Bundle (std::string const &, bool i = true);
|
||||
Bundle (std::string const &, DataType, bool i = true);
|
||||
Bundle (boost::shared_ptr<Bundle>);
|
||||
|
||||
virtual ~Bundle() {}
|
||||
|
@ -93,6 +78,8 @@ class Bundle : public sigc::trackable
|
|||
void add_port_to_channel (uint32_t, std::string);
|
||||
void set_port (uint32_t, std::string);
|
||||
void remove_port_from_channel (uint32_t, std::string);
|
||||
void remove_ports_from_channel (uint32_t);
|
||||
void remove_ports_from_channels ();
|
||||
bool port_attached_to_channel (uint32_t, std::string);
|
||||
bool uses_port (std::string) const;
|
||||
bool offers_port_alone (std::string) const;
|
||||
|
@ -107,7 +94,7 @@ class Bundle : public sigc::trackable
|
|||
*/
|
||||
void set_name (std::string const & n) {
|
||||
_name = n;
|
||||
NameChanged ();
|
||||
Changed (NameChanged);
|
||||
}
|
||||
|
||||
/** @return Bundle name */
|
||||
|
@ -126,14 +113,17 @@ class Bundle : public sigc::trackable
|
|||
bool ports_are_inputs () const { return _ports_are_inputs; }
|
||||
bool ports_are_outputs () const { return !_ports_are_inputs; }
|
||||
|
||||
bool operator== (Bundle const &) const;
|
||||
void suspend_signals ();
|
||||
void resume_signals ();
|
||||
|
||||
/** Emitted when the bundle name or a channel name has changed */
|
||||
sigc::signal<void> NameChanged;
|
||||
/** The number of channels has changed */
|
||||
sigc::signal<void> ConfigurationChanged;
|
||||
/** The port list associated with one of our channels has changed */
|
||||
sigc::signal<void, int> PortsChanged;
|
||||
/** Things that might change about this bundle */
|
||||
enum Change {
|
||||
NameChanged = 0x1, ///< the bundle name or a channel name has changed
|
||||
ConfigurationChanged = 0x2, ///< the number of channels has changed
|
||||
PortsChanged = 0x4 ///< the port list associated with one of our channels has changed
|
||||
};
|
||||
|
||||
sigc::signal<void, Change> Changed;
|
||||
|
||||
protected:
|
||||
|
||||
|
@ -145,10 +135,14 @@ class Bundle : public sigc::trackable
|
|||
private:
|
||||
int set_channels (std::string const &);
|
||||
int parse_io_string (std::string const &, std::vector<std::string> &);
|
||||
void emit_changed (Change);
|
||||
|
||||
std::string _name;
|
||||
DataType _type;
|
||||
bool _ports_are_inputs;
|
||||
|
||||
bool _signals_suspended;
|
||||
Change _pending_change;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#include <ardour/latent.h>
|
||||
#include <ardour/automation_control.h>
|
||||
#include <ardour/session_object.h>
|
||||
#include <ardour/bundle.h>
|
||||
|
||||
using std::string;
|
||||
using std::vector;
|
||||
|
@ -53,8 +54,8 @@ namespace ARDOUR {
|
|||
|
||||
class Session;
|
||||
class AudioEngine;
|
||||
class Bundle;
|
||||
class UserBundle;
|
||||
class Bundle;
|
||||
class Panner;
|
||||
class PeakMeter;
|
||||
class Port;
|
||||
|
@ -62,7 +63,6 @@ class AudioPort;
|
|||
class MidiPort;
|
||||
class BufferSet;
|
||||
|
||||
|
||||
/** A collection of input and output ports with connections.
|
||||
*
|
||||
* An IO can contain ports of varying types, making routes/inserts/etc with
|
||||
|
@ -336,8 +336,7 @@ class IO : public SessionObject, public AutomatableControls, public Latent
|
|||
UserBundleInfo (IO*, boost::shared_ptr<UserBundle> b);
|
||||
|
||||
boost::shared_ptr<UserBundle> bundle;
|
||||
sigc::connection configuration_changed;
|
||||
sigc::connection ports_changed;
|
||||
sigc::connection changed;
|
||||
};
|
||||
|
||||
std::vector<UserBundleInfo> _bundles_connected_to_outputs; ///< user bundles connected to our outputs
|
||||
|
@ -357,8 +356,7 @@ class IO : public SessionObject, public AutomatableControls, public Latent
|
|||
void check_bundles_connected_to_outputs ();
|
||||
void check_bundles (std::vector<UserBundleInfo>&, const PortSet&);
|
||||
|
||||
void bundle_configuration_changed ();
|
||||
void bundle_ports_changed (int);
|
||||
void bundle_changed (Bundle::Change);
|
||||
|
||||
int create_ports (const XMLNode&);
|
||||
int make_connections (const XMLNode&);
|
||||
|
@ -375,6 +373,8 @@ class IO : public SessionObject, public AutomatableControls, public Latent
|
|||
int32_t find_output_port_hole (const char* base);
|
||||
|
||||
void setup_bundles_for_inputs_and_outputs ();
|
||||
void setup_bundle_for_inputs ();
|
||||
void setup_bundle_for_outputs ();
|
||||
std::string bundle_channel_name (uint32_t, uint32_t) const;
|
||||
};
|
||||
|
||||
|
|
|
@ -30,11 +30,57 @@
|
|||
using namespace ARDOUR;
|
||||
using namespace PBD;
|
||||
|
||||
/** Construct an audio bundle.
|
||||
* @param i true if ports are inputs, otherwise false.
|
||||
*/
|
||||
Bundle::Bundle (bool i)
|
||||
: _type (DataType::AUDIO),
|
||||
_ports_are_inputs (i),
|
||||
_signals_suspended (false),
|
||||
_pending_change (Change (0))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
/** Construct an audio bundle.
|
||||
* @param n Name.
|
||||
* @param i true if ports are inputs, otherwise false.
|
||||
*/
|
||||
Bundle::Bundle (std::string const & n, bool i)
|
||||
: _name (n),
|
||||
_type (DataType::AUDIO),
|
||||
_ports_are_inputs (i),
|
||||
_signals_suspended (false),
|
||||
_pending_change (Change (0))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
/** Construct a bundle.
|
||||
* @param n Name.
|
||||
* @param t Type.
|
||||
* @param i true if ports are inputs, otherwise false.
|
||||
*/
|
||||
Bundle::Bundle (std::string const & n, DataType t, bool i)
|
||||
: _name (n),
|
||||
_type (t),
|
||||
_ports_are_inputs (i),
|
||||
_signals_suspended (false),
|
||||
_pending_change (Change (0))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
Bundle::Bundle (boost::shared_ptr<Bundle> other)
|
||||
: _channel (other->_channel),
|
||||
_name (other->_name),
|
||||
_type (other->_type),
|
||||
_ports_are_inputs (other->_ports_are_inputs)
|
||||
_ports_are_inputs (other->_ports_are_inputs),
|
||||
_signals_suspended (other->_signals_suspended),
|
||||
_pending_change (other->_pending_change)
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -69,8 +115,8 @@ Bundle::add_port_to_channel (uint32_t ch, string portname)
|
|||
Glib::Mutex::Lock lm (_channel_mutex);
|
||||
_channel[ch].ports.push_back (portname);
|
||||
}
|
||||
|
||||
PortsChanged (ch); /* EMIT SIGNAL */
|
||||
|
||||
emit_changed (PortsChanged);
|
||||
}
|
||||
|
||||
/** Disassociate a port from one of our channels.
|
||||
|
@ -96,20 +142,10 @@ Bundle::remove_port_from_channel (uint32_t ch, string portname)
|
|||
}
|
||||
|
||||
if (changed) {
|
||||
PortsChanged (ch); /* EMIT SIGNAL */
|
||||
emit_changed (PortsChanged);
|
||||
}
|
||||
}
|
||||
|
||||
/** operator== for Bundles; they are equal if their channels are the same.
|
||||
* @param other Bundle to compare with this one.
|
||||
*/
|
||||
bool
|
||||
Bundle::operator== (const Bundle& other) const
|
||||
{
|
||||
return other._channel == _channel;
|
||||
}
|
||||
|
||||
|
||||
/** Set a single port to be associated with a channel, removing any others.
|
||||
* @param ch Channel.
|
||||
* @param portname Full port name, including prefix.
|
||||
|
@ -126,7 +162,7 @@ Bundle::set_port (uint32_t ch, string portname)
|
|||
_channel[ch].ports.push_back (portname);
|
||||
}
|
||||
|
||||
PortsChanged (ch); /* EMIT SIGNAL */
|
||||
emit_changed (PortsChanged);
|
||||
}
|
||||
|
||||
/** @param n Channel name */
|
||||
|
@ -138,7 +174,7 @@ Bundle::add_channel (std::string const & n)
|
|||
_channel.push_back (Channel (n));
|
||||
}
|
||||
|
||||
ConfigurationChanged (); /* EMIT SIGNAL */
|
||||
emit_changed (ConfigurationChanged);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -150,6 +186,9 @@ Bundle::port_attached_to_channel (uint32_t ch, std::string portname)
|
|||
return (std::find (_channel[ch].ports.begin (), _channel[ch].ports.end (), portname) != _channel[ch].ports.end ());
|
||||
}
|
||||
|
||||
/** Remove a channel.
|
||||
* @param ch Channel.
|
||||
*/
|
||||
void
|
||||
Bundle::remove_channel (uint32_t ch)
|
||||
{
|
||||
|
@ -159,6 +198,7 @@ Bundle::remove_channel (uint32_t ch)
|
|||
_channel.erase (_channel.begin () + ch);
|
||||
}
|
||||
|
||||
/** Remove all channels */
|
||||
void
|
||||
Bundle::remove_channels ()
|
||||
{
|
||||
|
@ -167,6 +207,9 @@ Bundle::remove_channels ()
|
|||
_channel.clear ();
|
||||
}
|
||||
|
||||
/** @param p Port name.
|
||||
* @return true if any channel is associated with p.
|
||||
*/
|
||||
bool
|
||||
Bundle::uses_port (std::string p) const
|
||||
{
|
||||
|
@ -200,6 +243,10 @@ Bundle::offers_port_alone (std::string p) const
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
/** @param ch Channel.
|
||||
* @return Channel name.
|
||||
*/
|
||||
std::string
|
||||
Bundle::channel_name (uint32_t ch) const
|
||||
{
|
||||
|
@ -209,6 +256,10 @@ Bundle::channel_name (uint32_t ch) const
|
|||
return _channel[ch].name;
|
||||
}
|
||||
|
||||
/** Set the name of a channel.
|
||||
* @param ch Channel.
|
||||
* @param n New name.
|
||||
*/
|
||||
void
|
||||
Bundle::set_channel_name (uint32_t ch, std::string const & n)
|
||||
{
|
||||
|
@ -219,7 +270,7 @@ Bundle::set_channel_name (uint32_t ch, std::string const & n)
|
|||
_channel[ch].name = n;
|
||||
}
|
||||
|
||||
NameChanged (); /* EMIT SIGNAL */
|
||||
emit_changed (NameChanged);
|
||||
}
|
||||
|
||||
/** Take the channels from another bundle and add them to this bundle,
|
||||
|
@ -245,6 +296,11 @@ Bundle::add_channels_from_bundle (boost::shared_ptr<Bundle> other)
|
|||
}
|
||||
}
|
||||
|
||||
/** Connect the ports associated with our channels to the ports associated
|
||||
* with another bundle's channels.
|
||||
* @param other Other bundle.
|
||||
* @param engine AudioEngine to use to make the connections.
|
||||
*/
|
||||
void
|
||||
Bundle::connect (boost::shared_ptr<Bundle> other, AudioEngine & engine)
|
||||
{
|
||||
|
@ -280,3 +336,62 @@ Bundle::disconnect (boost::shared_ptr<Bundle> other, AudioEngine & engine)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Remove all ports from all channels */
|
||||
void
|
||||
Bundle::remove_ports_from_channels ()
|
||||
{
|
||||
{
|
||||
Glib::Mutex::Lock lm (_channel_mutex);
|
||||
for (uint32_t c = 0; c < _channel.size(); ++c) {
|
||||
_channel[c].ports.clear ();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
emit_changed (PortsChanged);
|
||||
}
|
||||
|
||||
/** Remove all ports from a given channel.
|
||||
* @param ch Channel.
|
||||
*/
|
||||
void
|
||||
Bundle::remove_ports_from_channel (uint32_t ch)
|
||||
{
|
||||
assert (ch < nchannels ());
|
||||
|
||||
{
|
||||
Glib::Mutex::Lock lm (_channel_mutex);
|
||||
_channel[ch].ports.clear ();
|
||||
}
|
||||
|
||||
emit_changed (PortsChanged);
|
||||
}
|
||||
|
||||
void
|
||||
Bundle::suspend_signals ()
|
||||
{
|
||||
_signals_suspended = true;
|
||||
}
|
||||
|
||||
void
|
||||
Bundle::resume_signals ()
|
||||
{
|
||||
if (_pending_change) {
|
||||
Changed (_pending_change);
|
||||
_pending_change = Change (0);
|
||||
}
|
||||
|
||||
_signals_suspended = false;
|
||||
}
|
||||
|
||||
void
|
||||
Bundle::emit_changed (Change c)
|
||||
{
|
||||
if (_signals_suspended) {
|
||||
_pending_change = Change (int (_pending_change) | int (c));
|
||||
} else {
|
||||
Changed (c);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -396,8 +396,7 @@ IO::check_bundles (std::vector<UserBundleInfo>& list, const PortSet& ports)
|
|||
if (ok) {
|
||||
new_list.push_back (*i);
|
||||
} else {
|
||||
i->configuration_changed.disconnect ();
|
||||
i->ports_changed.disconnect ();
|
||||
i->changed.disconnect ();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -604,7 +603,7 @@ IO::remove_output_port (Port* port, void* src)
|
|||
}
|
||||
|
||||
if (change == ConfigurationChanged) {
|
||||
setup_bundles_for_inputs_and_outputs ();
|
||||
setup_bundle_for_outputs ();
|
||||
}
|
||||
|
||||
if (change != NoChange) {
|
||||
|
@ -666,7 +665,7 @@ IO::add_output_port (string destination, void* src, DataType type)
|
|||
|
||||
// pan_changed (src); /* EMIT SIGNAL */
|
||||
output_changed (ConfigurationChanged, src); /* EMIT SIGNAL */
|
||||
setup_bundles_for_inputs_and_outputs ();
|
||||
setup_bundle_for_outputs ();
|
||||
_session.set_dirty ();
|
||||
|
||||
return 0;
|
||||
|
@ -708,7 +707,7 @@ IO::remove_input_port (Port* port, void* src)
|
|||
}
|
||||
|
||||
if (change == ConfigurationChanged) {
|
||||
setup_bundles_for_inputs_and_outputs ();
|
||||
setup_bundle_for_inputs ();
|
||||
}
|
||||
|
||||
if (change != NoChange) {
|
||||
|
@ -771,7 +770,7 @@ IO::add_input_port (string source, void* src, DataType type)
|
|||
|
||||
// pan_changed (src); /* EMIT SIGNAL */
|
||||
input_changed (ConfigurationChanged, src); /* EMIT SIGNAL */
|
||||
setup_bundles_for_inputs_and_outputs ();
|
||||
setup_bundle_for_inputs ();
|
||||
_session.set_dirty ();
|
||||
|
||||
return 0;
|
||||
|
@ -1013,16 +1012,17 @@ IO::ensure_io (ChanCount in, ChanCount out, bool clear, void* src)
|
|||
if (out_changed) {
|
||||
check_bundles_connected_to_outputs ();
|
||||
output_changed (ConfigurationChanged, src); /* EMIT SIGNAL */
|
||||
setup_bundle_for_outputs ();
|
||||
}
|
||||
|
||||
if (in_changed) {
|
||||
check_bundles_connected_to_inputs ();
|
||||
input_changed (ConfigurationChanged, src); /* EMIT SIGNAL */
|
||||
setup_bundle_for_inputs ();
|
||||
}
|
||||
|
||||
if (in_changed || out_changed) {
|
||||
PortCountChanged (max (n_outputs(), n_inputs())); /* EMIT SIGNAL */
|
||||
setup_bundles_for_inputs_and_outputs ();
|
||||
_session.set_dirty ();
|
||||
}
|
||||
|
||||
|
@ -1050,7 +1050,7 @@ IO::ensure_inputs (ChanCount count, bool clear, bool lockit, void* src)
|
|||
|
||||
if (changed) {
|
||||
input_changed (ConfigurationChanged, src); /* EMIT SIGNAL */
|
||||
setup_bundles_for_inputs_and_outputs ();
|
||||
setup_bundle_for_inputs ();
|
||||
_session.set_dirty ();
|
||||
}
|
||||
return 0;
|
||||
|
@ -1142,7 +1142,7 @@ IO::ensure_outputs (ChanCount count, bool clear, bool lockit, void* src)
|
|||
|
||||
if (changed) {
|
||||
output_changed (ConfigurationChanged, src); /* EMIT SIGNAL */
|
||||
setup_bundles_for_inputs_and_outputs ();
|
||||
setup_bundle_for_outputs ();
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -2220,19 +2220,12 @@ IO::reset_panners ()
|
|||
}
|
||||
|
||||
void
|
||||
IO::bundle_configuration_changed ()
|
||||
IO::bundle_changed (Bundle::Change c)
|
||||
{
|
||||
//XXX
|
||||
// connect_input_ports_to_bundle (_input_bundle, this);
|
||||
}
|
||||
|
||||
void
|
||||
IO::bundle_ports_changed (int ignored)
|
||||
{
|
||||
//XXX
|
||||
// connect_output_ports_to_bundle (_output_bundle, this);
|
||||
}
|
||||
|
||||
void
|
||||
IO::GainControl::set_value (float val)
|
||||
{
|
||||
|
@ -2614,19 +2607,25 @@ IO::update_port_total_latencies ()
|
|||
|
||||
void
|
||||
IO::setup_bundles_for_inputs_and_outputs ()
|
||||
{
|
||||
setup_bundle_for_inputs ();
|
||||
setup_bundle_for_outputs ();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
IO::setup_bundle_for_inputs ()
|
||||
{
|
||||
char buf[32];
|
||||
|
||||
if (!_bundle_for_inputs) {
|
||||
_bundle_for_inputs.reset (new Bundle (true));
|
||||
}
|
||||
if (!_bundle_for_outputs) {
|
||||
_bundle_for_outputs.reset (new Bundle (false));
|
||||
}
|
||||
|
||||
_bundle_for_inputs->suspend_signals ();
|
||||
|
||||
_bundle_for_inputs->remove_channels ();
|
||||
_bundle_for_outputs->remove_channels ();
|
||||
|
||||
|
||||
snprintf(buf, sizeof (buf), _("%s in"), _name.c_str());
|
||||
_bundle_for_inputs->set_name (buf);
|
||||
uint32_t const ni = inputs().num_ports();
|
||||
|
@ -2635,6 +2634,23 @@ IO::setup_bundles_for_inputs_and_outputs ()
|
|||
_bundle_for_inputs->set_port (i, _session.engine().make_port_name_non_relative (inputs().port(i)->name()));
|
||||
}
|
||||
|
||||
_bundle_for_inputs->resume_signals ();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
IO::setup_bundle_for_outputs ()
|
||||
{
|
||||
char buf[32];
|
||||
|
||||
if (!_bundle_for_outputs) {
|
||||
_bundle_for_outputs.reset (new Bundle (false));
|
||||
}
|
||||
|
||||
_bundle_for_outputs->suspend_signals ();
|
||||
|
||||
_bundle_for_outputs->remove_channels ();
|
||||
|
||||
snprintf(buf, sizeof (buf), _("%s out"), _name.c_str());
|
||||
_bundle_for_outputs->set_name (buf);
|
||||
uint32_t const no = outputs().num_ports();
|
||||
|
@ -2642,8 +2658,11 @@ IO::setup_bundles_for_inputs_and_outputs ()
|
|||
_bundle_for_outputs->add_channel (bundle_channel_name (i, no));
|
||||
_bundle_for_outputs->set_port (i, _session.engine().make_port_name_non_relative (outputs().port(i)->name()));
|
||||
}
|
||||
|
||||
_bundle_for_outputs->resume_signals ();
|
||||
}
|
||||
|
||||
|
||||
/** @return Bundles connected to our inputs */
|
||||
BundleList
|
||||
IO::bundles_connected_to_inputs ()
|
||||
|
@ -2711,11 +2730,8 @@ IO::bundles_connected_to_outputs ()
|
|||
IO::UserBundleInfo::UserBundleInfo (IO* io, boost::shared_ptr<UserBundle> b)
|
||||
{
|
||||
bundle = b;
|
||||
configuration_changed = b->ConfigurationChanged.connect (
|
||||
sigc::mem_fun (*io, &IO::bundle_configuration_changed)
|
||||
);
|
||||
ports_changed = b->PortsChanged.connect (
|
||||
sigc::mem_fun (*io, &IO::bundle_ports_changed)
|
||||
changed = b->Changed.connect (
|
||||
sigc::mem_fun (*io, &IO::bundle_changed)
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -45,7 +45,12 @@ ARDOUR::UserBundle::set_state (XMLNode const & node)
|
|||
return -1;
|
||||
}
|
||||
|
||||
add_channel ("XXX");
|
||||
if ((name = (*i)->property ("name")) == 0) {
|
||||
PBD::error << _("Node for Channel has no \"name\" property") << endmsg;
|
||||
return -1;
|
||||
}
|
||||
|
||||
add_channel (name->value ());
|
||||
|
||||
XMLNodeList const ports = (*i)->children ();
|
||||
|
||||
|
|
Loading…
Reference in New Issue