Fixes to bundle manager to make it vaguely usable.
[ardour.git] / gtk2_ardour / io_selector.cc
index d61a37d655d39b3fb5e27cd46884e67ec7942a47..76892dcd3ddc48cbd8f26a9d25391ee97e0d97b5 100644 (file)
 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))
-       , _session (session)
+IOSelector::IOSelector (ARDOUR::Session& session, boost::shared_ptr<ARDOUR::IO> io, bool in)
+       : PortMatrix (session, io->default_type())
        , _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;
+               _ours = 0;
+       } else {
+               _other = 0;
+               _ours = 1;
+       }
+
+       _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)
 {
-       _our_bundles.clear ();
-       _our_bundles.push_back (boost::shared_ptr<ARDOUR::Bundle> (new ARDOUR::Bundle));
-       _our_bundles.front()->set_name (_io->name());
-
-       if (offering_input ()) {
-               const PortSet& ps (_io->outputs());
-
-               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);
-                       _our_bundles.front()->add_channel (buf);
-                       _our_bundles.front()->add_port_to_channel (j, _session.engine().make_port_name_non_relative (i->name()));
-                       ++j;
-               }
+       _ports[dim].suspend_signals ();
+
+       if (dim == _other) {
+
+               _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);
-                       _our_bundles.front()->add_channel (buf);
-                       _our_bundles.front()->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 ();
+       _ports[dim].resume_signals ();
 }
 
 void
