File size: 3,546 Bytes
18a519f | 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 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 | using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Timeline;
namespace UnityEditor.Timeline
{
enum Layer : byte
{
Clips,
ClipHandles,
Markers,
MarkerHeaderTrack,
MarkersOnHeader
}
struct LayerZOrder : IComparable<LayerZOrder>
{
Layer m_Layer;
int m_ZOrder;
public LayerZOrder(Layer layer, int zOrder)
{
m_Layer = layer;
m_ZOrder = zOrder;
}
public int CompareTo(LayerZOrder other)
{
if (m_Layer == other.m_Layer)
return m_ZOrder.CompareTo(other.m_ZOrder);
return m_Layer.CompareTo(other.m_Layer);
}
public static LayerZOrder operator ++(LayerZOrder x)
{
return new LayerZOrder(x.m_Layer, x.m_ZOrder + 1);
}
public LayerZOrder ChangeLayer(Layer layer)
{
return new LayerZOrder(layer, m_ZOrder);
}
}
interface ILayerable
{
LayerZOrder zOrder { get; }
}
interface IZOrderProvider
{
LayerZOrder Next();
}
interface ILayer : IZOrderProvider
{
void Draw(Rect rect, WindowState state);
}
abstract class ItemsLayer<T> : ILayer where T : TimelineItemGUI
{
// provide a buffer for time-based culling to allow for UI that extends slightly beyond the time (e.g. markers)
// prevents popping of marker visibility.
const int kVisibilityBufferInPixels = 10;
int m_PreviousLayerStateHash = -1;
LayerZOrder m_LastZOrder;
public LayerZOrder Next()
{
m_NeedSort = true;
return m_LastZOrder++;
}
readonly List<T> m_Items = new List<T>();
bool m_NeedSort = true;
public virtual void Draw(Rect rect, WindowState state)
{
if (m_Items.Count <= 0) return;
Sort();
// buffer to prevent flickering of markers at boundaries
var onePixelTime = state.PixelDeltaToDeltaTime(kVisibilityBufferInPixels);
var visibleTime = state.timeAreaShownRange + new Vector2(-onePixelTime, onePixelTime);
var layerViewStateHasChanged = GetLayerViewStateChanged(rect, state);
foreach (var item in m_Items)
{
item.visible = item.end > visibleTime.x && item.start < visibleTime.y;
if (!item.visible)
continue;
item.Draw(rect, layerViewStateHasChanged, state);
}
}
public List<T> items => m_Items;
protected void AddItem(T item)
{
m_Items.Add(item);
m_NeedSort = true;
}
protected ItemsLayer(Layer layerOrder)
{
m_LastZOrder = new LayerZOrder(layerOrder, 0);
}
void Sort()
{
if (!m_NeedSort)
return;
m_Items.Sort((a, b) => a.zOrder.CompareTo(b.zOrder));
m_NeedSort = false;
}
bool GetLayerViewStateChanged(Rect rect, WindowState state)
{
var layerStateHash = rect.GetHashCode().CombineHash(state.viewStateHash);
var layerViewStateHasChanged = layerStateHash != m_PreviousLayerStateHash;
if (Event.current.type == EventType.Layout && layerViewStateHasChanged)
m_PreviousLayerStateHash = layerStateHash;
return layerViewStateHasChanged;
}
}
}
|