251 lines
7.3 KiB
C#
251 lines
7.3 KiB
C#
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<LayoutElement>() ?? leftTarget.gameObject.AddComponent<LayoutElement>();
|
|
}
|
|
return leftTargetElement;
|
|
}
|
|
}
|
|
|
|
private LayoutElement RightTargetElement
|
|
{
|
|
get
|
|
{
|
|
if (rightTargetElement == null)
|
|
{
|
|
rightTargetElement = rightTarget.GetComponent<LayoutElement>() ?? rightTarget.gameObject.AddComponent<LayoutElement>();
|
|
}
|
|
return rightTargetElement;
|
|
}
|
|
}
|
|
|
|
private void Start()
|
|
{
|
|
Init();
|
|
}
|
|
|
|
public void OnInitializePotentialDrag(PointerEventData eventData)
|
|
{
|
|
Init();
|
|
}
|
|
|
|
public void Init()
|
|
{
|
|
canvas = Utilites.FindCanvas(base.transform).GetComponent<Canvas>();
|
|
}
|
|
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
}
|