diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2015-10-12 13:36:22 -0400 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2015-10-12 13:36:22 -0400 |
commit | d4e0e8e963c8ce168542a024da32d68d7d8fb7ea (patch) | |
tree | 17965cb4ac8016dfd5b496f5f6d950915035f469 /libs/surfaces | |
parent | d369894dd545e2a97e74d5282bb45bbc1028f7f2 (diff) |
make MCP port buttons work
Diffstat (limited to 'libs/surfaces')
-rw-r--r-- | libs/surfaces/mackie/gui.cc | 149 | ||||
-rw-r--r-- | libs/surfaces/mackie/gui.h | 24 | ||||
-rw-r--r-- | libs/surfaces/mackie/surface.cc | 2 |
3 files changed, 127 insertions, 48 deletions
diff --git a/libs/surfaces/mackie/gui.cc b/libs/surfaces/mackie/gui.cc index 4b33126c8d..407ded8b12 100644 --- a/libs/surfaces/mackie/gui.cc +++ b/libs/surfaces/mackie/gui.cc @@ -29,7 +29,9 @@ #include <gtkmm/alignment.h> #include "pbd/error.h" +#include "pbd/unwind.h" #include "pbd/strsplit.h" +#include "pbd/stacktrace.h" #include "gtkmm2ext/actions.h" #include "gtkmm2ext/gui_thread.h" @@ -91,6 +93,7 @@ MackieControlProtocolGUI::MackieControlProtocolGUI (MackieControlProtocol& p) , ipmidi_base_port_adjustment (_cp.ipmidi_base(), 0, 32767, 1, 1000) , discover_button (_("Discover Mackie Devices")) , _device_dependent_widget (0) + , ignore_active_change (false) { Gtk::Label* l; Gtk::Alignment* align; @@ -243,8 +246,15 @@ MackieControlProtocolGUI::MackieControlProtocolGUI (MackieControlProtocol& p) void MackieControlProtocolGUI::connection_handler () { - vector<Gtk::ComboBoxText*>::iterator ic; - vector<Gtk::ComboBoxText*>::iterator oc; + /* ignore all changes to combobox active strings here, because we're + updating them to match a new ("external") reality - we were called + because port connections have changed. + */ + + PBD::Unwinder<bool> ici (ignore_active_change, true); + + vector<Gtk::ComboBox*>::iterator ic; + vector<Gtk::ComboBox*>::iterator oc; vector<string> midi_inputs; vector<string> midi_outputs; @@ -252,7 +262,6 @@ MackieControlProtocolGUI::connection_handler () ARDOUR::AudioEngine::instance()->get_ports ("", ARDOUR::DataType::MIDI, ARDOUR::PortFlags (ARDOUR::IsOutput|ARDOUR::IsPhysical), midi_inputs); ARDOUR::AudioEngine::instance()->get_ports ("", ARDOUR::DataType::MIDI, ARDOUR::PortFlags (ARDOUR::IsInput|ARDOUR::IsPhysical), midi_outputs); - for (ic = input_combos.begin(), oc = output_combos.begin(); ic != input_combos.end() && oc != output_combos.end(); ++ic, ++oc) { boost::shared_ptr<Surface> surface = _cp.get_surface_by_raw_pointer ((*ic)->get_data ("surface")); @@ -265,62 +274,53 @@ MackieControlProtocolGUI::connection_handler () void MackieControlProtocolGUI::update_port_combos (vector<string> const& midi_inputs, vector<string> const& midi_outputs, - Gtk::ComboBoxText* input_combo, - Gtk::ComboBoxText* output_combo, + Gtk::ComboBox* input_combo, + Gtk::ComboBox* output_combo, boost::shared_ptr<Surface> surface) { - vector<string> short_midi_inputs; - vector<string> short_midi_outputs; - - /* Prepend "Disconnected" */ - - short_midi_inputs.push_back (_("Disconnected")); - short_midi_outputs.push_back (_("Disconnected")); - - /* generate short versions of all the port names */ - - for (vector<string>::const_iterator s = midi_inputs.begin(); s != midi_inputs.end(); ++s) { - short_midi_inputs.push_back ((*s).substr ((*s).find (':') + 1)); - } - for (vector<string>::const_iterator s = midi_outputs.begin(); s != midi_outputs.end(); ++s) { - short_midi_outputs.push_back ((*s).substr ((*s).find (':') + 1)); - } - + Glib::RefPtr<Gtk::ListStore> input = build_midi_port_list (midi_inputs, true); + Glib::RefPtr<Gtk::ListStore> output = build_midi_port_list (midi_outputs, false); bool input_found = false; - bool output_found = true; + bool output_found = false; + int n; + + input_combo->set_model (input); + output_combo->set_model (output); - Gtkmm2ext::set_popdown_strings (*input_combo, short_midi_inputs); + Gtk::TreeModel::Children children = input->children(); + Gtk::TreeModel::Children::iterator i; + i = children.begin(); + ++i; /* skip "Disconnected" */ - vector<string>::iterator shrt = short_midi_inputs.begin(); - shrt++; /* skip "Disconnected" */ - for (vector<string>::const_iterator s = midi_inputs.begin(); s != midi_inputs.end(); ++s, ++shrt) { - if (surface->port().input().connected_to (*s)) { - input_combo->set_active_text (*shrt); + for (n = 1; i != children.end(); ++i, ++n) { + string port_name = (*i)[midi_port_columns.full_name]; + if (surface->port().input().connected_to (port_name)) { + input_combo->set_active (n); input_found = true; break; } } if (!input_found) { - input_combo->set_active_text (_("Disconnected")); + input_combo->set_active (0); /* disconnected */ } - Gtkmm2ext::set_popdown_strings (*output_combo, short_midi_outputs); - - shrt = short_midi_outputs.begin(); - shrt++; /* skip "Disconnected" */ + children = output->children(); + i = children.begin(); + ++i; /* skip "Disconnected" */ - for (vector<string>::const_iterator s = midi_outputs.begin(); s != midi_outputs.end(); ++s, ++shrt) { - if (surface->port().output().connected_to (*s)) { - output_combo->set_active_text (*shrt); + for (n = 1; i != children.end(); ++i, ++n) { + string port_name = (*i)[midi_port_columns.full_name]; + if (surface->port().output().connected_to (port_name)) { + output_combo->set_active (n); output_found = true; break; } } if (!output_found) { - output_combo->set_active_text (_("Disconnected")); + output_combo->set_active (0); /* disconnected */ } } @@ -366,16 +366,21 @@ MackieControlProtocolGUI::device_dependent_widget () /*NOTREACHED*/ } - Gtk::ComboBoxText* input_combo = manage (new Gtk::ComboBoxText); - Gtk::ComboBoxText* output_combo = manage (new Gtk::ComboBoxText); + Gtk::ComboBox* input_combo = manage (new Gtk::ComboBox); + Gtk::ComboBox* output_combo = manage (new Gtk::ComboBox); - input_combo->set_data ("surface", surface.get()); - output_combo->set_data ("surface", surface.get()); + update_port_combos (midi_inputs, midi_outputs, input_combo, output_combo, surface); + input_combo->pack_start (midi_port_columns.short_name); + input_combo->set_data ("surface", surface.get()); input_combos.push_back (input_combo); + output_combo->pack_start (midi_port_columns.short_name); + output_combo->set_data ("surface", surface.get()); output_combos.push_back (output_combo); - update_port_combos (midi_inputs, midi_outputs, input_combo, output_combo, surface); + boost::weak_ptr<Surface> ws (surface); + input_combo->signal_changed().connect (sigc::bind (sigc::mem_fun (*this, &MackieControlProtocolGUI::active_port_changed), input_combo, ws, true)); + output_combo->signal_changed().connect (sigc::bind (sigc::mem_fun (*this, &MackieControlProtocolGUI::active_port_changed), output_combo, ws, false)); string send_string; string receive_string; @@ -851,3 +856,61 @@ MackieControlProtocolGUI::touch_sensitive_change () int sensitivity = (int) touch_sensitivity_adjustment.get_value (); _cp.set_touch_sensitivity (sensitivity); } + +Glib::RefPtr<Gtk::ListStore> +MackieControlProtocolGUI::build_midi_port_list (vector<string> const & ports, bool for_input) +{ + Glib::RefPtr<Gtk::ListStore> store = ListStore::create (midi_port_columns); + TreeModel::Row row; + + row = *store->append (); + row[midi_port_columns.full_name] = string(); + row[midi_port_columns.short_name] = _("Disconnected"); + + for (vector<string>::const_iterator p = ports.begin(); p != ports.end(); ++p) { + row = *store->append (); + row[midi_port_columns.full_name] = *p; + row[midi_port_columns.short_name] = (*p).substr ((*p).find (':') + 1); + } + + return store; +} + +void +MackieControlProtocolGUI::active_port_changed (Gtk::ComboBox* combo, boost::weak_ptr<Surface> ws, bool for_input) +{ + if (ignore_active_change) { + return; + } + + boost::shared_ptr<Surface> surface = ws.lock(); + + if (!surface) { + return; + } + + TreeModel::iterator active = combo->get_active (); + string new_port = (*active)[midi_port_columns.full_name]; + + if (new_port.empty()) { + if (for_input) { + surface->port().input().disconnect_all (); + } else { + surface->port().output().disconnect_all (); + } + + return; + } + + if (for_input) { + if (!surface->port().input().connected_to (new_port)) { + surface->port().input().disconnect_all (); + surface->port().input().connect (new_port); + } + } else { + if (!surface->port().output().connected_to (new_port)) { + surface->port().output().disconnect_all (); + surface->port().output().connect (new_port); + } + } +} diff --git a/libs/surfaces/mackie/gui.h b/libs/surfaces/mackie/gui.h index b2df91ed7a..754c4ac5aa 100644 --- a/libs/surfaces/mackie/gui.h +++ b/libs/surfaces/mackie/gui.h @@ -18,7 +18,7 @@ #include <vector> -#include <gtkmm/comboboxtext.h> +#include <gtkmm/combobox.h> #include <gtkmm/box.h> #include <gtkmm/spinbutton.h> #include <gtkmm/table.h> @@ -54,10 +54,19 @@ class MackieControlProtocolGUI : public Gtk::Notebook Gtk::ComboBoxText _surface_combo; Gtk::ComboBoxText _profile_combo; - typedef std::vector<Gtk::ComboBoxText*> PortCombos; + typedef std::vector<Gtk::ComboBox*> PortCombos; PortCombos input_combos; PortCombos output_combos; + struct MidiPortColumns : public Gtk::TreeModel::ColumnRecord { + MidiPortColumns() { + add (short_name); + add (full_name); + } + Gtk::TreeModelColumn<std::string> short_name; + Gtk::TreeModelColumn<std::string> full_name; + }; + struct AvailableActionColumns : public Gtk::TreeModel::ColumnRecord { AvailableActionColumns() { add (name); @@ -90,12 +99,15 @@ class MackieControlProtocolGUI : public Gtk::Notebook AvailableActionColumns available_action_columns; FunctionKeyColumns function_key_columns; + MidiPortColumns midi_port_columns; Gtk::ScrolledWindow function_key_scroller; Gtk::TreeView function_key_editor; Glib::RefPtr<Gtk::ListStore> function_key_model; Glib::RefPtr<Gtk::TreeStore> available_action_model; + Glib::RefPtr<Gtk::ListStore> build_midi_port_list (bool for_input); + void build_available_action_menu (); void refresh_function_key_editor (); void build_function_key_editor (); @@ -131,12 +143,16 @@ class MackieControlProtocolGUI : public Gtk::Notebook void device_changed (); void update_port_combos (std::vector<std::string> const&, std::vector<std::string> const&, - Gtk::ComboBoxText* input_combo, - Gtk::ComboBoxText* output_combo, + Gtk::ComboBox* input_combo, + Gtk::ComboBox* output_combo, boost::shared_ptr<Mackie::Surface> surface); PBD::ScopedConnection connection_change_connection; void connection_handler (); + + Glib::RefPtr<Gtk::ListStore> build_midi_port_list (std::vector<std::string> const & ports, bool for_input); + bool ignore_active_change; + void active_port_changed (Gtk::ComboBox* combo, boost::weak_ptr<Mackie::Surface> ws, bool for_input); }; } diff --git a/libs/surfaces/mackie/surface.cc b/libs/surfaces/mackie/surface.cc index a7ba8406a5..ff5de96513 100644 --- a/libs/surfaces/mackie/surface.cc +++ b/libs/surfaces/mackie/surface.cc @@ -251,7 +251,7 @@ Surface::get_state() int Surface::set_state (const XMLNode& node, int version) { - /* Look for a node named after this surface */ + /* Look for a node named after the device we're part of */ XMLNodeList const& children = node.children(); XMLNode* mynode = 0; |