Zrythm v2.0.0-DEV
a highly automated and intuitive digital audio workstation
Loading...
Searching...
No Matches
track_lane_list.h
1// SPDX-FileCopyrightText: © 2024-2025 Alexandros Theodotou <alex@zrythm.org>
2// SPDX-License-Identifier: LicenseRef-ZrythmLicense
3
4#pragma once
5
6#include "structure/tracks/track_lane.h"
7#include "structure/tracks/track_processor.h"
8#include "utils/expandable_tick_range.h"
9
10namespace zrythm::structure::tracks
11{
12class TrackLaneList : public QAbstractListModel
13{
14 Q_OBJECT
15 Q_PROPERTY (
16 bool lanesVisible READ lanesVisible WRITE setLanesVisible NOTIFY
17 lanesVisibleChanged)
18 QML_ELEMENT
19 QML_UNCREATABLE ("")
20
21public:
22 enum Roles
23 {
24 TrackLanePtrRole = Qt::UserRole + 1,
25 };
26 Q_ENUM (Roles)
27
28public:
29 TrackLaneList (
30 structure::arrangement::ArrangerObjectRegistry &obj_registry,
31 dsp::FileAudioSourceRegistry &file_audio_source_registry,
32 QObject * parent = nullptr);
33 ~TrackLaneList () override;
34 Z_DISABLE_COPY_MOVE (TrackLaneList)
35
36 // ========================================================================
37 // QML Interface
38 // ========================================================================
39 QHash<int, QByteArray> roleNames () const override;
40 int rowCount (const QModelIndex &parent = QModelIndex ()) const override;
41 QVariant
42 data (const QModelIndex &index, int role = Qt::DisplayRole) const override;
43
44 Q_INVOKABLE TrackLane * getFirstLane () const
45 {
46 return lanes_.front ().get ();
47 }
48
49 bool lanesVisible () const { return lanes_visible_; }
50 void setLanesVisible (bool visible)
51 {
52 if (lanes_visible_ == visible)
53 return;
54
55 lanes_visible_ = visible;
56 Q_EMIT lanesVisibleChanged (visible);
57 }
58 Q_SIGNAL void lanesVisibleChanged (bool visible);
59
63 Q_INVOKABLE TrackLane * addLane () { return insertLane (rowCount ()); }
64 Q_INVOKABLE TrackLane * insertLane (size_t index);
65 Q_INVOKABLE void removeLane (size_t index);
66
67 Q_INVOKABLE void moveLane (size_t from_index, size_t to_index);
68
69 Q_SIGNAL void
70 laneObjectsNeedRecache (utils::ExpandableTickRange affectedRange);
71
72 // ========================================================================
73
74 friend void init_from (
75 TrackLaneList &obj,
76 const TrackLaneList &other,
77 utils::ObjectCloneType clone_type);
78
79 [[nodiscard]] size_t size () const noexcept { return lanes_.size (); }
80
81 [[nodiscard]] bool empty () const noexcept { return lanes_.empty (); }
82
83 TrackLane * at (size_t idx) const { return lanes_.at (idx).get (); }
84
85#if 0
86 void reserve (size_t size) { lanes_.reserve (size); }
87
88 void push_back (utils::QObjectUniquePtr<TrackLane> &&lane)
89 {
90 const int idx = static_cast<int> (lanes_.size ());
91 beginInsertRows (QModelIndex (), idx, idx);
92 lane->setParent (this);
93 lanes_.emplace_back (std::move (lane));
94 endInsertRows ();
95 }
96#endif
100 {
101 if (!empty ())
102 {
103 const int idx = static_cast<int> (lanes_.size () - 1);
104 beginRemoveRows (QModelIndex (), idx, idx);
105 auto lane = std::move (lanes_.back ());
106 lanes_.pop_back ();
107 endRemoveRows ();
108 return lane;
109 }
110 return {};
111 }
112
113 void clear ()
114 {
115 if (!empty ())
116 {
117 beginRemoveRows (
118 QModelIndex (), 0, static_cast<int> (lanes_.size () - 1));
119 lanes_.clear ();
120 endRemoveRows ();
121 }
122 }
123
124 auto &lanes () const { return lanes_; }
125
126 auto lanes_view () const
127 {
128 return lanes_
129 | std::views::transform (&utils::QObjectUniquePtr<TrackLane>::get);
130 }
131
133 * @brief Gets the total height of all visible lanes (if any).
134 */
135 double get_visible_lane_heights () const
136 {
137 if (!lanes_visible_)
138 return 0;
139
140 return std::ranges::fold_left (
141 lanes_view () | std::views::transform (&TrackLane::height), 0,
142 std::plus{});
143 }
144
148 void create_missing_lanes (size_t index);
149
154
155private:
156 static constexpr auto kLanesKey = "lanes"sv;
157 static constexpr std::string_view kLanesVisibleKey = "lanesVisible";
158 friend void to_json (nlohmann::json &j, const TrackLaneList &p)
159 {
160 j[kLanesKey] = p.lanes_;
161 j[kLanesVisibleKey] = p.lanes_visible_;
162 }
163 friend void from_json (const nlohmann::json &j, TrackLaneList &p)
164 {
165 p.lanes_.clear ();
166 for (const auto &lane_json : j.at (kLanesKey))
167 {
168 p.lanes_.emplace_back (
169 utils::make_qobject_unique<TrackLane> (p.dependencies_, &p));
170 lane_json.get_to (*p.lanes_.back ());
171 }
172 j.at (kLanesVisibleKey).get_to (p.lanes_visible_);
173 }
174
175 void erase (size_t pos);
176
177 void update_default_lane_names ();
178
179private:
180 TrackLane::TrackLaneDependencies dependencies_;
181 std::vector<utils::QObjectUniquePtr<TrackLane>> lanes_;
182
184 bool lanes_visible_ = false;
185
186 BOOST_DESCRIBE_CLASS (TrackLaneList, (), (), (), (lanes_, lanes_visible_))
187};
188}
double get_visible_lane_heights() const
Gets the total height of all visible lanes (if any).
void create_missing_lanes(size_t index)
Creates missing TrackLane's until index.
void remove_empty_last_lanes()
Removes the empty last lanes of the Track (except the last one).
Q_INVOKABLE TrackLane * addLane()
Adds a lane to the end of the list with default settings.
utils::QObjectUniquePtr< TrackLane > pop_back()
Removes last lane.
A container of MIDI or Audio regions.
Definition track_lane.h:28
A unique pointer for QObject objects that also works with QObject-based ownership.
Definition qt.h:38