A game about forced loneliness, made by TACStudios
1using System;
2using System.Collections;
3using System.Collections.Generic;
4using System.Linq;
5using UnityEngine;
6using UnityEvent = UnityEngine.Event;
7using SelectionType = UnityEditor.U2D.Sprites.ShapeEditor.SelectionType;
8
9namespace UnityEditor.U2D.Sprites
10{
11 internal class ShapeEditorRectSelectionTool
12 {
13 Vector2 m_SelectStartPoint;
14 Vector2 m_SelectMousePoint;
15 bool m_RectSelecting;
16 int m_RectSelectionID;
17 const float k_MinSelectionSize = 6f;
18
19 public event Action<Rect, SelectionType> RectSelect = (i, p) => {};
20 public event Action ClearSelection = () => {};
21
22 public ShapeEditorRectSelectionTool(IGUIUtility gu)
23 {
24 guiUtility = gu;
25 m_RectSelectionID = guiUtility.GetPermanentControlID();
26 }
27
28 public void OnGUI()
29 {
30 var evt = UnityEvent.current;
31
32 Handles.BeginGUI();
33
34 Vector2 mousePos = evt.mousePosition;
35 int id = m_RectSelectionID;
36
37 switch (evt.GetTypeForControl(id))
38 {
39 case EventType.Layout:
40 case EventType.MouseMove:
41 if (!Tools.viewToolActive)
42 HandleUtility.AddDefaultControl(id);
43 break;
44
45 case EventType.MouseDown:
46 if (HandleUtility.nearestControl == id && evt.button == 0)
47 {
48 guiUtility.hotControl = id;
49 m_SelectStartPoint = mousePos;
50 }
51 break;
52 case EventType.MouseDrag:
53 if (guiUtility.hotControl == id)
54 {
55 if (!m_RectSelecting && (mousePos - m_SelectStartPoint).magnitude > k_MinSelectionSize)
56 {
57 m_RectSelecting = true;
58 }
59 if (m_RectSelecting)
60 {
61 m_SelectMousePoint = mousePos;
62
63 SelectionType type = SelectionType.Normal;
64 if (UnityEvent.current.control)
65 type = SelectionType.Subtractive;
66 else if (UnityEvent.current.shift)
67 type = SelectionType.Additive;
68 RectSelect(EditorGUIExt.FromToRect(m_SelectStartPoint, m_SelectMousePoint), type);
69 }
70 evt.Use();
71 }
72 break;
73
74 case EventType.Repaint:
75 if (guiUtility.hotControl == id && m_RectSelecting)
76 {
77 EditorStyles.selectionRect.Draw(EditorGUIExt.FromToRect(m_SelectStartPoint, m_SelectMousePoint), GUIContent.none,
78 false, false, false, false);
79 }
80 break;
81
82 case EventType.MouseUp:
83 if (guiUtility.hotControl == id && evt.button == 0)
84 {
85 guiUtility.hotControl = 0;
86 guiUtility.keyboardControl = 0;
87 if (m_RectSelecting)
88 {
89 m_SelectMousePoint = new Vector2(mousePos.x, mousePos.y);
90
91 SelectionType type = SelectionType.Normal;
92 if (UnityEvent.current.control)
93 type = SelectionType.Subtractive;
94 else if (UnityEvent.current.shift)
95 type = SelectionType.Additive;
96
97 RectSelect(EditorGUIExt.FromToRect(m_SelectStartPoint, m_SelectMousePoint), type);
98
99 m_RectSelecting = false;
100 }
101 else
102 {
103 ClearSelection();
104 }
105 evt.Use();
106 }
107 break;
108 }
109
110 Handles.EndGUI();
111 }
112
113 public bool isSelecting
114 {
115 get { return guiUtility.hotControl == m_RectSelectionID; }
116 }
117
118 IGUIUtility guiUtility
119 {
120 get; set;
121 }
122 }
123
124 // TODO: For now we copy-paste from RectSelection. Refactor to avoid duplicate codes.
125 internal class ShapeEditorSelection : IEnumerable<int>
126 {
127 HashSet<int> m_SelectedPoints = new HashSet<int>();
128 ShapeEditor m_ShapeEditor;
129
130 public ShapeEditorSelection(ShapeEditor owner)
131 {
132 m_ShapeEditor = owner;
133 }
134
135 public bool Contains(int i)
136 {
137 return m_SelectedPoints.Contains(i);
138 }
139
140 public int Count
141 {
142 get { return m_SelectedPoints.Count; }
143 }
144
145 public void DeleteSelection()
146 {
147 var sorted = m_SelectedPoints.OrderByDescending(x => x);
148 foreach (int selectedIndex in sorted)
149 {
150 m_ShapeEditor.RemovePointAt(selectedIndex);
151 }
152 if (m_ShapeEditor.activePoint >= m_ShapeEditor.GetPointsCount())
153 m_ShapeEditor.activePoint = m_ShapeEditor.GetPointsCount() - 1;
154 m_SelectedPoints.Clear();
155 }
156
157 public void MoveSelection(Vector3 delta)
158 {
159 if (delta.sqrMagnitude < float.Epsilon)
160 return;
161
162 foreach (int selectedIndex in m_SelectedPoints)
163 {
164 m_ShapeEditor.SetPointPosition(selectedIndex, m_ShapeEditor.GetPointPosition(selectedIndex) + delta);
165 }
166 }
167
168 public void Clear()
169 {
170 m_SelectedPoints.Clear();
171 if (m_ShapeEditor != null)
172 m_ShapeEditor.activePoint = -1;
173 }
174
175 public void SelectPoint(int i, SelectionType type)
176 {
177 switch (type)
178 {
179 case SelectionType.Additive:
180 m_ShapeEditor.activePoint = i;
181 m_SelectedPoints.Add(i);
182 break;
183 case SelectionType.Subtractive:
184 m_ShapeEditor.activePoint = i > 0 ? i - 1 : 0;
185 m_SelectedPoints.Remove(i);
186 break;
187 case SelectionType.Normal:
188 m_SelectedPoints.Clear();
189 m_ShapeEditor.activePoint = i;
190 m_SelectedPoints.Add(i);
191 break;
192 default:
193 m_ShapeEditor.activePoint = i; break;
194 }
195 m_ShapeEditor.Repaint();
196 }
197
198 public void RectSelect(Rect rect, SelectionType type)
199 {
200 if (type == SelectionType.Normal)
201 {
202 m_SelectedPoints.Clear();
203 m_ShapeEditor.activePoint = -1;
204 type = SelectionType.Additive;
205 }
206
207 for (int i = 0; i < m_ShapeEditor.GetPointsCount(); i++)
208 {
209 var p0 = m_ShapeEditor.GetPointPosition(i);
210 if (rect.Contains(p0))
211 {
212 SelectPoint(i, type);
213 }
214 }
215 m_ShapeEditor.Repaint();
216 }
217
218 public HashSet<int> indices { get { return m_SelectedPoints; } }
219
220 public IEnumerator<int> GetEnumerator()
221 {
222 return m_SelectedPoints.GetEnumerator();
223 }
224
225 IEnumerator IEnumerable.GetEnumerator()
226 {
227 return GetEnumerator();
228 }
229 }
230} // namespace