6#include "dsp/tempo_map.h"
7#include "structure/arrangement/arranger_object_span.h"
8#include "structure/tracks/track.h"
9#include "structure/tracks/track_span.h"
11#include <QtQmlIntegration>
15#define TRACKLIST (PROJECT->tracklist_)
17namespace zrythm::engine::session
24namespace zrythm::structure::tracks
38class Tracklist final :
public QAbstractListModel
45 using ArrangerObjectPtrVariant = arrangement::ArrangerObjectPtrVariant;
61 TrackPtrRole = Qt::UserRole + 1,
68 PortRegistry &port_registry,
69 TrackRegistry &track_registry,
71 const dsp::TempoMap &tempo_map);
74 PortRegistry &port_registry,
75 TrackRegistry &track_registry,
77 const dsp::TempoMap &tempo_map);
78 Z_DISABLE_COPY_MOVE (Tracklist)
79 ~Tracklist ()
override;
84 QHash<int, QByteArray> roleNames ()
const override;
85 int rowCount (
const QModelIndex &parent = QModelIndex ())
const override;
87 data (
const QModelIndex &index,
int role = Qt::DisplayRole)
const override;
89 Q_INVOKABLE
void setExclusivelySelectedTrack (QVariant track);
100 auto get_track_span ()
const {
return TrackSpan{ tracks_ }; }
102 bool is_auditioner ()
const {
return sample_processor_ !=
nullptr; }
104 friend void init_from (
106 const Tracklist &other,
113 PortRegistry &port_registry,
122 PortRegistry &port_registry,
125 init_loaded (port_registry,
nullptr, &sample_processor);
136 const TrackUuidReference &track_id,
152 track_id, tracks_.size (), engine, publish_events, recalc_graph);
175 bool always_before_pos,
176 std::optional<std::reference_wrapper<engine::session::Router>> router);
178 std::optional<TrackPtrVariant> get_track (
const TrackUuid &
id)
const
180 auto span = get_track_span ();
181 auto it = std::ranges::find (span,
id, TrackSpan::uuid_projection);
182 if (it == span.end ()) [[unlikely]]
186 return std::make_optional (*it);
212 std::optional<TrackPtrVariant>
219 std::optional<TrackPtrVariant>
239 std::optional<TrackPtrVariant>
243 return get_track_span ().get_track_by_pos (
255 std::optional<TrackPtrVariant>
266 Track::TrackUuid src_track,
267 Track::TrackUuid dest_track)
const;
283 void handle_click (TrackUuid track_id,
bool ctrl,
bool shift,
bool dragged);
285 std::vector<ArrangerObjectPtrVariant> get_timeline_objects_in_range (
286 std::optional<std::pair<dsp::Position, dsp::Position>> range = std::nullopt)
314 std::vector<std::vector<std::shared_ptr<Region>>> ®ion_arrays,
315 const FileImportInfo * import_info,
316 TracksReadyCallback ready_cb);
336 ArrangerObjectPtrVariant region,
338 int lane_or_at_index,
345 const Plugin::Uuid &plugin_id,
359 const Plugin::Uuid &plugin_id,
362 bool confirm_overwrite);
364 Channel * get_channel_for_plugin (
const Plugin::Uuid &plugin_id);
380 std::optional<std::vector<utils::Utf8String>> uri_list,
386 TracksReadyCallback ready_cb);
396 void handle_move_or_copy (
399 GdkDragAction action);
416 return index < pinned_tracks_cutoff_;
419 auto get_track_index (
const Track::TrackUuid &track_id)
const
421 return std::distance (
423 std::ranges::find (tracks_, track_id, &TrackUuidReference::id));
426 auto get_track_at_index (
size_t index)
const
428 if (index >= tracks_.size ())
429 throw std::out_of_range (
"Track index out of range");
430 return get_track_span ().at (index);
433 auto get_track_ref_at_index (
size_t index)
const
435 if (index >= tracks_.size ())
436 throw std::out_of_range (
"Track index out of range");
437 return tracks_.at (index);
445 auto get_selection_manager ()
447 return TrackSelectionManager{ selected_tracks_, *track_registry_ };
456 auto selected_vec = std::ranges::to<std::vector> (selected_tracks_);
457 TrackSpan span{ *track_registry_, selected_vec };
458 std::ranges::for_each (span, [&] (
auto &&track_var) {
460 [&] (
auto &&track_ref) {
461 using TrackT = base_type<
decltype (track_ref)>;
462 if constexpr (std::derived_from<TrackT, FoldableTrack>)
464 for (
int i = 1; i < track_ref->size_; ++i)
466 const size_t child_pos =
467 get_track_index (track_ref->get_uuid ()) + i;
468 const auto &child_track_var = get_track_at_index (child_pos);
469 get_selection_manager ().append_to_selection (
470 TrackSpan::uuid_projection (child_track_var));
478 auto get_pinned_tracks_cutoff_index ()
const {
return pinned_tracks_cutoff_; }
479 void set_pinned_tracks_cutoff_index (
size_t index)
481 pinned_tracks_cutoff_ = index;
483 auto track_count ()
const {
return tracks_.size (); }
494 TrackPtrVariant track_var,
500 void mark_all_tracks_for_bounce (
bool bounce)
502 get_track_span ().mark_all_tracks_for_bounce (*
this, bounce);
505 void disconnect_plugin (
const Plugin::Uuid &plugin_id);
510 static constexpr auto kPinnedTracksCutoffKey =
"pinnedTracksCutoff"sv;
511 static constexpr auto kTracksKey =
"tracks"sv;
512 static constexpr auto kSelectedTracksKey =
"selectedTracks"sv;
513 friend void to_json (nlohmann::json &j,
const Tracklist &t)
516 { kPinnedTracksCutoffKey, t.pinned_tracks_cutoff_ },
517 { kTracksKey, t.tracks_ },
518 { kSelectedTracksKey, t.selected_tracks_ },
521 friend void from_json (
const nlohmann::json &j, Tracklist &t)
523 j.at (kPinnedTracksCutoffKey).get_to (t.pinned_tracks_cutoff_);
524 j.at (kTracksKey).get_to (t.tracks_);
525 j.at (kSelectedTracksKey).get_to (t.selected_tracks_);
528 void swap_tracks (
size_t index1,
size_t index2);
536 void disconnect_port (
const Port::Uuid &port_id);
544 void disconnect_channel (Channel &channel);
557 void disconnect_track_processor (
TrackProcessor &track_processor);
562 void disconnect_track (
Track &track);
564 auto &get_track_registry ()
const {
return *track_registry_; }
565 auto &get_track_registry () {
return *track_registry_; }
568 const dsp::TempoMap &tempo_map_;
591 std::vector<TrackUuidReference> tracks_;
598 TrackSelectionManager::UuidSet selected_tracks_;
619 size_t pinned_tracks_cutoff_ = 0;
623 std::atomic<bool> swapping_tracks_ =
false;
633 mutable QHash<Port::Uuid, AutomationTrack *> port_to_at_mappings_;
Contains all of the info that will be serialized into a project file.
A connection between two ports.
Port connections manager.
Represents the position of an object.
The Router class manages the processing graph for the audio engine.
A processor to be used in the routing graph for playing samples independent of the timeline.
Base class for all objects in the arranger.
A region (clip) is an object on the timeline that contains either MidiNote's or AudioClip's.
Represents a channel strip on the mixer.
The ChordTrack class is responsible for managing the chord and scale information in the project.
A Fader is a processor that is used for volume controls and pan.
A track that can host modulator plugins.
A TrackLane belongs to a Track (can have many TrackLanes in a Track) and contains Regions.
A TrackProcessor is a processor that is used as the first entry point when processing a track.
Track span that offers helper methods on a range of tracks.
Represents a track in the project.
@ Marker
Marker Track's contain named markers at specific Position's in the song.
@ Modulator
Special track to contain global Modulator's.
@ Chord
The chord track contains chords that can be used to modify midi in real time or to color the piano ro...
The Tracklist contains all the tracks in the Project.
void import_files(std::optional< std::vector< utils::Utf8String > > uri_list, const FileDescriptor *orig_file, const Track *track, const TrackLane *lane, int index, const zrythm::dsp::Position *pos, TracksReadyCallback ready_cb)
Begins file import Handles a file drop inside the timeline or in empty space in the tracklist.
void move_region_to_track(ArrangerObjectPtrVariant region, const Track::Uuid &to_track_id, int lane_or_at_index, int index)
Moves the Region to the given Track, maintaining the selection status of the Region.
void set_track_pinned(TrackUuid track_id, bool pinned, int publish_events, int recalc_graph)
Pins or unpins the Track.
void init_loaded(PortRegistry &port_registry, Project *project, engine::session::SampleProcessor *sample_processor)
Initializes the tracklist when loading a project.
TrackPtrVariant insert_track(const TrackUuidReference &track_id, int pos, engine::device_io::AudioEngine &engine, bool publish_events, bool recalc_graph)
Adds given track to given spot in tracklist.
PinOption
Used in track search functions.
void clear_selections_for_object_siblings(const ArrangerObject::Uuid &object_id)
Clears either the timeline selections or the clip editor selections.
std::optional< TrackPtrVariant > get_first_visible_track(bool pinned) const
Returns the first visible Track.
void move_plugin_automation(const Plugin::Uuid &plugin_id, const Track::Uuid &prev_track_id, const Track::Uuid &track_id_to_move_to, zrythm::plugins::PluginSlot new_slot)
Moves the Plugin's automation from one Channel to another.
ChordTrack * chord_track_
The chord track, for convenience.
void select_foldable_children_of_current_selections()
Also selects the children of foldable tracks in the currently selected tracks.
bool multiply_track_heights(double multiplier, bool visible_only, bool check_only, bool fire_events)
Multiplies all tracks' heights and returns if the operation was valid.
Project * project_
Pointer to owner project, if any.
MarkerTrack * marker_track_
The marker track, for convenience.
MasterTrack * master_track_
The master track, for convenience.
QPointer< dsp::PortConnectionsManager > port_connections_manager_
Width of track widgets.
void move_plugin(const Plugin::Uuid &plugin_id, const Track::Uuid &target_track_id, plugins::PluginSlot slot, bool confirm_overwrite)
Moves the plugin to the given slot in the given channel.
void handle_click(TrackUuid track_id, bool ctrl, bool shift, bool dragged)
Handle a click selection.
void import_regions(std::vector< std::vector< std::shared_ptr< Region > > > ®ion_arrays, const FileImportInfo *import_info, TracksReadyCallback ready_cb)
Imports regions from a region array.
AutomationTrack * get_automation_track_for_port(const Port::Uuid &port_id) const
Gets the automation track for a port.
std::optional< TrackPtrVariant > get_prev_visible_track(Track::TrackUuid track_id) const
Returns the previous visible Track in the same Tracklist as the given one (ie, pinned or not).
std::optional< TrackPtrVariant > get_visible_track_after_delta(Track::TrackUuid track_id, int delta) const
Returns the Track after delta visible Track's.
bool is_track_pinned(size_t index) const
Returns whether the track at index is pinned.
void remove_track(const TrackUuid &track_id)
Removes the given track from the tracklist.
bool track_name_is_unique(const utils::Utf8String &name, TrackUuid track_to_skip) const
Returns whether the track name is not taken.
std::optional< TrackPtrVariant > get_next_visible_track(Track::TrackUuid track_id) const
Returns the next visible Track in the same Tracklist as the given one (ie, pinned or not).
int get_visible_track_diff(Track::TrackUuid src_track, Track::TrackUuid dest_track) const
Returns the number of visible Tracks between src and dest (negative if dest is before src).
TrackPtrVariant append_track(auto track_id, engine::device_io::AudioEngine &engine, bool publish_events, bool recalc_graph)
Calls insert_track with the given options.
ModulatorTrack * modulator_track_
The modulator track, for convenience.
void move_track(TrackUuid track_id, int pos, bool always_before_pos, std::optional< std::reference_wrapper< engine::session::Router > > router)
Moves a track from its current position to the position given by pos.
void disconnect_fader(Fader &fader)
Disconnects all ports connected to the fader.
int get_last_pos(PinOption pin_opt=PinOption::Both, bool visible_only=false) const
Returns the index of the last Track.
std::optional< TrackPtrVariant > get_last_track(PinOption pin_opt=PinOption::Both, bool visible_only=false) const
Returns the last Track.
static constexpr std::array< Track::Type, 4 > unique_track_types_
A list of track types that must be unique in the tracklist.
void mark_track_for_bounce(TrackPtrVariant track_var, bool bounce, bool mark_regions, bool mark_children, bool mark_parents)
Marks the track for bouncing.
Lightweight UTF-8 string wrapper with safe conversions.
Wrapper around std::optional<std::reference_wrapper<T>> that provides a more convenient API.