UniversalViewer/Assets/Scripts/ModelViewerBase/UI/UIElementDragger.cs

188 lines
5.9 KiB
C#

using UnityEngine;
using UnityEngine.EventSystems;
using static UnityEngine.Rendering.VirtualTexturing.Debugging;
[RequireComponent(typeof(CanvasGroup))]
public class UIElementDragger : MonoBehaviour, IDragHandler, IEndDragHandler, IPointerDownHandler, IPointerUpHandler
{
public bool LockSize;
[ShowIf("LockSize", false)]
public Vector2
SizeMin = new Vector2(100, 100),
SizeMax = new Vector2(1920, 1080);
//Prevent the element for being attached or detached from a toolbar
public bool LockProxyState;
public string ProxyName;
public UIDraggableProxy Proxy;
public UIToolbar.ElementType ElementType;
public GameObject HandlePosition, HandleSize;
private Vector2 mouseOffset;
private float currentScale = 1;
private float sizeWhenClicked;
private Vector2 savedMousePos;
private bool _awake;
private CanvasGroup _canvasGroup;
public DragAction LastDragAction;
public enum DragAction
{
None,
Position,
Scale,
Size
}
private void Awake()
{
if (_awake) return;
_awake = true;
_canvasGroup = GetComponent<CanvasGroup>();
if (LockSize)
{
HandleSize.SetActive(false);
}
}
private void OnEnable()
{
var handle = HandlePosition.GetComponent<RectTransform>();
transform.position = new Vector2(
Mathf.Clamp(transform.position.x, 0, Screen.width - handle.rect.width),
Mathf.Clamp(transform.position.y, handle.sizeDelta.y, Screen.height));
}
public void SetProxyMode(UIDraggableProxy proxy)
{
Awake();
OnEndDrag(null);
Proxy = proxy;
if (proxy != null)
{
transform.position = proxy.GetComponent<RectTransform>().position;
HandlePosition.gameObject.SetActive(false);
}
else
{
gameObject.SetActive(true);
HandlePosition.gameObject.SetActive(true);
}
}
public void ProxySetVisible(bool visible)
{
if (!visible)
{
gameObject.SetActive(false);
}
else
{
var proxyRect = Proxy.transform as RectTransform;
var handleRect = HandlePosition.transform as RectTransform;
var handleOffset = handleRect.sizeDelta.y * Vector3.up;
if (Proxy.GetComponentInParent<UIToolbar>().Layout == UIToolbar.LayoutMode.Vertical)
{
//anchor to top-right of button
transform.position = proxyRect.position + proxyRect.sizeDelta.x * Vector3.right + handleOffset;
}
else
{
//anchor to bottom-left of button
transform.position = proxyRect.position + proxyRect.sizeDelta.y * Vector3.up - handleOffset;
}
gameObject.SetActive(true);
}
}
public void OnDrag(PointerEventData eventData)
{
var rectTsf = GetComponent<RectTransform>();
switch (LastDragAction)
{
case DragAction.Scale:
{
currentScale = Mathf.Clamp((Input.mousePosition.x - savedMousePos.x) / Screen.width + sizeWhenClicked, 0.5f, 1);
transform.localScale = Vector3.one * currentScale;
break;
}
case DragAction.Size:
{
var mousePos = (Vector2)Input.mousePosition;
mousePos.y = -(Screen.height - mousePos.y); //convert anchor from bottom-left to top-left
var sizeDelta = mousePos - rectTsf.anchoredPosition;
sizeDelta.x = Mathf.Clamp(sizeDelta.x, SizeMin.x, Mathf.Min(Screen.width, SizeMax.x));
sizeDelta.y = Mathf.Clamp(-sizeDelta.y, SizeMin.y, Mathf.Min(Screen.height, SizeMax.y));
if (currentScale > 0)
{
sizeDelta *= currentScale;
}
rectTsf.sizeDelta = sizeDelta;
break;
}
case DragAction.Position:
{
var handle = HandlePosition.GetComponent<RectTransform>();
transform.position = new Vector2(
Mathf.Clamp(Input.mousePosition.x + mouseOffset.x, 0, Screen.width - handle.rect.width),
Mathf.Clamp(Input.mousePosition.y + mouseOffset.y, handle.sizeDelta.y, Screen.height));
break;
}
}
}
public void OnEndDrag(PointerEventData eventData)
{
_canvasGroup.blocksRaycasts = true;
}
private void OnDestroy()
{
if(Proxy != null)
{
Destroy(Proxy.gameObject);
}
}
public void OnPointerDown(PointerEventData eventData)
{
eventData.pointerDrag = this.gameObject;
_canvasGroup.blocksRaycasts = false;
if (eventData.button == PointerEventData.InputButton.Right)
{
LastDragAction = DragAction.Scale;
ModelViewerMain.GetInstance().GetCamera().LightLock = true;
savedMousePos = Input.mousePosition;
sizeWhenClicked = currentScale;
transform.SetAsLastSibling();
}
else if (eventData.hovered.Contains(HandlePosition))
{
LastDragAction = DragAction.Position;
mouseOffset = transform.position - Input.mousePosition;
transform.SetAsLastSibling();
}
else if (eventData.hovered.Contains(HandleSize))
{
LastDragAction = DragAction.Size;
mouseOffset = transform.position - Input.mousePosition;
}
else
{
LastDragAction = DragAction.None;
_canvasGroup.blocksRaycasts = true;
eventData.pointerDrag = null;
}
}
public void OnPointerUp(PointerEventData eventData)
{
OnEndDrag(null);
}
}