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 };
40
41 AutomationTrackHolder (Dependencies dependencies, QObject * parent = nullptr)
42 : QObject (parent), dependencies_ (dependencies)
43 {
44 }
46 Dependencies dependencies,
48 QObject * parent = nullptr)
49 : AutomationTrackHolder (dependencies, parent)
50 {
51 automation_track_ = std::move (at);
52 automation_track_->setParent (this);
53 }
54
55 // ========================================================================
56 // QML Interface
57 // ========================================================================
58
59 double height () const { return height_; }
60 void setHeight (double height)
61 {
62 height =
63 std::max (height, static_cast<double> (MIN_AUTOMATION_TRACK_HEIGHT));
64 if (qFuzzyCompare (height, height_))
65 return;
66
67 height_ = height;
68 Q_EMIT heightChanged (height);
69 }
70 Q_SIGNAL void heightChanged (double height);
71
72 bool visible () const { return visible_; }
73 void setVisible (bool visible)
74 {
75 assert (created_by_user_);
76 if (visible == visible_)
77 return;
78
79 visible_ = visible;
80 Q_EMIT visibleChanged (visible);
81 }
82 Q_SIGNAL void visibleChanged (bool visible);
83
84 bool createdByUser () const { return created_by_user_; }
85 void setCreatedByUser (bool created)
86 {
87 if (created == created_by_user_)
88 return;
89
90 created_by_user_ = created;
91 Q_EMIT createdByUserChanged (created);
92 }
93 Q_SIGNAL void createdByUserChanged (bool created);
94
95 AutomationTrack * automationTrack () const
96 {
97 return automation_track_.get ();
98 }
99
100 // ========================================================================
101
102public:
107 bool created_by_user_{};
108
109private:
110 Dependencies dependencies_;
111
113
119 bool visible_{};
120
122 double height_{ DEFAULT_AUTOMATION_TRACK_HEIGHT };
123
124private:
125 static constexpr auto kAutomationTrackKey = "automationTrack"sv;
126 static constexpr auto kCreatedByUserKey = "createdByUser"sv;
127 static constexpr auto kVisible = "visible"sv;
128 static constexpr auto kHeightKey = "height"sv;
129 friend void to_json (nlohmann::json &j, const AutomationTrackHolder &nfo);
130 friend void from_json (const nlohmann::json &j, AutomationTrackHolder &nfo);
131};
132
136class AutomationTracklist : public QAbstractListModel
137{
138 Q_OBJECT
139 QML_ELEMENT
140 Q_PROPERTY (
141 bool automationVisible READ automationVisible WRITE setAutomationVisible
142 NOTIFY automationVisibleChanged)
143 QML_UNCREATABLE ("")
144
145public:
146 AutomationTracklist (
148 QObject * parent = nullptr);
149
150public:
151 enum Roles
152 {
153 AutomationTrackHolderRole = Qt::UserRole + 1,
154 AutomationTrackRole,
155 };
156
157 // ========================================================================
158 // QML Interface
159 // ========================================================================
160 QHash<int, QByteArray> roleNames () const override;
161 int rowCount (const QModelIndex &parent = QModelIndex ()) const override;
162 QVariant
163 data (const QModelIndex &index, int role = Qt::DisplayRole) const override;
164
165 Q_INVOKABLE void
166 showNextAvailableAutomationTrack (AutomationTrack * current_automation_track);
167 Q_INVOKABLE void
168 hideAutomationTrack (AutomationTrack * current_automation_track);
169
170 bool automationVisible () const { return automation_visible_; }
171 void setAutomationVisible (bool visible);
172 Q_SIGNAL void automationVisibleChanged (bool visible);
173
174 // ========================================================================
175
176 friend void init_from (
177 AutomationTracklist &obj,
178 const AutomationTracklist &other,
179 utils::ObjectCloneType clone_type);
180
186
189
190 AutomationTrack * automation_track_at (size_t index) const
191 {
192 return automation_tracks_.at (index)->automationTrack ();
193 }
194
202 const;
203
204 int get_visible_automation_track_count_between (
205 const AutomationTrack &src,
206 const AutomationTrack &dest) const;
207
217
222
225 * automation track.
226 */
228 const double automation_track_height,
229 const float normalized_val)
230 {
231 return static_cast<int> (
232 automation_track_height - (normalized_val * automation_track_height));
233 }
234
246 void
247 set_automation_track_index (AutomationTrack &at, int index, bool push_down);
248
260
261 auto &automation_track_holders () const { return automation_tracks_; }
262
263 auto automation_tracks () const
264 {
265 return std::views::transform (
266 automation_track_holders (),
267 [] (const auto &th) { return th->automationTrack (); });
268 }
269
270 AutomationTrack *
271 get_previous_visible_automation_track (const AutomationTrack &at) const;
272
273 AutomationTrack *
274 get_next_visible_automation_track (const AutomationTrack &at) const;
275
276private:
277 static constexpr auto kAutomationTracksKey = "automationTracks"sv;
278 static constexpr auto kAutomationVisibleKey = "automationVisible"sv;
279 friend void to_json (nlohmann::json &j, const AutomationTracklist &ats);
280 friend void from_json (const nlohmann::json &j, AutomationTracklist &ats);
281
282 auto &automation_track_holders () { return automation_tracks_; }
283 auto get_iterator_for_automation_track (const AutomationTrack &at) const
284 {
285 auto it = std::ranges::find (
286 automation_track_holders (), &at,
287 [&] (const auto &ath) { return ath->automationTrack (); });
288 if (it == automation_track_holders ().end ())
289 {
290 throw std::runtime_error ("Automation track not found");
291 }
292 return it;
293 }
294 auto get_iterator_for_automation_track (const AutomationTrack &at)
295 {
296 auto it = std::ranges::find (
297 automation_track_holders (), &at,
298 [&] (const auto &ath) { return ath->automationTrack (); });
299 if (it == automation_track_holders ().end ())
300 {
301 throw std::runtime_error ("Automation track not found");
302 }
303 return it;
304 }
305 int get_automation_track_index (const AutomationTrack &at) const
306 {
307 return static_cast<int> (std::distance (
308 automation_track_holders ().begin (),
309 get_iterator_for_automation_track (at)));
310 }
311
312private:
313 AutomationTrackHolder::Dependencies dependencies_;
314
328 std::vector<utils::QObjectUniquePtr<AutomationTrackHolder>> automation_tracks_;
329
331 bool automation_visible_{};
332
333 BOOST_DESCRIBE_CLASS (
334 AutomationTracklist,
335 (),
336 (),
337 (),
338 (automation_tracks_, automation_visible_))
339};
340
341}
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