Zrythm v2.0.0-DEV
a highly automated and intuitive digital audio workstation
Loading...
Searching...
No Matches
automation_tracklist.h
1// SPDX-FileCopyrightText: © 2018-2025 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 (AutomationTrack * automationTrack READ automationTrack CONSTANT)
27 QML_UNCREATABLE ("")
28
29public:
31 {
32 const dsp::TempoMapWrapper &tempo_map_;
33 dsp::FileAudioSourceRegistry &file_audio_source_registry_;
34 dsp::PortRegistry &port_registry_;
35 dsp::ProcessorParameterRegistry &param_registry_;
36 structure::arrangement::ArrangerObjectRegistry &object_registry_;
37 };
38
39 AutomationTrackHolder (Dependencies dependencies, QObject * parent = nullptr)
40 : QObject (parent), dependencies_ (dependencies)
41 {
42 }
44 Dependencies dependencies,
46 QObject * parent = nullptr)
47 : AutomationTrackHolder (dependencies, parent)
48 {
49 automation_track_ = std::move (at);
50 automation_track_->setParent (this);
51 }
52
53 // ========================================================================
54 // QML Interface
55 // ========================================================================
56
57 double height () const { return height_; }
58 void setHeight (double height)
59 {
60 height =
61 std::max (height, static_cast<double> (MIN_AUTOMATION_TRACK_HEIGHT));
62 if (qFuzzyCompare (height, height_))
63 return;
64
65 height_ = height;
66 Q_EMIT heightChanged (height);
67 }
68 Q_SIGNAL void heightChanged (double height);
69
70 bool visible () const { return visible_; }
71 void setVisible (bool visible)
72 {
73 assert (created_by_user_);
74 if (visible == visible_)
75 return;
76
77 visible_ = visible;
78 Q_EMIT visibleChanged (visible);
79 }
80 Q_SIGNAL void visibleChanged (bool visible);
81
82 AutomationTrack * automationTrack () const
83 {
84 return automation_track_.get ();
85 }
86
87 // ========================================================================
88
89public:
95
96private:
97 Dependencies dependencies_;
98
100
106 bool visible_{};
107
109 double height_{ DEFAULT_AUTOMATION_TRACK_HEIGHT };
110
111private:
112 static constexpr auto kAutomationTrackKey = "automationTrack"sv;
113 static constexpr auto kCreatedByUserKey = "createdByUser"sv;
114 static constexpr auto kVisible = "visible"sv;
115 static constexpr auto kHeightKey = "height"sv;
116 friend void to_json (nlohmann::json &j, const AutomationTrackHolder &nfo)
117 {
118 j[kAutomationTrackKey] = nfo.automation_track_;
119 j[kCreatedByUserKey] = nfo.created_by_user_;
120 j[kVisible] = nfo.visible_;
121 j[kHeightKey] = nfo.height_;
122 }
123 friend void from_json (const nlohmann::json &j, AutomationTrackHolder &nfo);
124};
125
129class AutomationTracklist : public QAbstractListModel
130{
131 Q_OBJECT
132 QML_ELEMENT
133 Q_PROPERTY (
134 bool automationVisible READ automationVisible WRITE setAutomationVisible
135 NOTIFY automationVisibleChanged)
136 QML_UNCREATABLE ("")
137
138 using ArrangerObjectRegistry = arrangement::ArrangerObjectRegistry;
139
140public:
141 AutomationTracklist (
143 QObject * parent = nullptr);
144
145public:
146 enum Roles
147 {
148 AutomationTrackHolderRole = Qt::UserRole + 1,
149 AutomationTrackRole,
150 };
151
152 // ========================================================================
153 // QML Interface
154 // ========================================================================
155 QHash<int, QByteArray> roleNames () const override;
156 int rowCount (const QModelIndex &parent = QModelIndex ()) const override;
157 QVariant
158 data (const QModelIndex &index, int role = Qt::DisplayRole) const override;
159
160 Q_INVOKABLE void
161 showNextAvailableAutomationTrack (AutomationTrack * current_automation_track);
162 Q_INVOKABLE void
163 hideAutomationTrack (AutomationTrack * current_automation_track);
164
165 bool automationVisible () const { return automation_visible_; }
166 void setAutomationVisible (bool visible);
167 Q_SIGNAL void automationVisibleChanged (bool visible);
168
169 // ========================================================================
170
171 friend void init_from (
172 AutomationTracklist &obj,
173 const AutomationTracklist &other,
174 utils::ObjectCloneType clone_type);
175
181
184
185 AutomationTrack * automation_track_at (size_t index) const
186 {
187 return automation_tracks_.at (index)->automationTrack ();
188 }
189
197 const;
198
199 int get_visible_automation_track_count_between (
200 const AutomationTrack &src,
201 const AutomationTrack &dest) const;
202
212
217
220 * automation track.
221 */
223 const double automation_track_height,
224 const float normalized_val)
225 {
226 return static_cast<int> (
227 automation_track_height - (normalized_val * automation_track_height));
228 }
229
241 void
242 set_automation_track_index (AutomationTrack &at, int index, bool push_down);
243
255
256 auto &automation_track_holders () const { return automation_tracks_; }
257
258 auto automation_tracks () const
259 {
260 return std::views::transform (
261 automation_track_holders (),
262 [] (const auto &th) { return th->automationTrack (); });
263 }
264
265 AutomationTrack *
266 get_previous_visible_automation_track (const AutomationTrack &at) const;
267
268 AutomationTrack *
269 get_next_visible_automation_track (const AutomationTrack &at) const;
270
271private:
272 static constexpr auto kAutomationTracksKey = "automationTracks"sv;
273 static constexpr auto kAutomationVisibleKey = "automationVisible"sv;
274 friend void to_json (nlohmann::json &j, const AutomationTracklist &ats)
275 {
276 j[kAutomationTracksKey] = ats.automation_tracks_;
277 j[kAutomationVisibleKey] = ats.automation_visible_;
278 }
279 friend void from_json (const nlohmann::json &j, AutomationTracklist &ats);
280
281 auto &get_port_registry () { return dependencies_.port_registry_; }
282 auto &get_port_registry () const { return dependencies_.port_registry_; }
283
284 auto &automation_track_holders () { return automation_tracks_; }
285 auto get_iterator_for_automation_track (const AutomationTrack &at) const
286 {
287 auto it = std::ranges::find (
288 automation_track_holders (), &at,
289 [&] (const auto &ath) { return ath->automationTrack (); });
290 if (it == automation_track_holders ().end ())
291 {
292 throw std::runtime_error ("Automation track not found");
293 }
294 return it;
295 }
296 auto get_iterator_for_automation_track (const AutomationTrack &at)
297 {
298 auto it = std::ranges::find (
299 automation_track_holders (), &at,
300 [&] (const auto &ath) { return ath->automationTrack (); });
301 if (it == automation_track_holders ().end ())
302 {
303 throw std::runtime_error ("Automation track not found");
304 }
305 return it;
306 }
307 int get_automation_track_index (const AutomationTrack &at) const
308 {
309 return static_cast<int> (std::distance (
310 automation_track_holders ().begin (),
311 get_iterator_for_automation_track (at)));
312 }
313
314private:
315 AutomationTrackHolder::Dependencies dependencies_;
316
330 std::vector<utils::QObjectUniquePtr<AutomationTrackHolder>> automation_tracks_;
331
333 bool automation_visible_{};
334
335 BOOST_DESCRIBE_CLASS (
336 AutomationTracklist,
337 (),
338 (),
339 (),
340 (automation_tracks_, automation_visible_))
341};
342
343}
Wrapper over a Uuid registry that provides (slow) lookup by unique ID.
Definition parameter.h:523
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:38