libardour changes to support new selection/group logic

This commit is contained in:
Paul Davis 2023-07-31 13:36:14 -06:00
parent 8340be4808
commit 03105aa760
7 changed files with 77 additions and 35 deletions

View file

@ -35,6 +35,8 @@
namespace ARDOUR { namespace ARDOUR {
class CoreSelection; class CoreSelection;
class RouteGroup;
class Stripable;
class LIBARDOUR_API ControlGroup : public std::enable_shared_from_this<ControlGroup> class LIBARDOUR_API ControlGroup : public std::enable_shared_from_this<ControlGroup>
{ {
@ -47,7 +49,7 @@ class LIBARDOUR_API ControlGroup : public std::enable_shared_from_this<ControlGr
Inverted = 0x2, Inverted = 0x2,
}; };
void fill_from_selection (CoreSelection const &, Evoral::Parameter const &); void fill_from_selection_or_group (std::shared_ptr<Stripable>, CoreSelection const &, Evoral::Parameter const &, bool (RouteGroup::*group_predicate)() const);
int add_control (std::shared_ptr<AutomationControl>, bool push = false); int add_control (std::shared_ptr<AutomationControl>, bool push = false);
int remove_control (std::shared_ptr<AutomationControl>, bool pop = false); int remove_control (std::shared_ptr<AutomationControl>, bool pop = false);

View file

@ -73,6 +73,8 @@ class LIBARDOUR_API CoreSelection : public PBD::Stateful {
typedef std::vector<StripableAutomationControl> StripableAutomationControls; typedef std::vector<StripableAutomationControl> StripableAutomationControls;
void get_stripables (StripableAutomationControls&) const; void get_stripables (StripableAutomationControls&) const;
void get_stripables_for_op (StripableList&, std::shared_ptr<Stripable> base, bool (RouteGroup::*group_predicate)() const) const;
void get_stripables_for_op (std::shared_ptr<StripableList>, std::shared_ptr<Stripable> base, bool (RouteGroup::*group_predicate)() const) const;
XMLNode& get_state () const; XMLNode& get_state () const;
int set_state (const XMLNode&, int version); int set_state (const XMLNode&, int version);

View file

@ -38,9 +38,9 @@ public:
void set_exclusive (bool exclusive = true); void set_exclusive (bool exclusive = true);
void set (std::shared_ptr<Route>); void set (std::shared_ptr<Stripable>);
void set (std::shared_ptr<RouteList const>); void set (std::shared_ptr<StripableList const>);
void set (std::shared_ptr<RouteList const>, std::shared_ptr<RouteList const>); void set (std::shared_ptr<StripableList const>, std::shared_ptr<StripableList const>);
void set (std::shared_ptr<std::list<std::string> >); void set (std::shared_ptr<std::list<std::string> >);
void release (Session*, bool mute) const; void release (Session*, bool mute) const;
@ -49,8 +49,8 @@ private:
bool active; bool active;
bool exclusive; bool exclusive;
std::shared_ptr<RouteList const> routes_on; std::shared_ptr<StripableList const> routes_on;
std::shared_ptr<RouteList const> routes_off; std::shared_ptr<StripableList const> routes_off;
std::shared_ptr<std::list<std::string> > port_monitors; std::shared_ptr<std::list<std::string> > port_monitors;
}; };

View file

@ -218,11 +218,11 @@ ControlGroup::set_group_value (std::shared_ptr<AutomationControl> control, doubl
} }
void void
ControlGroup::fill_from_selection (CoreSelection const & sel, Evoral::Parameter const & p) ControlGroup::fill_from_selection_or_group (std::shared_ptr<Stripable> target, CoreSelection const & sel, Evoral::Parameter const & p, bool (RouteGroup::*group_predicate)() const)
{ {
CoreSelection::StripableAutomationControls stripables; StripableList sl;
sel.get_stripables (stripables); sel.get_stripables_for_op (sl, target, group_predicate);
/* Very unfortunate that gain control is special cased. Routes do not /* Very unfortunate that gain control is special cased. Routes do not
* call ::add_control() for their gain control, but instead pass it to * call ::add_control() for their gain control, but instead pass it to
@ -231,24 +231,24 @@ ControlGroup::fill_from_selection (CoreSelection const & sel, Evoral::Parameter
switch (p.type()) { switch (p.type()) {
case GainAutomation: case GainAutomation:
for (auto & s : stripables) { for (auto & s : sl) {
std::shared_ptr<AutomationControl> ac = s.stripable->gain_control (); std::shared_ptr<AutomationControl> ac = s->gain_control ();
if (ac) { if (ac) {
add_control (ac, true); add_control (ac, true);
} }
} }
break; break;
case TrimAutomation: case TrimAutomation:
for (auto & s : stripables) { for (auto & s : sl) {
std::shared_ptr<AutomationControl> ac = s.stripable->trim_control (); std::shared_ptr<AutomationControl> ac = s->trim_control ();
if (ac) { if (ac) {
add_control (ac, true); add_control (ac, true);
} }
} }
break; break;
default: default:
for (auto & s : stripables) { for (auto & s : sl) {
std::shared_ptr<AutomationControl> ac = s.stripable->automation_control (p, true); std::shared_ptr<AutomationControl> ac = s->automation_control (p, true);
if (ac) { if (ac) {
add_control (ac, true); add_control (ac, true);
} }

View file

@ -613,3 +613,41 @@ CoreSelection::selected () const
Glib::Threads::RWLock::ReaderLock lm (_lock); Glib::Threads::RWLock::ReaderLock lm (_lock);
return _stripables.size(); return _stripables.size();
} }
void
CoreSelection::get_stripables_for_op (std::shared_ptr<StripableList> sl, std::shared_ptr<Stripable> target, bool (RouteGroup::*group_predicate)() const) const
{
return get_stripables_for_op (*sl.get(), target, group_predicate);
}
void
CoreSelection::get_stripables_for_op (StripableList& sl, std::shared_ptr<Stripable> target, bool (RouteGroup::*group_predicate)() const) const
{
if (_stripables.empty()) {
std::shared_ptr<Route> r (std::dynamic_pointer_cast<Route> (target));
if (r) {
RouteGroup* rg = r->route_group();
if (rg && rg->is_active() && (rg->*group_predicate)()) {
for (auto & r : *rg->route_list()) {
sl.push_back (r);
}
} else {
sl.push_back (target);
}
} else {
/* Base is not a route, use it and it alone */
sl.push_back (target);
}
} else {
StripableAutomationControls sc;
get_stripables (sc);
for (auto & s : sc) {
sl.push_back (s.stripable);
}
}
}

