17 using VariantType =
typename Base::VariantType;
18 using TrackUuid =
typename Base::UuidType;
21 using ArrangerObjectRegistry = arrangement::ArrangerObjectRegistry;
23 bool contains_track (
const TrackUuid &
id)
const
25 return std::ranges::contains (*
this,
id, Base::uuid_projection);
28 static auto name_projection (
const VariantType &track_var)
31 [] (
const auto &track) {
return track->get_name (); }, track_var);
33 static auto foldable_projection (
const VariantType &track_var)
36 [] (
const auto &track) {
37 using TrackT = base_type<
decltype (track)>;
43#define DEFINE_PROJECTION_FOR_TRACK_TYPE(func_name, base_class) \
44 static auto func_name##_projection (const VariantType &track_var) \
47 [] (const auto &track) { \
48 auto &track_ref = *track; \
49 using TrackT = base_type<decltype (track_ref)>; \
50 if constexpr (std::derived_from<TrackT, base_class>) \
52 return track_ref.func_name (); \
61 DEFINE_PROJECTION_FOR_TRACK_TYPE (enabled,
Track)
63 template <
typename BaseType>
64 static auto derived_type_transformation (
const VariantType &track_var)
67 [] (
const auto &track) {
68 using TrackT = base_type<
decltype (track)>;
69 if constexpr (!std::derived_from<TrackT, BaseType>)
71 throw std::runtime_error (
72 "Must filter before using this transformation.");
74 return dynamic_cast<BaseType *
> (track);
79 std::optional<VariantType>
82 auto it = std::ranges::find (*
this, name, name_projection);
83 return it != this->end () ? std::make_optional (*it) : std::nullopt;
88 return std::ranges::contains (*
this, name, name_projection);
93 auto it = std::ranges::find_if (*
this, [] (
const auto &track_var) {
94 return std::holds_alternative<MasterTrack *> (track_var);
96 if (it == this->end ())
98 throw std::runtime_error (
"Master track not found");
100 return *std::get<MasterTrack *> (*it);
108 std::ranges::for_each (*
this, [&] (
auto &&track_var) {
110 [&] (
auto &&tr) { tr->setVisible (!tr->visible ()); }, track_var);
118 void select_last_visible ()
120 auto res = std::ranges::find_last_if (*
this, visible_projection);
124 [&] (
auto &&tr) { select_single (tr->get_uuid ()); }, res.front ());
128 void select_all_visible_tracks ()
130 std::ranges::for_each (
131 *
this | std::views::filter (visible_projection), [] (
auto &&track_var) {
132 std::visit ([] (
auto &&tr) { tr->setSelected (
true); }, track_var);
143 return std::ranges::any_of (*
this, [&] (
auto &&track_var) {
145 [] (
auto &&tr) {
return !tr->has_automation (); }, track_var);
149 bool contains_undeletable_track ()
const
151 return std::ranges::any_of (*
this, [&] (
auto &&track_var) {
153 [] (
auto &&tr) {
return !tr->is_deletable (); }, track_var);
157 bool contains_uncopyable_track ()
const
159 return std::ranges::any_of (*
this, [&] (
auto &&track_var) {
161 [] (
auto &&tr) {
return !tr->is_copyable (); }, track_var);
165 bool contains_uninstantiated_plugin ()
const
167 return std::ranges::any_of (*
this, [] (
const auto &track_var) {
169 [&] (
auto &&tr) {
return tr->contains_uninstantiated_plugin (); },
179 std::ranges::for_each (*
this, [&container] (
const auto &track_var) {
181 [&container] (
auto &&track) { track->collect_plugins (container); },
186 void deselect_all_plugins ()
191 static bool currently_soloed_projection (
const VariantType &var)
195 if (!track->channel ())
197 return track->channel ()->fader ()->currently_soloed ();
201 static bool currently_muted_projection (
const VariantType &var)
205 if (!track->channel ())
207 return track->channel ()->fader ()->currently_muted ();
211 static bool currently_listened_projection (
const VariantType &var)
215 if (!track->channel ())
217 return track->channel ()->fader ()->currently_listened ();
222 static bool soloed_projection (
const VariantType &var)
226 if (!track->channel ())
228 const auto * solo = track->channel ()->fader ()->solo ();
229 return solo->range ().is_toggled (solo->baseValue ());
233 static bool muted_projection (
const VariantType &var)
237 if (!track->channel ())
239 const auto * mute = track->channel ()->fader ()->mute ();
240 return mute->range ().is_toggled (mute->baseValue ());
244 static bool listened_projection (
const VariantType &var)
248 if (!track->channel ())
250 const auto * listen = track->channel ()->fader ()->listen ();
251 return listen->range ().is_toggled (listen->baseValue ());
256 auto has_soloed ()
const
258 return std::ranges::any_of (*
this, currently_soloed_projection);
261 auto has_listened ()
const
263 return std::ranges::any_of (*
this, currently_listened_projection);
266 auto get_num_muted_tracks ()
const
268 return std::ranges::count_if (*
this, muted_projection);
271 auto get_num_soloed_tracks ()
const
273 return std::ranges::count_if (*
this, soloed_projection);
276 auto get_num_listened_tracks ()
const
278 return std::ranges::count_if (*
this, listened_projection);
287 std::ranges::for_each (*
this, [&] (
const auto &track_var) {
288 std::visit ([&] (
auto &&track) { track->set_caches (types); }, track_var);
301 std::vector<VariantType> create_snapshots (
303 TrackRegistry &track_registry,
304 PluginRegistry &plugin_registry,
305 PortRegistry &port_registry,
306 ArrangerObjectRegistry &obj_registry)
const
308 return std::ranges::to<std::vector> (
309 *
this | std::views::transform ([&] (
const auto &track_var) {
311 [&] (
auto &&track) -> VariantType {
312 return utils::clone_qobject (
314 plugin_registry, port_registry, obj_registry,
false);
320 std::vector<TrackUuidReference>
321 create_new_identities (FinalTrackDependencies track_deps)
const
323 return std::ranges::to<std::vector> (
324 *
this | std::views::transform ([&] (
const auto &track_var) {
326 [&] (
auto &&track) -> TrackUuidReference {
327 return track_deps.track_registry_.clone_object (*track, track_deps);