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 (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 friend void from_json (const nlohmann::json &j, AutomationTrackHolder &nfo);
118};
119
123class AutomationTracklist : public QAbstractListModel
124{
125 Q_OBJECT
126 QML_ELEMENT
127 Q_PROPERTY (
128 bool automationVisible READ automationVisible WRITE setAutomationVisible
129 NOTIFY automationVisibleChanged)
130 QML_UNCREATABLE ("")
131
132 using ArrangerObjectRegistry = arrangement::ArrangerObjectRegistry;
133
134public:
135 AutomationTracklist (
137 QObject * parent = nullptr);
138
139public:
140 enum Roles
141 {
142 AutomationTrackHolderRole = Qt::UserRole + 1,
143 AutomationTrackRole,
144 };
145
146 // ========================================================================
147 // QML Interface
148 // ========================================================================
149 QHash<int, QByteArray> roleNames () const override;
150 int rowCount (const QModelIndex &parent = QModelIndex ()) const override;
151 QVariant
152 data (const QModelIndex &index, int role = Qt::DisplayRole) const override;
153
154 Q_INVOKABLE void
155 showNextAvailableAutomationTrack (AutomationTrack * current_automation_track);
156 Q_INVOKABLE void
157 hideAutomationTrack (AutomationTrack * current_automation_track);
158
159 bool automationVisible () const { return automation_visible_; }
160 void setAutomationVisible (bool visible);
161 Q_SIGNAL void automationVisibleChanged (bool visible);
162
163 // ========================================================================
164
165 friend void init_from (
166 AutomationTracklist &obj,
167 const AutomationTracklist &other,
168 utils::ObjectCloneType clone_type);
169
175
178
179 AutomationTrack * automation_track_at (size_t index) const
180 {
181 return automation_tracks_.at (index)->automationTrack ();
182 }
183
191 const;
192
193 int get_visible_automation_track_count_between (
194 const AutomationTrack &src,
195 const AutomationTrack &dest) const;
196
206
211
214 * automation track.
215 */
217 const double automation_track_height,
218 const float normalized_val)
219 {
220 return static_cast<int> (
221 automation_track_height - (normalized_val * automation_track_height));
222 }
223
235 void
236 set_automation_track_index (AutomationTrack &at, int index, bool push_down);
237
249
250 auto &automation_track_holders () const { return automation_tracks_; }
251
252 auto automation_tracks () const
253 {
254 return std::views::transform (
255 automation_track_holders (),
256 [] (const auto &th) { return th->automationTrack (); });
257 }
258
259 AutomationTrack *
260 get_previous_visible_automation_track (const AutomationTrack &at) const;
261
262 AutomationTrack *
263 get_next_visible_automation_track (const AutomationTrack &at) const;
264
265private:
266 static constexpr auto kAutomationTracksKey = "automationTracks"sv;
267 static constexpr auto kAutomationVisibleKey = "automationVisible"sv;
268 friend void to_json (nlohmann::json &j, const AutomationTracklist &ats);
269 friend void from_json (const nlohmann::json &j, AutomationTracklist &ats);
270
271 auto &get_port_registry () { return dependencies_.port_registry_; }
272 auto &get_port_registry () const { return dependencies_.port_registry_; }
273
274 auto &automation_track_holders () { return automation_tracks_; }
275 auto get_iterator_for_automation_track (const AutomationTrack &at) const
276 {
277 auto it = std::ranges::find (
278 automation_track_holders (), &at,
279 [&] (const auto &ath) { return ath->automationTrack (); });
280 if (it == automation_track_holders ().end ())
281 {
282 throw std::runtime_error ("Automation track not found");
283 }
284 return it;
285 }
286 auto get_iterator_for_automation_track (const AutomationTrack &at)
287 {
288 auto it = std::ranges::find (
289 automation_track_holders (), &at,
290 [&] (const auto &ath) { return ath->automationTrack (); });
291 if (it == automation_track_holders ().end ())
292 {
293 throw std::runtime_error ("Automation track not found");
294 }
295 return it;
296 }
297 int get_automation_track_index (const AutomationTrack &at) const
298 {
299 return static_cast<int> (std::distance (
300 automation_track_holders ().begin (),
301 get_iterator_for_automation_track (at)));
302 }
303
304private:
305 AutomationTrackHolder::Dependencies dependencies_;
306
320 std::vector<utils::QObjectUniquePtr<AutomationTrackHolder>> automation_tracks_;
321
323 bool automation_visible_{};
324
325 BOOST_DESCRIBE_CLASS (
326 AutomationTracklist,
327 (),
328 (),
329 (),
330 (automation_tracks_, automation_visible_))
331};
332
333}
Wrapper over a Uuid registry that provides (slow) lookup by unique ID.
Definition parameter.h:500
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