21class SnapGrid :
public QObject
25 bool snapAdaptive READ snapAdaptive WRITE setSnapAdaptive NOTIFY
28 bool snapToGrid READ snapToGrid WRITE setSnapToGrid NOTIFY snapToGridChanged)
30 bool snapToEvents READ snapToEvents WRITE setSnapToEvents NOTIFY
33 bool keepOffset READ keepOffset WRITE setKeepOffset NOTIFY keepOffsetChanged)
35 bool sixteenthsVisible READ sixteenthsVisible WRITE setSixteenthsVisible
36 NOTIFY sixteenthsVisibleChanged)
38 bool beatsVisible READ beatsVisible WRITE setBeatsVisible NOTIFY
41 zrythm::utils::NoteLength snapNoteLength READ snapNoteLength WRITE
42 setSnapNoteLength NOTIFY snapNoteLengthChanged)
45 NOTIFY snapNoteTypeChanged)
47 NoteLengthType lengthType READ lengthType WRITE setLengthType NOTIFY
49 Q_PROPERTY (QString snapString READ snapString NOTIFY snapChanged)
52 QML_EXTENDED_NAMESPACE (zrythm::
utils)
68 using SnapEventCallback =
69 std::function<std::vector<double> (
double start_ticks,
double end_ticks)>;
70 using LastObjectLengthProvider = std::function<double ()>;
73 const TempoMap &tempo_map,
74 utils::NoteLength default_note_length,
75 LastObjectLengthProvider last_object_length_provider,
76 QObject * parent =
nullptr);
79 bool snapAdaptive ()
const {
return snap_adaptive_; }
80 void setSnapAdaptive (
bool adaptive);
82 bool snapToGrid ()
const {
return snap_to_grid_; }
83 void setSnapToGrid (
bool snap);
85 bool snapToEvents ()
const {
return snap_to_events_; }
86 void setSnapToEvents (
bool snap);
88 bool keepOffset ()
const {
return snap_to_grid_keep_offset_; }
89 void setKeepOffset (
bool keep);
91 bool sixteenthsVisible ()
const {
return sixteenths_visible_; }
92 void setSixteenthsVisible (
bool visible);
94 bool beatsVisible ()
const {
return beats_visible_; }
95 void setBeatsVisible (
bool visible);
97 utils::NoteLength snapNoteLength ()
const {
return snap_note_length_; }
98 void setSnapNoteLength (utils::NoteLength length);
106 QString snapString ()
const;
109 Q_INVOKABLE
double snapWithoutStartTicks (
double ticks)
111 return snap (units::ticks (ticks)).in (units::ticks);
113 Q_INVOKABLE
double snapWithStartTicks (
double ticks,
double startTicks)
115 return snap (units::ticks (ticks), units::ticks (startTicks))
118 Q_INVOKABLE
double nextSnapPoint (
double ticks)
const;
119 Q_INVOKABLE
double prevSnapPoint (
double ticks)
const;
120 Q_INVOKABLE
double closestSnapPoint (
double ticks)
const;
121 Q_INVOKABLE
double snapTicks (int64_t ticks)
const;
122 Q_INVOKABLE
double defaultTicks (int64_t ticks)
const;
130 units::precise_tick_t
snap (
131 units::precise_tick_t ticks,
132 std::optional<units::precise_tick_t> start_ticks = std::nullopt)
const;
135 void set_event_callback (SnapEventCallback callback);
136 void set_last_object_length_callback (LastObjectLengthProvider callback)
138 last_object_length_provider_ = callback;
140 void clear_callbacks ();
142 static constexpr int get_ticks_from_length_and_type (
143 utils::NoteLength length,
148 assert (ticks_per_beat > 0);
149 assert (ticks_per_bar > 0);
154 case utils::NoteLength::Bar:
155 ticks = ticks_per_bar;
157 case utils::NoteLength::Beat:
158 ticks = ticks_per_beat;
160 case utils::NoteLength::Note_2_1:
163 case utils::NoteLength::Note_1_1:
166 case utils::NoteLength::Note_1_2:
169 case utils::NoteLength::Note_1_4:
172 case utils::NoteLength::Note_1_8:
175 case utils::NoteLength::Note_1_16:
178 case utils::NoteLength::Note_1_32:
181 case utils::NoteLength::Note_1_64:
184 case utils::NoteLength::Note_1_128:
191 case utils::NoteType::Normal:
195 assert (ticks % 2 == 0);
200 assert (ticks % 3 == 0);
208 static QString stringize_length_and_type (
209 utils::NoteLength note_length,
213 void snapAdaptiveChanged ();
214 void snapToGridChanged ();
215 void snapToEventsChanged ();
216 void keepOffsetChanged ();
217 void sixteenthsVisibleChanged ();
218 void beatsVisibleChanged ();
219 void snapNoteLengthChanged ();
220 void snapNoteTypeChanged ();
221 void lengthTypeChanged ();
225 static constexpr auto kSnapNoteLengthKey =
"snapNoteLength"sv;
226 static constexpr auto kSnapNoteTypeKey =
"snapNoteType"sv;
227 static constexpr auto kSnapAdaptiveKey =
"snapAdaptive"sv;
228 static constexpr auto kLengthTypeKey =
"lengthType"sv;
229 static constexpr auto kSnapToGridKey =
"snapToGrid"sv;
230 static constexpr auto kKeepOffsetKey =
"keepOffset"sv;
231 static constexpr auto kSnapToEventsKey =
"snapToEvents"sv;
232 friend void to_json (nlohmann::json &j,
const SnapGrid &p)
235 { kSnapNoteLengthKey, p.snap_note_length_ },
236 { kSnapNoteTypeKey, p.snap_note_type_ },
237 { kSnapAdaptiveKey, p.snap_adaptive_ },
238 { kLengthTypeKey, p.length_type_ },
239 { kSnapToGridKey, p.snap_to_grid_ },
240 { kKeepOffsetKey, p.snap_to_grid_keep_offset_ },
241 { kSnapToEventsKey, p.snap_to_events_ }
244 friend void from_json (
const nlohmann::json &j, SnapGrid &p)
246 j.at (kSnapNoteLengthKey).get_to (p.snap_note_length_);
247 j.at (kSnapNoteTypeKey).get_to (p.snap_note_type_);
248 j.at (kSnapAdaptiveKey).get_to (p.snap_adaptive_);
249 j.at (kLengthTypeKey).get_to (p.length_type_);
250 j.at (kSnapToGridKey).get_to (p.snap_to_grid_);
251 j.at (kKeepOffsetKey).get_to (p.snap_to_grid_keep_offset_);
252 j.at (kSnapToEventsKey).get_to (p.snap_to_events_);
255 bool get_prev_or_next_snap_point (
258 bool get_prev_point)
const;
260 get_event_snap_points (
double start_ticks,
double end_ticks)
const;
268 constexpr utils::NoteLength get_effective_note_length ()
const
270 return snap_adaptive_
271 ? (sixteenths_visible_
272 ? utils::NoteLength::Note_1_16
273 : (beats_visible_ ? utils::NoteLength::Beat : utils::NoteLength::Bar))
278 bool snap_adaptive_ =
false;
279 utils::NoteLength snap_note_length_{ utils::NoteLength::Note_1_4 };
283 bool snap_to_grid_ =
true;
290 bool snap_to_grid_keep_offset_ =
false;
298 bool snap_to_events_ =
false;
301 bool sixteenths_visible_ =
false;
302 bool beats_visible_ =
false;
308 utils::NoteLength default_note_length_;
310 const TempoMap &tempo_map_;
311 std::optional<SnapEventCallback> event_callback_;
312 LastObjectLengthProvider last_object_length_provider_;