Zrythm v2.0.0-DEV
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 dsp::FileAudioSourceRegistry &file_audio_source_registry_;
39 dsp::PortRegistry &port_registry_;
40 dsp::ProcessorParameterRegistry &param_registry_;
41 structure::arrangement::ArrangerObjectRegistry &object_registry_;
42 };
43
44 AutomationTrackHolder (Dependencies dependencies, QObject * parent = nullptr)
45 : QObject (parent), dependencies_ (dependencies)
46 {
47 }
49 Dependencies dependencies,
51 QObject * parent = nullptr)
52 : AutomationTrackHolder (dependencies, parent)
53 {
54 automation_track_ = std::move (at);
55 automation_track_->setParent (this);
56 }
57
58 // ========================================================================
59 // QML Interface
60 // ========================================================================
61
62 double height () const { return height_; }
63 void setHeight (double height)
64 {
65 height =
66 std::max (height, static_cast<double> (MIN_AUTOMATION_TRACK_HEIGHT));
67 if (qFuzzyCompare (height, height_))
68 return;
69
70 height_ = height;
71 Q_EMIT heightChanged (height);
72 }
73 Q_SIGNAL void heightChanged (double height);
74
75 bool visible () const { return visible_; }
76 void setVisible (bool visible)
77 {
78 assert (created_by_user_);
79 if (visible == visible_)
80 return;
81
82 visible_ = visible;
83 Q_EMIT visibleChanged (visible);
84 }
85 Q_SIGNAL void visibleChanged (bool visible);
86
87 bool createdByUser () const { return created_by_user_; }
88 void setCreatedByUser (bool created)
89 {
90 if (created == created_by_user_)
91 return;
92
93 created_by_user_ = created;
94 Q_EMIT createdByUserChanged (created);
95 }
96 Q_SIGNAL void createdByUserChanged (bool created);
97
98 AutomationTrack * automationTrack () const
99 {
100 return automation_track_.get ();
101 }
102
103 // ========================================================================
104
105public:
110 bool created_by_user_{};
111
112private:
113 Dependencies dependencies_;
114
116
122 bool visible_{};
123
125 double height_{ DEFAULT_AUTOMATION_TRACK_HEIGHT };
126
127private:
128 static constexpr auto kAutomationTrackKey = "automationTrack"sv;
129 static constexpr auto kCreatedByUserKey = "createdByUser"sv;
130 static constexpr auto kVisible = "visible"sv;
131 static constexpr auto kHeightKey = "height"sv;
132 friend void to_json (nlohmann::json &j, const AutomationTrackHolder &nfo);
133 friend void from_json (const nlohmann::json &j, AutomationTrackHolder &nfo);
134};
135
139class AutomationTracklist : public QAbstractListModel
140{
141 Q_OBJECT
142 QML_ELEMENT
143 Q_PROPERTY (
144 bool automationVisible READ automationVisible WRITE setAutomationVisible
145 NOTIFY automationVisibleChanged)
146 QML_UNCREATABLE ("")
147
148 using ArrangerObjectRegistry = arrangement::ArrangerObjectRegistry;
149
150public:
151 AutomationTracklist (
153 QObject * parent = nullptr);
154
155public:
156 enum Roles
157 {
158 AutomationTrackHolderRole = Qt::UserRole + 1,
159 AutomationTrackRole,
160 };
161
162 // ========================================================================
163 // QML Interface
164 // ========================================================================
165 QHash<int, QByteArray> roleNames () const override;
166 int rowCount (const QModelIndex &parent = QModelIndex ()) const override;
167 QVariant
168 data (const QModelIndex &index, int role = Qt::DisplayRole) const override;
169
170 Q_INVOKABLE void
171 showNextAvailableAutomationTrack (AutomationTrack * current_automation_track);
172 Q_INVOKABLE void
173 hideAutomationTrack (AutomationTrack * current_automation_track);
174
175 bool automationVisible () const { return automation_visible_; }
176 void setAutomationVisible (bool visible);
177 Q_SIGNAL void automationVisibleChanged (bool visible);
178
179 // ========================================================================
180
181 friend void init_from (
182 AutomationTracklist &obj,
183 const AutomationTracklist &other,
184 utils::ObjectCloneType clone_type);
185
191
194
195 AutomationTrack * automation_track_at (size_t index) const
196 {
197 return automation_tracks_.at (index)->automationTrack ();
198 }
199
207 const;
208
209 int get_visible_automation_track_count_between (
210 const AutomationTrack &src,
211 const AutomationTrack &dest) const;
212
222
227
230 * automation track.
231 */
233 const double automation_track_height,
234 const float normalized_val)
235 {
236 return static_cast<int> (
237 automation_track_height - (normalized_val * automation_track_height));
238 }
239
251 void
252 set_automation_track_index (AutomationTrack &at, int index, bool push_down);
253
265
266 auto &automation_track_holders () const { return automation_tracks_; }
267
268 auto automation_tracks () const
269 {
270 return std::views::transform (
271 automation_track_holders (),
272 [] (const auto &th) { return th->automationTrack (); });
273 }
274
275 AutomationTrack *
276 get_previous_visible_automation_track (const AutomationTrack &at) const;
277
278 AutomationTrack *
279 get_next_visible_automation_track (const AutomationTrack &at) const;
280
281private:
282 static constexpr auto kAutomationTracksKey = "automationTracks"sv;
283 static constexpr auto kAutomationVisibleKey = "automationVisible"sv;
284 friend void to_json (nlohmann::json &j, const AutomationTracklist &ats);
285 friend void from_json (const nlohmann::json &j, AutomationTracklist &ats);
286
287 auto &get_port_registry () { return dependencies_.port_registry_; }
288 auto &get_port_registry () const { return dependencies_.port_registry_; }
289
290 auto &automation_track_holders () { return automation_tracks_; }
291 auto get_iterator_for_automation_track (const AutomationTrack &at) const
292 {
293 auto it = std::ranges::find (
294 automation_track_holders (), &at,
295 [&] (const auto &ath) { return ath->automationTrack (); });
296 if (it == automation_track_holders ().end ())
297 {
298 throw std::runtime_error ("Automation track not found");
299 }
300 return it;
301 }
302 auto get_iterator_for_automation_track (const AutomationTrack &at)
303 {
304 auto it = std::ranges::find (
305 automation_track_holders (), &at,
306 [&] (const auto &ath) { return ath->automationTrack (); });
307 if (it == automation_track_holders ().end ())
308 {
309 throw std::runtime_error ("Automation track not found");
310 }
311 return it;
312 }
313 int get_automation_track_index (const AutomationTrack &at) const
314 {
315 return static_cast<int> (std::distance (
316 automation_track_holders ().begin (),
317 get_iterator_for_automation_track (at)));
318 }
319
320private:
321 AutomationTrackHolder::Dependencies dependencies_;
322
336 std::vector<utils::QObjectUniquePtr<AutomationTrackHolder>> automation_tracks_;
337
339 bool automation_visible_{};
340
341 BOOST_DESCRIBE_CLASS (
342 AutomationTracklist,
343 (),
344 (),
345 (),
346 (automation_tracks_, automation_visible_))
347};
348
349}
Wrapper over a Uuid registry that provides (slow) lookup by unique ID.
Definition parameter.h:542
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.
A unique pointer for QObject objects that also works with QObject-based ownership.
Definition qt.h:36