using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Events;
using UnityEngine.EventSystems;
using Lean.Transition;
using Lean.Common;
namespace Lean.Gui
{
/// This component allows you to resize the specified RectTransform when you drag on this UI element.
[RequireComponent(typeof(RectTransform))]
[HelpURL(LeanGui.HelpUrlPrefix + "LeanResize")]
[AddComponentMenu(LeanGui.ComponentMenuPrefix + "Resize")]
public class LeanResize : LeanSelectable, IBeginDragHandler, IDragHandler, IEndDragHandler
{
/// If you want this GameObject to act as a resize handle, and for a different object to actually be resized then specify the target object here.
public RectTransform Target { set { target = value; } get { return target; } } [SerializeField] private RectTransform target;
/// Should you be able to drag horizontally?
public bool Horizontal { set { horizontal = value; } get { return horizontal; } } [SerializeField] private bool horizontal = true;
/// Horizontal resize strength.
/// 0 = none
/// 1 = normal
/// -1 = inverted
/// 2 = centered
public float HorizontalScale { set { horizontalScale = value; } get { return horizontalScale; } } [SerializeField] private float horizontalScale = 1.0f;
/// Should the horizontal size value be clamped?
public bool HorizontalClamp { set { horizontalClamp = value; } get { return horizontalClamp; } } [SerializeField] private bool horizontalClamp;
/// The minimum size value.
public float HorizontalMin { set { horizontalMin = value; } get { return horizontalMin; } } [SerializeField] private float horizontalMin = 50.0f;
/// The maximum size value.
public float HorizontalMax { set { horizontalMax = value; } get { return horizontalMax; } } [SerializeField] private float horizontalMax = 500.0f;
/// Should you be able to drag vertically?
public bool Vertical { set { vertical = value; } get { return vertical; } } [SerializeField] private bool vertical = true;
/// Vertical resize strength.
/// 0 = none
/// 1 = normal
/// -1 = inverted
/// 2 = centered
public float VerticalScale { set { verticalScale = value; } get { return verticalScale; } } [SerializeField] private float verticalScale = 1.0f;
/// Should the vertical size value be clamped?
public bool VerticalClamp { set { verticalClamp = value; } get { return verticalClamp; } } [SerializeField] private bool verticalClamp;
/// The minimum size value.
public float VerticalMin { set { verticalMin = value; } get { return verticalMin; } } [SerializeField] private float verticalMin = 50.0f;
/// The maximum size value.
public float VerticalMax { set { verticalMax = value; } get { return verticalMax; } } [SerializeField] private float verticalMax = 500.0f;
/// This allows you to perform a transition when this element begins being resized.
/// You can create a new transition GameObject by right clicking the transition name, and selecting Create.
/// For example, the Graphic.color Transition (LeanGraphicColor) component can be used to change the color.
/// NOTE: Any transitions you perform here must be reverted in the Normal Transitions setting using a matching transition component.
public LeanPlayer BeginTransitions { get { if (beginTransitions == null) beginTransitions = new LeanPlayer(); return beginTransitions; } } [SerializeField] private LeanPlayer beginTransitions;
/// This allows you to perform a transition when this element ends being resized.
/// You can create a new transition GameObject by right clicking the transition name, and selecting Create.
/// For example, the Graphic.color Transition (LeanGraphicColor) component can be used to change the color.
public LeanPlayer EndTransitions { get { if (endTransitions == null) endTransitions = new LeanPlayer(); return endTransitions; } } [SerializeField] private LeanPlayer endTransitions;
/// This allows you to perform an actions when this element begins being resized.
public UnityEvent OnBegin { get { if (onBegin == null) { onBegin = new UnityEvent(); } return onBegin; } } [SerializeField] private UnityEvent onBegin;
/// This allows you to perform an actions when this element ends being resized.
public UnityEvent OnEnd { get { if (onEnd == null) { onEnd = new UnityEvent(); } return onEnd; } } [SerializeField] private UnityEvent onEnd;
[System.NonSerialized]
private bool dragging;
[System.NonSerialized]
private Vector2 startSize;
[System.NonSerialized]
private Vector2 startOffset;
[System.NonSerialized]
private RectTransform cachedRectTransform;
[System.NonSerialized]
private bool cachedRectTransformSet;
public RectTransform TargetTransform
{
get
{
if (target != null)
{
return target;
}
if (cachedRectTransformSet == false)
{
cachedRectTransform = GetComponent();
cachedRectTransformSet = true;
}
return cachedRectTransform;
}
}
public void OnBeginDrag(PointerEventData eventData)
{
if (MayDrag(eventData) == true)
{
var target = TargetTransform;
var vector = default(Vector2);
if (RectTransformUtility.ScreenPointToLocalPointInRectangle(target, eventData.position, eventData.pressEventCamera, out vector) == true)
{
dragging = true;
startSize = target.sizeDelta;
startOffset = vector - target.anchoredPosition;
if (beginTransitions != null)
{
beginTransitions.Begin();
}
if (onBegin != null)
{
onBegin.Invoke();
}
}
}
}
public void OnDrag(PointerEventData eventData)
{
if (dragging == true)
{
if (MayDrag(eventData) == true)
{
var vector = default(Vector2);
var target = TargetTransform;
if (RectTransformUtility.ScreenPointToLocalPointInRectangle(target, eventData.position, eventData.pressEventCamera, out vector) == true)
{
var offsetDelta = (vector - target.anchoredPosition) - startOffset;
var sizeDelta = target.sizeDelta;
if (horizontal == true)
{
sizeDelta.x = startSize.x + offsetDelta.x * horizontalScale;
if (horizontalClamp == true)
{
sizeDelta.x = Mathf.Clamp(sizeDelta.x, horizontalMin, horizontalMax);
}
}
if (vertical == true)
{
sizeDelta.y = startSize.y + offsetDelta.y * verticalScale;
if (verticalClamp == true)
{
sizeDelta.y = Mathf.Clamp(sizeDelta.y, verticalMin, verticalMax);
}
}
target.sizeDelta = sizeDelta;
}
}
}
}
public void OnEndDrag(PointerEventData eventData)
{
dragging = false;
if (endTransitions != null)
{
endTransitions.Begin();
}
if (onEnd != null)
{
onEnd.Invoke();
}
}
protected override void Start()
{
base.Start();
transition = Transition.None;
interactable = true;
}
protected override void OnEnable()
{
base.OnEnable();
LeanGui.OnDraggingCheck += DraggingCheck;
}
protected override void OnDisable()
{
base.OnDisable();
LeanGui.OnDraggingCheck -= DraggingCheck;
}
private void DraggingCheck(ref bool check)
{
if (dragging == true)
{
check = true;
}
}
private bool MayDrag(PointerEventData eventData)
{
return IsActive() && IsInteractable();// && eventData.button == PointerEventData.InputButton.Left;
}
}
}
#if UNITY_EDITOR
namespace Lean.Gui.Editor
{
using TARGET = LeanResize;
[UnityEditor.CanEditMultipleObjects]
[UnityEditor.CustomEditor(typeof(TARGET))]
public class LeanResize_Editor : LeanSelectable_Editor
{
protected override void DrawSelectableSettings()
{
base.DrawSelectableSettings();
TARGET tgt; TARGET[] tgts; GetTargets(out tgt, out tgts);
base.DrawSelectableSettings();
Draw("target", "If you want this GameObject to act as a resize handle, and for a different object to actually be resized then specify the target object here.");
Separator();
Draw("horizontal", "Should you be able to drag horizontally?");
if (Any(tgts, t => t.Horizontal == true))
{
BeginIndent();
Draw("horizontalScale", "Horizontal resize strength.\n\n0 = none\n\n1 = normal\n\n-1 = inverted\n\n2 = centered", "Scale");
Draw("horizontalClamp", "Should the horizontal position value be clamped?", "Clamp");
if (Any(tgts, t => t.HorizontalClamp == true))
{
BeginIndent();
Draw("horizontalMin", "The minimum position value.", "Min");
Draw("horizontalMax", "The maximum position value.", "Max");
EndIndent();
}
EndIndent();
}
Separator();
Draw("vertical", "Should you be able to drag vertically?");
if (Any(tgts, t => t.Vertical == true))
{
BeginIndent();
Draw("verticalScale", "Vertical resize strength.\n\n0 = none\n\n1 = normal\n\n-1 = inverted\n\n2 = centered", "Scale");
Draw("verticalClamp", "Should the vertical position value be clamped?", "Clamp");
if (Any(tgts, t => t.VerticalClamp == true))
{
BeginIndent();
Draw("verticalMin", "The minimum position value.", "Min");
Draw("verticalMax", "The maximum position value.", "Max");
EndIndent();
}
EndIndent();
}
}
protected override void DrawSelectableTransitions(bool showUnusedEvents)
{
TARGET tgt; TARGET[] tgts; GetTargets(out tgt, out tgts);
if (showUnusedEvents == true || Any(tgts, t => t.BeginTransitions.IsUsed == true))
{
Draw("beginTransitions", "This allows you to perform a transition when this element begins being dragged. You can create a new transition GameObject by right clicking the transition name, and selecting Create. For example, the Graphic.color Transition (LeanGraphicColor) component can be used to change the color.\n\nNOTE: Any transitions you perform here must be reverted in the Normal Transitions setting using a matching transition component.");
}
if (showUnusedEvents == true || Any(tgts, t => t.EndTransitions.IsUsed == true))
{
Draw("endTransitions", "This allows you to perform a transition when this element ends being dragged. You can create a new transition GameObject by right clicking the transition name, and selecting Create. For example, the Graphic.color Transition (LeanGraphicColor) component can be used to change the color.");
}
base.DrawSelectableTransitions(showUnusedEvents);
}
protected override void DrawSelectableEvents(bool showUnusedEvents)
{
TARGET tgt; TARGET[] tgts; GetTargets(out tgt, out tgts);
if (showUnusedEvents == true || Any(tgts, t => t.OnBegin.GetPersistentEventCount() > 0))
{
Draw("onBegin");
}
if (showUnusedEvents == true || Any(tgts, t => t.OnEnd.GetPersistentEventCount() > 0))
{
Draw("onEnd");
}
base.DrawSelectableEvents(showUnusedEvents);
}
}
}
#endif