13
0

Refactor IOButton::update, expose API to set connection-text

This commit is contained in:
Robin Gareus 2022-04-27 23:15:45 +02:00
parent 9e77d8923a
commit 706140181e
Signed by: rgareus
GPG Key ID: A090BCE02CF57F04
2 changed files with 61 additions and 59 deletions

View File

@ -222,7 +222,7 @@ IOButton::button_press (GdkEventButton* ev)
} }
} else { } else {
/* guess the user-intended main type of the route output */ /* guess the user-intended main type of the route output */
DataType intended_type = guess_main_type (); DataType intended_type = guess_main_type (_input ? _route->input () : _route->output ());
/* try adding the master bus first */ /* try adding the master bus first */
boost::shared_ptr<Route> master = _route->session ().master_out (); boost::shared_ptr<Route> master = _route->session ().master_out ();
@ -248,7 +248,7 @@ IOButton::button_press (GdkEventButton* ev)
maybe_add_bundle_to_menu ((*i)->output ()->bundle (), current); maybe_add_bundle_to_menu ((*i)->output ()->bundle (), current);
} }
} else { } else {
DataType intended_type = guess_main_type (); DataType intended_type = guess_main_type (_input ? _route->input () : _route->output ());
/* other routes inputs */ /* other routes inputs */
for (ARDOUR::RouteList::const_iterator i = copy.begin(); i != copy.end(); ++i) { for (ARDOUR::RouteList::const_iterator i = copy.begin(); i != copy.end(); ++i) {
@ -309,7 +309,7 @@ IOButton::button_press (GdkEventButton* ev)
} }
DataType DataType
IOButton::guess_main_type (bool favor_connected) const IOButton::guess_main_type (boost::shared_ptr<IO> io)
{ {
/* The heuristic follows these principles: /* The heuristic follows these principles:
* A) If all ports that the user connected are of the same type, then he * A) If all ports that the user connected are of the same type, then he
@ -329,19 +329,15 @@ IOButton::guess_main_type (bool favor_connected) const
* available ports if any (since if all ports are of the same type, the most * available ports if any (since if all ports are of the same type, the most
* likely found will be that one obviously). */ * likely found will be that one obviously). */
boost::shared_ptr<IO> io = _input ? _route->input () : _route->output ();
/* Find most likely type among connected ports */ /* Find most likely type among connected ports */
if (favor_connected) { DataType type = DataType::NIL; /* NIL is always last so least likely */
DataType type = DataType::NIL; /* NIL is always last so least likely */ for (PortSet::iterator p = io->ports ().begin (); p != io->ports ().end (); ++p) {
for (PortSet::iterator p = io->ports ().begin (); p != io->ports ().end (); ++p) { if (p->connected () && p->type () < type)
if (p->connected () && p->type () < type) type = p->type ();
type = p->type (); }
} if (type != DataType::NIL) {
if (type != DataType::NIL) { /* There has been a connected port (necessarily non-NIL) */
/* There has been a connected port (necessarily non-NIL) */ return type;
return type;
}
} }
/* Find most likely type among available ports. /* Find most likely type among available ports.
@ -396,6 +392,19 @@ IOButton::guess_main_type (bool favor_connected) const
void void
IOButton::update () IOButton::update ()
{
boost::shared_ptr<ARDOUR::Bundle> bundle;
_bundle_connections.drop_connections ();
set_label (*this, _route->session(), bundle, _input ? _route->input () : _route->output ());
if (bundle) {
bundle->Changed.connect (_bundle_connections, invalidator (*this), boost::bind (&IOButton::update, this), gui_context ());
}
}
void
IOButton::set_label (ArdourWidgets::ArdourButton& self, ARDOUR::Session& session, boost::shared_ptr<ARDOUR::Bundle>& bndl, boost::shared_ptr<ARDOUR::IO> io)
{ {
ostringstream tooltip; ostringstream tooltip;
ostringstream label; ostringstream label;
@ -405,48 +414,42 @@ IOButton::update ()
uint32_t typed_connection_count = 0; uint32_t typed_connection_count = 0;
bool each_typed_port_has_one_connection = true; bool each_typed_port_has_one_connection = true;
DataType dt = guess_main_type (); DataType dt = guess_main_type (io);
boost::shared_ptr<IO> io = _input ? _route->input () : _route->output (); bool input = io->direction () == IO::Input;
string arrow = Gtkmm2ext::markup_escape_text (input ? " <- " : " -> ");
_bundle_connections.drop_connections ();
/* Fill in the tooltip. Also count: /* Fill in the tooltip. Also count:
* - The total number of connections. * - The total number of connections.
* - The number of main-typed connections. * - The number of main-typed connections.
* - Whether each main-typed port has exactly one connection. */ * - Whether each main-typed port has exactly one connection. */
if (_input) { if (input) {
tooltip << string_compose (_("<b>INPUT</b> to %1"), tooltip << string_compose (_("<b>INPUT</b> to %1"),
Gtkmm2ext::markup_escape_text (_route->name ())); Gtkmm2ext::markup_escape_text (io->name ()));
} else { } else {
tooltip << string_compose (_("<b>OUTPUT</b> from %1"), tooltip << string_compose (_("<b>OUTPUT</b> from %1"),
Gtkmm2ext::markup_escape_text (_route->name ())); Gtkmm2ext::markup_escape_text (io->name ()));
} }
string arrow = Gtkmm2ext::markup_escape_text (_input ? " <- " : " -> ");
vector<string> port_connections; vector<string> port_connections;
for (PortSet::iterator port = io->ports ().begin ();
port != io->ports ().end (); for (auto const& port : io->ports ()) {
++port) {
port_connections.clear (); port_connections.clear ();
port->get_connections (port_connections); port->get_connections (port_connections);
uint32_t port_connection_count = 0; uint32_t port_connection_count = 0;
for (vector<string>::iterator i = port_connections.begin (); for (auto const& i : port_connections) {
i != port_connections.end ();
++i) {
++port_connection_count; ++port_connection_count;
if (port_connection_count == 1) { if (port_connection_count == 1) {
tooltip << endl tooltip << endl
<< Gtkmm2ext::markup_escape_text ( << Gtkmm2ext::markup_escape_text (port->name ().substr (port->name ().find ("/") + 1));
port->name ().substr (port->name ().find ("/") + 1));
tooltip << arrow; tooltip << arrow;
} else { } else {
tooltip << ", "; tooltip << ", ";
} }
tooltip << Gtkmm2ext::markup_escape_text (*i); tooltip << Gtkmm2ext::markup_escape_text (i);
} }
total_connection_count += port_connection_count; total_connection_count += port_connection_count;
@ -468,12 +471,12 @@ IOButton::update ()
/* Are all main-typed channels connected to the same route ? */ /* Are all main-typed channels connected to the same route ? */
if (!have_label) { if (!have_label) {
boost::shared_ptr<ARDOUR::RouteList> routes = _route->session ().get_routes (); boost::shared_ptr<ARDOUR::RouteList> routes = session.get_routes ();
for (ARDOUR::RouteList::const_iterator route = routes->begin (); for (ARDOUR::RouteList::const_iterator route = routes->begin ();
route != routes->end (); route != routes->end ();
++route) { ++route) {
boost::shared_ptr<IO> dest_io = _input ? (*route)->output () : (*route)->input (); boost::shared_ptr<IO> dest_io = input ? (*route)->output () : (*route)->input ();
if (io->bundle ()->connected_to (dest_io->bundle (), _route->session ().engine (), dt, true)) { if (io->bundle ()->connected_to (dest_io->bundle (), session.engine (), dt, true)) {
label << Gtkmm2ext::markup_escape_text ((*route)->name ()); label << Gtkmm2ext::markup_escape_text ((*route)->name ());
have_label = true; have_label = true;
break; break;
@ -483,21 +486,19 @@ IOButton::update ()
/* Are all main-typed channels connected to the same (user) bundle ? */ /* Are all main-typed channels connected to the same (user) bundle ? */
if (!have_label) { if (!have_label) {
boost::shared_ptr<ARDOUR::BundleList> bundles = _route->session ().bundles (); boost::shared_ptr<ARDOUR::BundleList> bundles = session.bundles ();
boost::shared_ptr<ARDOUR::Port> ap = boost::dynamic_pointer_cast<ARDOUR::Port> (_route->session ().vkbd_output_port ()); boost::shared_ptr<ARDOUR::Port> ap = boost::dynamic_pointer_cast<ARDOUR::Port> (session.vkbd_output_port ());
std::string vkbd_portname = AudioEngine::instance ()->make_port_name_non_relative (ap->name ()); std::string vkbd_portname = AudioEngine::instance ()->make_port_name_non_relative (ap->name ());
for (ARDOUR::BundleList::iterator bundle = bundles->begin (); for (auto const& bundle : *bundles) {
bundle != bundles->end (); if (boost::dynamic_pointer_cast<UserBundle> (bundle) == 0) {
++bundle) { if (!bundle->offers_port (vkbd_portname)) {
if (boost::dynamic_pointer_cast<UserBundle> (*bundle) == 0) {
if (!(*bundle)->offers_port (vkbd_portname)) {
continue; continue;
} }
} }
if (io->bundle ()->connected_to (*bundle, _route->session ().engine (), dt, true)) { if (io->bundle ()->connected_to (bundle, session.engine (), dt, true)) {
label << Gtkmm2ext::markup_escape_text ((*bundle)->name ()); label << Gtkmm2ext::markup_escape_text (bundle->name ());
have_label = true; have_label = true;
(*bundle)->Changed.connect (_bundle_connections, invalidator (*this), boost::bind (&IOButton::update, this), gui_context ()); bndl = bundle;
break; break;
} }
} }
@ -508,28 +509,26 @@ IOButton::update ()
ostringstream temp_label; ostringstream temp_label;
vector<string> phys; vector<string> phys;
string playorcapture; string playorcapture;
if (_input) { if (input) {
_route->session ().engine ().get_physical_inputs (dt, phys); session.engine ().get_physical_inputs (dt, phys);
playorcapture = "capture_"; playorcapture = "capture_";
} else { } else {
_route->session ().engine ().get_physical_outputs (dt, phys); session.engine ().get_physical_outputs (dt, phys);
playorcapture = "playback_"; playorcapture = "playback_";
} }
for (PortSet::iterator port = io->ports ().begin (dt); for (PortSet::iterator port = io->ports ().begin (dt);
port != io->ports ().end (dt); port != io->ports ().end (dt);
++port) { ++port) {
string pn = ""; string pn = "";
for (vector<string>::iterator s = phys.begin (); for (auto const& s : phys) {
s != phys.end (); if (!port->connected_to (s)) {
++s) {
if (!port->connected_to (*s)) {
continue; continue;
} }
pn = AudioEngine::instance ()->get_pretty_name_by_name (*s); pn = AudioEngine::instance ()->get_pretty_name_by_name (s);
if (pn.empty ()) { if (pn.empty ()) {
string::size_type start = (*s).find (playorcapture); string::size_type start = (s).find (playorcapture);
if (start != string::npos) { if (start != string::npos) {
pn = (*s).substr (start + playorcapture.size ()); pn = (s).substr (start + playorcapture.size ());
} }
} }
break; break;
@ -539,8 +538,9 @@ IOButton::update ()
temp_label.str (""); /* erase the failed attempt */ temp_label.str (""); /* erase the failed attempt */
break; break;
} }
if (port != io->ports ().begin (dt)) if (port != io->ports ().begin (dt)) {
temp_label << "/"; temp_label << "/";
}
temp_label << pn; temp_label << pn;
} }
@ -595,8 +595,8 @@ IOButton::update ()
label << "\u2295"; /* circled plus */ label << "\u2295"; /* circled plus */
} }
set_text (label.str ()); self.set_text (label.str ());
set_tooltip (this, tooltip.str ()); set_tooltip (&self, tooltip.str ());
} }
void void

View File

@ -46,6 +46,9 @@ public:
void set_route (boost::shared_ptr<ARDOUR::Route>, RouteUI*); void set_route (boost::shared_ptr<ARDOUR::Route>, RouteUI*);
static ARDOUR::DataType guess_main_type (boost::shared_ptr<ARDOUR::IO>);
static void set_label (ArdourWidgets::ArdourButton&, ARDOUR::Session&, boost::shared_ptr<ARDOUR::Bundle>&, boost::shared_ptr<ARDOUR::IO>);
private: private:
void update (); void update ();
bool button_press (GdkEventButton*); bool button_press (GdkEventButton*);
@ -60,7 +63,6 @@ private:
boost::shared_ptr<ARDOUR::IO> io () const; boost::shared_ptr<ARDOUR::IO> io () const;
boost::shared_ptr<ARDOUR::Track> track () const; boost::shared_ptr<ARDOUR::Track> track () const;
ARDOUR::DataType guess_main_type (bool favor_connected = true) const;
bool _input; bool _input;
boost::shared_ptr<ARDOUR::Route> _route; boost::shared_ptr<ARDOUR::Route> _route;