1 /*
2  * Copyright (C) 2019-2021 Alexandros Theodotou <alex at zrythm dot org>
3  *
4  * This file is part of Zrythm
5  *
6  * Zrythm is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU Affero General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * Zrythm is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU Affero General Public License for more details.
15  *
16  * You should have received a copy of the GNU Affero General Public License
17  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
18  */
19 
20 /**
21  * \file
22  *
23  * Mixer selections.
24  */
25 
26 #ifndef __GUI_BACKEND_MIXER_SELECTIONS_H__
27 #define __GUI_BACKEND_MIXER_SELECTIONS_H__
28 
29 #include "audio/automation_point.h"
30 #include "audio/channel.h"
31 #include "audio/midi_region.h"
32 #include "audio/region.h"
33 #include "utils/yaml.h"
34 
35 typedef struct Plugin Plugin;
36 
37 /**
38  * @addtogroup gui_backend
39  *
40  * @{
41  */
42 
43 #define MIXER_SELECTIONS_SCHEMA_VERSION 1
44 
45 #define MIXER_SELECTIONS \
46   (PROJECT->mixer_selections)
47 
48 #define MIXER_SELECTIONS_MAX_SLOTS 60
49 
50 /**
51  * Selections to be used for the timeline's current
52  * selections, copying, undoing, etc.
53  */
54 typedef struct MixerSelections
55 {
56   int            schema_version;
57 
58   PluginSlotType type;
59 
60   /** Slots selected. */
61   int       slots[MIXER_SELECTIONS_MAX_SLOTS];
62 
63   /** Cache, used in actions. */
64   Plugin *  plugins[MIXER_SELECTIONS_MAX_SLOTS];
65 
66   int       num_slots;
67 
68   /** Channel selected. */
69   unsigned int track_name_hash;
70 
71   /** Whether any slot is selected. */
72   int       has_any;
73 } MixerSelections;
74 
75 static const cyaml_schema_field_t
76   mixer_selections_fields_schema[] =
77 {
78   YAML_FIELD_INT (
79     MixerSelections, schema_version),
80   YAML_FIELD_ENUM (
81     MixerSelections, type,
82     plugin_slot_type_strings),
83   YAML_FIELD_FIXED_SIZE_PTR_ARRAY_VAR_COUNT (
84     MixerSelections, slots, int_schema),
85   CYAML_FIELD_SEQUENCE_COUNT (
86     "plugins", CYAML_FLAG_DEFAULT,
87     MixerSelections, plugins,
88     num_slots,
89     &plugin_schema, 0, CYAML_UNLIMITED),
90   YAML_FIELD_UINT (
91     MixerSelections, track_name_hash),
92   YAML_FIELD_INT (
93     MixerSelections, has_any),
94 
95   CYAML_FIELD_END
96 };
97 
98 static const cyaml_schema_value_t
99 mixer_selections_schema = {
100   YAML_VALUE_PTR (
101     MixerSelections,
102     mixer_selections_fields_schema),
103 };
104 
105 void
106 mixer_selections_init_loaded (
107   MixerSelections * ms,
108   bool              is_project);
109 
110 MixerSelections *
111 mixer_selections_new (void);
112 
113 void
114 mixer_selections_init (
115   MixerSelections * self);
116 
117 /**
118  * Clone the struct for copying, undoing, etc.
119  *
120  * @bool src_is_project Whether \ref src are the
121  *   project selections.
122  */
123 MixerSelections *
124 mixer_selections_clone (
125   MixerSelections * src,
126   bool              src_is_project);
127 
128 /**
129  * Returns if there are any selections.
130  */
131 int
132 mixer_selections_has_any (
133   MixerSelections * ms);
134 
135 /**
136  * Gets highest slot in the selections.
137  */
138 int
139 mixer_selections_get_highest_slot (
140   MixerSelections * ms);
141 
142 /**
143  * Gets lowest slot in the selections.
144  */
145 int
146 mixer_selections_get_lowest_slot (
147   MixerSelections * ms);
148 
149 void
150 mixer_selections_post_deserialize (
151   MixerSelections * self);
152 
153 /**
154  * Returns whether the selections can be pasted to
155  * MixerWidget.paste_slot.
156  */
157 NONNULL
158 bool
159 mixer_selections_can_be_pasted (
160   MixerSelections * self,
161   Channel *         ch,
162   PluginSlotType    type,
163   int               slot);
164 
165 /**
166  * Paste the selections starting at the slot in the
167  * given channel.
168  */
169 NONNULL
170 void
171 mixer_selections_paste_to_slot (
172   MixerSelections * ms,
173   Channel *         ch,
174   PluginSlotType    type,
175   int               slot);
176 
177 /**
178  * Get current Track.
179  */
180 Track *
181 mixer_selections_get_track (
182   MixerSelections * self);
183 
184 /**
185  * Returns if the slot is selected or not.
186  */
187 bool
188 mixer_selections_contains_slot (
189   MixerSelections * ms,
190   PluginSlotType    type,
191   int               slot);
192 
193 /**
194  * Returns if the plugin is selected or not.
195  */
196 bool
197 mixer_selections_contains_plugin (
198   MixerSelections * ms,
199   Plugin *          pl);
200 
201 /**
202  * Adds a slot to the selections.
203  *
204  * The selections can only be from one channel.
205  *
206  * @param track The track.
207  * @param slot The slot to add to the selections.
208  * @param clone_pl Whether to clone the plugin
209  *   when storing it in \ref
210  *   MixerSelections.plugins. Used in some actions.
211  */
212 void
213 mixer_selections_add_slot (
214   MixerSelections * ms,
215   Track *           track,
216   PluginSlotType    type,
217   int               slot,
218   bool              clone_pl);
219 
220 /**
221  * Removes a slot from the selections.
222  *
223  * Assumes that the channel is the one already
224  * selected.
225  */
226 NONNULL
227 void
228 mixer_selections_remove_slot (
229   MixerSelections * ms,
230   int               slot,
231   PluginSlotType    type,
232   bool              publish_events);
233 
234 /**
235  * Sorts the selections by slot index.
236  *
237  * @param asc Ascending or not.
238  */
239 NONNULL
240 void
241 mixer_selections_sort (
242   MixerSelections * self,
243   bool              asc);
244 
245 /**
246  * Returns the first selected plugin if any is
247  * selected, otherwise NULL.
248  */
249 NONNULL
250 Plugin *
251 mixer_selections_get_first_plugin (
252   MixerSelections * self);
253 
254 NONNULL
255 bool
256 mixer_selections_validate (
257   MixerSelections * self);
258 
259 /**
260  * Clears selections.
261  */
262 NONNULL
263 void
264 mixer_selections_clear (
265   MixerSelections * ms,
266   const int         pub_events);
267 
268 NONNULL
269 void
270 mixer_selections_free (
271   MixerSelections * self);
272 
273 /**
274  * @}
275  */
276 
277 #endif
278