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 #include <limits.h>
21 
22 #include "audio/chord_track.h"
23 #include "audio/engine.h"
24 #include "audio/marker_track.h"
25 #include "audio/position.h"
26 #include "audio/track.h"
27 #include "audio/transport.h"
28 #include "gui/backend/event.h"
29 #include "gui/backend/event_manager.h"
30 #include "gui/backend/timeline_selections.h"
31 #include "gui/widgets/midi_region.h"
32 #include "project.h"
33 #include "utils/arrays.h"
34 #include "utils/audio.h"
35 #include "utils/flags.h"
36 #include "utils/objects.h"
37 #include "utils/yaml.h"
38 #include "zrythm_app.h"
39 
40 #include <gtk/gtk.h>
41 
42 /**
43  * Creates a new TimelineSelections instance for
44  * the given range.
45  *
46  * @bool clone_objs True to clone each object,
47  *   false to use pointers to project objects.
48  */
49 TimelineSelections *
timeline_selections_new_for_range(Position * start_pos,Position * end_pos,bool clone_objs)50 timeline_selections_new_for_range (
51   Position * start_pos,
52   Position * end_pos,
53   bool       clone_objs)
54 {
55   TimelineSelections * self =
56     (TimelineSelections *)
57     arranger_selections_new (
58       ARRANGER_SELECTIONS_TYPE_TIMELINE);
59 
60 #define ADD_OBJ(obj) \
61   if (arranger_object_is_hit ( \
62         (ArrangerObject *) (obj), \
63         start_pos, end_pos)) \
64     { \
65       ArrangerObject * _obj = \
66         (ArrangerObject *) (obj); \
67       if (clone_objs) \
68         { \
69           _obj =  \
70           arranger_object_clone (_obj); \
71         } \
72       arranger_selections_add_object ( \
73         (ArrangerSelections *) self, _obj); \
74     }
75 
76   /* regions */
77   for (int i = 0; i < TRACKLIST->num_tracks; i++)
78     {
79       Track * track = TRACKLIST->tracks[i];
80       AutomationTracklist * atl =
81         track_get_automation_tracklist (track);
82       for (int j = 0; j < track->num_lanes; j++)
83         {
84           TrackLane * lane = track->lanes[j];
85           for (int k = 0; k < lane->num_regions; k++)
86             {
87               ADD_OBJ (lane->regions[k]);
88             }
89         }
90       for (int j = 0; j < track->num_chord_regions;
91            j++)
92         {
93           ADD_OBJ (track->chord_regions[j]);
94         }
95       if (atl)
96         {
97           for (int j = 0; j < atl->num_ats; j++)
98             {
99               AutomationTrack * at = atl->ats[j];
100 
101               for (int k = 0; k < at->num_regions;
102                    k++)
103                 {
104                   ADD_OBJ (at->regions[k]);
105                 }
106             }
107         }
108       for (int j = 0; j < track->num_scales; j++)
109         {
110           ADD_OBJ (track->scales[j]);
111         }
112       for (int j = 0; j < track->num_markers; j++)
113         {
114           ADD_OBJ (track->markers[j]);
115         }
116     }
117 
118 #undef ADD_OBJ
119 
120   return self;
121 }
122 
123 /**
124  * Gets highest track in the selections.
125  */
126 Track *
timeline_selections_get_last_track(TimelineSelections * ts)127 timeline_selections_get_last_track (
128   TimelineSelections * ts)
129 {
130   int track_pos = -1;
131   Track * track = NULL;
132   int tmp_pos;
133   Track * tmp_track;
134 
135 #define CHECK_POS(_track) \
136   tmp_track = _track; \
137   tmp_pos = \
138     tracklist_get_track_pos ( \
139       TRACKLIST, tmp_track); \
140   if (tmp_pos > track_pos) \
141     { \
142       track_pos = tmp_pos; \
143       track = tmp_track; \
144     }
145 
146   ZRegion * region;
147   for (int i = 0; i < ts->num_regions; i++)
148     {
149       region = ts->regions[i];
150       ArrangerObject * r_obj =
151         (ArrangerObject *) region;
152       Track * _track =
153         arranger_object_get_track (r_obj);
154       CHECK_POS (_track);
155     }
156   CHECK_POS (P_CHORD_TRACK);
157 
158   return track;
159 #undef CHECK_POS
160 }
161 
162 /**
163  * Gets lowest track in the selections.
164  */
165 Track *
timeline_selections_get_first_track(TimelineSelections * ts)166 timeline_selections_get_first_track (
167   TimelineSelections * ts)
168 {
169   int track_pos = INT_MAX;
170   Track * track = NULL;
171   int tmp_pos;
172   Track * tmp_track;
173 
174 #define CHECK_POS(_track) \
175   tmp_track = _track; \
176   tmp_pos = \
177     tracklist_get_track_pos ( \
178       TRACKLIST, tmp_track); \
179   if (tmp_pos < track_pos) \
180     { \
181       track_pos = tmp_pos; \
182       track = tmp_track; \
183     }
184 
185   ZRegion * region;
186   for (int i = 0; i < ts->num_regions; i++)
187     {
188       region = ts->regions[i];
189       ArrangerObject * r_obj =
190         (ArrangerObject *) region;
191       Track * _track =
192         arranger_object_get_track (r_obj);
193       CHECK_POS (_track);
194     }
195   if (ts->num_scale_objects > 0)
196     {
197       CHECK_POS (P_CHORD_TRACK);
198     }
199   if (ts->num_markers > 0)
200     {
201       CHECK_POS (P_MARKER_TRACK);
202     }
203 
204   return track;
205 #undef CHECK_POS
206 }
207 
208 /**
209  * Gets index of the lowest track in the selections.
210  *
211  * Used during pasting.
212  */
213 static int
get_lowest_track_pos(TimelineSelections * ts)214 get_lowest_track_pos (
215   TimelineSelections * ts)
216 {
217   int track_pos = INT_MAX;
218 
219 #define CHECK_POS(id) \
220   { \
221   }
222 
223   for (int i = 0; i < ts->num_regions; i++)
224     {
225       ZRegion * r = ts->regions[i];
226       Track * tr =
227         tracklist_find_track_by_name_hash (
228           TRACKLIST, r->id.track_name_hash);
229       if (tr->pos < track_pos)
230         {
231           track_pos = tr->pos;
232         }
233     }
234 
235   if (ts->num_scale_objects > 0)
236     {
237       if (ts->chord_track_vis_index < track_pos)
238         track_pos = ts->chord_track_vis_index;
239     }
240   if (ts->num_markers > 0)
241     {
242       if (ts->marker_track_vis_index < track_pos)
243         track_pos = ts->marker_track_vis_index;
244     }
245 
246   return track_pos;
247 }
248 
249 /**
250  * Replaces the track positions in each object with
251  * visible track indices starting from 0.
252  *
253  * Used during copying.
254  */
255 void
timeline_selections_set_vis_track_indices(TimelineSelections * ts)256 timeline_selections_set_vis_track_indices (
257   TimelineSelections * ts)
258 {
259   int i;
260   Track * highest_tr =
261     timeline_selections_get_first_track (ts);
262 
263   for (i = 0; i < ts->num_regions; i++)
264     {
265       ZRegion * r = ts->regions[i];
266       Track * region_track =
267         arranger_object_get_track (
268           (ArrangerObject *) r);
269       ts->region_track_vis_index =
270         tracklist_get_visible_track_diff (
271           TRACKLIST, highest_tr, region_track);
272     }
273   if (ts->num_scale_objects > 0)
274     ts->chord_track_vis_index =
275       tracklist_get_visible_track_diff (
276         TRACKLIST, highest_tr, P_CHORD_TRACK);
277   if (ts->num_markers > 0)
278     ts->marker_track_vis_index =
279       tracklist_get_visible_track_diff (
280         TRACKLIST, highest_tr, P_MARKER_TRACK);
281 }
282 
283 /**
284  * Saves the track positions in the poses array
285  * and the size in num_poses.
286  */
287 static void
get_track_poses(TimelineSelections * ts,int * poses,int * num_poses)288 get_track_poses (
289   TimelineSelections * ts,
290   int *                poses,
291   int *                num_poses)
292 {
293   int i;
294   for (i = 0; i < ts->num_regions; i++)
295     {
296       ZRegion * r = ts->regions[i];
297       Track * region_track =
298         arranger_object_get_track (
299           (ArrangerObject *) r);
300       if (!array_contains_int (
301             poses, *num_poses, region_track->pos))
302         {
303           array_append (
304             poses, *num_poses, region_track->pos);
305         }
306     }
307   if (ts->num_scale_objects > 0)
308     if (!array_contains_int (
309           poses, *num_poses,
310           ts->chord_track_vis_index))
311       {
312         array_append (
313           poses, *num_poses,
314           ts->chord_track_vis_index);
315       }
316   if (ts->num_markers > 0)
317     if (!array_contains_int (
318           poses, *num_poses,
319           ts->marker_track_vis_index))
320       {
321         array_append (
322           poses, *num_poses,
323           ts->marker_track_vis_index);
324       }
325 }
326 
327 /**
328  * Returns if the selections can be pasted.
329  *
330  * @param pos Position to paste to.
331  * @param idx Track index to start pasting to.
332  */
333 int
timeline_selections_can_be_pasted(TimelineSelections * ts,Position * pos,const int idx)334 timeline_selections_can_be_pasted (
335   TimelineSelections * ts,
336   Position *           pos,
337   const int            idx)
338 {
339   int i, j;
340   ZRegion * r;
341   /*Marker * m;*/
342   /*ScaleObject * s;*/
343   int lowest_track_pos =
344     get_lowest_track_pos (ts);
345   Track * cur_track =
346     TRACKLIST_SELECTIONS->tracks[0];
347   int poses[800];
348   int num_poses = 0;
349   get_track_poses (ts, poses, &num_poses);
350   if (!cur_track || num_poses <= 0
351       || lowest_track_pos == INT_MAX)
352     return false;
353 
354   /*check if enough visible tracks exist and the*/
355   /*content can be pasted in each*/
356   int ts_pos;
357   for (i = 0; i < num_poses; i++)
358     {
359       ts_pos = poses[i];
360       g_return_val_if_fail (ts_pos >= 0, 0);
361 
362       /*[> track at the new position <]*/
363       Track * tr =
364         tracklist_get_visible_track_after_delta (
365           TRACKLIST, cur_track, ts_pos);
366       if (!tr)
367         {
368           g_message (
369             "no track at current pos (%d) + "
370             "ts pos (%d)",
371             cur_track->pos, ts_pos);
372           return false;
373         }
374 
375       /* check if content matches */
376       for (j = 0; j < ts->num_regions; j++)
377         {
378           /* get region at this ts_pos */
379           r = ts->regions[j];
380           Track * region_track =
381             arranger_object_get_track (
382               (ArrangerObject *) r);
383           if (region_track->pos != ts_pos)
384             continue;
385 
386            /*check if this track can host this*/
387            /*region*/
388           if (!track_type_can_host_region_type (
389                 tr->type, r->id.type))
390             {
391               g_message (
392                 "track %s cant host region type %d",
393                 tr->name, r->id.type);
394               return false;
395             }
396         }
397 
398       /* check for chord track/marker track too */
399       if (ts->num_scale_objects > 0 &&
400           ts_pos == ts->chord_track_vis_index &&
401           tr->type != TRACK_TYPE_CHORD)
402         return false;
403       if (ts->num_markers > 0 &&
404           ts_pos == ts->marker_track_vis_index &&
405           tr->type != TRACK_TYPE_MARKER)
406         return false;
407     }
408 
409   return true;
410 }
411 
412 #if 0
413 void
414 timeline_selections_paste_to_pos (
415   TimelineSelections * ts,
416   Position *           pos)
417 {
418   Track * track =
419     TRACKLIST_SELECTIONS->tracks[0];
420 
421   arranger_selections_clear (
422     (ArrangerSelections *) TL_SELECTIONS, F_NO_FREE);
423 
424   double pos_ticks = position_to_ticks (pos);
425 
426   /* get pos of earliest object */
427   Position start_pos;
428   arranger_selections_get_start_pos (
429     (ArrangerSelections *) ts, &start_pos,
430     F_GLOBAL);
431   double start_pos_ticks =
432     position_to_ticks (&start_pos);
433 
434   double curr_ticks, diff;
435   int i;
436   for (i = 0; i < ts->num_regions; i++)
437     {
438       ZRegion * region = ts->regions[i];
439       ArrangerObject * r_obj =
440         (ArrangerObject *) region;
441       Track * region_track =
442         tracklist_get_visible_track_after_delta (
443           TRACKLIST, track, region->id.track_pos);
444       g_return_if_fail (region_track);
445 
446       /* update positions */
447       curr_ticks =
448         position_to_ticks (&r_obj->pos);
449       diff = curr_ticks - start_pos_ticks;
450       position_from_ticks (
451         &r_obj->pos, pos_ticks + diff);
452       curr_ticks =
453         position_to_ticks (&r_obj->end_pos);
454       diff = curr_ticks - start_pos_ticks;
455       position_from_ticks (
456         &r_obj->end_pos, pos_ticks + diff);
457       /* TODO */
458 
459       /* clone and add to track */
460       ZRegion * cp =
461         (ZRegion *)
462         arranger_object_clone (
463           r_obj,
464           ARRANGER_OBJECT_CLONE_COPY_MAIN);
465 
466       switch (region->id.type)
467         {
468         case REGION_TYPE_MIDI:
469         case REGION_TYPE_AUDIO:
470           track_add_region (
471             region_track, cp, NULL,
472             region->id.lane_pos,
473             F_GEN_NAME, F_PUBLISH_EVENTS);
474           break;
475         case REGION_TYPE_AUTOMATION:
476           {
477             AutomationTrack * at =
478               region_track->automation_tracklist.
479                 ats[region->id.at_idx];
480             g_return_if_fail (at);
481             track_add_region (
482               region_track, cp, at, -1,
483               F_GEN_NAME, F_PUBLISH_EVENTS);
484           }
485           break;
486         case REGION_TYPE_CHORD:
487           track_add_region (
488             region_track, cp, NULL, -1,
489             F_GEN_NAME, F_PUBLISH_EVENTS);
490           break;
491         }
492 
493       /* select it */
494       arranger_object_select (
495         (ArrangerObject *) cp, F_SELECT,
496         F_APPEND);
497     }
498   for (i = 0; i < ts->num_scale_objects; i++)
499     {
500       ScaleObject * scale = ts->scale_objects[i];
501       ArrangerObject * s_obj =
502         (ArrangerObject *) scale;
503 
504       curr_ticks =
505         position_to_ticks (&s_obj->pos);
506       diff = curr_ticks - start_pos_ticks;
507       position_from_ticks (
508         &s_obj->pos, pos_ticks + diff);
509 
510       /* clone and add to track */
511       ScaleObject * clone =
512         (ScaleObject *)
513         arranger_object_clone (
514           s_obj,
515           ARRANGER_OBJECT_CLONE_COPY_MAIN);
516       chord_track_add_scale (
517         P_CHORD_TRACK, clone);
518 
519       /* select it */
520       arranger_object_select (
521         (ArrangerObject *) clone, F_SELECT,
522         F_APPEND);
523     }
524   for (i = 0; i < ts->num_markers; i++)
525     {
526       Marker * m = ts->markers[i];
527       ArrangerObject * m_obj =
528         (ArrangerObject *) m;
529 
530       curr_ticks =
531         position_to_ticks (&m_obj->pos);
532       diff = curr_ticks - start_pos_ticks;
533       position_from_ticks (
534         &m_obj->pos, pos_ticks + diff);
535 
536       /* clone and add to track */
537       Marker * clone =
538         (Marker *)
539         arranger_object_clone (
540           m_obj,
541           ARRANGER_OBJECT_CLONE_COPY_MAIN);
542       marker_track_add_marker (
543         P_MARKER_TRACK, clone);
544 
545       /* select it */
546       arranger_object_select (
547         (ArrangerObject *) clone, F_SELECT,
548         F_APPEND);
549     }
550 #undef DIFF
551 }
552 #endif
553 
554 /**
555  * @param with_parents Also mark all the track's
556  *   parents recursively.
557  */
558 void
timeline_selections_mark_for_bounce(TimelineSelections * ts,bool with_parents)559 timeline_selections_mark_for_bounce (
560   TimelineSelections * ts,
561   bool                 with_parents)
562 {
563   engine_reset_bounce_mode (AUDIO_ENGINE);
564 
565   for (int i = 0; i < ts->num_regions; i++)
566     {
567       ZRegion * r = ts->regions[i];
568       Track * track =
569         arranger_object_get_track (
570           (ArrangerObject *) r);
571       g_return_if_fail (track);
572 
573       track_mark_for_bounce (
574         track, F_BOUNCE, F_NO_MARK_REGIONS,
575         F_MARK_CHILDREN, with_parents);
576       r->bounce = 1;
577     }
578 }
579 
580 /**
581  * Move the selected Regions to new Lanes.
582  *
583  * @param diff The delta to move the
584  *   Tracks.
585  *
586  * @return True if moved.
587  */
588 bool
timeline_selections_move_regions_to_new_lanes(TimelineSelections * self,const int diff)589 timeline_selections_move_regions_to_new_lanes (
590   TimelineSelections * self,
591   const int            diff)
592 {
593   arranger_selections_sort_by_indices (
594     (ArrangerSelections *) self, false);
595 
596   /* store selected regions because they will be
597    * deselected during moving */
598   ZRegion * regions[600];
599   int num_regions = 0;
600   ZRegion * region;
601   for (int i = 0; i < self->num_regions; i++)
602     {
603       regions[num_regions++] =
604         self->regions[i];
605     }
606 
607   /* check that:
608    * - all regions are in the same track
609    * - only lane regions are selected
610    * - the lane bounds are not exceeded */
611   bool compatible = true;
612   for (int i = 0; i < num_regions; i++)
613     {
614       region = regions[i];
615       if (region->id.lane_pos + diff < 0)
616         {
617           compatible = false;
618           break;
619         }
620     }
621   if (self->num_scale_objects > 0 ||
622       self->num_markers > 0)
623     {
624       compatible = false;
625     }
626   if (!compatible)
627     return false;
628 
629   /* new positions are all compatible, move the
630    * regions */
631   for (int i = 0; i < num_regions; i++)
632     {
633       region = regions[i];
634       TrackLane * lane = region_get_lane (region);
635       g_return_val_if_fail (region && lane, -1);
636 
637       TrackLane * lane_to_move_to = NULL;
638       int new_lane_pos =
639         lane->pos +  diff;
640       g_return_val_if_fail (
641         new_lane_pos >= 0, -1);
642       Track * track = track_lane_get_track (lane);
643       track_create_missing_lanes (
644         track, new_lane_pos);
645       lane_to_move_to =
646         track->lanes[new_lane_pos];
647       g_warn_if_fail (lane_to_move_to);
648 
649       region_move_to_lane (
650         region, lane_to_move_to, -1);
651     }
652 
653   EVENTS_PUSH (
654     ET_TRACK_LANES_VISIBILITY_CHANGED, NULL);
655 
656   return true;
657 }
658 
659 /**
660  * Move the selected Regions to the new Track.
661  *
662  * @param new_track_is_before 1 if the Region's
663  *   should move to their previous tracks, 0 for
664  *   their next tracks.
665  *
666  * @return True if moved.
667  */
668 bool
timeline_selections_move_regions_to_new_tracks(TimelineSelections * self,const int vis_track_diff)669 timeline_selections_move_regions_to_new_tracks (
670   TimelineSelections * self,
671   const int            vis_track_diff)
672 {
673   g_debug (
674     "moving %d regions to new tracks "
675     "(visible track diff %d)...",
676     self->num_regions, vis_track_diff);
677 
678   arranger_selections_sort_by_indices (
679     (ArrangerSelections *) self, false);
680 
681   /* store selected regions because they will be
682    * deselected during moving */
683   ZRegion * regions[600];
684   int num_regions = 0;
685   ZRegion * region;
686   ArrangerObject * r_obj;
687   for (int i = 0; i < self->num_regions; i++)
688     {
689       regions[num_regions++] =
690         self->regions[i];
691     }
692 
693   /* check that all regions can be moved to a
694    * compatible track */
695   bool compatible = true;
696   for (int i = 0; i < num_regions; i++)
697     {
698       region = regions[i];
699       r_obj = (ArrangerObject *) region;
700       Track * region_track =
701         arranger_object_get_track (r_obj);
702       Track * visible =
703         tracklist_get_visible_track_after_delta (
704           TRACKLIST,
705           region_track,
706           vis_track_diff);
707       if (
708         !visible ||
709         !track_type_is_compatible_for_moving (
710            region_track->type,
711            visible->type) ||
712         /* do not allow moving automation tracks
713          * to other tracks for now */
714         region->id.type == REGION_TYPE_AUTOMATION)
715         {
716           compatible = false;
717           break;
718         }
719     }
720   if (!compatible)
721     {
722       return false;
723     }
724 
725   /* new positions are all compatible, move the
726    * regions */
727   for (int i = 0; i < num_regions; i++)
728     {
729       region = regions[i];
730       r_obj = (ArrangerObject *) region;
731       Track * region_track =
732         arranger_object_get_track (r_obj);
733       g_warn_if_fail (region && region_track);
734       Track * track_to_move_to =
735         tracklist_get_visible_track_after_delta (
736           TRACKLIST,
737           region_track,
738           vis_track_diff);
739       g_warn_if_fail (track_to_move_to);
740 
741       region_move_to_track (
742         region, track_to_move_to, -1);
743     }
744 
745   g_debug ("moved");
746 
747   return true;
748 }
749 
750 /**
751  * Sets the regions'
752  * \ref ZRegion.index_in_prev_lane.
753  */
754 void
timeline_selections_set_index_in_prev_lane(TimelineSelections * self)755 timeline_selections_set_index_in_prev_lane (
756   TimelineSelections * self)
757 {
758   for (int i = 0; i < self->num_regions; i++)
759     {
760       ZRegion * r = self->regions[i];
761       ArrangerObject * r_obj = (ArrangerObject *) r;
762       r_obj->index_in_prev_lane = r->id.idx;
763     }
764 }
765 
766 bool
timeline_selections_contains_only_regions(TimelineSelections * self)767 timeline_selections_contains_only_regions (
768   TimelineSelections * self)
769 {
770   return
771     self->num_regions > 0
772     && self->num_scale_objects == 0
773     && self->num_markers == 0 ;
774 }
775 
776 bool
timeline_selections_contains_only_region_types(TimelineSelections * self,RegionType types)777 timeline_selections_contains_only_region_types (
778   TimelineSelections * self,
779   RegionType           types)
780 {
781   if (!timeline_selections_contains_only_regions (self))
782     return false;
783 
784   for (int i = 0; i < self->num_regions; i++)
785     {
786       ZRegion * r = self->regions[i];
787       if (!(types & r->id.type))
788         return false;
789     }
790   return true;
791 }
792