199 lines
3.7 KiB
C#
199 lines
3.7 KiB
C#
using System.Collections;
|
|
using UnityEngine;
|
|
using UnityEngine.EventSystems;
|
|
using UnityEngine.UI;
|
|
|
|
namespace UIWidgets
|
|
{
|
|
public class Switch : Selectable, ISubmitHandler, IPointerClickHandler, IEventSystemHandler
|
|
{
|
|
[SerializeField]
|
|
protected bool isOn;
|
|
|
|
[SerializeField]
|
|
protected SwitchDirection direction;
|
|
|
|
[SerializeField]
|
|
public RectTransform Mark;
|
|
|
|
[SerializeField]
|
|
public Image Background;
|
|
|
|
[SerializeField]
|
|
private Color backgroundOnColor = new Color(1f, 1f, 1f, 1f);
|
|
|
|
[SerializeField]
|
|
private Color backgroundOffColor = new Color(1f, 43f / 51f, 23f / 51f, 1f);
|
|
|
|
[SerializeField]
|
|
public float AnimationDuration = 0.3f;
|
|
|
|
[SerializeField]
|
|
public SwitchEvent OnValueChanged = new SwitchEvent();
|
|
|
|
protected Coroutine CurrentCorutine;
|
|
|
|
public bool IsOn
|
|
{
|
|
get
|
|
{
|
|
return isOn;
|
|
}
|
|
set
|
|
{
|
|
if (isOn != value)
|
|
{
|
|
isOn = value;
|
|
Changed();
|
|
}
|
|
}
|
|
}
|
|
|
|
public SwitchDirection Direction
|
|
{
|
|
get
|
|
{
|
|
return direction;
|
|
}
|
|
set
|
|
{
|
|
direction = value;
|
|
SetMarkPosition(false);
|
|
}
|
|
}
|
|
|
|
public Color BackgroundOnColor
|
|
{
|
|
get
|
|
{
|
|
return backgroundOnColor;
|
|
}
|
|
set
|
|
{
|
|
backgroundOnColor = value;
|
|
SetBackgroundColor();
|
|
}
|
|
}
|
|
|
|
public Color BackgroundOffColor
|
|
{
|
|
get
|
|
{
|
|
return backgroundOffColor;
|
|
}
|
|
set
|
|
{
|
|
backgroundOffColor = value;
|
|
SetBackgroundColor();
|
|
}
|
|
}
|
|
|
|
protected virtual void Changed()
|
|
{
|
|
SetMarkPosition();
|
|
SetBackgroundColor();
|
|
OnValueChanged.Invoke(IsOn);
|
|
}
|
|
|
|
protected virtual void SetMarkPosition(bool animate = true)
|
|
{
|
|
if (CurrentCorutine != null)
|
|
{
|
|
StopCoroutine(CurrentCorutine);
|
|
}
|
|
if (animate)
|
|
{
|
|
StartCoroutine(AnimateSwitch(IsOn, AnimationDuration));
|
|
}
|
|
else
|
|
{
|
|
SetMarkPosition(GetPosition(IsOn));
|
|
}
|
|
}
|
|
|
|
protected virtual IEnumerator AnimateSwitch(bool state, float time)
|
|
{
|
|
SetMarkPosition(GetPosition(!IsOn));
|
|
float prev_position = GetPosition(!IsOn);
|
|
float next_position = GetPosition(IsOn);
|
|
float end_time = Time.time + time;
|
|
while (Time.time <= end_time)
|
|
{
|
|
float distance = 1f - (end_time - Time.time) / time;
|
|
float pos = Mathf.Lerp(prev_position, next_position, distance);
|
|
SetMarkPosition(pos);
|
|
yield return null;
|
|
}
|
|
SetMarkPosition(GetPosition(IsOn));
|
|
}
|
|
|
|
protected virtual void SetMarkPosition(float position)
|
|
{
|
|
if (!(Mark == null))
|
|
{
|
|
if (IsHorizontal())
|
|
{
|
|
Mark.anchorMin = new Vector2(position, Mark.anchorMin.y);
|
|
Mark.anchorMax = new Vector2(position, Mark.anchorMax.y);
|
|
Mark.pivot = new Vector2(position, Mark.pivot.y);
|
|
}
|
|
else
|
|
{
|
|
Mark.anchorMin = new Vector2(Mark.anchorMin.x, position);
|
|
Mark.anchorMax = new Vector2(Mark.anchorMax.x, position);
|
|
Mark.pivot = new Vector2(Mark.pivot.x, position);
|
|
}
|
|
}
|
|
}
|
|
|
|
protected bool IsHorizontal()
|
|
{
|
|
return Direction == SwitchDirection.LeftToRight || Direction == SwitchDirection.RightToLeft;
|
|
}
|
|
|
|
protected float GetPosition(bool state)
|
|
{
|
|
switch (Direction)
|
|
{
|
|
case SwitchDirection.LeftToRight:
|
|
case SwitchDirection.BottomToTop:
|
|
return (!state) ? 0f : 1f;
|
|
case SwitchDirection.RightToLeft:
|
|
case SwitchDirection.TopToBottom:
|
|
return (!state) ? 1f : 0f;
|
|
default:
|
|
return 0f;
|
|
}
|
|
}
|
|
|
|
protected virtual void SetBackgroundColor()
|
|
{
|
|
if (!(Background == null))
|
|
{
|
|
Background.color = ((!IsOn) ? BackgroundOffColor : BackgroundOnColor);
|
|
}
|
|
}
|
|
|
|
protected virtual void CallChanged()
|
|
{
|
|
if (IsActive() && IsInteractable())
|
|
{
|
|
IsOn = !IsOn;
|
|
}
|
|
}
|
|
|
|
public virtual void OnSubmit(BaseEventData eventData)
|
|
{
|
|
CallChanged();
|
|
}
|
|
|
|
public virtual void OnPointerClick(PointerEventData eventData)
|
|
{
|
|
if (eventData.button == PointerEventData.InputButton.Left)
|
|
{
|
|
CallChanged();
|
|
}
|
|
}
|
|
}
|
|
}
|