using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.UI; namespace UIWidgets { public class Splitter : MonoBehaviour, IInitializePotentialDragHandler, IBeginDragHandler, IEndDragHandler, IDragHandler, IEventSystemHandler { public SplitterType Type = SplitterType.Vertical; [SerializeField] public bool UpdateRectTransforms = true; [SerializeField] public bool UpdateLayoutElements = true; [SerializeField] public Camera CurrentCamera; [SerializeField] public Texture2D CursorTexture; [SerializeField] public Vector2 CursorHotSpot = new Vector2(16f, 16f); [SerializeField] public Texture2D DefaultCursorTexture; [SerializeField] public Vector2 DefaultCursorHotSpot; public SplitterResizeEvent OnStartResize = new SplitterResizeEvent(); public SplitterResizeEvent OnEndResize = new SplitterResizeEvent(); private RectTransform rectTransform; private Canvas canvas; private RectTransform leftTarget; private RectTransform rightTarget; private LayoutElement leftTargetElement; private LayoutElement rightTargetElement; private Vector2 summarySize; private bool processDrag; private bool cursorSetted; public RectTransform RectTransform { get { if (rectTransform == null) { rectTransform = base.transform as RectTransform; } return rectTransform; } } private LayoutElement LeftTargetElement { get { if (leftTargetElement == null) { leftTargetElement = leftTarget.GetComponent() ?? leftTarget.gameObject.AddComponent(); } return leftTargetElement; } } private LayoutElement RightTargetElement { get { if (rightTargetElement == null) { rightTargetElement = rightTarget.GetComponent() ?? rightTarget.gameObject.AddComponent(); } return rightTargetElement; } } private void Start() { Init(); } public void OnInitializePotentialDrag(PointerEventData eventData) { Init(); } public void Init() { canvas = Utilites.FindCanvas(base.transform).GetComponent(); } private void LateUpdate() { Vector2 localPoint; if (!processDrag && !(CursorTexture == null) && Input.mousePresent && RectTransformUtility.ScreenPointToLocalPointInRectangle(RectTransform, Input.mousePosition, CurrentCamera, out localPoint)) { if (RectTransform.rect.Contains(localPoint)) { cursorSetted = true; Cursor.SetCursor(CursorTexture, CursorHotSpot, Utilites.GetCursorMode()); } else if (cursorSetted) { cursorSetted = false; Cursor.SetCursor(DefaultCursorTexture, DefaultCursorHotSpot, Utilites.GetCursorMode()); } } } public void OnBeginDrag(PointerEventData eventData) { processDrag = false; Vector2 localPoint; if (RectTransformUtility.ScreenPointToLocalPointInRectangle(RectTransform, eventData.pressPosition, eventData.pressEventCamera, out localPoint)) { int siblingIndex = base.transform.GetSiblingIndex(); if (siblingIndex != 0 && base.transform.parent.childCount != siblingIndex + 1) { Cursor.SetCursor(CursorTexture, CursorHotSpot, Utilites.GetCursorMode()); cursorSetted = true; processDrag = true; leftTarget = base.transform.parent.GetChild(siblingIndex - 1) as RectTransform; LeftTargetElement.preferredWidth = leftTarget.rect.width; LeftTargetElement.preferredHeight = leftTarget.rect.height; rightTarget = base.transform.parent.GetChild(siblingIndex + 1) as RectTransform; RightTargetElement.preferredWidth = rightTarget.rect.width; RightTargetElement.preferredHeight = rightTarget.rect.height; summarySize = new Vector2(leftTarget.rect.width + rightTarget.rect.width, leftTarget.rect.height + rightTarget.rect.height); OnStartResize.Invoke(this); } } } public void OnEndDrag(PointerEventData eventData) { Cursor.SetCursor(DefaultCursorTexture, DefaultCursorHotSpot, Utilites.GetCursorMode()); cursorSetted = false; processDrag = false; OnEndResize.Invoke(this); } public void OnDrag(PointerEventData eventData) { if (processDrag) { if (canvas == null) { throw new MissingComponentException(base.gameObject.name + " not in Canvas hierarchy."); } Vector2 localPoint; RectTransformUtility.ScreenPointToLocalPointInRectangle(RectTransform, eventData.position, CurrentCamera, out localPoint); Vector2 localPoint2; RectTransformUtility.ScreenPointToLocalPointInRectangle(RectTransform, eventData.position - eventData.delta, CurrentCamera, out localPoint2); Vector2 delta = localPoint - localPoint2; if (UpdateRectTransforms) { PerformUpdateRectTransforms(delta); } if (UpdateLayoutElements) { PerformUpdateLayoutElements(delta); } } } private bool IsHorizontal() { return SplitterType.Horizontal == Type; } private void PerformUpdateRectTransforms(Vector2 delta) { if (!IsHorizontal()) { float size; float size2; if (delta.x > 0f) { size = Mathf.Min(LeftTargetElement.preferredWidth + delta.x, summarySize.x - RightTargetElement.minWidth); size2 = summarySize.x - LeftTargetElement.preferredWidth; } else { size2 = Mathf.Min(RightTargetElement.preferredWidth - delta.x, summarySize.x - LeftTargetElement.minWidth); size = summarySize.x - RightTargetElement.preferredWidth; } leftTarget.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, size); rightTarget.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, size2); return; } delta.y *= -1f; float size3; float size4; if (delta.y > 0f) { size3 = Mathf.Min(LeftTargetElement.preferredHeight + delta.y, summarySize.y - RightTargetElement.minHeight); size4 = summarySize.y - LeftTargetElement.preferredHeight; } else { size4 = Mathf.Min(RightTargetElement.preferredHeight - delta.y, summarySize.y - LeftTargetElement.minHeight); size3 = summarySize.y - RightTargetElement.preferredHeight; } leftTarget.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, size3); rightTarget.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, size4); } private void PerformUpdateLayoutElements(Vector2 delta) { if (!IsHorizontal()) { if (delta.x > 0f) { LeftTargetElement.preferredWidth = Mathf.Min(LeftTargetElement.preferredWidth + delta.x, summarySize.x - RightTargetElement.minWidth); RightTargetElement.preferredWidth = summarySize.x - LeftTargetElement.preferredWidth; } else { RightTargetElement.preferredWidth = Mathf.Min(RightTargetElement.preferredWidth - delta.x, summarySize.x - LeftTargetElement.minWidth); LeftTargetElement.preferredWidth = summarySize.x - RightTargetElement.preferredWidth; } return; } delta.y *= -1f; if (delta.y > 0f) { LeftTargetElement.preferredHeight = Mathf.Min(LeftTargetElement.preferredHeight + delta.y, summarySize.y - RightTargetElement.minHeight); RightTargetElement.preferredHeight = summarySize.y - LeftTargetElement.preferredHeight; } else { RightTargetElement.preferredHeight = Mathf.Min(RightTargetElement.preferredHeight - delta.y, summarySize.y - LeftTargetElement.minHeight); LeftTargetElement.preferredHeight = summarySize.y - RightTargetElement.preferredHeight; } } } }