Zrythm v2.0.0-DEV
a highly automated and intuitive digital audio workstation
Loading...
Searching...
No Matches
clip_slot.h
1// SPDX-FileCopyrightText: © 2025-2026 Alexandros Theodotou <alex@zrythm.org>
2// SPDX-License-Identifier: LicenseRef-ZrythmLicense
3
4#pragma once
5
6#include "structure/arrangement/arranger_object_all.h"
7#include "structure/tracks/track_collection.h"
8
9#include <QtQmlIntegration/qqmlintegration.h>
10
11#include <nlohmann/json_fwd.hpp>
12
13namespace zrythm::structure::scenes
14{
15
16class ClipSlot : public QObject
17{
18 Q_OBJECT
19 Q_PROPERTY (
20 zrythm::structure::arrangement::ArrangerObject * region READ region WRITE
21 setRegion NOTIFY regionChanged)
22 Q_PROPERTY (ClipState state READ state WRITE setState NOTIFY stateChanged)
23 QML_ELEMENT
24 QML_UNCREATABLE ("")
25 QML_EXTENDED_NAMESPACE (zrythm::structure::tracks)
26
27public:
28 enum class ClipState
29 {
30 Stopped,
31 PlayQueued,
32 Playing,
33 StopQueued,
34 };
35 Q_ENUM (ClipState)
36
37 ClipSlot (
38 arrangement::ArrangerObjectRegistry &object_registry,
39 QObject * parent = nullptr);
40
41 arrangement::ArrangerObject * region () const
42 {
43 if (region_ref_.has_value ())
44 {
45 return region_ref_->get_object_base ();
46 }
47 return nullptr;
48 }
49 void setRegion (arrangement::ArrangerObject * region);
50 Q_SIGNAL void regionChanged (arrangement::ArrangerObject * region);
51
52 // Region management
53 Q_INVOKABLE void clearRegion ()
54 {
55 if (!region_ref_.has_value ())
56 {
57 return;
58 }
59
60 region_ref_.reset ();
61 Q_EMIT regionChanged (nullptr);
62 }
63
64 ClipState state () const { return state_.load (); }
65 void setState (ClipState state);
66 Q_SIGNAL void stateChanged (ClipState state);
67
68private:
69 static constexpr auto kRegionIdKey = "regionId"sv;
70 friend void to_json (nlohmann::json &j, const ClipSlot &slot);
71 friend void from_json (const nlohmann::json &j, ClipSlot &slot);
72
73private:
74 std::optional<arrangement::ArrangerObjectUuidReference> region_ref_;
75 arrangement::ArrangerObjectRegistry &object_registry_;
76 std::atomic<ClipState> state_{ ClipState::Stopped };
77};
78
79class ClipSlotList : public QAbstractListModel
80{
81 Q_OBJECT
82 QML_ELEMENT
83 QML_UNCREATABLE ("")
84
85public:
86 ClipSlotList (
87 arrangement::ArrangerObjectRegistry &object_registry,
88 const tracks::TrackCollection &track_collection,
89 QObject * parent = nullptr);
90 Z_DISABLE_COPY_MOVE (ClipSlotList)
91
92 enum ClipSlotListRoles
93 {
94 ClipSlotPtrRole = Qt::UserRole + 1,
95 };
96 Q_ENUM (ClipSlotListRoles)
97
98 // ========================================================================
99 // QML Interface
100 // ========================================================================
101
102 Q_INVOKABLE ClipSlot * clipSlotForTrack (const tracks::Track * track) const
103 {
104 return clip_slots_
105 .at (track_collection_.get_track_index (track->get_uuid ()))
106 .get ();
107 }
108
109 QHash<int, QByteArray> roleNames () const override
110 {
111 QHash<int, QByteArray> roles;
112 roles[ClipSlotPtrRole] = "clipSlot";
113 return roles;
114 }
115 int rowCount (const QModelIndex &parent = QModelIndex ()) const override
116 {
117 if (parent.isValid ())
118 return 0;
119 return static_cast<int> (clip_slots_.size ());
120 }
121 QVariant
122 data (const QModelIndex &index, int role = Qt::DisplayRole) const override
123 {
124 const auto index_int = index.row ();
125 if (!index.isValid () || index_int >= static_cast<int> (clip_slots_.size ()))
126 return {};
127
128 if (role == ClipSlotPtrRole)
129 {
130 return QVariant::fromValue (clip_slots_.at (index_int).get ());
131 }
132
133 return {};
134 }
135
136 // ========================================================================
137
138 auto &clip_slots () const { return clip_slots_; }
139
140private:
141 friend void to_json (nlohmann::json &j, const ClipSlotList &list);
142 friend void from_json (const nlohmann::json &j, ClipSlotList &list);
143
144private:
145 // These must be in the order of tracks in the tracklist.
146 std::vector<utils::QObjectUniquePtr<ClipSlot>> clip_slots_;
147
148 arrangement::ArrangerObjectRegistry &object_registry_;
149 const tracks::TrackCollection &track_collection_;
150};
151}
Base class for all objects in the arranger.
A collection of tracks that provides a QAbstractListModel interface.
Represents a track in the project.
Definition track.h:54