using UnityEngine;
using UnityEngine.Events;
namespace Rellac.Windows
{
///
/// Script to handle expanding and restoring a window to/from screen size
///
public class GUIWindowExpander : GUIPointerObject
{
private const float MaxTimeForDoubleClick = 0.5f;
///
/// Window to apply expand effect to
///
[Tooltip("")]
[SerializeField] private RectTransform parentWindow = null;
///
/// Expander is locked and unusable
///
[Tooltip("")]
[SerializeField] private bool isLocked = false;
///
/// Allows you to double click this target image to minimise/maximise
///
[Tooltip("Allows you to double click this target image to minimise/maximise")]
[SerializeField] private bool doubleClick = true;
///
/// Fires when window starts restoring to a smaller size
///
public UnityEvent onMinimised = null;
///
/// Fires when window starts expanding
///
public UnityEvent onMaximised = null;
private bool isMaximised = false;
private bool doAction = false;
private Vector2 initialPosition;
private Vector2 initialMinAnchor;
private Vector2 initialMaxAnchor;
private Vector2 initialSize;
private Vector2 initialPivot = Vector2.one * -1;
private Vector2 targetPosition;
private Vector2 targetSize;
private int numClicks;
void Start()
{
onPointerDown.AddListener(parentWindow.SetAsLastSibling);
onPointerDown.AddListener(TryDoubleClick);
}
// Update is called once per frame
void Update()
{
if (doAction)
{
// Lerp to position & size
parentWindow.sizeDelta = Vector2.MoveTowards(parentWindow.sizeDelta, targetSize, Time.deltaTime * 10000);
parentWindow.anchoredPosition = Vector2.MoveTowards(parentWindow.anchoredPosition, targetPosition, Time.deltaTime * 5000);
// reached target
if (parentWindow.sizeDelta == targetSize && parentWindow.anchoredPosition == targetPosition)
{
doAction = false;
if (isMaximised)
{ // set to a full stretched rect
parentWindow.anchorMin = Vector2.zero;
parentWindow.anchorMax = Vector2.one;
parentWindow.sizeDelta = Vector2.zero;
parentWindow.anchoredPosition = Vector2.zero;
if (onMaximised != null)
{
onMaximised.Invoke();
}
}
else
{ // just invoke the event for a minimised window
if (onMinimised != null)
{
onMinimised.Invoke();
}
}
}
}
}
///
/// Toggle interactivity of expander
///
/// is interactive
public void SetIsLocked(bool input)
{
isLocked = input;
parentWindow.SetAsLastSibling();
}
///
/// Set window to fill screen
///
public void MaximiseWindow()
{
if (isLocked) return;
initialPosition = parentWindow.anchoredPosition;
initialMinAnchor = parentWindow.anchorMin;
initialMaxAnchor = parentWindow.anchorMax;
initialSize = parentWindow.sizeDelta;
initialPivot = parentWindow.pivot;
parentWindow.SetPivot(Vector2.one * 0.5f);
targetPosition = Vector2.zero;
targetSize = new Vector2(Screen.width, Screen.height);
isMaximised = true;
doAction = true;
parentWindow.SetAsLastSibling();
}
///
/// Set window to small size
///
public void MinimiseWindow()
{
if (isLocked) return;
parentWindow.anchorMin = initialMinAnchor;
parentWindow.anchorMax = initialMaxAnchor;
parentWindow.sizeDelta = new Vector2(Screen.width, Screen.height);
if (initialPivot != Vector2.one * -1)
{
parentWindow.SetPivot(initialPivot);
}
targetPosition = initialPosition;
targetSize = initialSize;
isMaximised = false;
doAction = true;
parentWindow.SetAsLastSibling();
}
///
/// Do a click for attempting to expand by double click
///
public void TryDoubleClick()
{
parentWindow.SetAsLastSibling();
if (isLocked || !doubleClick) return;
numClicks++;
if (numClicks == 1)
{
Invoke("ResetDoubleClick", MaxTimeForDoubleClick);
}
else if (numClicks >= 2)
{
Invoke("Swap", 0.1f); // wait in case we're interrupting a mover
}
}
///
/// Swap between minimised and maximised
///
public void Swap()
{
if (isMaximised)
{
MinimiseWindow();
}
else
{
MaximiseWindow();
}
}
private void ResetDoubleClick()
{
numClicks = 0;
}
}
}