139 lines
3.4 KiB
C#
139 lines
3.4 KiB
C#
|
using System;
|
||
|
using System.Collections.Generic;
|
||
|
using UnityEngine;
|
||
|
|
||
|
namespace UnityEditor.U2D.Animation
|
||
|
{
|
||
|
[Serializable]
|
||
|
internal abstract class SerializableSelection<T> : ISelection<T>, ISerializationCallbackReceiver
|
||
|
{
|
||
|
internal readonly static int kInvalidID = -1;
|
||
|
|
||
|
[SerializeField]
|
||
|
private T[] m_Keys = new T[0];
|
||
|
|
||
|
private HashSet<T> m_Selection = new HashSet<T>();
|
||
|
private HashSet<T> m_TemporalSelection = new HashSet<T>();
|
||
|
private bool m_SelectionInProgress = false;
|
||
|
|
||
|
public int Count
|
||
|
{
|
||
|
get { return m_Selection.Count + m_TemporalSelection.Count; }
|
||
|
}
|
||
|
|
||
|
public T activeElement
|
||
|
{
|
||
|
get { return First(); }
|
||
|
set
|
||
|
{
|
||
|
Clear();
|
||
|
Select(value, true);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public T[] elements
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
var set = m_Selection;
|
||
|
|
||
|
if (m_SelectionInProgress)
|
||
|
{
|
||
|
var union = new HashSet<T>(m_Selection);
|
||
|
union.UnionWith(m_TemporalSelection);
|
||
|
set = union;
|
||
|
}
|
||
|
|
||
|
return new List<T>(set).ToArray();
|
||
|
}
|
||
|
set
|
||
|
{
|
||
|
Clear();
|
||
|
foreach(var element in value)
|
||
|
Select(element, true);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
protected abstract T GetInvalidElement();
|
||
|
|
||
|
public void Clear()
|
||
|
{
|
||
|
GetSelection().Clear();
|
||
|
}
|
||
|
|
||
|
public void BeginSelection()
|
||
|
{
|
||
|
m_SelectionInProgress = true;
|
||
|
Clear();
|
||
|
}
|
||
|
|
||
|
public void EndSelection(bool select)
|
||
|
{
|
||
|
m_SelectionInProgress = false;
|
||
|
|
||
|
if (select)
|
||
|
m_Selection.UnionWith(m_TemporalSelection);
|
||
|
else
|
||
|
m_Selection.ExceptWith(m_TemporalSelection);
|
||
|
|
||
|
m_TemporalSelection.Clear();
|
||
|
}
|
||
|
|
||
|
public void Select(T element, bool select)
|
||
|
{
|
||
|
if(EqualityComparer<T>.Default.Equals(element, GetInvalidElement()))
|
||
|
return;
|
||
|
|
||
|
if (select)
|
||
|
GetSelection().Add(element);
|
||
|
else if (Contains(element))
|
||
|
GetSelection().Remove(element);
|
||
|
}
|
||
|
|
||
|
public bool Contains(T element)
|
||
|
{
|
||
|
return m_Selection.Contains(element) || m_TemporalSelection.Contains(element);
|
||
|
}
|
||
|
|
||
|
private HashSet<T> GetSelection()
|
||
|
{
|
||
|
if (m_SelectionInProgress)
|
||
|
return m_TemporalSelection;
|
||
|
|
||
|
return m_Selection;
|
||
|
}
|
||
|
|
||
|
private T First()
|
||
|
{
|
||
|
T element = First(m_Selection);
|
||
|
|
||
|
if(EqualityComparer<T>.Default.Equals(element, GetInvalidElement()))
|
||
|
element = First(m_TemporalSelection);
|
||
|
|
||
|
return element;
|
||
|
}
|
||
|
|
||
|
private T First(HashSet<T> set)
|
||
|
{
|
||
|
if(set.Count == 0)
|
||
|
return GetInvalidElement();
|
||
|
|
||
|
using (var enumerator = set.GetEnumerator())
|
||
|
{
|
||
|
Debug.Assert(enumerator.MoveNext());
|
||
|
return enumerator.Current;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void ISerializationCallbackReceiver.OnBeforeSerialize()
|
||
|
{
|
||
|
m_Keys = new List<T>(m_Selection).ToArray();
|
||
|
}
|
||
|
|
||
|
void ISerializationCallbackReceiver.OnAfterDeserialize()
|
||
|
{
|
||
|
elements = m_Keys;
|
||
|
}
|
||
|
}
|
||
|
}
|