-IOSelector::ports_changed ()
+IOSelector::set_state (ARDOUR::BundleChannel c[2], bool s)
 {
-       ENSURE_GUI_THREAD (mem_fun (*this, &IOSelector::ports_changed));
-
-       setup ();
-}
-
-void
-IOSelector::set_state (
-       boost::shared_ptr<ARDOUR::Bundle> ab,
-       uint32_t ac,
-       boost::shared_ptr<ARDOUR::Bundle> bb,
-       uint32_t bc,
-       bool s,
-       uint32_t k
-       )
-{
-       ARDOUR::Bundle::PortList const& our_ports = ab->channel_ports (ac);
-       ARDOUR::Bundle::PortList const& other_ports = bb->channel_ports (bc);
+       ARDOUR::Bundle::PortList const & our_ports = c[_ours].bundle->channel_ports (c[_ours].channel);
+       ARDOUR::Bundle::PortList const & other_ports = c[_other].bundle->channel_ports (c[_other].channel);
 
        for (ARDOUR::Bundle::PortList::const_iterator i = our_ports.begin(); i != our_ports.end(); ++i) {
                for (ARDOUR::Bundle::PortList::const_iterator j = other_ports.begin(); j != other_ports.end(); ++j) {
@@ -122,13 +96,13 @@ IOSelector::set_state (
                        }
 
                        if (s) {
-                               if (!offering_input()) {
+                               if (!_find_inputs_for_io_outputs) {
                                        _io->connect_input (f, *j, 0);
                                } else {
                                        _io->connect_output (f, *j, 0);
                                }
                        } else {
-                               if (!offering_input()) {
+                               if (!_find_inputs_for_io_outputs) {
                                        _io->disconnect_input (f, *j, 0);
                                } else {
                                        _io->disconnect_output (f, *j, 0);
@@ -139,15 +113,10 @@ IOSelector::set_state (
 }
 
 PortMatrix::State
-IOSelector::get_state (
-       boost::shared_ptr<ARDOUR::Bundle> ab,
-       uint32_t ac,
-       boost::shared_ptr<ARDOUR::Bundle> bb,
-       uint32_t bc
-       ) const
+IOSelector::get_state (ARDOUR::BundleChannel c[2]) const
 {
-       ARDOUR::Bundle::PortList const& our_ports = ab->channel_ports (ac);
-       ARDOUR::Bundle::PortList const& other_ports = bb->channel_ports (bc);
+       ARDOUR::Bundle::PortList const & our_ports = c[_ours].bundle->channel_ports (c[_ours].channel);
+       ARDOUR::Bundle::PortList const & other_ports = c[_other].bundle->channel_ports (c[_other].channel);
 
        for (ARDOUR::Bundle::PortList::const_iterator i = our_ports.begin(); i != our_ports.end(); ++i) {
                for (ARDOUR::Bundle::PortList::const_iterator j = other_ports.begin(); j != other_ports.end(); ++j) {
@@ -169,9 +138,9 @@ IOSelector::get_state (
 }
 
 uint32_t
-IOSelector::n_rows () const
+IOSelector::n_io_ports () const
 {
-       if (!offering_input()) {
+       if (!_find_inputs_for_io_outputs) {
                return _io->inputs().num_ports (_io->default_type());
        } else {
                return _io->outputs().num_ports (_io->default_type());
@@ -179,9 +148,9 @@ IOSelector::n_rows () const
 }
 
 uint32_t
-IOSelector::maximum_rows () const
+IOSelector::maximum_io_ports () const
 {
-       if (!offering_input()) {
+       if (!_find_inputs_for_io_outputs) {
                return _io->input_maximum ().get (_io->default_type());
        } else {
                return _io->output_maximum ().get (_io->default_type());
@@ -190,9 +159,9 @@ IOSelector::maximum_rows () const
 
 
 uint32_t
-IOSelector::minimum_rows () const
+IOSelector::minimum_io_ports () const
 {
-       if (!offering_input()) {
+       if (!_find_inputs_for_io_outputs) {
                return _io->input_minimum ().get (_io->default_type());
        } else {
                return _io->output_minimum ().get (_io->default_type());
@@ -207,7 +176,7 @@ IOSelector::add_channel (boost::shared_ptr<ARDOUR::Bundle> b)
        // The IO selector only works for single typed IOs
        const ARDOUR::DataType t = _io->default_type ();
 
-       if (!offering_input()) {
+       if (!_find_inputs_for_io_outputs) {
 
                try {
                        _io->add_input_port ("", this);
@@ -232,20 +201,26 @@ IOSelector::add_channel (boost::shared_ptr<ARDOUR::Bundle> b)
 }
 
 void
-IOSelector::remove_channel (boost::shared_ptr<ARDOUR::Bundle> b, uint32_t c)
+IOSelector::remove_channel (ARDOUR::BundleChannel bc)
 {
-       Port* f = _session.engine().get_port_by_name (b->channel_ports(c)[0]);
+       Port* f = _session.engine().get_port_by_name (bc.bundle->channel_ports(bc.channel)[0]);
        if (!f) {
                return;
        }
        
-       if (offering_input()) {
+       if (_find_inputs_for_io_outputs) {
                _io->remove_output_port (f, this);
        } else {
                _io->remove_input_port (f, this);
        }
 }
 
+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)
@@ -268,7 +243,7 @@ IOSelectorWindow::IOSelectorWindow (ARDOUR::Session& session, boost::shared_ptr<
        get_action_area()->pack_start (disconnect_button, false, false);
 
        /* Add Port button */
-       if (_selector.maximum_rows() > _selector.n_rows()) {
+       if (_selector.maximum_io_ports() > _selector.n_io_ports()) {
                add_button.set_name ("IOSelectorButton");
                add_button.set_image (*Gtk::manage (new Gtk::Image (Gtk::Stock::ADD, Gtk::ICON_SIZE_BUTTON)));
                get_action_area()->pack_start (add_button, false, false);
@@ -278,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)));
@@ -303,11 +278,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);
 
@@ -322,13 +293,19 @@ IOSelectorWindow::IOSelectorWindow (ARDOUR::Session& session, boost::shared_ptr<
 void
 IOSelectorWindow::ports_changed ()
 {
-       if (_selector.maximum_rows() > _selector.n_rows()) {
+       if (_selector.maximum_io_ports() > _selector.n_io_ports()) {
                add_button.set_sensitive (true);
        } else {
                add_button.set_sensitive (false);
        }
 }
 
+void
+IOSelectorWindow::rescan ()
+{
+       _selector.setup_ports (_selector.other());
+}
+
 void
 IOSelectorWindow::cancel ()
 {
@@ -346,7 +323,7 @@ IOSelectorWindow::accept ()
 void
 IOSelectorWindow::on_map ()
 {
-       _selector.setup ();
+       _selector.setup_all_ports ();
        Window::on_map ();
 }
 
@@ -357,7 +334,7 @@ IOSelectorWindow::io_name_changed (void* src)
        
        string title;
 
-       if (!_selector.offering_input()) {
+       if (!_selector.find_inputs_for_io_outputs()) {
                title = string_compose(_("%1 input"), _selector.io()->name());
        } else {
                title = string_compose(_("%1 output"), _selector.io()->name());
@@ -377,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
@@ -459,3 +436,4 @@ PortInsertWindow::accept ()
        _portinsertui.finished (IOSelector::Accepted);
        hide ();
 }
+