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 Zrythm. If not, see <https://www.gnu.org/licenses/>. 18 */ 19 20 #ifndef __UNDO_MIXER_SELECTIONS_ACTION_H__ 21 #define __UNDO_MIXER_SELECTIONS_ACTION_H__ 22 23 #include "audio/automation_track.h" 24 #include "audio/port_connections_manager.h" 25 #include "actions/undoable_action.h" 26 #include "gui/backend/mixer_selections.h" 27 #include "utils/yaml.h" 28 29 typedef struct Plugin Plugin; 30 typedef struct Track Track; 31 typedef struct MixerSelections MixerSelections; 32 33 typedef enum MixerSelectionsActionType 34 { 35 /** Duplicate from existing plugins. */ 36 MIXER_SELECTIONS_ACTION_COPY, 37 /** Create new from clipboard. */ 38 MIXER_SELECTIONS_ACTION_PASTE, 39 /** Create new from PluginSetting. */ 40 MIXER_SELECTIONS_ACTION_CREATE, 41 MIXER_SELECTIONS_ACTION_DELETE, 42 MIXER_SELECTIONS_ACTION_MOVE, 43 } MixerSelectionsActionType; 44 45 static const cyaml_strval_t 46 mixer_selections_action_type_strings[] = 47 { 48 { "Copy", MIXER_SELECTIONS_ACTION_COPY }, 49 { "Paste", MIXER_SELECTIONS_ACTION_PASTE }, 50 { "Create", MIXER_SELECTIONS_ACTION_CREATE }, 51 { "Delete", MIXER_SELECTIONS_ACTION_DELETE }, 52 { "Move", MIXER_SELECTIONS_ACTION_MOVE }, 53 }; 54 55 /** 56 * Restrict selections to a channel. 57 */ 58 typedef struct MixerSelectionsAction 59 { 60 UndoableAction parent_instance; 61 62 MixerSelectionsActionType type; 63 64 /** Type of starting slot to move plugins to. */ 65 PluginSlotType slot_type; 66 67 /** 68 * Starting target slot. 69 * 70 * The rest of the slots will start from this so 71 * they can be calculated when doing/undoing. 72 */ 73 int to_slot; 74 75 /** To track position. */ 76 unsigned int to_track_name_hash; 77 78 /** Whether the plugins will be copied/moved into 79 * a new channel, if applicable. */ 80 bool new_channel; 81 82 /** Number of plugins to create, when creating 83 * new plugins. */ 84 int num_plugins; 85 86 /** 87 * PluginSetting to use when creating. 88 */ 89 PluginSetting * setting; 90 91 /** 92 * Clone of mixer selections at start. 93 */ 94 MixerSelections * ms_before; 95 96 /** 97 * Deleted plugins (ie, plugins replaced during 98 * move/copy). 99 * 100 * Used during undo to bring them back. 101 */ 102 MixerSelections * deleted_ms; 103 104 /** 105 * Automation tracks associated with the deleted 106 * plugins. 107 * 108 * These are used when undoing so we can readd 109 * the automation events, if applicable. 110 */ 111 AutomationTrack * deleted_ats[16000]; 112 int num_deleted_ats; 113 114 /** 115 * Automation tracks associated with the plugins. 116 * 117 * These are used when undoing so we can readd 118 * the automation events, if applicable. 119 */ 120 AutomationTrack * ats[16000]; 121 int num_ats; 122 123 /** A clone of the port connections at the 124 * start of the action. */ 125 PortConnectionsManager * connections_mgr_before; 126 127 /** A clone of the port connections after 128 * applying the action. */ 129 PortConnectionsManager * connections_mgr_after; 130 } MixerSelectionsAction; 131 132 static const cyaml_schema_field_t 133 mixer_selections_action_fields_schema[] = 134 { 135 YAML_FIELD_MAPPING_EMBEDDED ( 136 MixerSelectionsAction, parent_instance, 137 undoable_action_fields_schema), 138 YAML_FIELD_ENUM ( 139 MixerSelectionsAction, type, 140 mixer_selections_action_type_strings), 141 YAML_FIELD_ENUM ( 142 MixerSelectionsAction, slot_type, 143 plugin_slot_type_strings), 144 YAML_FIELD_INT ( 145 MixerSelectionsAction, to_slot), 146 YAML_FIELD_UINT ( 147 MixerSelectionsAction, to_track_name_hash), 148 YAML_FIELD_INT ( 149 MixerSelectionsAction, new_channel), 150 YAML_FIELD_INT ( 151 MixerSelectionsAction, num_plugins), 152 YAML_FIELD_MAPPING_PTR_OPTIONAL ( 153 MixerSelectionsAction, setting, 154 plugin_setting_fields_schema), 155 YAML_FIELD_MAPPING_PTR_OPTIONAL ( 156 MixerSelectionsAction, ms_before, 157 mixer_selections_fields_schema), 158 YAML_FIELD_MAPPING_PTR_OPTIONAL ( 159 MixerSelectionsAction, deleted_ms, 160 mixer_selections_fields_schema), 161 YAML_FIELD_FIXED_SIZE_PTR_ARRAY_VAR_COUNT ( 162 MixerSelectionsAction, ats, 163 automation_track_schema), 164 YAML_FIELD_FIXED_SIZE_PTR_ARRAY_VAR_COUNT ( 165 MixerSelectionsAction, deleted_ats, 166 automation_track_schema), 167 YAML_FIELD_MAPPING_PTR_OPTIONAL ( 168 MixerSelectionsAction, 169 connections_mgr_before, 170 port_connections_manager_fields_schema), 171 YAML_FIELD_MAPPING_PTR_OPTIONAL ( 172 MixerSelectionsAction, 173 connections_mgr_after, 174 port_connections_manager_fields_schema), 175 176 CYAML_FIELD_END 177 }; 178 179 static const cyaml_schema_value_t 180 mixer_selections_action_schema = 181 { 182 YAML_VALUE_PTR ( 183 MixerSelectionsAction, 184 mixer_selections_action_fields_schema), 185 }; 186 187 void 188 mixer_selections_action_init_loaded ( 189 MixerSelectionsAction * self); 190 191 /** 192 * Create a new action. 193 * 194 * @param ms The mixer selections before the action 195 * is performed. 196 * @param slot_type Target slot type. 197 * @param to_track_name_hash Target track name hash, 198 * or 0 for new channel. 199 * @param to_slot Target slot. 200 * @param setting The plugin setting, if creating 201 * plugins. 202 * @param num_plugins The number of plugins to create, 203 * if creating plugins. 204 */ 205 WARN_UNUSED_RESULT 206 UndoableAction * 207 mixer_selections_action_new ( 208 MixerSelections * ms, 209 const PortConnectionsManager * connections_mgr, 210 MixerSelectionsActionType type, 211 PluginSlotType slot_type, 212 unsigned int to_track_name_hash, 213 int to_slot, 214 PluginSetting * setting, 215 int num_plugins, 216 GError ** error); 217 218 #define mixer_selections_action_new_create( \ 219 slot_type,to_tr,to_slot,setting,num_plugins, \ 220 error) \ 221 mixer_selections_action_new ( \ 222 NULL, NULL, MIXER_SELECTIONS_ACTION_CREATE, \ 223 slot_type, to_tr, to_slot, setting, \ 224 num_plugins, error) 225 226 #define mixer_selections_action_new_copy( \ 227 ms,port_connections_mgr,slot_type, \ 228 to_tr,to_slot,error) \ 229 mixer_selections_action_new ( \ 230 ms, port_connections_mgr, \ 231 MIXER_SELECTIONS_ACTION_COPY, slot_type, \ 232 to_tr, to_slot, NULL, 0, error) 233 234 #define mixer_selections_action_new_paste( \ 235 ms,port_connections_mgr,slot_type, \ 236 to_tr,to_slot,error) \ 237 mixer_selections_action_new ( \ 238 ms, port_connections_mgr, \ 239 MIXER_SELECTIONS_ACTION_PASTE, slot_type, \ 240 to_tr, to_slot, NULL, 0, error) 241 242 #define mixer_selections_action_new_move( \ 243 ms,port_connections_mgr,slot_type, \ 244 to_tr,to_slot,error) \ 245 mixer_selections_action_new ( \ 246 ms, port_connections_mgr, \ 247 MIXER_SELECTIONS_ACTION_MOVE, slot_type, \ 248 to_tr, to_slot, NULL, 0, error) 249 250 #define mixer_selections_action_new_delete( \ 251 ms,port_connections_mgr,error) \ 252 mixer_selections_action_new ( \ 253 ms, port_connections_mgr, \ 254 MIXER_SELECTIONS_ACTION_DELETE, 0, \ 255 0, 0, NULL, 0, error) 256 257 NONNULL 258 MixerSelectionsAction * 259 mixer_selections_action_clone ( 260 const MixerSelectionsAction * src); 261 262 bool 263 mixer_selections_action_perform ( 264 MixerSelections * ms, 265 const PortConnectionsManager * connections_mgr, 266 MixerSelectionsActionType type, 267 PluginSlotType slot_type, 268 unsigned int to_track_name_hash, 269 int to_slot, 270 PluginSetting * setting, 271 int num_plugins, 272 GError ** error); 273 274 #define mixer_selections_action_perform_create( \ 275 slot_type,to_tr,to_slot,setting,num_plugins, \ 276 error) \ 277 mixer_selections_action_perform ( \ 278 NULL, NULL, MIXER_SELECTIONS_ACTION_CREATE, \ 279 slot_type, to_tr, to_slot, setting, \ 280 num_plugins, error) 281 282 #define mixer_selections_action_perform_copy( \ 283 ms,port_connections_mgr,slot_type, \ 284 to_tr,to_slot,error) \ 285 mixer_selections_action_perform ( \ 286 ms, port_connections_mgr, \ 287 MIXER_SELECTIONS_ACTION_COPY, slot_type, \ 288 to_tr, to_slot, NULL, 0, error) 289 290 #define mixer_selections_action_perform_paste( \ 291 ms,port_connections_mgr,slot_type, \ 292 to_tr,to_slot,error) \ 293 mixer_selections_action_perform ( \ 294 ms, port_connections_mgr, \ 295 MIXER_SELECTIONS_ACTION_PASTE, slot_type, \ 296 to_tr, to_slot, NULL, 0, error) 297 298 #define mixer_selections_action_perform_move( \ 299 ms,port_connections_mgr,slot_type, \ 300 to_tr,to_slot,error) \ 301 mixer_selections_action_perform ( \ 302 ms, port_connections_mgr, \ 303 MIXER_SELECTIONS_ACTION_MOVE, slot_type, \ 304 to_tr, to_slot, NULL, 0, error) 305 306 #define mixer_selections_action_perform_delete( \ 307 ms,port_connections_mgr,error) \ 308 mixer_selections_action_perform ( \ 309 ms, port_connections_mgr, \ 310 MIXER_SELECTIONS_ACTION_DELETE, 0, \ 311 0, 0, NULL, 0, error) 312 313 int 314 mixer_selections_action_do ( 315 MixerSelectionsAction * self, 316 GError ** error); 317 318 int 319 mixer_selections_action_undo ( 320 MixerSelectionsAction * self, 321 GError ** error); 322 323 char * 324 mixer_selections_action_stringize ( 325 MixerSelectionsAction * self); 326 327 void 328 mixer_selections_action_free ( 329 MixerSelectionsAction * self); 330 331 #endif 332