Skip to content

Instantly share code, notes, and snippets.

@stramit
Created July 14, 2014 09:00
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save stramit/d473dec2a6fe7dd6fb61 to your computer and use it in GitHub Desktop.
Save stramit/d473dec2a6fe7dd6fb61 to your computer and use it in GitHub Desktop.
using System;
using UnityEngine.Events;
using UnityEngine.EventSystems;
namespace UnityEngine.UI
{
/// <summary>
/// Simple toggle -- something that has an 'on' and 'off' states: checkbox, toggle button, radio button, etc.
/// </summary>
[AddComponentMenu("UI/Toggle", 35)]
[RequireComponent (typeof (RectTransform))]
public class Toggle : Selectable, IPointerClickHandler, ISubmitHandler
{
public enum ToggleTransition
{
None,
Fade
}
[Serializable]
public class ToggleEvent : UnityEvent<bool>
{}
/// <summary>
/// Transition type.
/// </summary>
public ToggleTransition toggleTransition = ToggleTransition.Fade;
/// <summary>
/// Graphic the toggle should be working with.
/// </summary>
public Graphic graphic;
// group that this toggle can belong to
[SerializeField]
private ToggleGroup m_Group;
public ToggleGroup group
{
get { return m_Group; }
set
{
m_Group = value;
#if UNITY_EDITOR
if (Application.isPlaying)
#endif
OnEnable();
}
}
/// <summary>
/// Allow for delegate-based subscriptions for faster events than 'eventReceiver', and allowing for multiple receivers.
/// </summary>
public ToggleEvent onValueChanged = new ToggleEvent();
// Whether the toggle is on
[RenamedSerializedData ("m_IsActive")]
[SerializeField]
private bool m_IsOn;
protected Toggle()
{}
#if UNITY_EDITOR
protected override void OnValidate()
{
base.OnValidate ();
PlayEffect(transition == Transition.None);
}
#endif
protected override void OnEnable()
{
base.OnEnable ();
isOn = m_IsOn;
SetToggleGroup(m_Group);
PlayEffect(true);
}
protected override void OnDisable()
{
base.OnDisable ();
isOn = m_IsOn;
}
private void SetToggleGroup(ToggleGroup newGroup)
{
if (m_Group != null)
m_Group.UnregisterToggle(this);
m_Group = newGroup;
if (m_Group != null)
m_Group.RegisterToggle(this);
// if we are in a group
if (m_Group != null && isOn)
m_Group.NotifyEnabled(this);
}
/// <summary>
/// Whether the toggle is currently active.
/// </summary>
public bool isOn
{
get { return m_IsOn; }
set
{
if (m_IsOn == value)
return;
// if we are in a group and set to true
// do group logic
m_IsOn = value;
if (m_Group != null)
{
if (m_IsOn || !m_Group.AnyTogglesActive())
{
m_IsOn = true;
m_Group.NotifyEnabled(this);
}
}
// Always send event when toggle is clicked, even if value didn't change
// due to already active toggle in a toggle group being clicked.
// Controls like SelectionList reply on this.
// It's up to the user to ignore a selection being set to the same value it already was, if desired.
PlayEffect(transition == Transition.None);
if (onValueChanged != null
#if UNITY_EDITOR
&& Application.isPlaying
#endif
)
onValueChanged.Invoke(m_IsOn);
}
}
/// <summary>
/// Play the appropriate effect.
/// </summary>
private void PlayEffect(bool instant)
{
if (graphic == null)
return;
#if UNITY_EDITOR
if (!Application.isPlaying)
graphic.canvasRenderer.SetAlpha(m_IsOn ? 1f : 0f);
else
#endif
graphic.CrossFadeAlpha(m_IsOn ? 1f : 0f, instant ? 0f : 0.1f, true);
}
/// <summary>
/// Assume the correct visual state.
/// </summary>
protected override void Start()
{
PlayEffect(true);
}
private void InternalToggle()
{
if (!IsActive() || !IsInteractable ())
return;
isOn = !isOn;
}
/// <summary>
/// React to clicks.
/// </summary>
public virtual void OnPointerClick(PointerEventData eventData)
{
InternalToggle ();
}
public void OnSubmit(BaseEventData eventData)
{
InternalToggle ();
}
}
}
@snovak
Copy link

snovak commented May 14, 2016

I love you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment