// This function implements selection of points. Returns true is selection changes
public static bool SelectPoints(IEditablePoint points, Transform cloudTransform, ref List <int> selection, bool firstSelect)
{
int id = GUIUtility.GetControlID(FocusType.Passive);
if (Event.current.alt && Event.current.type != EventType.Repaint)
{
return(false);
}
bool selectionChanged = false;
Event evt = Event.current;
switch (evt.GetTypeForControl(id))
{
case EventType.Layout:
// Tell the handles system that we're the default tool (the one that should get focus when user clicks on nothing else.)
HandleUtility.AddDefaultControl(id);
break;
case EventType.MouseDown:
// If we got a left-mouse down (HandleUtility.nearestControl== id is only true when the user clicked outside any handles),
// we should begin selecting.
if ((HandleUtility.nearestControl == id || firstSelect) && evt.button == 0)
{
// If neither shift nor control is held down, we'll clear the selection as the fist thing.
if (!evt.shift && !EditorGUI.actionKey)
{
selection.Clear();
selectionChanged = true;
}
s_SelectionStart = new List <int>(selection);
// Grab focus so that we can do a rect selection.
GUIUtility.hotControl = id;
// And remember where the drag was from.
s_StartMouseDragPosition = evt.mousePosition;
// Also remember the selection at the start so additive rect selection will work correctly
s_StartDragSelection = new List <int>(selection);
// Use the mouse down event so no other controls get them
evt.Use();
}
break;
case EventType.MouseDrag:
// The user dragged the mouse (and we have the focus from MouseDown). We have a rect selection here
if (GUIUtility.hotControl == id && evt.button == 0)
{
s_DidDrag = true;
// Start by resetting the selection to what it was when the drag began.
selection.Clear();
selection.AddRange(s_StartDragSelection);
// now, we'll go over every point and see if it's inside the Rect defined by the mouse position and
// the start drag position
Rect r = FromToRect(s_StartMouseDragPosition, evt.mousePosition);
var oldMatrix = Handles.matrix;
Handles.matrix = cloudTransform.localToWorldMatrix;
// Go over all the points and add them if they are inside the rect
for (int i = 0; i < points.Count; i++)
{
var point = HandleUtility.WorldToGUIPoint(points.GetPosition(i));
if (r.Contains(point))
{
if (EditorGUI.actionKey)
{
if (s_SelectionStart.Contains(i))
{
selection.Remove(i);
}
}
else
{
if (!s_SelectionStart.Contains(i))
{
selection.Add(i);
}
}
}
}
Handles.matrix = oldMatrix;
// We'll assume the selection has changed and set GUI.changed to true.
// Worst case, somebody will validate a bit too much, but oh well.
GUI.changed = true;
evt.Use();
}
break;
case EventType.MouseUp:
// If we got the mousedown event, the mouseup is ours as well - this is where we clean up.
if (GUIUtility.hotControl == id && evt.button == 0)
{
//Dragging vs clicking
if (!s_DidDrag)
{
// Find out if it was on top of a point.
int selectedPoint = FindNearest(s_StartMouseDragPosition, cloudTransform, points);
// We found a point. We either need to make it selected or add it to an existing selection.
if (selectedPoint != -1)
{
// If neither shift nor action is held down, simply set selection to the picked point.
if (!evt.shift && !EditorGUI.actionKey)
{
selection.Add(selectedPoint);
}
else
{
// Shift was held down. This means we need to add/remove the point
int alreadyInSelection = selection.IndexOf(selectedPoint);
if (alreadyInSelection != -1)
{
selection.RemoveAt(alreadyInSelection);
}
else
{
selection.Add(selectedPoint);
}
}
}
// Selection has changed. set GUI.changed to true so caller can react (e.g. repaint inspector).
GUI.changed = true;
selectionChanged = true;
}
// Clean up various stuff.
s_StartDragSelection = null;
s_StartMouseDragPosition = Vector2.zero;
s_DidDrag = false;
// Release the mouse focus
GUIUtility.hotControl = 0;
// use the event
evt.Use();
}
break;
case EventType.Repaint:
// If we have focus and the mouse has been moved, we'll the draw selection rect.
if (GUIUtility.hotControl == id && evt.mousePosition != s_StartMouseDragPosition)
{
GUIStyle gs = "SelectionRect";
Handles.BeginGUI();
gs.Draw(FromToRect(s_StartMouseDragPosition, evt.mousePosition), false, false, false, false);
Handles.EndGUI();
}
break;
}
if (selectionChanged)
{
selection = selection.Distinct().ToList();
}
return(selectionChanged);
}