summaryrefslogtreecommitdiff
path: root/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Manipulators/Utils/EditModeRippleUtils.cs
blob: a705fc6849e50aaff23556ec26fa12a2b62d4809 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine.Timeline;

namespace UnityEditor.Timeline
{
    static class EditModeRippleUtils
    {
        public static void Insert(IEnumerable<ItemsPerTrack> itemsGroups)
        {
            var start = double.MaxValue;
            var end = double.MinValue;

            foreach (var itemsGroup in itemsGroups)
            {
                start = Math.Min(start, itemsGroup.items.Min(c => c.start));
                end = Math.Max(end, itemsGroup.items.Max(c => c.end));
            }

            var offset = 0.0;
            var discreteStart = (DiscreteTime)start;
            var discreteEnd = (DiscreteTime)end;
            var itemTypes = ItemsUtils.GetItemTypes(itemsGroups);
            var siblingsToRipple = new List<ITimelineItem>();

            foreach (var itemsGroup in itemsGroups)
            {
                //can only ripple items of the same type as those selected
                siblingsToRipple.AddRange(ItemsUtils.GetItemsExcept(itemsGroup.targetTrack, itemsGroup.items).Where(i => itemTypes.Contains(i.GetType())));
                foreach (var item in siblingsToRipple)
                {
                    var discreteItemStart = (DiscreteTime)item.start;
                    var discreteItemEnd = (DiscreteTime)item.end;

                    if ((discreteItemStart < discreteStart && discreteItemEnd > discreteStart) || (discreteItemStart >= discreteStart && discreteItemStart < discreteEnd))
                        offset = Math.Max(offset, end - item.start);
                }
            }

            if (offset > 0.0)
            {
                foreach (var sibling in siblingsToRipple)
                {
                    if ((DiscreteTime)sibling.end > (DiscreteTime)start)
                        sibling.start += offset;
                }
            }
        }

        public static void Remove(IEnumerable<ItemsPerTrack> itemsGroups)
        {
            foreach (var itemsGroup in itemsGroups)
                Remove(itemsGroup.targetTrack, itemsGroup.items);
        }

        static void Remove(TrackAsset track, IEnumerable<ITimelineItem> items)
        {
            if (track == null) return;

            //can only ripple items of the same type as those selected
            var itemTypes = ItemsUtils.GetItemTypes(items);
            var siblingsToRipple = ItemsUtils.GetItemsExcept(track, items)
                .Where(i => itemTypes.Contains(i.GetType()))
                .OrderBy(c => c.start)
                .ToArray();

            var orderedItems = items
                .OrderBy(c => c.start)
                .ToArray();

            var cumulativeOffset = 0.0;

            foreach (var item in orderedItems)
            {
                var offset = item.end - item.start;
                var start = item.start - cumulativeOffset;
                var end = item.end - cumulativeOffset;

                var nextItem = siblingsToRipple.FirstOrDefault(c => (DiscreteTime)c.start > (DiscreteTime)start && (DiscreteTime)c.start < (DiscreteTime)end);
                if (nextItem != null)
                {
                    offset -= end - nextItem.start;
                }

                var prevItem = siblingsToRipple.FirstOrDefault(c => (DiscreteTime)c.end > (DiscreteTime)start && (DiscreteTime)c.end < (DiscreteTime)end);
                if (prevItem != null)
                {
                    offset -= prevItem.end - start;
                }

                if (offset <= 0.0)
                    continue;

                cumulativeOffset += offset;

                for (int i = siblingsToRipple.Length - 1; i >= 0; --i)
                {
                    var c = siblingsToRipple[i];
                    if ((DiscreteTime)c.start < (DiscreteTime)start)
                        break;

                    c.start = c.start - offset;
                }
            }
        }
    }
}