Zrythm v2.0.0-alpha.1
a highly automated and intuitive digital audio workstation
Loading...
Searching...
No Matches
track_lane.h
1// SPDX-FileCopyrightText: © 2019-2026 Alexandros Theodotou <alex@zrythm.org>
2// SPDX-License-Identifier: LicenseRef-ZrythmLicense
3
4#pragma once
5
6#include <utility>
7
8#include "dsp/timebase.h"
9#include "structure/arrangement/arranger_object_all.h"
10#include "structure/arrangement/arranger_object_owner.h"
11
12namespace zrythm::structure::tracks
13{
14
24class TrackLane
25 : public utils::UuidIdentifiableObject<TrackLane>,
26 public arrangement::ArrangerObjectOwner<arrangement::MidiClip>,
27 public arrangement::ArrangerObjectOwner<arrangement::AudioClip>
28{
29 Q_OBJECT
30 DEFINE_ARRANGER_OBJECT_OWNER_QML_PROPERTIES (
31 TrackLane,
32 midiClips,
34 DEFINE_ARRANGER_OBJECT_OWNER_QML_PROPERTIES (
35 TrackLane,
36 audioClips,
38 Q_PROPERTY (QString name READ name WRITE setName NOTIFY nameChanged)
39 Q_PROPERTY (double height READ height WRITE setHeight NOTIFY heightChanged)
40 Q_PROPERTY (bool muted READ muted WRITE setMuted NOTIFY muteChanged)
41 Q_PROPERTY (bool soloed READ soloed WRITE setSoloed NOTIFY soloChanged)
42 Q_PROPERTY (
43 std::uint8_t midiChannel READ midiChannel WRITE setMidiChannel NOTIFY
44 midiChannelChanged)
45 QML_ELEMENT
46 QML_UNCREATABLE ("")
47
48 static constexpr double DEFAULT_HEIGHT = 48;
49
50public:
54 using SoloedLanesExistFunc = std::function<bool ()>;
55
56 static constexpr auto default_format_str = QT_TR_NOOP_UTF8 ("Lane {}");
57
59 {
60 utils::IObjectRegistry &registry_;
61 SoloedLanesExistFunc soloed_lanes_exist_func_;
62 dsp::TimebaseProvider * timebase_provider_ = nullptr;
63 };
64
65 TrackLane (TrackLaneDependencies dependencies, QObject * parent = nullptr);
66 Q_DISABLE_COPY_MOVE (TrackLane)
67 ~TrackLane () override;
68
69 // ========================================================================
70 // QML Interface
71 // ========================================================================
72
73 QString name () const { return name_.to_qstring (); }
74 void setName (const QString &name)
75 {
76 const auto std_name = utils::Utf8String::from_qstring (name);
77 if (name_ == std_name)
78 return;
79
80 name_ = std_name;
81 Q_EMIT nameChanged (name);
82 }
83 Q_SIGNAL void nameChanged (const QString &name);
84
85 double height () const { return height_; }
86 void setHeight (const double height)
87 {
88 if (qFuzzyCompare (height_, height))
89 return;
90
91 height_ = height;
92 Q_EMIT heightChanged (height);
93 }
94 Q_SIGNAL void heightChanged (double height);
95
96 bool soloed () const { return solo_; }
97 void setSoloed (bool solo)
98 {
99 if (solo_ == solo)
100 return;
101
102 solo_ = solo;
103 Q_EMIT soloChanged (solo);
104 }
105 Q_SIGNAL void soloChanged (bool solo);
106
107 bool muted () const { return mute_; }
108 void setMuted (bool mute)
109 {
110 if (mute_ == mute)
111 return;
112
113 mute_ = mute;
114 Q_EMIT muteChanged (mute);
115 }
116 Q_SIGNAL void muteChanged (bool mute);
117
120 * muted).
121 */
122 Q_INVOKABLE bool effectivelyMuted () const
123 {
124 if (muted ())
125 return true;
126
127 /* if lane is non-soloed while other soloed lanes exist, this should
128 * be muted */
129 if (soloed_lanes_exist_func_ () && !soloed ())
130 return true;
131
132 return false;
133 }
134
135 std::uint8_t midiChannel () const { return midi_ch_; }
136 void setMidiChannel (std::uint8_t midi_ch)
137 {
138 if (midi_ch_ == midi_ch)
139 return;
140
141 midi_ch_ = midi_ch;
142 Q_EMIT midiChannelChanged (midi_ch);
143 }
144 Q_SIGNAL void midiChannelChanged (std::uint8_t midi_ch);
145
146 // ========================================================================
147
153 void generate_name (size_t index);
154
160 // std::unique_ptr<TrackLaneT> gen_snapshot () const;
161
163 const arrangement::MidiClip * _) const override
164 {
165 return "midiClips";
166 }
168 const arrangement::AudioClip * _) const override
169 {
170 return "audioClips";
171 }
172
173private:
174 static constexpr std::string_view kNameKey = "name";
175 static constexpr std::string_view kHeightKey = "height";
176 static constexpr std::string_view kMuteKey = "mute";
177 static constexpr std::string_view kSoloKey = "solo";
178 static constexpr std::string_view kMidiChannelKey = "midiChannel";
179 friend void to_json (nlohmann::json &j, const TrackLane &lane);
180 friend void from_json (const nlohmann::json &j, TrackLane &lane);
181
182 friend void init_from (
183 TrackLane &obj,
184 const TrackLane &other,
185 utils::ObjectCloneType clone_type);
186
187private:
188 SoloedLanesExistFunc soloed_lanes_exist_func_;
189
190 QPointer<dsp::TimebaseProvider> timebase_provider_;
191
193 utils::Utf8String name_;
194
196 double height_{ DEFAULT_HEIGHT };
197
199 bool mute_{};
200
202 bool solo_{};
203
209 uint8_t midi_ch_ = 0;
210
211 BOOST_DESCRIBE_CLASS (
212 TrackLane,
213 (utils::UuidIdentifiableObject<TrackLane>),
214 (),
215 (),
216 (name_, height_, mute_, solo_, midi_ch_))
217};
218}
A clip for playing back audio samples.
Definition audio_clip.h:24
A Clip containing MIDI events.
Definition midi_clip.h:26
Q_INVOKABLE bool effectivelyMuted() const
Returns if the lane is effectively muted (explicitly or implicitly muted).
Definition track_lane.h:120
void generate_name(size_t index)
Generates a default name for the lane at the given index.
std::function< bool()> SoloedLanesExistFunc
Function to check if other soloed lanes exist in the owner.
Definition track_lane.h:52
std::string get_field_name_for_serialization(const arrangement::MidiClip *_) const override
Generate a snapshot for playback.
Definition track_lane.h:160
Abstract interface for a UUID-keyed object registry.
Lightweight UTF-8 string wrapper with safe conversions.
Definition utf8_string.h:37
CRTP base that adds a typed UUID strong-typedef to a class hierarchy.