2024-04-22 06:00:51 +08:00
|
|
|
using System.Collections;
|
2024-04-21 22:38:26 +08:00
|
|
|
using UnityEngine;
|
|
|
|
using UnityEngine.EventSystems;
|
2024-04-22 06:00:51 +08:00
|
|
|
using UnityEngine.UI;
|
2024-04-21 22:38:26 +08:00
|
|
|
|
|
|
|
[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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-04-22 06:00:51 +08:00
|
|
|
private void Start()
|
2024-04-21 22:38:26 +08:00
|
|
|
{
|
2024-04-22 06:00:51 +08:00
|
|
|
if (Proxy == null)
|
|
|
|
{
|
|
|
|
transform.position = RecalculatePosition(transform.position);
|
|
|
|
}
|
2024-04-21 22:38:26 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
|
{
|
2024-04-22 06:00:51 +08:00
|
|
|
var canvas = ModelViewerInterface.GetInstance().MainCanvas;
|
2024-04-21 22:38:26 +08:00
|
|
|
var proxyRect = Proxy.transform as RectTransform;
|
|
|
|
var handleRect = HandlePosition.transform as RectTransform;
|
2024-04-22 06:00:51 +08:00
|
|
|
var handleOffset = handleRect.sizeDelta.y * canvas.scaleFactor * Vector3.up;
|
2024-04-21 22:38:26 +08:00
|
|
|
if (Proxy.GetComponentInParent<UIToolbar>().Layout == UIToolbar.LayoutMode.Vertical)
|
|
|
|
{
|
|
|
|
//anchor to top-right of button
|
2024-04-22 06:00:51 +08:00
|
|
|
transform.position = proxyRect.position + proxyRect.sizeDelta.x * canvas.scaleFactor * Vector3.right + handleOffset;
|
2024-04-21 22:38:26 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
//anchor to bottom-left of button
|
2024-04-22 06:00:51 +08:00
|
|
|
transform.position = proxyRect.position + proxyRect.sizeDelta.y * canvas.scaleFactor * Vector3.up - handleOffset;
|
2024-04-21 22:38:26 +08:00
|
|
|
}
|
|
|
|
gameObject.SetActive(true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public void OnDrag(PointerEventData eventData)
|
|
|
|
{
|
2024-04-23 18:25:12 +08:00
|
|
|
var rectTsf = transform as RectTransform;
|
|
|
|
var canvas = ModelViewerInterface.GetInstance().MainCanvas;
|
2024-04-21 22:38:26 +08:00
|
|
|
|
|
|
|
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
|
2024-04-23 18:25:12 +08:00
|
|
|
var sizeDelta = mousePos / canvas.scaleFactor - (Vector2)rectTsf.anchoredPosition;
|
|
|
|
sizeDelta.x = Mathf.Clamp(sizeDelta.x, SizeMin.x, Mathf.Min(Screen.width / canvas.scaleFactor, SizeMax.x));
|
|
|
|
sizeDelta.y = Mathf.Clamp(-sizeDelta.y, SizeMin.y, Mathf.Min(Screen.height / canvas.scaleFactor, SizeMax.y));
|
2024-04-21 22:38:26 +08:00
|
|
|
if (currentScale > 0)
|
|
|
|
{
|
|
|
|
sizeDelta *= currentScale;
|
|
|
|
}
|
|
|
|
rectTsf.sizeDelta = sizeDelta;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case DragAction.Position:
|
|
|
|
{
|
2024-04-22 06:00:51 +08:00
|
|
|
transform.position = RecalculatePosition((Vector2)Input.mousePosition + mouseOffset);
|
2024-04-21 22:38:26 +08:00
|
|
|
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);
|
|
|
|
}
|
2024-04-22 06:00:51 +08:00
|
|
|
|
|
|
|
public Vector2 RecalculatePosition(Vector2 pos)
|
|
|
|
{
|
|
|
|
var handle = HandlePosition.transform as RectTransform;
|
|
|
|
var tsf = transform as RectTransform;
|
|
|
|
var canvas = ModelViewerInterface.GetInstance().MainCanvas;
|
|
|
|
|
|
|
|
var xPos = Mathf.Clamp(pos.x, 0, Screen.width - tsf.sizeDelta.x * canvas.scaleFactor);
|
|
|
|
var yPos = Mathf.Clamp(pos.y, handle.sizeDelta.y * canvas.scaleFactor, Screen.height);
|
|
|
|
|
|
|
|
return new Vector2 (xPos, yPos);
|
|
|
|
}
|
2024-04-21 22:38:26 +08:00
|
|
|
}
|