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

179 行
5.3 KiB

using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.RMGUI;
namespace RMGUI.GraphView
{
public class RectangleSelector : MouseManipulator, IDecorator
{
private Vector2 m_Start = Vector2.zero;
private Vector2 m_End = Vector2.zero;
public RectangleSelector()
{
activateButton = MouseButton.LeftMouse;
}
// 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();
target.AddDecorator(this);
m_Start = evt.mousePosition;
m_End = m_Start;
return EventPropagation.Stop;
}
break;
case EventType.MouseUp:
if (CanStopManipulation(evt))
{
this.ReleaseCapture();
target.RemoveDecorator(this);
m_End = evt.mousePosition;
var selectionRect = new Rect();
selectionRect.min = new Vector2(Math.Min(m_Start.x, m_End.x), Math.Min(m_Start.y, m_End.y));
selectionRect.max = new Vector2(Math.Max(m_Start.x, m_End.x), Math.Max(m_Start.y, m_End.y));
selectionRect = ComputeAAAlignedBound(selectionRect, graphView.contentViewContainer.transform.inverse);
selectionRect.width = Mathf.Max(selectionRect.width, 5.0f);
selectionRect.height = Mathf.Max(selectionRect.height, 5.0f);
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_End = evt.mousePosition;
return EventPropagation.Stop;
}
break;
}
return EventPropagation.Continue;
}
public override void OnLostCapture()
{
target.RemoveDecorator(this);
}
public void PrePaint(VisualElement t, IStylePainter painter)
{
}
// todo shanti move paint dotted border to StylePainter
// todo move text render to style painter
public void PostPaint(VisualElement t, IStylePainter painter)
{
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();
}
}
}