Zrythm v2.0.0-alpha.0+26.6dd8d70b0368
a highly automated and intuitive digital audio workstation
Loading...
Searching...
No Matches
plugin_list.h
1// SPDX-FileCopyrightText: © 2025 Alexandros Theodotou <alex@zrythm.org>
2// SPDX-License-Identifier: LicenseRef-ZrythmLicense
3
4#pragma once
5
6#include "plugins/plugin_all.h"
7#include "utils/views.h"
8
9#include <QtQmlIntegration>
10
11namespace zrythm::plugins
12{
13
14class PluginList : public QAbstractListModel
15{
16 Q_OBJECT
17 QML_ELEMENT
18 QML_UNCREATABLE ("")
19
20public:
21 PluginList (
22 plugins::PluginRegistry &plugin_registry,
23 QObject * parent = nullptr)
24 : QAbstractListModel (parent), plugin_registry_ (plugin_registry)
25 {
26 }
27
28 // ========================================================================
29 // QML Interface
30 // ========================================================================
31
32 enum Roles
33 {
34 PluginVariantRole = Qt::UserRole + 1,
35 };
36
37 QHash<int, QByteArray> roleNames () const override
38 {
39 static QHash<int, QByteArray> roles = {
40 { PluginVariantRole, "plugin" },
41 };
42 return roles;
43 }
44 int rowCount (const QModelIndex &parent = QModelIndex ()) const override
45 {
46 if (parent.isValid ())
47 return 0;
48 return static_cast<int> (plugins_.size ());
49 }
50 QVariant
51 data (const QModelIndex &index, int role = Qt::DisplayRole) const override
52 {
53 if (!index.isValid () || index.row () >= static_cast<int> (plugins_.size ()))
54 return {};
55
56 switch (role)
57 {
58 case PluginVariantRole:
59 return QVariant::fromStdVariant (
60 plugins_.at (index.row ()).get_object ());
61 default:
62 return {};
63 }
64 }
65
66 // ========================================================================
67
68 // Note: plugin add/remove API does not concern itself with automation tracks
69 // or graph rebuilding.
70 // When plugins are added or removed,
71 // automation tracks should be generated/moved accordingly and the DSP graph
72 // should be regenerated.
73
74 void insert_plugin (plugins::PluginUuidReference plugin_ref, int index = -1)
75 {
76 index = std::clamp (index, -1, static_cast<int> (plugins_.size ()));
77
78 if (index == -1)
79 {
80 beginInsertRows (
81 {}, static_cast<int> (plugins_.size ()),
82 static_cast<int> (plugins_.size ()));
83 plugins_.push_back (plugin_ref);
84 }
85 else
86 {
87 beginInsertRows ({}, index, index);
88 plugins_.insert (
89 std::ranges::next (plugins_.begin (), index), plugin_ref);
90 }
91 endInsertRows ();
92 }
93 void append_plugin (plugins::PluginUuidReference plugin_ref)
94 {
95 insert_plugin (plugin_ref, -1);
96 }
97 plugins::PluginUuidReference
98 remove_plugin (const plugins::Plugin::Uuid &plugin_id)
99 {
100 auto it = std::ranges::find (
101 plugins_, plugin_id, &plugins::PluginUuidReference::id);
102 if (it == plugins_.end ())
103 throw std::invalid_argument ("Plugin ID not found");
104
105 const auto index = std::ranges::distance (plugins_.begin (), it);
106 auto ret = *it;
107 beginRemoveRows ({}, static_cast<int> (index), static_cast<int> (index));
108 plugins_.erase (it);
109 endRemoveRows ();
110
111 return ret;
112 }
113
114 auto &plugins () const { return plugins_; }
115
116private:
117 static constexpr auto kPluginsKey = "plugins"sv;
118 friend void to_json (nlohmann::json &j, const PluginList &l)
119 {
120 j[kPluginsKey] = l.plugins_;
121 }
122 friend void from_json (const nlohmann::json &j, PluginList &l)
123 {
124 for (
125 const auto &[index, pl_json] :
126 utils::views::enumerate (j.at (kPluginsKey)))
127 {
128 plugins::PluginUuidReference ref{ l.plugin_registry_ };
129 from_json (pl_json, ref);
130 l.append_plugin (ref);
131 }
132 }
133
134private:
135 plugins::PluginRegistry &plugin_registry_;
136 std::vector<plugins::PluginUuidReference> plugins_;
137};
138} // namespace zrythm::plugins