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 {
class CoreSelection;
class RouteGroup;
class Stripable;
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,
};
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 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;
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;
int set_state (const XMLNode&, int version);

View File

@ -38,9 +38,9 @@ public:
void set_exclusive (bool exclusive = true);
void set (std::shared_ptr<Route>);
void set (std::shared_ptr<RouteList const>);
void set (std::shared_ptr<RouteList const>, std::shared_ptr<RouteList const>);
void set (std::shared_ptr<Stripable>);
void set (std::shared_ptr<StripableList const>);
void set (std::shared_ptr<StripableList const>, std::shared_ptr<StripableList const>);
void set (std::shared_ptr<std::list<std::string> >);
void release (Session*, bool mute) const;
@ -49,8 +49,8 @@ private:
bool active;
bool exclusive;
std::shared_ptr<RouteList const> routes_on;
std::shared_ptr<RouteList const> routes_off;
std::shared_ptr<StripableList const> routes_on;
std::shared_ptr<StripableList const> routes_off;
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
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
* 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()) {
case GainAutomation:
for (auto & s : stripables) {
std::shared_ptr<AutomationControl> ac = s.stripable->gain_control ();
for (auto & s : sl) {
std::shared_ptr<AutomationControl> ac = s->gain_control ();
if (ac) {
add_control (ac, true);
}
}
break;
case TrimAutomation:
for (auto & s : stripables) {
std::shared_ptr<AutomationControl> ac = s.stripable->trim_control ();
for (auto & s : sl) {
std::shared_ptr<AutomationControl> ac = s->trim_control ();
if (ac) {
add_control (ac, true);
}
}
break;
default:
for (auto & s : stripables) {
std::shared_ptr<AutomationControl> ac = s.stripable->automation_control (p, true);
for (auto & s : sl) {
std::shared_ptr<AutomationControl> ac = s->automation_control (p, true);
if (ac) {
add_control (ac, true);
}

View File

@ -613,3 +613,41 @@ CoreSelection::selected () const
Glib::Threads::RWLock::ReaderLock lm (_lock);
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
Session::prepare_momentary_solo (SoloMuteRelease* smr, bool exclusive, std::shared_ptr<Route> route)
{
std::shared_ptr<RouteList> routes_on (new RouteList);
std::shared_ptr<RouteList> routes_off (new RouteList);
std::shared_ptr<StripableList> routes_on (new StripableList);
std::shared_ptr<StripableList> routes_off (new StripableList);
std::shared_ptr<RouteList const> routes = get_routes();
for (auto const& i : *routes) {
for (auto const & r : *routes) {
#ifdef MIXBUS
if (route && (0 == route->mixbus()) != (0 == i->mixbus ())) {
if (route && (0 == route->mixbus()) != (0 == r->mixbus ())) {
continue;
}
#endif
if (i->soloed ()) {
routes_on->push_back (i);
if (r->soloed ()) {
routes_on->push_back (r);
} else if (smr) {
routes_off->push_back (i);
routes_off->push_back (r);
}
}
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) {

View File

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