View file

@ -130,25 +130,25 @@ Session::rt_set_controls (std::shared_ptr<WeakControlList> cl, double val, Contr
void void
Session::prepare_momentary_solo (SoloMuteRelease* smr, bool exclusive, std::shared_ptr<Route> route) Session::prepare_momentary_solo (SoloMuteRelease* smr, bool exclusive, std::shared_ptr<Route> route)
{ {
std::shared_ptr<RouteList> routes_on (new RouteList); std::shared_ptr<StripableList> routes_on (new StripableList);
std::shared_ptr<RouteList> routes_off (new RouteList); std::shared_ptr<StripableList> routes_off (new StripableList);
std::shared_ptr<RouteList const> routes = get_routes(); std::shared_ptr<RouteList const> routes = get_routes();
for (auto const& i : *routes) { for (auto const & r : *routes) {
#ifdef MIXBUS #ifdef MIXBUS
if (route && (0 == route->mixbus()) != (0 == i->mixbus ())) { if (route && (0 == route->mixbus()) != (0 == r->mixbus ())) {
continue; continue;
} }
#endif #endif
if (i->soloed ()) { if (r->soloed ()) {
routes_on->push_back (i); routes_on->push_back (r);
} else if (smr) { } else if (smr) {
routes_off->push_back (i); routes_off->push_back (r);
} }
} }
if (exclusive) { if (exclusive) {
set_controls (route_list_to_control_list (routes_on, &Stripable::solo_control), false, Controllable::UseGroup); set_controls (stripable_list_to_control_list (routes_on, &Stripable::solo_control), false, Controllable::UseGroup);
} }
if (smr) { if (smr) {

View file

@ -40,20 +40,20 @@ SoloMuteRelease::set_exclusive (bool e)
} }
void void
SoloMuteRelease::set (std::shared_ptr<Route> r) SoloMuteRelease::set (std::shared_ptr<Stripable> r)
{ {
std::shared_ptr<RouteList> rl (new RouteList); std::shared_ptr<StripableList> sl (new StripableList);
if (active) { if (active) {
rl->push_back (r); sl->push_back (r);
routes_on = rl; routes_on = sl;
} else { } else {
rl->push_back (r); sl->push_back (r);
routes_off = rl; routes_off = sl;
} }
} }
void void
SoloMuteRelease::set (std::shared_ptr<RouteList const> rl) SoloMuteRelease::set (std::shared_ptr<StripableList const> rl)
{ {
if (active) { if (active) {
routes_on = rl; routes_on = rl;
@ -63,7 +63,7 @@ SoloMuteRelease::set (std::shared_ptr<RouteList const> rl)
} }
void void
SoloMuteRelease::set (std::shared_ptr<RouteList const> on, std::shared_ptr<RouteList const> off) SoloMuteRelease::set (std::shared_ptr<StripableList const> on, std::shared_ptr<StripableList const> off)
{ {
routes_on = on; routes_on = on;
routes_off = off; routes_off = off;
@ -79,11 +79,11 @@ void
SoloMuteRelease::release (Session* s, bool mute) const SoloMuteRelease::release (Session* s, bool mute) const
{ {
if (mute) { if (mute) {
s->set_controls (route_list_to_control_list (routes_off, &Stripable::mute_control), 0.0, exclusive ? Controllable::NoGroup : Controllable::UseGroup); s->set_controls (stripable_list_to_control_list (routes_off, &Stripable::mute_control), 0.0, exclusive ? Controllable::NoGroup : Controllable::NoGroup);
s->set_controls (route_list_to_control_list (routes_on, &Stripable::mute_control), 1.0, exclusive ? Controllable::NoGroup : Controllable::UseGroup); s->set_controls (stripable_list_to_control_list (routes_on, &Stripable::mute_control), 1.0, exclusive ? Controllable::NoGroup : Controllable::NoGroup);
} else { } else {
s->set_controls (route_list_to_control_list (routes_off, &Stripable::solo_control), 0.0, exclusive ? Controllable::NoGroup : Controllable::UseGroup); s->set_controls (stripable_list_to_control_list (routes_off, &Stripable::solo_control), 0.0, exclusive ? Controllable::NoGroup : Controllable::NoGroup);
s->set_controls (route_list_to_control_list (routes_on, &Stripable::solo_control), 1.0, exclusive ? Controllable::NoGroup : Controllable::UseGroup); s->set_controls (stripable_list_to_control_list (routes_on, &Stripable::solo_control), 1.0, exclusive ? Controllable::NoGroup : Controllable::NoGroup);
if (port_monitors && s->monitor_out ()) { if (port_monitors && s->monitor_out ()) {
s->engine().monitor_port().set_active_monitors (*port_monitors); s->engine().monitor_port().set_active_monitors (*port_monitors);