Zrythm v2.0.0-alpha.1
a highly automated and intuitive digital audio workstation
Loading...
Searching...
No Matches
automation_tracklist.h
1// SPDX-FileCopyrightText: © 2018-2026 Alexandros Theodotou <alex@zrythm.org>
2// SPDX-License-Identifier: LicenseRef-ZrythmLicense
3
4#pragma once
5
6#include "structure/tracks/automation_track.h"
7
8#include <QAbstractListModel>
9
10namespace zrythm::structure::tracks
11{
12static constexpr int DEFAULT_AUTOMATION_TRACK_HEIGHT = 48;
13static constexpr int MIN_AUTOMATION_TRACK_HEIGHT = 26;
14
16
20class AutomationTrackHolder : public QObject
21{
22 Q_OBJECT
23 QML_ELEMENT
24 Q_PROPERTY (double height READ height WRITE setHeight NOTIFY heightChanged)
25 Q_PROPERTY (bool visible READ visible WRITE setVisible NOTIFY visibleChanged)
26 Q_PROPERTY (
27 bool createdByUser READ createdByUser WRITE setCreatedByUser NOTIFY
28 createdByUserChanged)
29 Q_PROPERTY (
31 automationTrack CONSTANT)
32 QML_UNCREATABLE ("")
33
34public:
35 struct Dependencies
36 {
37 const dsp::TempoMapWrapper &tempo_map_;
38 utils::IObjectRegistry &registry_;
39 dsp::TimebaseProvider * timebase_provider_ = nullptr;
40 };
41
42 AutomationTrackHolder (Dependencies dependencies, QObject * parent = nullptr)
43 : QObject (parent), dependencies_ (dependencies)
44 {
45 }
47 Dependencies dependencies,
49 QObject * parent = nullptr)
50 : AutomationTrackHolder (dependencies, parent)
51 {
52 automation_track_ = std::move (at);
53 automation_track_->setParent (this);
54 }
55
56 // ========================================================================
57 // QML Interface
58 // ========================================================================
59
60 double height () const { return height_; }
61 void setHeight (double height)
62 {
63 height =
64 std::max (height, static_cast<double> (MIN_AUTOMATION_TRACK_HEIGHT));
65 if (qFuzzyCompare (height, height_))
66 return;
67
68 height_ = height;
69 Q_EMIT heightChanged (height);
70 }
71 Q_SIGNAL void heightChanged (double height);
72
73 bool visible () const { return visible_; }
74 void setVisible (bool visible)
75 {
76 assert (created_by_user_);
77 if (visible == visible_)
78 return;
79
80 visible_ = visible;
81 Q_EMIT visibleChanged (visible);
82 }
83 Q_SIGNAL void visibleChanged (bool visible);
84
85 bool createdByUser () const { return created_by_user_; }
86 void setCreatedByUser (bool created)
87 {
88 if (created == created_by_user_)
89 return;
90
91 created_by_user_ = created;
92 Q_EMIT createdByUserChanged (created);
93 }
94 Q_SIGNAL void createdByUserChanged (bool created);
95
96 AutomationTrack * automationTrack () const
97 {
98 return automation_track_.get ();
99 }
100
101 // ========================================================================
102
103public:
108 bool created_by_user_{};
109
110private:
111 Dependencies dependencies_;
112
114
120 bool visible_{};
121
123 double height_{ DEFAULT_AUTOMATION_TRACK_HEIGHT };
124
125private:
126 static constexpr auto kAutomationTrackKey = "automationTrack"sv;
127 static constexpr auto kCreatedByUserKey = "createdByUser"sv;
128 static constexpr auto kVisible = "visible"sv;
129 static constexpr auto kHeightKey = "height"sv;
130 friend void to_json (nlohmann::json &j, const AutomationTrackHolder &nfo);
131 friend void from_json (const nlohmann::json &j, AutomationTrackHolder &nfo);
132};
133
137class AutomationTracklist : public QAbstractListModel
138{
139 Q_OBJECT
140 QML_ELEMENT
141 Q_PROPERTY (
142 bool automationVisible READ automationVisible WRITE setAutomationVisible
143 NOTIFY automationVisibleChanged)
144 QML_UNCREATABLE ("")
145
146public:
147 AutomationTracklist (
149 QObject * parent = nullptr);
150
151public:
152 enum Roles
153 {
154 AutomationTrackHolderRole = Qt::UserRole + 1,
155 AutomationTrackRole,
156 };
157
158 // ========================================================================
159 // QML Interface
160 // ========================================================================
161 QHash<int, QByteArray> roleNames () const override;
162 int rowCount (const QModelIndex &parent = QModelIndex ()) const override;
163 QVariant
164 data (const QModelIndex &index, int role = Qt::DisplayRole) const override;
165
166 Q_INVOKABLE void
167 showNextAvailableAutomationTrack (AutomationTrack * current_automation_track);
168 Q_INVOKABLE void
169 hideAutomationTrack (AutomationTrack * current_automation_track);
170
171 bool automationVisible () const { return automation_visible_; }
172 void setAutomationVisible (bool visible);
173 Q_SIGNAL void automationVisibleChanged (bool visible);
174
175 // ========================================================================
176
177 friend void init_from (
178 AutomationTracklist &obj,
179 const AutomationTracklist &other,
180 utils::ObjectCloneType clone_type);
181
187
190
191 AutomationTrack * automation_track_at (size_t index) const
192 {
193 return automation_tracks_.at (index)->automationTrack ();
194 }
195
203 const;
204
205 int get_visible_automation_track_count_between (
206 const AutomationTrack &src,
207 const AutomationTrack &dest) const;
208
218
223
226 * automation track.
227 */
229 const double automation_track_height,
230 const float normalized_val)
231 {
232 return static_cast<int> (
233 automation_track_height - (normalized_val * automation_track_height));
234 }
235
247 void
248 set_automation_track_index (AutomationTrack &at, int index, bool push_down);
249
261
262 auto &automation_track_holders () const { return automation_tracks_; }
263
264 auto automation_tracks () const
265 {
266 return std::views::transform (
267 automation_track_holders (),
268 [] (const auto &th) { return th->automationTrack (); });
269 }
270
271 AutomationTrack *
272 get_previous_visible_automation_track (const AutomationTrack &at) const;
273
274 AutomationTrack *
275 get_next_visible_automation_track (const AutomationTrack &at) const;
276
277private:
278 static constexpr auto kAutomationTracksKey = "automationTracks"sv;
279 static constexpr auto kAutomationVisibleKey = "automationVisible"sv;
280 friend void to_json (nlohmann::json &j, const AutomationTracklist &ats);
281 friend void from_json (const nlohmann::json &j, AutomationTracklist &ats);
282
283 auto &automation_track_holders () { return automation_tracks_; }
284 auto get_iterator_for_automation_track (const AutomationTrack &at) const
285 {
286 auto it = std::ranges::find (
287 automation_track_holders (), &at,
288 [&] (const auto &ath) { return ath->automationTrack (); });
289 if (it == automation_track_holders ().end ())
290 {
291 throw std::runtime_error ("Automation track not found");
292 }
293 return it;
294 }
295 auto get_iterator_for_automation_track (const AutomationTrack &at)
296 {
297 auto it = std::ranges::find (
298 automation_track_holders (), &at,
299 [&] (const auto &ath) { return ath->automationTrack (); });
300 if (it == automation_track_holders ().end ())
301 {
302 throw std::runtime_error ("Automation track not found");
303 }
304 return it;
305 }
306 int get_automation_track_index (const AutomationTrack &at) const
307 {
308 return static_cast<int> (std::distance (
309 automation_track_holders ().begin (),
310 get_iterator_for_automation_track (at)));
311 }
312
313private:
314 AutomationTrackHolder::Dependencies dependencies_;
315
329 std::vector<utils::QObjectUniquePtr<AutomationTrackHolder>> automation_tracks_;
330
332 bool automation_visible_{};
333
334 BOOST_DESCRIBE_CLASS (
335 AutomationTracklist,
336 (),
337 (),
338 (),
339 (automation_tracks_, automation_visible_))
340};
341
342}
Holder of an automation track and some metadata about it.
bool created_by_user_
Whether this automation track has been created by the user in the UI.
A container that manages a list of automation tracks.
AutomationTrack * get_visible_automation_track_after_delta(const AutomationTrack &at, int delta) const
Returns the AutomationTrack after delta visible AutomationTrack's.
void clear_arranger_objects()
Removes all arranger objects recursively.
utils::QObjectUniquePtr< AutomationTrackHolder > remove_automation_track(AutomationTrack &at)
Removes the AutomationTrack from the AutomationTracklist, optionally freeing it.
void set_automation_track_index(AutomationTrack &at, int index, bool push_down)
Swaps at with the automation track at index or pushes the other automation tracks down.
static int get_y_px_from_normalized_val(const double automation_track_height, const float normalized_val)
Returns the y pixels from the value based on the allocation of the automation track.
AutomationTrack * add_automation_track(utils::QObjectUniquePtr< AutomationTrack > &&at)
Adds the given automation track.
AutomationTrackHolder * get_first_invisible_automation_track_holder() const
Used when the add button is added and a new automation track is requested to be shown.
Abstract interface for a UUID-keyed object registry.
A unique pointer for QObject objects that also works with QObject-based ownership.
Definition qt.h:36