mirror of
https://github.com/Ardour/ardour.git
synced 2026-01-04 12:45:45 +01:00
somewhat convoluted reworking to get TransportMastersWidget's per-row port combos to update for hotplug
This approach should extended to other things, notably control surfaces
This commit is contained in:
parent
d95f6039f8
commit
91a87fbc5b
2 changed files with 100 additions and 58 deletions
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
#include "pbd/enumwriter.h"
|
||||
#include "pbd/i18n.h"
|
||||
#include "pbd/unwind.h"
|
||||
|
||||
#include "temporal/time.h"
|
||||
|
||||
|
|
@ -48,7 +49,14 @@ using namespace ArdourWidgets;
|
|||
TransportMastersWidget::TransportMastersWidget ()
|
||||
: table (4, 13)
|
||||
, add_button (_("Add a new Transport Master"))
|
||||
, ignore_active_change (false)
|
||||
{
|
||||
midi_port_store = ListStore::create (port_columns);
|
||||
audio_port_store = ListStore::create (port_columns);
|
||||
|
||||
AudioEngine::instance()->PortRegisteredOrUnregistered.connect (port_reg_connection, invalidator (*this), boost::bind (&TransportMastersWidget::update_ports, this), gui_context());
|
||||
update_ports ();
|
||||
|
||||
pack_start (table, PACK_EXPAND_WIDGET, 12);
|
||||
pack_start (add_button, FALSE, FALSE);
|
||||
|
||||
|
|
@ -255,6 +263,35 @@ TransportMastersWidget::rebuild ()
|
|||
update_usability ();
|
||||
}
|
||||
|
||||
bool
|
||||
TransportMastersWidget::idle_remove (TransportMastersWidget::Row* row)
|
||||
{
|
||||
TransportMasterManager::instance().remove (row->tm->name());
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
TransportMastersWidget::update_ports ()
|
||||
{
|
||||
{
|
||||
PBD::Unwinder<bool> uw (ignore_active_change, true);
|
||||
vector<string> inputs;
|
||||
|
||||
ARDOUR::AudioEngine::instance()->get_ports ("", ARDOUR::DataType::MIDI, ARDOUR::PortFlags (ARDOUR::IsOutput), inputs);
|
||||
build_port_model (midi_port_store, inputs);
|
||||
|
||||
inputs.clear ();
|
||||
|
||||
ARDOUR::AudioEngine::instance()->get_ports ("", ARDOUR::DataType::AUDIO, ARDOUR::PortFlags (ARDOUR::IsOutput), inputs);
|
||||
build_port_model (audio_port_store, inputs);
|
||||
}
|
||||
|
||||
for (vector<Row*>::iterator r = rows.begin(); r != rows.end(); ++r) {
|
||||
(*r)->port_choice_changed ();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
TransportMastersWidget::update_usability ()
|
||||
{
|
||||
|
|
@ -272,7 +309,6 @@ TransportMastersWidget::Row::Row (TransportMastersWidget& p)
|
|||
, remove_button (X_("x"))
|
||||
, name_editor (0)
|
||||
, save_when (0)
|
||||
, ignore_active_change (false)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -297,11 +333,32 @@ TransportMastersWidget::Row::name_press (GdkEventButton* ev)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
TransportMastersWidget::idle_remove (TransportMastersWidget::Row* row)
|
||||
void
|
||||
TransportMastersWidget::build_port_model (Glib::RefPtr<Gtk::ListStore> model, vector<string> const & ports)
|
||||
{
|
||||
TransportMasterManager::instance().remove (row->tm->name());
|
||||
return false;
|
||||
TreeModel::Row row;
|
||||
|
||||
model->clear ();
|
||||
|
||||
row = *model->append ();
|
||||
row[port_columns.full_name] = string();
|
||||
row[port_columns.short_name] = _("Disconnected");
|
||||
|
||||
for (vector<string>::const_iterator p = ports.begin(); p != ports.end(); ++p) {
|
||||
|
||||
if (AudioEngine::instance()->port_is_mine (*p)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
row = *model->append ();
|
||||
row[port_columns.full_name] = *p;
|
||||
|
||||
std::string pn = ARDOUR::AudioEngine::instance()->get_pretty_name_by_name (*p);
|
||||
if (pn.empty ()) {
|
||||
pn = (*p).substr ((*p).find (':') + 1);
|
||||
}
|
||||
row[port_columns.short_name] = pn;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -422,35 +479,6 @@ TransportMastersWidget::Row::mod_request_type (TransportRequestType t)
|
|||
tm->set_request_mask (TransportRequestType ((tm->request_mask() & t) ? (tm->request_mask() & ~t) : (tm->request_mask() | t)));
|
||||
}
|
||||
|
||||
Glib::RefPtr<Gtk::ListStore>
|
||||
TransportMastersWidget::Row::build_port_list (vector<string> const & ports)
|
||||
{
|
||||
Glib::RefPtr<Gtk::ListStore> store = ListStore::create (port_columns);
|
||||
TreeModel::Row row;
|
||||
|
||||
row = *store->append ();
|
||||
row[port_columns.full_name] = string();
|
||||
row[port_columns.short_name] = _("Disconnected");
|
||||
|
||||
for (vector<string>::const_iterator p = ports.begin(); p != ports.end(); ++p) {
|
||||
|
||||
if (AudioEngine::instance()->port_is_mine (*p)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
row = *store->append ();
|
||||
row[port_columns.full_name] = *p;
|
||||
|
||||
std::string pn = ARDOUR::AudioEngine::instance()->get_pretty_name_by_name (*p);
|
||||
if (pn.empty ()) {
|
||||
pn = (*p).substr ((*p).find (':') + 1);
|
||||
}
|
||||
row[port_columns.short_name] = pn;
|
||||
}
|
||||
|
||||
return store;
|
||||
}
|
||||
|
||||
void
|
||||
TransportMastersWidget::Row::populate_port_combo ()
|
||||
{
|
||||
|
|
@ -461,15 +489,13 @@ TransportMastersWidget::Row::populate_port_combo ()
|
|||
port_combo.show ();
|
||||
}
|
||||
|
||||
vector<string> inputs;
|
||||
build_port_list (tm->port()->type());
|
||||
}
|
||||
|
||||
if (tm->port()->type() == DataType::MIDI) {
|
||||
ARDOUR::AudioEngine::instance()->get_ports ("", ARDOUR::DataType::MIDI, ARDOUR::PortFlags (ARDOUR::IsOutput), inputs);
|
||||
} else {
|
||||
ARDOUR::AudioEngine::instance()->get_ports ("", ARDOUR::DataType::AUDIO, ARDOUR::PortFlags (ARDOUR::IsOutput), inputs);
|
||||
}
|
||||
|
||||
Glib::RefPtr<Gtk::ListStore> input = build_port_list (inputs);
|
||||
void
|
||||
TransportMastersWidget::Row::build_port_list (DataType type)
|
||||
{
|
||||
Glib::RefPtr<Gtk::ListStore> input = (type == DataType::MIDI ? parent.midi_port_store : parent.audio_port_store);
|
||||
bool input_found = false;
|
||||
int n;
|
||||
|
||||
|
|
@ -480,9 +506,8 @@ TransportMastersWidget::Row::populate_port_combo ()
|
|||
i = children.begin();
|
||||
++i; /* skip "Disconnected" */
|
||||
|
||||
|
||||
for (n = 1; i != children.end(); ++i, ++n) {
|
||||
string port_name = (*i)[port_columns.full_name];
|
||||
string port_name = (*i)[parent.port_columns.full_name];
|
||||
if (tm->port()->connected_to (port_name)) {
|
||||
port_combo.set_active (n);
|
||||
input_found = true;
|
||||
|
|
@ -498,12 +523,18 @@ TransportMastersWidget::Row::populate_port_combo ()
|
|||
void
|
||||
TransportMastersWidget::Row::port_choice_changed ()
|
||||
{
|
||||
if (ignore_active_change) {
|
||||
if (!tm->port()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (parent.ignore_active_change) {
|
||||
return;
|
||||
}
|
||||
|
||||
build_port_list (tm->port()->type());
|
||||
|
||||
TreeModel::iterator active = port_combo.get_active ();
|
||||
string new_port = (*active)[port_columns.full_name];
|
||||
string new_port = (*active)[parent.port_columns.full_name];
|
||||
|
||||
if (new_port.empty()) {
|
||||
tm->port()->disconnect_all ();
|
||||
|
|
|
|||
|
|
@ -103,19 +103,8 @@ class TransportMastersWidget : public Gtk::VBox, public ARDOUR::SessionHandlePtr
|
|||
Row (TransportMastersWidget& parent);
|
||||
~Row ();
|
||||
|
||||
struct PortColumns : public Gtk::TreeModel::ColumnRecord {
|
||||
PortColumns() {
|
||||
add (short_name);
|
||||
add (full_name);
|
||||
}
|
||||
Gtk::TreeModelColumn<std::string> short_name;
|
||||
Gtk::TreeModelColumn<std::string> full_name;
|
||||
};
|
||||
|
||||
PortColumns port_columns;
|
||||
|
||||
void populate_port_combo ();
|
||||
Glib::RefPtr<Gtk::ListStore> build_port_list (std::vector<std::string> const & ports);
|
||||
void build_port_list (ARDOUR::DataType);
|
||||
|
||||
void use_button_toggled ();
|
||||
void collect_button_toggled ();
|
||||
|
|
@ -132,6 +121,8 @@ class TransportMastersWidget : public Gtk::VBox, public ARDOUR::SessionHandlePtr
|
|||
|
||||
PBD::ScopedConnection property_change_connection;
|
||||
bool ignore_active_change;
|
||||
|
||||
bool port_combo_proxy (GdkEventButton*);
|
||||
};
|
||||
|
||||
std::vector<Row*> rows;
|
||||
|
|
@ -146,6 +137,26 @@ class TransportMastersWidget : public Gtk::VBox, public ARDOUR::SessionHandlePtr
|
|||
PBD::ScopedConnection remove_connection;
|
||||
PBD::ScopedConnection engine_running_connection;
|
||||
|
||||
struct PortColumns : public Gtk::TreeModel::ColumnRecord {
|
||||
PortColumns() {
|
||||
add (short_name);
|
||||
add (full_name);
|
||||
}
|
||||
Gtk::TreeModelColumn<std::string> short_name;
|
||||
Gtk::TreeModelColumn<std::string> full_name;
|
||||
};
|
||||
|
||||
PortColumns port_columns;
|
||||
|
||||
friend class Row;
|
||||
Glib::RefPtr<Gtk::ListStore> midi_port_store;
|
||||
Glib::RefPtr<Gtk::ListStore> audio_port_store;
|
||||
|
||||
PBD::ScopedConnection port_reg_connection;
|
||||
void update_ports ();
|
||||
bool ignore_active_change;
|
||||
void build_port_model (Glib::RefPtr<Gtk::ListStore>, std::vector<std::string> const &);
|
||||
|
||||
void rebuild ();
|
||||
void clear ();
|
||||
void current_changed (boost::shared_ptr<ARDOUR::TransportMaster> old_master, boost::shared_ptr<ARDOUR::TransportMaster> new_master);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue