using System; using System.Collections.Generic; using UnityEngine; using UnityEditor; using UnityEditor.Experimental.Rendering.Universal.Path2D.GUIFramework; namespace UnityEditor.Experimental.Rendering.Universal.Path2D { internal abstract class RectSelector : ISelector { public Action, bool> onSelectionBegin; public Action> onSelectionChanged; public Action> onSelectionEnd = null; private GUISystem m_GUISystem; private Control m_RectSelectorControl; private GUIAction m_RectSelectAction; private Vector3 m_RectStart; private Vector3 m_RectEnd; private Rect m_GUIRect; private IDrawer m_Drawer = new Drawer(); public Rect guiRect { get { return m_GUIRect; } } public RectSelector() : this(new GUISystem(new GUIState())) { } public RectSelector(GUISystem guiSystem) { m_GUISystem = guiSystem; m_RectSelectorControl = new GenericDefaultControl("RectSelector") { position = (guiState) => { return GUIToWorld(guiState, guiState.mousePosition); }, forward = (guiState) => { if (Camera.current) return Camera.current.transform.forward; return Vector3.forward; }, right = (guiState) => { if (Camera.current) return Camera.current.transform.right; return Vector3.right; }, up = (guiState) => { if (Camera.current) return Camera.current.transform.up; return Vector3.up; } }; m_RectSelectAction = new SliderAction(m_RectSelectorControl) { enableRepaint = (guiState, action) => { var size = m_RectStart - m_RectEnd; return size != Vector3.zero && guiState.hotControl == action.ID; }, onClick = (guiState, control) => { m_RectStart = GUIToWorld(guiState, guiState.mousePosition); m_RectEnd = m_RectStart; m_GUIRect = CalculateGUIRect(); }, onSliderBegin = (guiState, control, position) => { m_RectEnd = position; m_GUIRect = CalculateGUIRect(); if (onSelectionBegin != null) onSelectionBegin(this, guiState.isShiftDown); }, onSliderChanged = (guiState, control, position) => { m_RectEnd = position; m_GUIRect = CalculateGUIRect(); if (onSelectionChanged != null) onSelectionChanged(this); }, onSliderEnd = (guiState, control, position) => { if (onSelectionEnd != null) onSelectionEnd(this); }, onRepaint = (guiState, action) => { m_Drawer.DrawSelectionRect(m_GUIRect); } }; m_GUISystem.AddControl(m_RectSelectorControl); m_GUISystem.AddAction(m_RectSelectAction); } private Vector3 GUIToWorld(IGUIState guiState, Vector2 guiPosition) { var forward = Vector3.forward; if (guiState.HasCurrentCamera()) forward = Camera.current.transform.forward; return guiState.GUIToWorld(guiPosition, forward, Vector3.zero); } private Rect CalculateGUIRect() { return FromToRect(HandleUtility.WorldToGUIPoint(m_RectStart), HandleUtility.WorldToGUIPoint(m_RectEnd)); } private Rect FromToRect(Vector2 start, Vector2 end) { Rect r = new Rect(start.x, start.y, end.x - start.x, end.y - start.y); if (r.width < 0) { r.x += r.width; r.width = -r.width; } if (r.height < 0) { r.y += r.height; r.height = -r.height; } return r; } public void OnGUI() { m_GUISystem.OnGUI(); } bool ISelector.Select(T element) { return Select(element); } protected abstract bool Select(T element); } }