您最多选择25个主题 主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 

193 行
5.6 KiB

using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.RMGUI;
using UnityEngine.RMGUI.StyleEnums;
namespace RMGUI.GraphView
{
public class RectangleSelector : MouseManipulator
{
private RectangleSelect m_Rectangle;
public RectangleSelector()
{
activators.Add(new ManipActivator {button = MouseButton.LeftMouse});
m_Rectangle = new RectangleSelect
{
positionType = PositionType.Absolute,
positionTop = 0,
positionLeft = 0,
positionBottom = 0,
positionRight = 0
};
}
// get the AA aligned bound
public Rect ComputeAAAlignedBound(Rect position, Matrix4x4 transform)
{
Vector3 min = transform.MultiplyPoint3x4(position.min);
Vector3 max = transform.MultiplyPoint3x4(position.max);
return Rect.MinMaxRect(Math.Min(min.x, max.x), Math.Min(min.y, max.y), Math.Max(min.x, max.x), Math.Max(min.y, max.y));
}
public override EventPropagation HandleEvent(Event evt, VisualElement finalTarget)
{
if (finalTarget != target && !this.HasCapture())
return EventPropagation.Continue;
var graphView = target as GraphView;
if (graphView == null)
{
throw new InvalidOperationException("Manipulator can only be added to a GraphView");
}
switch (evt.type)
{
case EventType.MouseDown:
if (CanStartManipulation(evt))
{
if (!evt.control)
{
graphView.ClearSelection();
}
this.TakeCapture();
var c = (VisualContainer)target;
c.AddChild(m_Rectangle);
m_Rectangle.m_Start = evt.mousePosition;
m_Rectangle.m_End = m_Rectangle.m_Start;
return EventPropagation.Stop;
}
break;
case EventType.MouseUp:
if (CanStopManipulation(evt))
{
this.ReleaseCapture();
var c = (VisualContainer)target;
c.RemoveChild(m_Rectangle);
m_Rectangle.m_End = evt.mousePosition;
var selectionRect = new Rect()
{
min = new Vector2(Math.Min(m_Rectangle.m_Start.x, m_Rectangle.m_End.x), Math.Min(m_Rectangle.m_Start.y, m_Rectangle.m_End.y)),
max = new Vector2(Math.Max(m_Rectangle.m_Start.x, m_Rectangle.m_End.x), Math.Max(m_Rectangle.m_Start.y, m_Rectangle.m_End.y))
};
selectionRect = ComputeAAAlignedBound(selectionRect, graphView.contentViewContainer.transform.inverse);
List<ISelectable> selection = graphView.selection;
List<VisualElement>.Enumerator children = graphView.contentViewContainer.GetChildren();
while (children.MoveNext())
{
VisualElement child = children.Current;
if (child == null)
continue;
var selectable = child as ISelectable;
Matrix4x4 selectableTransform = child.transform.inverse;
var localSelRect = new Rect(selectableTransform.MultiplyPoint3x4(selectionRect.position), selectableTransform.MultiplyPoint3x4(selectionRect.size));
if (selectable != null && selectable.IsSelectable() && selectable.Overlaps(localSelRect))
{
if (selection.Contains(selectable))
graphView.RemoveFromSelection(selectable);
else
graphView.AddToSelection(selectable);
}
}
return EventPropagation.Stop;
}
break;
case EventType.MouseDrag:
if (this.HasCapture())
{
m_Rectangle.m_End = evt.mousePosition;
return EventPropagation.Stop;
}
break;
}
return EventPropagation.Continue;
}
public override void OnLostCapture()
{
var c = target as VisualContainer;
if (c != null)
c.RemoveChild(m_Rectangle);
}
class RectangleSelect : VisualElement
{
public Vector2 m_Start = Vector2.zero;
public Vector2 m_End = Vector2.zero;
public override void DoRepaint(IStylePainter painter)
{
VisualElement t = parent;
Vector2 screenStart = m_Start;
Vector2 screenEnd = m_End;
// Avoid drawing useless information
if (m_Start == m_End)
return;
// Apply offset
screenStart += t.position.position;
screenEnd += t.position.position;
var r = new Rect
{
min = new Vector2(Math.Min(screenStart.x, screenEnd.x), Math.Min(screenStart.y, screenEnd.y)),
max = new Vector2(Math.Max(screenStart.x, screenEnd.x), Math.Max(screenStart.y, screenEnd.y))
};
var lineColor = new Color(1.0f, 0.6f, 0.0f, 1.0f);
var segmentSize = 5f;
Vector3[] points =
{
new Vector3(r.xMin, r.yMin, 0.0f),
new Vector3(r.xMax, r.yMin, 0.0f),
new Vector3(r.xMax, r.yMax, 0.0f),
new Vector3(r.xMin, r.yMax, 0.0f)
};
DrawDottedLine(points[0], points[1], segmentSize, lineColor);
DrawDottedLine(points[1], points[2], segmentSize, lineColor);
DrawDottedLine(points[2], points[3], segmentSize, lineColor);
DrawDottedLine(points[3], points[0], segmentSize, lineColor);
var str = "(" + String.Format("{0:0}", m_Start.x) + ", " + String.Format("{0:0}", m_Start.y) + ")";
GUI.skin.label.Draw(new Rect(screenStart.x, screenStart.y - 18.0f, 200.0f, 20.0f), new GUIContent(str), 0);
str = "(" + String.Format("{0:0}", m_End.x) + ", " + String.Format("{0:0}", m_End.y) + ")";
GUI.skin.label.Draw(new Rect(screenEnd.x - 80.0f, screenEnd.y + 5.0f, 200.0f, 20.0f), new GUIContent(str), 0);
}
private void DrawDottedLine(Vector3 p1, Vector3 p2, float segmentsLength, Color col)
{
UIHelpers.ApplyWireMaterial();
GL.Begin(GL.LINES);
GL.Color(col);
float length = Vector3.Distance(p1, p2); // ignore z component
int count = Mathf.CeilToInt(length / segmentsLength);
for (int i = 0; i < count; i += 2)
{
GL.Vertex((Vector3.Lerp(p1, p2, i * segmentsLength / length)));
GL.Vertex((Vector3.Lerp(p1, p2, (i + 1) * segmentsLength / length)));
}
GL.End();
}
}
}
}