231 lines
7.5 KiB
C#
231 lines
7.5 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using UnityEngine;
|
|
using UnityEvent = UnityEngine.Event;
|
|
using SelectionType = UnityEditor.U2D.Sprites.ShapeEditor.SelectionType;
|
|
|
|
namespace UnityEditor.U2D.Sprites
|
|
{
|
|
internal class ShapeEditorRectSelectionTool
|
|
{
|
|
Vector2 m_SelectStartPoint;
|
|
Vector2 m_SelectMousePoint;
|
|
bool m_RectSelecting;
|
|
int m_RectSelectionID;
|
|
const float k_MinSelectionSize = 6f;
|
|
|
|
public event Action<Rect, SelectionType> RectSelect = (i, p) => {};
|
|
public event Action ClearSelection = () => {};
|
|
|
|
public ShapeEditorRectSelectionTool(IGUIUtility gu)
|
|
{
|
|
guiUtility = gu;
|
|
m_RectSelectionID = guiUtility.GetPermanentControlID();
|
|
}
|
|
|
|
public void OnGUI()
|
|
{
|
|
var evt = UnityEvent.current;
|
|
|
|
Handles.BeginGUI();
|
|
|
|
Vector2 mousePos = evt.mousePosition;
|
|
int id = m_RectSelectionID;
|
|
|
|
switch (evt.GetTypeForControl(id))
|
|
{
|
|
case EventType.Layout:
|
|
case EventType.MouseMove:
|
|
if (!Tools.viewToolActive)
|
|
HandleUtility.AddDefaultControl(id);
|
|
break;
|
|
|
|
case EventType.MouseDown:
|
|
if (HandleUtility.nearestControl == id && evt.button == 0)
|
|
{
|
|
guiUtility.hotControl = id;
|
|
m_SelectStartPoint = mousePos;
|
|
}
|
|
break;
|
|
case EventType.MouseDrag:
|
|
if (guiUtility.hotControl == id)
|
|
{
|
|
if (!m_RectSelecting && (mousePos - m_SelectStartPoint).magnitude > k_MinSelectionSize)
|
|
{
|
|
m_RectSelecting = true;
|
|
}
|
|
if (m_RectSelecting)
|
|
{
|
|
m_SelectMousePoint = mousePos;
|
|
|
|
SelectionType type = SelectionType.Normal;
|
|
if (UnityEvent.current.control)
|
|
type = SelectionType.Subtractive;
|
|
else if (UnityEvent.current.shift)
|
|
type = SelectionType.Additive;
|
|
RectSelect(EditorGUIExt.FromToRect(m_SelectStartPoint, m_SelectMousePoint), type);
|
|
}
|
|
evt.Use();
|
|
}
|
|
break;
|
|
|
|
case EventType.Repaint:
|
|
if (guiUtility.hotControl == id && m_RectSelecting)
|
|
{
|
|
EditorStyles.selectionRect.Draw(EditorGUIExt.FromToRect(m_SelectStartPoint, m_SelectMousePoint), GUIContent.none,
|
|
false, false, false, false);
|
|
}
|
|
break;
|
|
|
|
case EventType.MouseUp:
|
|
if (guiUtility.hotControl == id && evt.button == 0)
|
|
{
|
|
guiUtility.hotControl = 0;
|
|
guiUtility.keyboardControl = 0;
|
|
if (m_RectSelecting)
|
|
{
|
|
m_SelectMousePoint = new Vector2(mousePos.x, mousePos.y);
|
|
|
|
SelectionType type = SelectionType.Normal;
|
|
if (UnityEvent.current.control)
|
|
type = SelectionType.Subtractive;
|
|
else if (UnityEvent.current.shift)
|
|
type = SelectionType.Additive;
|
|
|
|
RectSelect(EditorGUIExt.FromToRect(m_SelectStartPoint, m_SelectMousePoint), type);
|
|
|
|
m_RectSelecting = false;
|
|
}
|
|
else
|
|
{
|
|
ClearSelection();
|
|
}
|
|
evt.Use();
|
|
}
|
|
break;
|
|
}
|
|
|
|
Handles.EndGUI();
|
|
}
|
|
|
|
public bool isSelecting
|
|
{
|
|
get { return guiUtility.hotControl == m_RectSelectionID; }
|
|
}
|
|
|
|
IGUIUtility guiUtility
|
|
{
|
|
get; set;
|
|
}
|
|
}
|
|
|
|
// TODO: For now we copy-paste from RectSelection. Refactor to avoid duplicate codes.
|
|
internal class ShapeEditorSelection : IEnumerable<int>
|
|
{
|
|
HashSet<int> m_SelectedPoints = new HashSet<int>();
|
|
ShapeEditor m_ShapeEditor;
|
|
|
|
public ShapeEditorSelection(ShapeEditor owner)
|
|
{
|
|
m_ShapeEditor = owner;
|
|
}
|
|
|
|
public bool Contains(int i)
|
|
{
|
|
return m_SelectedPoints.Contains(i);
|
|
}
|
|
|
|
public int Count
|
|
{
|
|
get { return m_SelectedPoints.Count; }
|
|
}
|
|
|
|
public void DeleteSelection()
|
|
{
|
|
var sorted = m_SelectedPoints.OrderByDescending(x => x);
|
|
foreach (int selectedIndex in sorted)
|
|
{
|
|
m_ShapeEditor.RemovePointAt(selectedIndex);
|
|
}
|
|
if (m_ShapeEditor.activePoint >= m_ShapeEditor.GetPointsCount())
|
|
m_ShapeEditor.activePoint = m_ShapeEditor.GetPointsCount() - 1;
|
|
m_SelectedPoints.Clear();
|
|
}
|
|
|
|
public void MoveSelection(Vector3 delta)
|
|
{
|
|
if (delta.sqrMagnitude < float.Epsilon)
|
|
return;
|
|
|
|
foreach (int selectedIndex in m_SelectedPoints)
|
|
{
|
|
m_ShapeEditor.SetPointPosition(selectedIndex, m_ShapeEditor.GetPointPosition(selectedIndex) + delta);
|
|
}
|
|
}
|
|
|
|
public void Clear()
|
|
{
|
|
m_SelectedPoints.Clear();
|
|
if (m_ShapeEditor != null)
|
|
m_ShapeEditor.activePoint = -1;
|
|
}
|
|
|
|
public void SelectPoint(int i, SelectionType type)
|
|
{
|
|
switch (type)
|
|
{
|
|
case SelectionType.Additive:
|
|
m_ShapeEditor.activePoint = i;
|
|
m_SelectedPoints.Add(i);
|
|
break;
|
|
case SelectionType.Subtractive:
|
|
m_ShapeEditor.activePoint = i > 0 ? i - 1 : 0;
|
|
m_SelectedPoints.Remove(i);
|
|
break;
|
|
case SelectionType.Normal:
|
|
m_SelectedPoints.Clear();
|
|
m_ShapeEditor.activePoint = i;
|
|
m_SelectedPoints.Add(i);
|
|
break;
|
|
default:
|
|
m_ShapeEditor.activePoint = i; break;
|
|
}
|
|
m_ShapeEditor.Repaint();
|
|
}
|
|
|
|
public void RectSelect(Rect rect, SelectionType type)
|
|
{
|
|
if (type == SelectionType.Normal)
|
|
{
|
|
m_SelectedPoints.Clear();
|
|
m_ShapeEditor.activePoint = -1;
|
|
type = SelectionType.Additive;
|
|
}
|
|
|
|
for (int i = 0; i < m_ShapeEditor.GetPointsCount(); i++)
|
|
{
|
|
var p0 = m_ShapeEditor.GetPointPosition(i);
|
|
if (rect.Contains(p0))
|
|
{
|
|
SelectPoint(i, type);
|
|
}
|
|
}
|
|
m_ShapeEditor.Repaint();
|
|
}
|
|
|
|
public HashSet<int> indices { get { return m_SelectedPoints; } }
|
|
|
|
public IEnumerator<int> GetEnumerator()
|
|
{
|
|
return m_SelectedPoints.GetEnumerator();
|
|
}
|
|
|
|
IEnumerator IEnumerable.GetEnumerator()
|
|
{
|
|
return GetEnumerator();
|
|
}
|
|
}
|
|
} // namespace
|